diff options
author | Richard Guenther <rguenther@suse.de> | 2010-02-26 16:01:52 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2010-02-26 16:01:52 +0000 |
commit | 3753001420bcb94c509d028f41fc6f957b72e8d3 (patch) | |
tree | 5b2a9657dd7206c0286ba4768950454a5eb7b9fd /gcc/tree-cfgcleanup.c | |
parent | 095c7b3cbd4094944097b95b4a2c00d475b47ca9 (diff) | |
download | gcc-3753001420bcb94c509d028f41fc6f957b72e8d3.zip gcc-3753001420bcb94c509d028f41fc6f957b72e8d3.tar.gz gcc-3753001420bcb94c509d028f41fc6f957b72e8d3.tar.bz2 |
re PR tree-optimization/43186 (A loop in tree_unroll_loops_completely never ends)
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.
From-SVN: r157093
Diffstat (limited to 'gcc/tree-cfgcleanup.c')
-rw-r--r-- | gcc/tree-cfgcleanup.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 6810f4b..68929f8 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -90,9 +90,47 @@ cleanup_control_expr_graph (basic_block bb, gimple_stmt_iterator gsi) edge e; edge_iterator ei; bool warned; + location_t loc; fold_defer_overflow_warnings (); - val = gimple_fold (stmt); + 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) { |