This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR43186
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 26 Feb 2010 16:29:05 +0100 (CET)
- Subject: [PATCH] Fix PR43186
This fixes PR43186, a case where we end up with gazillions of
nested loops which are worthwhile to completely unroll. The
issue is that we do a bad job cleaning up after the individual
unrolls and thus while our estimates on what gets optimized
away are correct we spend a lot of useless time copying to-be
optimized away statements. The fix is to try a little harder
to fold COND_EXPRs in cfgcleanup. On the way I removed the
odd gimple_fold routine which is only called from
cleanup_control_expr_graph and only with conds and switches.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
2010-02-26 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43186
* gimple.h (gimple_fold): Remove.
* gimple.c (gimple_fold): Remove. Inline into single user ...
* tree-cfgcleanup.c (cleanup_control_expr_graph): ... here.
Try harder for conditions.
* gcc.c-torture/compile/pr43186.c: New testcase.
Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h (revision 157087)
--- gcc/gimple.h (working copy)
*************** bool gimple_assign_ssa_name_copy_p (gimp
*** 841,847 ****
bool gimple_assign_single_p (gimple);
bool gimple_assign_unary_nop_p (gimple);
void gimple_set_bb (gimple, struct basic_block_def *);
- tree gimple_fold (const_gimple);
void gimple_assign_set_rhs_from_tree (gimple_stmt_iterator *, tree);
void gimple_assign_set_rhs_with_ops (gimple_stmt_iterator *, enum tree_code,
tree, tree);
--- 841,846 ----
Index: gcc/gimple.c
===================================================================
*** gcc/gimple.c (revision 157087)
--- gcc/gimple.c (working copy)
*************** gimple_set_bb (gimple stmt, basic_block
*** 1835,1888 ****
}
- /* Fold the expression computed by STMT. If the expression can be
- folded, return the folded result, otherwise return NULL. STMT is
- not modified. */
-
- tree
- gimple_fold (const_gimple stmt)
- {
- location_t loc = gimple_location (stmt);
- switch (gimple_code (stmt))
- {
- case GIMPLE_COND:
- return fold_binary_loc (loc, gimple_cond_code (stmt),
- boolean_type_node,
- gimple_cond_lhs (stmt),
- gimple_cond_rhs (stmt));
-
- case GIMPLE_ASSIGN:
- switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
- {
- case GIMPLE_UNARY_RHS:
- return fold_unary_loc (loc, gimple_assign_rhs_code (stmt),
- TREE_TYPE (gimple_assign_lhs (stmt)),
- gimple_assign_rhs1 (stmt));
- case GIMPLE_BINARY_RHS:
- return fold_binary_loc (loc, gimple_assign_rhs_code (stmt),
- TREE_TYPE (gimple_assign_lhs (stmt)),
- gimple_assign_rhs1 (stmt),
- gimple_assign_rhs2 (stmt));
- case GIMPLE_SINGLE_RHS:
- return fold (gimple_assign_rhs1 (stmt));
- default:;
- }
- break;
-
- case GIMPLE_SWITCH:
- return gimple_switch_index (stmt);
-
- case GIMPLE_CALL:
- return NULL_TREE;
-
- default:
- break;
- }
-
- gcc_unreachable ();
- }
-
-
/* Modify the RHS of the assignment pointed-to by GSI using the
operands in the expression tree EXPR.
--- 1835,1840 ----
Index: gcc/tree-cfgcleanup.c
===================================================================
*** gcc/tree-cfgcleanup.c (revision 157087)
--- gcc/tree-cfgcleanup.c (working copy)
*************** cleanup_control_expr_graph (basic_block
*** 90,98 ****
edge e;
edge_iterator ei;
bool warned;
fold_defer_overflow_warnings ();
! val = gimple_fold (stmt);
taken_edge = find_taken_edge (bb, val);
if (!taken_edge)
{
--- 90,136 ----
edge e;
edge_iterator ei;
bool warned;
+ location_t loc;
fold_defer_overflow_warnings ();
! loc = gimple_location (stmt);
! switch (gimple_code (stmt))
! {
! case GIMPLE_COND:
! {
! tree lhs = gimple_cond_lhs (stmt);
! tree rhs = gimple_cond_rhs (stmt);
! /* For conditions try harder and lookup single-argument
! PHI nodes. Only do so from the same basic-block though
! as other basic-blocks may be dead already. */
! if (TREE_CODE (lhs) == SSA_NAME)
! {
! gimple def_stmt = SSA_NAME_DEF_STMT (lhs);
! if (gimple_code (def_stmt) == GIMPLE_PHI
! && gimple_phi_num_args (def_stmt) == 1
! && gimple_bb (def_stmt) == gimple_bb (stmt))
! lhs = PHI_ARG_DEF (def_stmt, 0);
! }
! if (TREE_CODE (rhs) == SSA_NAME)
! {
! gimple def_stmt = SSA_NAME_DEF_STMT (rhs);
! if (gimple_code (def_stmt) == GIMPLE_PHI
! && gimple_phi_num_args (def_stmt) == 1
! && gimple_bb (def_stmt) == gimple_bb (stmt))
! rhs = PHI_ARG_DEF (def_stmt, 0);
! }
! val = fold_binary_loc (loc, gimple_cond_code (stmt),
! boolean_type_node, lhs, rhs);
! break;
! }
!
! case GIMPLE_SWITCH:
! val = gimple_switch_index (stmt);
! break;
!
! default:
! val = NULL_TREE;
! }
taken_edge = find_taken_edge (bb, val);
if (!taken_edge)
{
Index: gcc/testsuite/gcc.c-torture/compile/pr43186.c
===================================================================
*** gcc/testsuite/gcc.c-torture/compile/pr43186.c (revision 0)
--- gcc/testsuite/gcc.c-torture/compile/pr43186.c (revision 0)
***************
*** 0 ****
--- 1,15 ----
+ int n;
+
+ void foo (int i)
+ {
+ int a, b;
+
+ if (!i)
+ for (a = 1; a < 3; a++)
+ if (a)
+ for (b = 1; b < 3; b++)
+ foo (b);
+
+ n++;
+ }
+