diff options
Diffstat (limited to 'gcc/tree-ssa-pre.cc')
-rw-r--r-- | gcc/tree-ssa-pre.cc | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/gcc/tree-ssa-pre.cc b/gcc/tree-ssa-pre.cc index 64ffaca..2a7dcbe 100644 --- a/gcc/tree-ssa-pre.cc +++ b/gcc/tree-ssa-pre.cc @@ -2049,8 +2049,12 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block, bool clean_traps) the bitmap_find_leader way to see if there's still an expression for it. For some ratio of to be removed values and number of values/expressions in the set this might be faster than rebuilding - the value-set. */ - if (any_removed) + the value-set. + Note when there's a MAX solution on one edge (clean_traps) do not + prune values as we need to consider the resulting expression set MAX + as well. This avoids a later growing ANTIC_IN value-set during + iteration, when the explicitly represented expression set grows. */ + if (any_removed && !clean_traps) { bitmap_clear (&set->values); FOR_EACH_EXPR_ID_IN_SET (set, i, bi) @@ -2080,6 +2084,7 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) edge e; edge_iterator ei; + bool was_visited = BB_VISITED (block); bool changed = ! BB_VISITED (block); bool any_max_on_edge = false; @@ -2215,6 +2220,32 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) /* clean (ANTIC_IN (block)) is defered to after the iteration converged because it can cause non-convergence, see for example PR81181. */ + if (was_visited + && bitmap_and_into (&ANTIC_IN (block)->values, &old->values)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + fprintf (dump_file, "warning: intersecting with old ANTIC_IN " + "shrinks the set\n"); + /* Prune expressions not in the value set. */ + bitmap_iterator bi; + unsigned int i; + unsigned int to_clear = -1U; + FOR_EACH_EXPR_ID_IN_SET (ANTIC_IN (block), i, bi) + { + if (to_clear != -1U) + { + bitmap_clear_bit (&ANTIC_IN (block)->expressions, to_clear); + to_clear = -1U; + } + pre_expr expr = expression_for_id (i); + unsigned int value_id = get_expr_value_id (expr); + if (!bitmap_bit_p (&ANTIC_IN (block)->values, value_id)) + to_clear = i; + } + if (to_clear != -1U) + bitmap_clear_bit (&ANTIC_IN (block)->expressions, to_clear); + } + if (!bitmap_set_equal (old, ANTIC_IN (block))) changed = true; |