[PATCH][RFC] Optimize more with PAREN_EXPR
Richard Guenther
rguenther@suse.de
Thu Feb 21 10:16:00 GMT 2008
As currently in mainline only the very obviously correct optimizations
are permitted with PAREN_EXPR (removing it around other PAREN_EXPR and
around constants). There are two more important cases and one that
may matter.
One is that we want to be able to still fold the difference of
x - ((x)) to zero. Basically whenever we ask for the value of
x or ((x)) it should be the same, while still not substituting
one for the other.
To allow this this patch makes SCCVN expose a PAREN_EXPR to the
folder, thus fold x_1 - ((x_1)) instead of x_1 - x_2 (where x_2
is the value number for ((x_1))). This is pretty straight-forward.
To not need to adjust individual transformations I chose to extend
operand_equal_p to simply look through PAREN_EXPR, making it
treating x and ((x)) the same. I think this is wrong, but this
was the easiest thing to do for experimenting. Any different
opinion on that? I don't think an existing transformation will
break because of this, though.
The third thing is simply transforming ((U x)) to U ((x)) where
U is any unary operator with the simple reasoning that you cannot
associate unary expressions. This allows x + ((-x)) or similar
constructs to simplify.
I have bootstrapped and tested this change on x86_64-unknown-linux-gnu,
but will wait for comments on the second issue before committing.
Thanks,
Richard.
2008-02-19 Richard Guenther <rguenther@suse.de>
* fold-const.c (operand_equal_p): See through PAREN_EXPR.
(fold_unary): Move PAREN_EXPR around unary operations inside
around its operand.
* tree-ssa-sccvn.c (simplify_binary_expression): Make
PAREN_EXPR visible to fold.
(simplify_unary_expression): Likewise.
* gfortran.dg/reassoc_4.f90: New testcase.
* gfortran.dg/reassoc_5.f90: Likewise.
Index: trunk/gcc/fold-const.c
===================================================================
*** trunk.orig/gcc/fold-const.c 2008-02-19 16:36:49.000000000 +0100
--- trunk/gcc/fold-const.c 2008-02-19 16:52:26.000000000 +0100
*************** operand_equal_p (const_tree arg0, const_
*** 3037,3042 ****
--- 3037,3051 ----
STRIP_NOPS (arg0);
STRIP_NOPS (arg1);
+ /* ??? The following is valid only if we compare values. */
+ if (!(flags & OEP_ONLY_CONST))
+ {
+ if (TREE_CODE (arg0) == PAREN_EXPR)
+ arg0 = TREE_OPERAND (arg0, 0);
+ if (TREE_CODE (arg1) == PAREN_EXPR)
+ arg1 = TREE_OPERAND (arg1, 0);
+ }
+
/* In case both args are comparisons but with different comparison
code, try to swap the comparison operands of one arg to produce
a match and compare that variant. */
*************** fold_unary (enum tree_code code, tree ty
*** 8034,8039 ****
--- 8043,8057 ----
if (CONSTANT_CLASS_P (op0)
|| TREE_CODE (op0) == PAREN_EXPR)
return fold_convert (type, op0);
+ /* There is nothing to re-associate for an unary operation, so move
+ the re-association barrier inside. */
+ if (UNARY_CLASS_P (op0))
+ {
+ tree tem = fold_build1 (PAREN_EXPR, TREE_TYPE (TREE_OPERAND (op0, 0)),
+ TREE_OPERAND (op0, 0));
+ return fold_convert (type, fold_build1 (TREE_CODE (op0),
+ TREE_TYPE (op0), tem));
+ }
return NULL_TREE;
case NOP_EXPR:
Index: trunk/gcc/tree-ssa-sccvn.c
===================================================================
*** trunk.orig/gcc/tree-ssa-sccvn.c 2008-02-15 14:46:44.000000000 +0100
--- trunk/gcc/tree-ssa-sccvn.c 2008-02-19 17:35:46.000000000 +0100
*************** simplify_binary_expression (tree stmt, t
*** 1433,1442 ****
/* This will not catch every single case we could combine, but will
catch those with constants. The goal here is to simultaneously
combine constants between expressions, but avoid infinite
! expansion of expressions during simplification. */
if (TREE_CODE (op0) == SSA_NAME)
{
! if (VN_INFO (op0)->has_constants)
op0 = valueize_expr (VN_INFO (op0)->expr);
else if (SSA_VAL (op0) != VN_TOP && SSA_VAL (op0) != op0)
op0 = SSA_VAL (op0);
--- 1433,1446 ----
/* This will not catch every single case we could combine, but will
catch those with constants. The goal here is to simultaneously
combine constants between expressions, but avoid infinite
! expansion of expressions during simplification.
! Make sure to expand PAREN_EXPR here as that doesn't change
! its argument value and fold can do for example simplification
! of x - (x). */
if (TREE_CODE (op0) == SSA_NAME)
{
! if (VN_INFO (op0)->has_constants
! || TREE_CODE (VN_INFO (op0)->expr) == PAREN_EXPR)
op0 = valueize_expr (VN_INFO (op0)->expr);
else if (SSA_VAL (op0) != VN_TOP && SSA_VAL (op0) != op0)
op0 = SSA_VAL (op0);
*************** simplify_binary_expression (tree stmt, t
*** 1444,1450 ****
if (TREE_CODE (op1) == SSA_NAME)
{
! if (VN_INFO (op1)->has_constants)
op1 = valueize_expr (VN_INFO (op1)->expr);
else if (SSA_VAL (op1) != VN_TOP && SSA_VAL (op1) != op1)
op1 = SSA_VAL (op1);
--- 1448,1455 ----
if (TREE_CODE (op1) == SSA_NAME)
{
! if (VN_INFO (op1)->has_constants
! || TREE_CODE (VN_INFO (op1)->expr) == PAREN_EXPR)
op1 = valueize_expr (VN_INFO (op1)->expr);
else if (SSA_VAL (op1) != VN_TOP && SSA_VAL (op1) != op1)
op1 = SSA_VAL (op1);
*************** simplify_unary_expression (tree rhs)
*** 1488,1493 ****
--- 1493,1499 ----
op0 = valueize_expr (VN_INFO (op0)->expr);
else if (TREE_CODE (rhs) == NOP_EXPR
|| TREE_CODE (rhs) == CONVERT_EXPR
+ || TREE_CODE (rhs) == PAREN_EXPR
|| TREE_CODE (rhs) == REALPART_EXPR
|| TREE_CODE (rhs) == IMAGPART_EXPR)
{
Index: trunk/gcc/testsuite/gfortran.dg/reassoc_4.f90
===================================================================
*** trunk.orig/gcc/testsuite/gfortran.dg/reassoc_4.f90 (revision 0)
--- trunk/gcc/testsuite/gfortran.dg/reassoc_4.f90 (revision 0)
***************
*** 0 ****
--- 1,11 ----
+ ! { dg-do compile }
+ ! { dg-options "-O -ffinite-math-only -fdump-tree-optimized" }
+
+ function test(b, c)
+ real a, b, c
+ a = (b + c)
+ a = b + c - a
+ test = a
+ end
+
+ ! { dg-final { scan-tree-dump "return 0" "optimized" } }
Index: trunk/gcc/testsuite/gfortran.dg/reassoc_5.f90
===================================================================
*** trunk.orig/gcc/testsuite/gfortran.dg/reassoc_5.f90 (revision 0)
--- trunk/gcc/testsuite/gfortran.dg/reassoc_5.f90 (revision 0)
***************
*** 0 ****
--- 1,10 ----
+ ! { dg-do compile }
+ ! { dg-options "-O0 -ffinite-math-only -fdump-tree-original" }
+
+ function test(b, c)
+ real a, b, c
+ a = b + c - (b + c)
+ test = a
+ end
+
+ ! { dg-final { scan-tree-dump "a = 0.0" "original" } }
More information about the Fortran
mailing list