[PATCH] Fix PR26198, a missed-optimization with combining into COND_EXPRs
Richard Guenther
rguenther@suse.de
Fri Oct 12 08:38:00 GMT 2007
This is low-hanging fruit to get this PR finally fixed and optimize the
loop-header copy comparisons properly. We already do all the work to
tree-combine both operands of COND_EXPRs, so it's easy to also try
forwarding both. Of course we need to be careful what to propagate
here, no side-effects or memory operations are allowed (it didn't bite
us before, but with combining both operands it would - hence the new
testcase).
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to mainline.
Richard.
2007-10-11 Richard Guenther <rguenther@suse.de>
PR middle-end/26198
* tree-ssa-forwprop.c (can_propagate_from): Do not propagate from
a rhs with side-effects or which is a load.
(forward_propagate_into_cond): Also try combining both operands.
* gcc.dg/tree-ssa/forwprop-3.c: New testcase.
* gcc.c-torture/execute/20071011-1.c: Likewise.
* gcc.dg/tree-ssa/ssa-pre-9.c: Adjust.
Index: testsuite/gcc.c-torture/execute/20071011-1.c
===================================================================
*** testsuite/gcc.c-torture/execute/20071011-1.c (revision 0)
--- testsuite/gcc.c-torture/execute/20071011-1.c (revision 0)
***************
*** 0 ****
--- 1,19 ----
+ extern void abort(void);
+ void foo(int *p)
+ {
+ int x;
+ int y;
+ x = *p;
+ *p = 0;
+ y = *p;
+ if (x != y)
+ return;
+ abort ();
+ }
+
+ int main()
+ {
+ int a = 1;
+ foo(&a);
+ return 0;
+ }
Index: testsuite/gcc.dg/tree-ssa/forwprop-3.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/forwprop-3.c (revision 0)
--- testsuite/gcc.dg/tree-ssa/forwprop-3.c (revision 0)
***************
*** 0 ****
--- 1,18 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-forwprop1" } */
+
+ struct bar {
+ int a[2];
+ };
+
+ int foo(struct bar *x)
+ {
+ int *p = &x->a[0];
+ int *q = &x->a[1];
+ if (p < q)
+ return 1;
+ return 0;
+ }
+
+ /* { dg-final { scan-tree-dump "Replaced .p_. < q_.. with .1." "forwprop1" } } */
+ /* { dg-final { cleanup-tree-dump "forwprop1" } } */
Index: tree-ssa-forwprop.c
===================================================================
*** tree-ssa-forwprop.c (revision 129227)
--- tree-ssa-forwprop.c (working copy)
*************** can_propagate_from (tree def_stmt)
*** 237,242 ****
--- 237,250 ----
{
tree rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
+ /* If the rhs has side-effects we cannot propagate from it. */
+ if (TREE_SIDE_EFFECTS (rhs))
+ return false;
+
+ /* If the rhs is a load we cannot propagate from it. */
+ if (REFERENCE_CLASS_P (rhs))
+ return false;
+
/* We cannot propagate ssa names that occur in abnormal phi nodes. */
switch (TREE_CODE_LENGTH (TREE_CODE (rhs)))
{
*************** forward_propagate_into_cond (tree cond_e
*** 351,357 ****
do {
tree tmp = NULL_TREE;
tree cond = COND_EXPR_COND (cond_expr);
! tree name, def_stmt, rhs;
bool single_use_p;
/* We can do tree combining on SSA_NAME and comparison expressions. */
--- 359,365 ----
do {
tree tmp = NULL_TREE;
tree cond = COND_EXPR_COND (cond_expr);
! tree name, def_stmt, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
bool single_use_p;
/* We can do tree combining on SSA_NAME and comparison expressions. */
*************** forward_propagate_into_cond (tree cond_e
*** 366,374 ****
&& can_propagate_from (def_stmt))
{
tree op1 = TREE_OPERAND (cond, 1);
! rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
! fold_convert (TREE_TYPE (op1), rhs),
op1, !single_use_p);
}
/* If that wasn't successful, try the second operand. */
--- 374,382 ----
&& can_propagate_from (def_stmt))
{
tree op1 = TREE_OPERAND (cond, 1);
! rhs0 = GIMPLE_STMT_OPERAND (def_stmt, 1);
tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
! fold_convert (TREE_TYPE (op1), rhs0),
op1, !single_use_p);
}
/* If that wasn't successful, try the second operand. */
*************** forward_propagate_into_cond (tree cond_e
*** 382,393 ****
|| !can_propagate_from (def_stmt))
return did_something;
! rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
op0,
! fold_convert (TREE_TYPE (op0), rhs),
!single_use_p);
}
}
else if (TREE_CODE (cond) == SSA_NAME)
{
--- 390,409 ----
|| !can_propagate_from (def_stmt))
return did_something;
! rhs1 = GIMPLE_STMT_OPERAND (def_stmt, 1);
tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
op0,
! fold_convert (TREE_TYPE (op0), rhs1),
!single_use_p);
}
+ /* If that wasn't successful either, try both operands. */
+ if (tmp == NULL_TREE
+ && rhs0 != NULL_TREE
+ && rhs1 != NULL_TREE)
+ tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
+ rhs0,
+ fold_convert (TREE_TYPE (rhs0), rhs1),
+ !single_use_p);
}
else if (TREE_CODE (cond) == SSA_NAME)
{
*************** forward_propagate_into_cond (tree cond_e
*** 397,405 ****
|| !can_propagate_from (def_stmt))
return did_something;
! rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
! tmp = combine_cond_expr_cond (NE_EXPR, boolean_type_node, rhs,
! build_int_cst (TREE_TYPE (rhs), 0),
false);
}
--- 413,421 ----
|| !can_propagate_from (def_stmt))
return did_something;
! rhs0 = GIMPLE_STMT_OPERAND (def_stmt, 1);
! tmp = combine_cond_expr_cond (NE_EXPR, boolean_type_node, rhs0,
! build_int_cst (TREE_TYPE (rhs0), 0),
false);
}
Index: testsuite/gcc.dg/tree-ssa/ssa-pre-9.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/ssa-pre-9.c (revision 129227)
--- testsuite/gcc.dg/tree-ssa/ssa-pre-9.c (working copy)
*************** foo (unsigned long a)
*** 9,13 ****
return 1;
return 0;
}
! /* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "fre"} } */
/* { dg-final { cleanup-tree-dump "fre" } } */
--- 9,13 ----
return 1;
return 0;
}
! /* { dg-final { scan-tree-dump-times "return 0;" 0 "fre"} } */
/* { dg-final { cleanup-tree-dump "fre" } } */
More information about the Gcc-patches
mailing list