public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [RFA] Factor conversion out of COND_EXPR using match.pd pattern
@ 2015-05-30  4:54 Jeff Law
  2015-05-30  9:57 ` Bernhard Reutner-Fischer
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Jeff Law @ 2015-05-30  4:54 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1541 bytes --]


I was working on polishing some of Kai's work to eliminate 
shorten_compare and stumbled on this tiny missed optimization.

Basically this change allows us to see something like this:

    n = (short unsigned int) mode_size[(unsigned int) mode] * 8 <= 64 ? 
(int) ((short unsigned int) mode_size[(unsigned int) mode] * 8) : 64;


Note the (int) cast on the true arm of the COND_EXPR.  We factor that 
out and adjust the constant (which is obviously free) into:

    n = (int)((short unsigned int) mode_size[(unsigned int) mode] * 8 <= 
64 ? ((short unsigned int) mode_size[(unsigned int) mode] * 8) : 64);


Seems subtle, but now the existing optimizers can recognize it as:

!   n = (int) MIN_EXPR <(short unsigned int) mode_size[(unsigned int) 
mode] * 8, 64>;


In another case I saw we had the same kind of transformation occur, but 
there was already a type conversation outside the MIN_EXPR.  So we ended 
up with

(T1) (T2) MIN_EXPR < ... >

And we were able to prove the conversion to T2 was redundant resulting 
in just (T) MIN_EXPR < ... >


You could legitimately ask why not apply this when both arguments are 
converted.  That leads to recursion via fold-const.c which wants to 
shove the conversion back into the arms in that case.  Removing that 
code results in testsuite regressions.  I felt it was time to cut that 
thread a bit as the real goal here is to remove the shorten_* bits in 
c-common, not convert all of fold-const.c to match.pd :-)

Bootstrapped and regression tested on x86_64-linux-gnu.  OK for the trunk?


[-- Attachment #2: patch --]
[-- Type: text/plain, Size: 2721 bytes --]

	* match.pd: Add pattern to factor type conversion out of the true/false
	arms of a COND_EXPR.

	* gcc.dg/fold-cond-2.c: New test.

diff --git a/gcc/match.pd b/gcc/match.pd
index abd7851..bf4da61 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -1182,3 +1182,41 @@ along with GCC; see the file COPYING3.  If not see
 	(convert (bit_and (op (convert:utype @0) (convert:utype @1))
 			  (convert:utype @4)))))))
 
+/* fold-const has a rich set of optimizations for expressions of the
+   form A op B ? A : B.   However, those optimizations can be easily
+   confused by typecasting, particularly in the true/false arms of the
+   conditional.
+
+   These patterns recognize cases where the typecasting can be moved
+   from the true/false arms to the final result.  This in turn allows
+   fold-const to do a better job.
+
+   Note there is no canonical ordering for the arms of the COND_EXPR,
+   so we have to match both variants. 
+
+   Handling a convert in each arm runs afoul of COND_EXPR folding in
+   fold-const.c which shoves the conversion back into each arm resulting
+   in infinite recursion.  */
+(simplify
+  (cond @0 (convert @1) INTEGER_CST@2)
+  (if (INTEGRAL_TYPE_P (TREE_TYPE (@1))
+       && COMPARISON_CLASS_P (@0)
+       && int_fits_type_p (@2, TREE_TYPE (@1))
+       && ((operand_equal_p (TREE_OPERAND (@0, 0), @2, 0)
+	    && operand_equal_p (TREE_OPERAND (@0, 1), @1, 0))
+	   || (operand_equal_p (TREE_OPERAND (@0, 0), @1, 0)
+	       && operand_equal_p (TREE_OPERAND (@0, 1), @2, 0))))
+    (with { tree itype = TREE_TYPE (@1); tree otype = TREE_TYPE (@2); }
+      (convert:otype (cond:itype @0 @1 (convert:itype @2))))))
+
+(simplify
+  (cond @0 INTEGER_CST@1 (convert @2))
+  (if (INTEGRAL_TYPE_P (TREE_TYPE (@2))
+       && COMPARISON_CLASS_P (@0)
+       && int_fits_type_p (@1, TREE_TYPE (@2))
+       && ((operand_equal_p (TREE_OPERAND (@0, 0), @2, 0)
+	    && operand_equal_p (TREE_OPERAND (@0, 1), @1, 0))
+	   || (operand_equal_p (TREE_OPERAND (@0, 0), @1, 0)
+	       && operand_equal_p (TREE_OPERAND (@0, 1), @2, 0))))
+    (with { tree itype = TREE_TYPE (@2); tree otype = TREE_TYPE (@1); }
+      (convert:otype (cond:itype @0 (convert:itype @1) @2)))))
diff --git a/gcc/testsuite/gcc.dg/fold-cond-2.c b/gcc/testsuite/gcc.dg/fold-cond-2.c
new file mode 100644
index 0000000..2039f6e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-cond-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-original" } */
+
+
+extern unsigned short mode_size[];
+int
+oof (int mode)
+{
+  return (64 < mode_size[mode] ? 64 : mode_size[mode]);
+}
+
+/* { dg-final { scan-tree-dump-times "MIN_EXPR" 1 "original" } } */
+/* { dg-final { cleanup-tree-dump "original" } } */
+

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2015-07-01 17:15 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-30  4:54 [RFA] Factor conversion out of COND_EXPR using match.pd pattern Jeff Law
2015-05-30  9:57 ` Bernhard Reutner-Fischer
2015-06-02 17:01   ` Jeff Law
2015-05-30 10:11 ` Marc Glisse
2015-06-01 10:55   ` Richard Biener
2015-06-02 17:35     ` Jeff Law
2015-06-29 17:58     ` Jeff Law
2015-06-29 22:22       ` Marc Glisse
2015-06-29 22:32         ` Andrew Pinski
2015-06-30  7:49       ` Richard Biener
2015-07-01 17:15         ` Jeff Law
2015-06-01 11:07 ` Richard Biener
2015-06-02 17:34   ` Jeff Law
2015-06-03 11:27     ` Richard Biener

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).