From 4bcc5786cca9aa729d2f3a94448dae22fd5f114b Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Mon, 10 Dec 2012 14:00:25 +0000 Subject: [PATCH] re PR tree-optimization/55107 (GCC in an infinite loop in PRE) 2012-12-10 Richard Biener PR tree-optimization/55107 * tree-ssa-pre.c (struct pre_stats): Remove constified field. (bitmap_set_replace_value): Add gcc_unreachable. (do_regular_insertion): Re-write all_same handling. Insert an assignment instead of a PHI in this case. (eliminate_bb): Record availability also for SSA names defined by a constant. (do_pre): Do not record constified events. (execute_fre): Likewise. * gcc.dg/torture/pr55107.c: New testcase. * gcc.dg/tree-ssa/ssa-pre-5.c: Adjust. From-SVN: r194358 --- gcc/ChangeLog | 12 ++++ gcc/testsuite/ChangeLog | 6 ++ gcc/testsuite/gcc.dg/torture/pr55107.c | 34 +++++++++++ gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-5.c | 3 +- gcc/tree-ssa-pre.c | 97 ++++++++++++++----------------- 5 files changed, 99 insertions(+), 53 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/torture/pr55107.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9eefc51..00c7fef 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2012-12-10 Richard Biener + + PR tree-optimization/55107 + * tree-ssa-pre.c (struct pre_stats): Remove constified field. + (bitmap_set_replace_value): Add gcc_unreachable. + (do_regular_insertion): Re-write all_same handling. Insert + an assignment instead of a PHI in this case. + (eliminate_bb): Record availability also for SSA names defined + by a constant. + (do_pre): Do not record constified events. + (execute_fre): Likewise. + 2012-12-10 Andreas Krebbel * config/spu/spu.md: Replace "operands" with "operands != NULL" in diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 60d95ae..5ada4db 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2012-12-10 Richard Biener + + PR tree-optimization/55107 + * gcc.dg/torture/pr55107.c: New testcase. + * gcc.dg/tree-ssa/ssa-pre-5.c: Adjust. + 2012-12-10 Jakub Jelinek * g++.dg/asan/asan_test.cc: Sync from upstream. diff --git a/gcc/testsuite/gcc.dg/torture/pr55107.c b/gcc/testsuite/gcc.dg/torture/pr55107.c new file mode 100644 index 0000000..2402716 --- /dev/null +++ b/gcc/testsuite/gcc.dg/torture/pr55107.c @@ -0,0 +1,34 @@ +/* { dg-do compile } */ + +typedef unsigned short uint16_t; + +uint16_t a, b; + +uint16_t f(void) +{ + int c, **p; + short d = 2, e = 4; + + for (;; b++) + { + int *j, k = 0; + + for (; *j; j++) + { + for(; c; c++) + for(; k < 1; k++) + { + short *f = &d; + + if(b) + return *f; + } + } + + if(!c) + d *= e; + + ((a = d) ? b = 0 : (**p ? : 1) != (d != 1 ? : (a = 0))) != (k ? a : 0) + < (a *= c = k) && (**p = 0); + } +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-5.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-5.c index 8756944..d0e985f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-5.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-5.c @@ -12,5 +12,6 @@ foo (int i) } /* We should detect that a+b is the same along both edges, and replace it with 5 */ -/* { dg-final { scan-tree-dump-times "Constified: 1" 1 "pre"} } */ +/* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "pre"} } */ +/* { dg-final { scan-tree-dump-times "Insertions" 0 "pre"} } */ /* { dg-final { cleanup-tree-dump "pre" } } */ diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 9cc795b..689d170 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -446,10 +446,6 @@ static struct /* The number of new PHI nodes added by PRE. */ int phis; - - /* The number of values found constant. */ - int constified; - } pre_stats; static bool do_partial_partial; @@ -867,6 +863,8 @@ bitmap_set_replace_value (bitmap_set_t set, unsigned int lookfor, return; } } + + gcc_unreachable (); } /* Return true if two bitmap sets are equal. */ @@ -3325,7 +3323,8 @@ do_regular_insertion (basic_block block, basic_block dom) FOR_EACH_VEC_ELT (exprs, i, expr) { - if (expr->kind != NAME) + if (expr->kind == NARY + || expr->kind == REFERENCE) { unsigned int val; bool by_some = false; @@ -3435,35 +3434,28 @@ do_regular_insertion (basic_block block, basic_block dom) /* If all edges produce the same value and that value is an invariant, then the PHI has the same value on all edges. Note this. */ - else if (!cant_insert && all_same && eprime - && (edoubleprime->kind == CONSTANT - || edoubleprime->kind == NAME) - && !value_id_constant_p (val)) + else if (!cant_insert && all_same) { - unsigned int j; - bitmap_iterator bi; - bitmap exprset = value_expressions[val]; - - unsigned int new_val = get_expr_value_id (edoubleprime); - EXECUTE_IF_SET_IN_BITMAP (exprset, 0, j, bi) - { - pre_expr expr = expression_for_id (j); - - if (expr->kind == NAME) - { - vn_ssa_aux_t info = VN_INFO (PRE_EXPR_NAME (expr)); - /* Just reset the value id and valnum so it is - the same as the constant we have discovered. */ - if (edoubleprime->kind == CONSTANT) - { - info->valnum = PRE_EXPR_CONSTANT (edoubleprime); - pre_stats.constified++; - } - else - info->valnum = VN_INFO (PRE_EXPR_NAME (edoubleprime))->valnum; - info->value_id = new_val; - } - } + gcc_assert (edoubleprime->kind == CONSTANT + || edoubleprime->kind == NAME); + + tree temp = make_temp_ssa_name (get_expr_type (expr), + NULL, "pretmp"); + gimple assign = gimple_build_assign (temp, + edoubleprime->kind == CONSTANT ? PRE_EXPR_CONSTANT (edoubleprime) : PRE_EXPR_NAME (edoubleprime)); + gimple_stmt_iterator gsi = gsi_after_labels (block); + gsi_insert_before (&gsi, assign, GSI_NEW_STMT); + + gimple_set_plf (assign, NECESSARY, false); + VN_INFO_GET (temp)->value_id = val; + VN_INFO (temp)->valnum = sccvn_valnum_from_value_id (val); + if (VN_INFO (temp)->valnum == NULL_TREE) + VN_INFO (temp)->valnum = temp; + bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (temp)); + pre_expr newe = get_or_alloc_expr_for_name (temp); + add_to_value (val, newe); + bitmap_value_replace_in_set (AVAIL_OUT (block), newe); + bitmap_insert_into_set (NEW_SETS (block), newe); } } } @@ -3495,7 +3487,8 @@ do_partial_partial_insertion (basic_block block, basic_block dom) FOR_EACH_VEC_ELT (exprs, i, expr) { - if (expr->kind != NAME) + if (expr->kind == NARY + || expr->kind == REFERENCE) { unsigned int val; bool by_all = true; @@ -4142,26 +4135,32 @@ eliminate_bb (dom_walk_data *, basic_block b) /* Lookup the RHS of the expression, see if we have an available computation for it. If so, replace the RHS with - the available computation. - - See PR43491. - We don't replace global register variable when it is a the RHS of - a single assign. We do replace local register variable since gcc - does not guarantee local variable will be allocated in register. */ + the available computation. */ if (gimple_has_lhs (stmt) && TREE_CODE (lhs) == SSA_NAME - && !gimple_assign_ssa_name_copy_p (stmt) - && (!gimple_assign_single_p (stmt) - || (!is_gimple_min_invariant (rhs) - && (gimple_assign_rhs_code (stmt) != VAR_DECL - || !is_global_var (rhs) - || !DECL_HARD_REGISTER (rhs)))) && !gimple_has_volatile_ops (stmt)) { tree sprime; gimple orig_stmt = stmt; sprime = eliminate_avail (lhs); + /* If there is no usable leader mark lhs as leader for its value. */ + if (!sprime) + eliminate_push_avail (lhs); + + /* See PR43491. Do not replace a global register variable when + it is a the RHS of an assignment. Do replace local register + variables since gcc does not guarantee a local variable will + be allocated in register. + Do not perform copy propagation or undo constant propagation. */ + if (gimple_assign_single_p (stmt) + && (TREE_CODE (rhs) == SSA_NAME + || is_gimple_min_invariant (rhs) + || (TREE_CODE (rhs) == VAR_DECL + && is_global_var (rhs) + && DECL_HARD_REGISTER (rhs)))) + continue; + if (!sprime) { /* If there is no existing usable leader but SCCVN thinks @@ -4208,10 +4207,6 @@ eliminate_bb (dom_walk_data *, basic_block b) continue; } - /* If there is no usable leader mark lhs as leader for its value. */ - if (!sprime) - eliminate_push_avail (lhs); - if (sprime && sprime != lhs && (rhs == NULL_TREE @@ -4742,7 +4737,6 @@ do_pre (void) statistics_counter_event (cfun, "PA inserted", pre_stats.pa_insert); statistics_counter_event (cfun, "New PHIs", pre_stats.phis); statistics_counter_event (cfun, "Eliminated", pre_stats.eliminations); - statistics_counter_event (cfun, "Constified", pre_stats.constified); clear_expression_ids (); remove_dead_inserted_code (); @@ -4823,7 +4817,6 @@ execute_fre (void) statistics_counter_event (cfun, "Insertions", pre_stats.insertions); statistics_counter_event (cfun, "Eliminated", pre_stats.eliminations); - statistics_counter_event (cfun, "Constified", pre_stats.constified); return todo; } -- 2.7.4