return NULL_TREE;
}
-/* Remove an expression EXPR from a bitmapped set. */
-
-static void
-bitmap_remove_expr_from_set (bitmap_set_t set, pre_expr expr)
-{
- unsigned int val = get_expr_value_id (expr);
- bitmap_clear_bit (&set->values, val);
- bitmap_clear_bit (&set->expressions, get_expression_id (expr));
-}
-
/* Insert an expression EXPR into a bitmapped set. */
static void
{
unsigned int i;
bitmap_iterator bi;
- pre_expr to_remove = NULL;
+ unsigned to_remove = -1U;
+ bitmap_and_compl_into (&a->values, &b->values);
FOR_EACH_EXPR_ID_IN_SET (a, i, bi)
{
- if (to_remove)
+ if (to_remove != -1U)
{
- bitmap_remove_expr_from_set (a, to_remove);
- to_remove = NULL;
+ bitmap_clear_bit (&a->expressions, to_remove);
+ to_remove = -1U;
}
pre_expr expr = expression_for_id (i);
- if (bitmap_bit_p (&b->values, get_expr_value_id (expr)))
- to_remove = expr;
+ if (! bitmap_bit_p (&a->values, get_expr_value_id (expr)))
+ to_remove = i;
}
- if (to_remove)
- bitmap_remove_expr_from_set (a, to_remove);
+ if (to_remove != -1U)
+ bitmap_clear_bit (&a->expressions, to_remove);
}
static pre_expr
-phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
- basic_block pred, basic_block phiblock);
+phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e);
/* Translate EXPR using phis in PHIBLOCK, so that it has the values of
the phis in PRED. Return NULL if we can't find a leader for each part
of the translated expression. */
static pre_expr
-phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
- basic_block pred, basic_block phiblock)
+phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e)
{
+ basic_block pred = e->src;
+ basic_block phiblock = e->dest;
switch (expr->kind)
{
case NARY:
pre_expr leader, result;
unsigned int op_val_id = VN_INFO (newnary->op[i])->value_id;
leader = find_leader_in_sets (op_val_id, set1, set2);
- result = phi_translate (leader, set1, set2, pred, phiblock);
+ result = phi_translate (leader, set1, set2, e);
if (result && result != leader)
/* Force a leader as well as we are simplifying this
expression. */
to be inserted and increased register pressure.
See PR77498 - this avoids doing predcoms work in
a less efficient way. */
- if (find_edge (pred, phiblock)->flags & EDGE_DFS_BACK)
+ if (e->flags & EDGE_DFS_BACK)
;
else
{
}
op_val_id = VN_INFO (op[n])->value_id;
leader = find_leader_in_sets (op_val_id, set1, set2);
- opresult = phi_translate (leader, set1, set2, pred, phiblock);
+ opresult = phi_translate (leader, set1, set2, e);
if (opresult && opresult != leader)
{
tree name = get_representative_for (opresult);
if (gimple_code (def_stmt) == GIMPLE_PHI
&& gimple_bb (def_stmt) == phiblock)
{
- edge e = find_edge (pred, gimple_bb (def_stmt));
tree def = PHI_ARG_DEF (def_stmt, e->dest_idx);
/* Handle constant. */
/* Wrapper around phi_translate_1 providing caching functionality. */
static pre_expr
-phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
- basic_block pred, basic_block phiblock)
+phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e)
{
expr_pred_trans_t slot = NULL;
pre_expr phitrans;
/* Don't add translations of NAMEs as those are cheap to translate. */
if (expr->kind != NAME)
{
- if (phi_trans_add (&slot, expr, pred))
+ if (phi_trans_add (&slot, expr, e->src))
return slot->v;
/* Store NULL for the value we want to return in the case of
recursing. */
}
/* Translate. */
- phitrans = phi_translate_1 (expr, set1, set2, pred, phiblock);
+ phitrans = phi_translate_1 (expr, set1, set2, e);
if (slot)
{
expressions in DEST. */
static void
-phi_translate_set (bitmap_set_t dest, bitmap_set_t set, basic_block pred,
- basic_block phiblock)
+phi_translate_set (bitmap_set_t dest, bitmap_set_t set, edge e)
{
vec<pre_expr> exprs;
pre_expr expr;
int i;
- if (gimple_seq_empty_p (phi_nodes (phiblock)))
+ if (gimple_seq_empty_p (phi_nodes (e->dest)))
{
bitmap_set_copy (dest, set);
return;
FOR_EACH_VEC_ELT (exprs, i, expr)
{
pre_expr translated;
- translated = phi_translate (expr, set, NULL, pred, phiblock);
+ translated = phi_translate (expr, set, NULL, e);
if (!translated)
continue;
- /* We might end up with multiple expressions from SET being
- translated to the same value. In this case we do not want
- to retain the NARY or REFERENCE expression but prefer a NAME
- which would be the leader. */
- if (translated->kind == NAME)
- bitmap_value_replace_in_set (dest, translated);
- else
- bitmap_value_insert_into_set (dest, translated);
+ bitmap_insert_into_set (dest, translated);
}
exprs.release ();
}
FOR_EACH_VEC_ELT (exprs, i, expr)
{
if (!valid_in_sets (set1, set2, expr))
- bitmap_remove_expr_from_set (set1, expr);
+ {
+ unsigned int val = get_expr_value_id (expr);
+ bitmap_clear_bit (&set1->expressions, get_expression_id (expr));
+ /* We are entered with possibly multiple expressions for a value
+ so before removing a value from the set see if there's an
+ expression for it left. */
+ if (! bitmap_find_leader (set1, val))
+ bitmap_clear_bit (&set1->values, val);
+ }
}
exprs.release ();
}
{
bitmap_iterator bi;
unsigned i;
- pre_expr to_remove = NULL;
+ unsigned to_remove = -1U;
+ bool any_removed = false;
FOR_EACH_EXPR_ID_IN_SET (set, i, bi)
{
/* Remove queued expr. */
- if (to_remove)
+ if (to_remove != -1U)
{
- bitmap_remove_expr_from_set (set, to_remove);
- to_remove = NULL;
+ bitmap_clear_bit (&set->expressions, to_remove);
+ any_removed = true;
+ to_remove = -1U;
}
pre_expr expr = expression_for_id (i);
block, gimple_bb (def_stmt)))
|| (gimple_bb (def_stmt) == block
&& value_dies_in_block_x (expr, block))))
- to_remove = expr;
+ to_remove = i;
}
}
else if (expr->kind == NARY)
as the available expression might be after the exit point. */
if (BB_MAY_NOTRETURN (block)
&& vn_nary_may_trap (nary))
- to_remove = expr;
+ to_remove = i;
}
}
/* Remove queued expr. */
- if (to_remove)
- bitmap_remove_expr_from_set (set, to_remove);
+ if (to_remove != -1U)
+ {
+ bitmap_clear_bit (&set->expressions, to_remove);
+ any_removed = true;
+ }
+
+ /* Above we only removed expressions, now clean the set of values
+ which no longer have any corresponding expression. We cannot
+ clear the value at the time we remove an expression since there
+ may be multiple expressions per value.
+ If we'd queue possibly to be removed values we could use
+ 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)
+ {
+ bitmap_clear (&set->values);
+ FOR_EACH_EXPR_ID_IN_SET (set, i, bi)
+ {
+ pre_expr expr = expression_for_id (i);
+ unsigned int value_id = get_expr_value_id (expr);
+ bitmap_set_bit (&set->values, value_id);
+ }
+ }
}
static sbitmap has_abnormal_preds;
compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
{
bitmap_set_t S, old, ANTIC_OUT;
- bitmap_iterator bi;
- unsigned int bii;
edge e;
edge_iterator ei;
+ bool was_visited = BB_VISITED (block);
bool changed = ! BB_VISITED (block);
BB_VISITED (block) = 1;
old = ANTIC_OUT = S = NULL;
translate through. */
else if (single_succ_p (block))
{
- basic_block succ_bb = single_succ (block);
- gcc_assert (BB_VISITED (succ_bb));
- phi_translate_set (ANTIC_OUT, ANTIC_IN (succ_bb), block, succ_bb);
+ e = single_succ_edge (block);
+ gcc_assert (BB_VISITED (e->dest));
+ phi_translate_set (ANTIC_OUT, ANTIC_IN (e->dest), e);
}
/* If we have multiple successors, we take the intersection of all of
them. Note that in the case of loop exit phi nodes, we may have
else
{
size_t i;
- basic_block bprime, first = NULL;
+ edge first = NULL;
- auto_vec<basic_block> worklist (EDGE_COUNT (block->succs));
+ auto_vec<edge> worklist (EDGE_COUNT (block->succs));
FOR_EACH_EDGE (e, ei, block->succs)
{
if (!first
&& BB_VISITED (e->dest))
- first = e->dest;
+ first = e;
else if (BB_VISITED (e->dest))
- worklist.quick_push (e->dest);
+ worklist.quick_push (e);
else
{
/* Unvisited successors get their ANTIC_IN replaced by the
which is guaranteed by iteration order. */
gcc_assert (first != NULL);
- phi_translate_set (ANTIC_OUT, ANTIC_IN (first), block, first);
+ phi_translate_set (ANTIC_OUT, ANTIC_IN (first->dest), first);
/* If we have multiple successors we need to intersect the ANTIC_OUT
sets. For values that's a simple intersection but for
Avoid randomness and running into cycles like for PR82129 and
canonicalize the expression we choose to the one with the
lowest id. This requires we actually compute the union first. */
- FOR_EACH_VEC_ELT (worklist, i, bprime)
+ FOR_EACH_VEC_ELT (worklist, i, e)
{
- if (!gimple_seq_empty_p (phi_nodes (bprime)))
+ if (!gimple_seq_empty_p (phi_nodes (e->dest)))
{
bitmap_set_t tmp = bitmap_set_new ();
- phi_translate_set (tmp, ANTIC_IN (bprime), block, bprime);
+ phi_translate_set (tmp, ANTIC_IN (e->dest), e);
bitmap_and_into (&ANTIC_OUT->values, &tmp->values);
bitmap_ior_into (&ANTIC_OUT->expressions, &tmp->expressions);
bitmap_set_free (tmp);
}
else
{
- bitmap_and_into (&ANTIC_OUT->values, &ANTIC_IN (bprime)->values);
+ bitmap_and_into (&ANTIC_OUT->values, &ANTIC_IN (e->dest)->values);
bitmap_ior_into (&ANTIC_OUT->expressions,
- &ANTIC_IN (bprime)->expressions);
+ &ANTIC_IN (e->dest)->expressions);
}
}
if (! worklist.is_empty ())
{
- /* Prune expressions not in the value set, canonicalizing to
- expression with lowest ID. */
+ /* Prune expressions not in the value set. */
bitmap_iterator bi;
unsigned int i;
unsigned int to_clear = -1U;
- bitmap seen_value = BITMAP_ALLOC (NULL);
FOR_EACH_EXPR_ID_IN_SET (ANTIC_OUT, i, bi)
{
if (to_clear != -1U)
}
pre_expr expr = expression_for_id (i);
unsigned int value_id = get_expr_value_id (expr);
- if (!bitmap_bit_p (&ANTIC_OUT->values, value_id)
- || !bitmap_set_bit (seen_value, value_id))
+ if (!bitmap_bit_p (&ANTIC_OUT->values, value_id))
to_clear = i;
}
if (to_clear != -1U)
bitmap_clear_bit (&ANTIC_OUT->expressions, to_clear);
- BITMAP_FREE (seen_value);
}
}
/* Then union in the ANTIC_OUT - TMP_GEN values,
to get ANTIC_OUT U EXP_GEN - TMP_GEN */
- FOR_EACH_EXPR_ID_IN_SET (S, bii, bi)
- bitmap_value_insert_into_set (ANTIC_IN (block),
- expression_for_id (bii));
+ bitmap_ior_into (&ANTIC_IN (block)->values, &S->values);
+ bitmap_ior_into (&ANTIC_IN (block)->expressions, &S->expressions);
/* clean (ANTIC_IN (block)) is defered to after the iteration converged
because it can cause non-convergence, see for example PR81181. */
if (!bitmap_set_equal (old, ANTIC_IN (block)))
- changed = true;
+ {
+ changed = true;
+ /* After the initial value set computation the value set may
+ only shrink during the iteration. */
+ if (was_visited && flag_checking)
+ {
+ bitmap_iterator bi;
+ unsigned int i;
+ EXECUTE_IF_AND_COMPL_IN_BITMAP (&ANTIC_IN (block)->values,
+ &old->values, 0, i, bi)
+ gcc_unreachable ();
+ }
+ }
maybe_dump_sets:
if (dump_file && (dump_flags & TDF_DETAILS))
VH.1 + 1 (VH.2), VH.2 + 1 (VH.3), etc), forever. */
else if (single_succ_p (block))
{
- basic_block succ = single_succ (block);
- if (!(single_succ_edge (block)->flags & EDGE_DFS_BACK))
- phi_translate_set (PA_OUT, PA_IN (succ), block, succ);
+ e = single_succ_edge (block);
+ if (!(e->flags & EDGE_DFS_BACK))
+ phi_translate_set (PA_OUT, PA_IN (e->dest), e);
}
/* If we have multiple successors, we take the union of all of
them. */
else
{
size_t i;
- basic_block bprime;
- auto_vec<basic_block> worklist (EDGE_COUNT (block->succs));
+ auto_vec<edge> worklist (EDGE_COUNT (block->succs));
FOR_EACH_EDGE (e, ei, block->succs)
{
if (e->flags & EDGE_DFS_BACK)
continue;
- worklist.quick_push (e->dest);
+ worklist.quick_push (e);
}
if (worklist.length () > 0)
{
- FOR_EACH_VEC_ELT (worklist, i, bprime)
+ FOR_EACH_VEC_ELT (worklist, i, e)
{
unsigned int i;
bitmap_iterator bi;
- FOR_EACH_EXPR_ID_IN_SET (ANTIC_IN (bprime), i, bi)
+ FOR_EACH_EXPR_ID_IN_SET (ANTIC_IN (e->dest), i, bi)
bitmap_value_insert_into_set (PA_OUT,
expression_for_id (i));
- if (!gimple_seq_empty_p (phi_nodes (bprime)))
+ if (!gimple_seq_empty_p (phi_nodes (e->dest)))
{
bitmap_set_t pa_in = bitmap_set_new ();
- phi_translate_set (pa_in, PA_IN (bprime), block, bprime);
+ phi_translate_set (pa_in, PA_IN (e->dest), e);
FOR_EACH_EXPR_ID_IN_SET (pa_in, i, bi)
bitmap_value_insert_into_set (PA_OUT,
expression_for_id (i));
bitmap_set_free (pa_in);
}
else
- FOR_EACH_EXPR_ID_IN_SET (PA_IN (bprime), i, bi)
+ FOR_EACH_EXPR_ID_IN_SET (PA_IN (e->dest), i, bi)
bitmap_value_insert_into_set (PA_OUT,
expression_for_id (i));
}
gcc_assert (!(pred->flags & EDGE_FAKE));
bprime = pred->src;
/* We are looking at ANTIC_OUT of bprime. */
- eprime = phi_translate (expr, ANTIC_IN (block), NULL,
- bprime, block);
+ eprime = phi_translate (expr, ANTIC_IN (block), NULL, pred);
/* eprime will generally only be NULL if the
value of the expression, translated
gcc_assert (!(pred->flags & EDGE_FAKE));
bprime = pred->src;
eprime = phi_translate (expr, ANTIC_IN (block),
- PA_IN (block),
- bprime, block);
+ PA_IN (block), pred);
/* eprime will generally only be NULL if the
value of the expression, translated