diff options
Diffstat (limited to 'gcc/tree-ssa-pre.c')
-rw-r--r-- | gcc/tree-ssa-pre.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index c6aa5879739..f8f03807ef0 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -2090,7 +2090,8 @@ static sbitmap has_abnormal_preds; ANTIC_OUT[BLOCK] = phi_translate (ANTIC_IN[succ(BLOCK)]) ANTIC_IN[BLOCK] = clean(ANTIC_OUT[BLOCK] U EXP_GEN[BLOCK] - TMP_GEN[BLOCK]) -*/ + + Note that clean() is deferred until after the iteration. */ static bool compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) @@ -2190,7 +2191,8 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) bitmap_value_insert_into_set (ANTIC_IN (block), expression_for_id (bii)); - clean (ANTIC_IN (block)); + /* 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_set_equal (old, ANTIC_IN (block))) changed = true; @@ -2424,6 +2426,12 @@ compute_antic (void) gcc_checking_assert (num_iterations < 500); } + /* We have to clean after the dataflow problem converged as cleaning + can cause non-convergence because it is based on expressions + rather than values. */ + FOR_EACH_BB_FN (block, cfun) + clean (ANTIC_IN (block)); + statistics_histogram_event (cfun, "compute_antic iterations", num_iterations); |