aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-pre.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-pre.c')
-rw-r--r--gcc/tree-ssa-pre.c51
1 files changed, 30 insertions, 21 deletions
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 0ec3d3c7f7e..a6a68cf8372 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -540,8 +540,6 @@ static void bitmap_set_copy (bitmap_set_t, bitmap_set_t);
static void bitmap_set_and (bitmap_set_t, bitmap_set_t);
static bool bitmap_set_contains_value (bitmap_set_t, unsigned int);
static void bitmap_insert_into_set (bitmap_set_t, pre_expr);
-static void bitmap_insert_into_set_1 (bitmap_set_t, pre_expr,
- unsigned int, bool);
static bitmap_set_t bitmap_set_new (void);
static tree create_expression_by_pieces (basic_block, pre_expr, gimple_seq *,
tree);
@@ -732,27 +730,22 @@ bitmap_remove_from_set (bitmap_set_t set, pre_expr expr)
}
}
+/* Insert an expression EXPR into a bitmapped set. */
+
static void
-bitmap_insert_into_set_1 (bitmap_set_t set, pre_expr expr,
- unsigned int val, bool allow_constants)
+bitmap_insert_into_set (bitmap_set_t set, pre_expr expr)
{
- if (allow_constants || !value_id_constant_p (val))
+ unsigned int val = get_expr_value_id (expr);
+ if (! value_id_constant_p (val))
{
- /* We specifically expect this and only this function to be able to
- insert constants into a set. */
+ /* Note this is the only function causing multiple expressions
+ for the same value to appear in a set. This is needed for
+ TMP_GEN, PHI_GEN and NEW_SETs. */
bitmap_set_bit (&set->values, val);
bitmap_set_bit (&set->expressions, get_or_alloc_expression_id (expr));
}
}
-/* Insert an expression EXPR into a bitmapped set. */
-
-static void
-bitmap_insert_into_set (bitmap_set_t set, pre_expr expr)
-{
- bitmap_insert_into_set_1 (set, expr, get_expr_value_id (expr), false);
-}
-
/* Copy a bitmapped set ORIG, into bitmapped set DEST. */
static void
@@ -837,7 +830,7 @@ bitmap_set_and (bitmap_set_t dest, bitmap_set_t orig)
}
}
-/* Subtract all values and expressions contained in ORIG from DEST. */
+/* Subtract all expressions contained in ORIG from DEST. */
static bitmap_set_t
bitmap_set_subtract (bitmap_set_t dest, bitmap_set_t orig)
@@ -859,7 +852,7 @@ bitmap_set_subtract (bitmap_set_t dest, bitmap_set_t orig)
return result;
}
-/* Subtract all the values in bitmap set B from bitmap set A. */
+/* Subtract all values in bitmap set B from bitmap set A. */
static void
bitmap_set_subtract_values (bitmap_set_t a, bitmap_set_t b)
@@ -987,6 +980,11 @@ bitmap_value_insert_into_set (bitmap_set_t set, pre_expr expr)
static void
print_pre_expr (FILE *outfile, const pre_expr expr)
{
+ if (! expr)
+ {
+ fprintf (outfile, "NULL");
+ return;
+ }
switch (expr->kind)
{
case CONSTANT:
@@ -2115,7 +2113,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)
@@ -2215,7 +2214,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;
@@ -2418,7 +2418,9 @@ compute_antic (void)
inverted_post_order_compute (&postorder);
auto_sbitmap worklist (last_basic_block_for_fn (cfun) + 1);
- bitmap_ones (worklist);
+ bitmap_clear (worklist);
+ FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
+ bitmap_set_bit (worklist, e->src->index);
while (changed)
{
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -2449,6 +2451,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);
@@ -2456,7 +2464,8 @@ compute_antic (void)
{
/* For partial antic we ignore backedges and thus we do not need
to perform any iteration when we process blocks in postorder. */
- int postorder_num = pre_and_rev_post_order_compute (NULL, postorder.address (), false);
+ int postorder_num
+ = pre_and_rev_post_order_compute (NULL, postorder.address (), false);
for (i = postorder_num - 1 ; i >= 0; i--)
{
basic_block block = BASIC_BLOCK_FOR_FN (cfun, postorder[i]);