Commit e8b3f7a4 by Richard Biener Committed by Richard Biener

re PR tree-optimization/84427 (gcc ICE at -O3 on x86_64-linux-gnu in…

re PR tree-optimization/84427 (gcc ICE at -O3 on x86_64-linux-gnu in compute_antic, at tree-ssa-pre.c:2356)

2018-03-02  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/84427
	* tree-ssa-pre.c (bitmap_remove_expr_from_set): Remove.
	(bitmap_set_subtract_values): Rewrite to handle multiple
	exprs per value.
	(clean): Likewise.
	(prune_clobbered_mems): Likewise.
	(phi_translate): Take edge instead of pred/phiblock.
	(phi_translate_1): Likewise.
	(phi_translate_set): Likewise.  Insert all translated
	exprs for a value into the set, keeping possibly multiple
	expressions per value.
	(compute_antic_aux): Adjust for phi_translate changes.
	When intersecting union the expressions and prune those
	not in the final value set, keeping possibly multiple
	expressions per value.  Do not use value-insertion
	for unioning ANTIC_OUT U EXP_GEN - TMP_GEN but merge
	all expressions.  Add verification that the value-sets
	only shrink during iteration.
	(compute_partial_antic_aux): Adjust for the phi_translate changes.
	(do_pre_regular_insertion): Likewise.
	(do_pre_partial_partial_insertion): Likewise.

	* gcc.dg/torture/pr84427.c: New testcase.

From-SVN: r258124
parent 2ebb413b
2018-03-02 Richard Biener <rguenther@suse.de> 2018-03-02 Richard Biener <rguenther@suse.de>
PR tree-optimization/84427
* tree-ssa-pre.c (bitmap_remove_expr_from_set): Remove.
(bitmap_set_subtract_values): Rewrite to handle multiple
exprs per value.
(clean): Likewise.
(prune_clobbered_mems): Likewise.
(phi_translate): Take edge instead of pred/phiblock.
(phi_translate_1): Likewise.
(phi_translate_set): Likewise. Insert all translated
exprs for a value into the set, keeping possibly multiple
expressions per value.
(compute_antic_aux): Adjust for phi_translate changes.
When intersecting union the expressions and prune those
not in the final value set, keeping possibly multiple
expressions per value. Do not use value-insertion
for unioning ANTIC_OUT U EXP_GEN - TMP_GEN but merge
all expressions. Add verification that the value-sets
only shrink during iteration.
(compute_partial_antic_aux): Adjust for the phi_translate changes.
(do_pre_regular_insertion): Likewise.
(do_pre_partial_partial_insertion): Likewise.
2018-03-02 Richard Biener <rguenther@suse.de>
PR target/82005 PR target/82005
* config/darwin.c (saved_debug_info_level): New static global. * config/darwin.c (saved_debug_info_level): New static global.
(darwin_asm_lto_start): Disable debug info generation for LTO out. (darwin_asm_lto_start): Disable debug info generation for LTO out.
......
2018-03-02 Richard Biener <rguenther@suse.de>
PR tree-optimization/84427
* gcc.dg/torture/pr84427.c: New testcase.
2018-03-01 Peter Bergner <bergner@vnet.ibm.com> 2018-03-01 Peter Bergner <bergner@vnet.ibm.com>
PR target/84534 PR target/84534
......
/* { dg-do compile } */
short a, d, e;
unsigned char b;
int c, f;
char g, h;
void fn2(int, int);
void fn1() { fn2(e, a); }
void fn2(int p1, int p2)
{
l1:
b = a;
for (; h; h--)
if (p1)
g = p2 * c;
else
{
c = d;
if (f)
goto l1;
}
}
...@@ -696,16 +696,6 @@ sccvn_valnum_from_value_id (unsigned int val) ...@@ -696,16 +696,6 @@ sccvn_valnum_from_value_id (unsigned int val)
return NULL_TREE; 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. */ /* Insert an expression EXPR into a bitmapped set. */
static void static void
...@@ -805,20 +795,21 @@ bitmap_set_subtract_values (bitmap_set_t a, bitmap_set_t b) ...@@ -805,20 +795,21 @@ bitmap_set_subtract_values (bitmap_set_t a, bitmap_set_t b)
{ {
unsigned int i; unsigned int i;
bitmap_iterator bi; 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) FOR_EACH_EXPR_ID_IN_SET (a, i, bi)
{ {
if (to_remove) if (to_remove != -1U)
{ {
bitmap_remove_expr_from_set (a, to_remove); bitmap_clear_bit (&a->expressions, to_remove);
to_remove = NULL; to_remove = -1U;
} }
pre_expr expr = expression_for_id (i); pre_expr expr = expression_for_id (i);
if (bitmap_bit_p (&b->values, get_expr_value_id (expr))) if (! bitmap_bit_p (&a->values, get_expr_value_id (expr)))
to_remove = expr; to_remove = i;
} }
if (to_remove) if (to_remove != -1U)
bitmap_remove_expr_from_set (a, to_remove); bitmap_clear_bit (&a->expressions, to_remove);
} }
...@@ -1335,17 +1326,17 @@ get_representative_for (const pre_expr e, basic_block b = NULL) ...@@ -1335,17 +1326,17 @@ get_representative_for (const pre_expr e, basic_block b = NULL)
static pre_expr static pre_expr
phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e);
basic_block pred, basic_block phiblock);
/* Translate EXPR using phis in PHIBLOCK, so that it has the values of /* 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 the phis in PRED. Return NULL if we can't find a leader for each part
of the translated expression. */ of the translated expression. */
static pre_expr static pre_expr
phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e)
basic_block pred, basic_block phiblock)
{ {
basic_block pred = e->src;
basic_block phiblock = e->dest;
switch (expr->kind) switch (expr->kind)
{ {
case NARY: case NARY:
...@@ -1366,7 +1357,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1366,7 +1357,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
pre_expr leader, result; pre_expr leader, result;
unsigned int op_val_id = VN_INFO (newnary->op[i])->value_id; unsigned int op_val_id = VN_INFO (newnary->op[i])->value_id;
leader = find_leader_in_sets (op_val_id, set1, set2); 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) if (result && result != leader)
/* Force a leader as well as we are simplifying this /* Force a leader as well as we are simplifying this
expression. */ expression. */
...@@ -1397,7 +1388,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1397,7 +1388,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
to be inserted and increased register pressure. to be inserted and increased register pressure.
See PR77498 - this avoids doing predcoms work in See PR77498 - this avoids doing predcoms work in
a less efficient way. */ a less efficient way. */
if (find_edge (pred, phiblock)->flags & EDGE_DFS_BACK) if (e->flags & EDGE_DFS_BACK)
; ;
else else
{ {
...@@ -1488,7 +1479,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1488,7 +1479,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
} }
op_val_id = VN_INFO (op[n])->value_id; op_val_id = VN_INFO (op[n])->value_id;
leader = find_leader_in_sets (op_val_id, set1, set2); 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) if (opresult && opresult != leader)
{ {
tree name = get_representative_for (opresult); tree name = get_representative_for (opresult);
...@@ -1616,7 +1607,6 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1616,7 +1607,6 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
if (gimple_code (def_stmt) == GIMPLE_PHI if (gimple_code (def_stmt) == GIMPLE_PHI
&& gimple_bb (def_stmt) == phiblock) && gimple_bb (def_stmt) == phiblock)
{ {
edge e = find_edge (pred, gimple_bb (def_stmt));
tree def = PHI_ARG_DEF (def_stmt, e->dest_idx); tree def = PHI_ARG_DEF (def_stmt, e->dest_idx);
/* Handle constant. */ /* Handle constant. */
...@@ -1639,8 +1629,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1639,8 +1629,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
/* Wrapper around phi_translate_1 providing caching functionality. */ /* Wrapper around phi_translate_1 providing caching functionality. */
static pre_expr static pre_expr
phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, edge e)
basic_block pred, basic_block phiblock)
{ {
expr_pred_trans_t slot = NULL; expr_pred_trans_t slot = NULL;
pre_expr phitrans; pre_expr phitrans;
...@@ -1658,7 +1647,7 @@ phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1658,7 +1647,7 @@ phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
/* Don't add translations of NAMEs as those are cheap to translate. */ /* Don't add translations of NAMEs as those are cheap to translate. */
if (expr->kind != NAME) if (expr->kind != NAME)
{ {
if (phi_trans_add (&slot, expr, pred)) if (phi_trans_add (&slot, expr, e->src))
return slot->v; return slot->v;
/* Store NULL for the value we want to return in the case of /* Store NULL for the value we want to return in the case of
recursing. */ recursing. */
...@@ -1666,7 +1655,7 @@ phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1666,7 +1655,7 @@ phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
} }
/* Translate. */ /* Translate. */
phitrans = phi_translate_1 (expr, set1, set2, pred, phiblock); phitrans = phi_translate_1 (expr, set1, set2, e);
if (slot) if (slot)
{ {
...@@ -1687,14 +1676,13 @@ phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1687,14 +1676,13 @@ phi_translate (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
expressions in DEST. */ expressions in DEST. */
static void static void
phi_translate_set (bitmap_set_t dest, bitmap_set_t set, basic_block pred, phi_translate_set (bitmap_set_t dest, bitmap_set_t set, edge e)
basic_block phiblock)
{ {
vec<pre_expr> exprs; vec<pre_expr> exprs;
pre_expr expr; pre_expr expr;
int i; int i;
if (gimple_seq_empty_p (phi_nodes (phiblock))) if (gimple_seq_empty_p (phi_nodes (e->dest)))
{ {
bitmap_set_copy (dest, set); bitmap_set_copy (dest, set);
return; return;
...@@ -1704,18 +1692,11 @@ phi_translate_set (bitmap_set_t dest, bitmap_set_t set, basic_block pred, ...@@ -1704,18 +1692,11 @@ phi_translate_set (bitmap_set_t dest, bitmap_set_t set, basic_block pred,
FOR_EACH_VEC_ELT (exprs, i, expr) FOR_EACH_VEC_ELT (exprs, i, expr)
{ {
pre_expr translated; pre_expr translated;
translated = phi_translate (expr, set, NULL, pred, phiblock); translated = phi_translate (expr, set, NULL, e);
if (!translated) if (!translated)
continue; continue;
/* We might end up with multiple expressions from SET being bitmap_insert_into_set (dest, translated);
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);
} }
exprs.release (); exprs.release ();
} }
...@@ -1918,7 +1899,15 @@ clean (bitmap_set_t set1, bitmap_set_t set2 = NULL) ...@@ -1918,7 +1899,15 @@ clean (bitmap_set_t set1, bitmap_set_t set2 = NULL)
FOR_EACH_VEC_ELT (exprs, i, expr) FOR_EACH_VEC_ELT (exprs, i, expr)
{ {
if (!valid_in_sets (set1, set2, 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 (); exprs.release ();
} }
...@@ -1931,15 +1920,17 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block) ...@@ -1931,15 +1920,17 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block)
{ {
bitmap_iterator bi; bitmap_iterator bi;
unsigned i; unsigned i;
pre_expr to_remove = NULL; unsigned to_remove = -1U;
bool any_removed = false;
FOR_EACH_EXPR_ID_IN_SET (set, i, bi) FOR_EACH_EXPR_ID_IN_SET (set, i, bi)
{ {
/* Remove queued expr. */ /* Remove queued expr. */
if (to_remove) if (to_remove != -1U)
{ {
bitmap_remove_expr_from_set (set, to_remove); bitmap_clear_bit (&set->expressions, to_remove);
to_remove = NULL; any_removed = true;
to_remove = -1U;
} }
pre_expr expr = expression_for_id (i); pre_expr expr = expression_for_id (i);
...@@ -1955,7 +1946,7 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block) ...@@ -1955,7 +1946,7 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block)
block, gimple_bb (def_stmt))) block, gimple_bb (def_stmt)))
|| (gimple_bb (def_stmt) == block || (gimple_bb (def_stmt) == block
&& value_dies_in_block_x (expr, block)))) && value_dies_in_block_x (expr, block))))
to_remove = expr; to_remove = i;
} }
} }
else if (expr->kind == NARY) else if (expr->kind == NARY)
...@@ -1967,13 +1958,36 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block) ...@@ -1967,13 +1958,36 @@ prune_clobbered_mems (bitmap_set_t set, basic_block block)
as the available expression might be after the exit point. */ as the available expression might be after the exit point. */
if (BB_MAY_NOTRETURN (block) if (BB_MAY_NOTRETURN (block)
&& vn_nary_may_trap (nary)) && vn_nary_may_trap (nary))
to_remove = expr; to_remove = i;
} }
} }
/* Remove queued expr. */ /* Remove queued expr. */
if (to_remove) if (to_remove != -1U)
bitmap_remove_expr_from_set (set, to_remove); {
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; static sbitmap has_abnormal_preds;
...@@ -1993,11 +2007,10 @@ static bool ...@@ -1993,11 +2007,10 @@ static bool
compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
{ {
bitmap_set_t S, old, ANTIC_OUT; bitmap_set_t S, old, ANTIC_OUT;
bitmap_iterator bi;
unsigned int bii;
edge e; edge e;
edge_iterator ei; edge_iterator ei;
bool was_visited = BB_VISITED (block);
bool changed = ! BB_VISITED (block); bool changed = ! BB_VISITED (block);
BB_VISITED (block) = 1; BB_VISITED (block) = 1;
old = ANTIC_OUT = S = NULL; old = ANTIC_OUT = S = NULL;
...@@ -2017,9 +2030,9 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) ...@@ -2017,9 +2030,9 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
translate through. */ translate through. */
else if (single_succ_p (block)) else if (single_succ_p (block))
{ {
basic_block succ_bb = single_succ (block); e = single_succ_edge (block);
gcc_assert (BB_VISITED (succ_bb)); gcc_assert (BB_VISITED (e->dest));
phi_translate_set (ANTIC_OUT, ANTIC_IN (succ_bb), block, succ_bb); phi_translate_set (ANTIC_OUT, ANTIC_IN (e->dest), e);
} }
/* If we have multiple successors, we take the intersection of all of /* 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 them. Note that in the case of loop exit phi nodes, we may have
...@@ -2027,16 +2040,16 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) ...@@ -2027,16 +2040,16 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
else else
{ {
size_t i; 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) FOR_EACH_EDGE (e, ei, block->succs)
{ {
if (!first if (!first
&& BB_VISITED (e->dest)) && BB_VISITED (e->dest))
first = e->dest; first = e;
else if (BB_VISITED (e->dest)) else if (BB_VISITED (e->dest))
worklist.quick_push (e->dest); worklist.quick_push (e);
else else
{ {
/* Unvisited successors get their ANTIC_IN replaced by the /* Unvisited successors get their ANTIC_IN replaced by the
...@@ -2053,7 +2066,7 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) ...@@ -2053,7 +2066,7 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
which is guaranteed by iteration order. */ which is guaranteed by iteration order. */
gcc_assert (first != NULL); 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 /* If we have multiple successors we need to intersect the ANTIC_OUT
sets. For values that's a simple intersection but for sets. For values that's a simple intersection but for
...@@ -2062,31 +2075,29 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) ...@@ -2062,31 +2075,29 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
Avoid randomness and running into cycles like for PR82129 and Avoid randomness and running into cycles like for PR82129 and
canonicalize the expression we choose to the one with the canonicalize the expression we choose to the one with the
lowest id. This requires we actually compute the union first. */ 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 (); 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_and_into (&ANTIC_OUT->values, &tmp->values);
bitmap_ior_into (&ANTIC_OUT->expressions, &tmp->expressions); bitmap_ior_into (&ANTIC_OUT->expressions, &tmp->expressions);
bitmap_set_free (tmp); bitmap_set_free (tmp);
} }
else 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, bitmap_ior_into (&ANTIC_OUT->expressions,
&ANTIC_IN (bprime)->expressions); &ANTIC_IN (e->dest)->expressions);
} }
} }
if (! worklist.is_empty ()) if (! worklist.is_empty ())
{ {
/* Prune expressions not in the value set, canonicalizing to /* Prune expressions not in the value set. */
expression with lowest ID. */
bitmap_iterator bi; bitmap_iterator bi;
unsigned int i; unsigned int i;
unsigned int to_clear = -1U; unsigned int to_clear = -1U;
bitmap seen_value = BITMAP_ALLOC (NULL);
FOR_EACH_EXPR_ID_IN_SET (ANTIC_OUT, i, bi) FOR_EACH_EXPR_ID_IN_SET (ANTIC_OUT, i, bi)
{ {
if (to_clear != -1U) if (to_clear != -1U)
...@@ -2096,13 +2107,11 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) ...@@ -2096,13 +2107,11 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
} }
pre_expr expr = expression_for_id (i); pre_expr expr = expression_for_id (i);
unsigned int value_id = get_expr_value_id (expr); unsigned int value_id = get_expr_value_id (expr);
if (!bitmap_bit_p (&ANTIC_OUT->values, value_id) if (!bitmap_bit_p (&ANTIC_OUT->values, value_id))
|| !bitmap_set_bit (seen_value, value_id))
to_clear = i; to_clear = i;
} }
if (to_clear != -1U) if (to_clear != -1U)
bitmap_clear_bit (&ANTIC_OUT->expressions, to_clear); bitmap_clear_bit (&ANTIC_OUT->expressions, to_clear);
BITMAP_FREE (seen_value);
} }
} }
...@@ -2119,15 +2128,26 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge) ...@@ -2119,15 +2128,26 @@ compute_antic_aux (basic_block block, bool block_has_abnormal_pred_edge)
/* Then union in the ANTIC_OUT - TMP_GEN values, /* Then union in the ANTIC_OUT - TMP_GEN values,
to get ANTIC_OUT U EXP_GEN - TMP_GEN */ to get ANTIC_OUT U EXP_GEN - TMP_GEN */
FOR_EACH_EXPR_ID_IN_SET (S, bii, bi) bitmap_ior_into (&ANTIC_IN (block)->values, &S->values);
bitmap_value_insert_into_set (ANTIC_IN (block), bitmap_ior_into (&ANTIC_IN (block)->expressions, &S->expressions);
expression_for_id (bii));
/* clean (ANTIC_IN (block)) is defered to after the iteration converged /* clean (ANTIC_IN (block)) is defered to after the iteration converged
because it can cause non-convergence, see for example PR81181. */ because it can cause non-convergence, see for example PR81181. */
if (!bitmap_set_equal (old, ANTIC_IN (block))) 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: maybe_dump_sets:
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
...@@ -2202,45 +2222,44 @@ compute_partial_antic_aux (basic_block block, ...@@ -2202,45 +2222,44 @@ compute_partial_antic_aux (basic_block block,
VH.1 + 1 (VH.2), VH.2 + 1 (VH.3), etc), forever. */ VH.1 + 1 (VH.2), VH.2 + 1 (VH.3), etc), forever. */
else if (single_succ_p (block)) else if (single_succ_p (block))
{ {
basic_block succ = single_succ (block); e = single_succ_edge (block);
if (!(single_succ_edge (block)->flags & EDGE_DFS_BACK)) if (!(e->flags & EDGE_DFS_BACK))
phi_translate_set (PA_OUT, PA_IN (succ), block, succ); phi_translate_set (PA_OUT, PA_IN (e->dest), e);
} }
/* If we have multiple successors, we take the union of all of /* If we have multiple successors, we take the union of all of
them. */ them. */
else else
{ {
size_t i; 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) FOR_EACH_EDGE (e, ei, block->succs)
{ {
if (e->flags & EDGE_DFS_BACK) if (e->flags & EDGE_DFS_BACK)
continue; continue;
worklist.quick_push (e->dest); worklist.quick_push (e);
} }
if (worklist.length () > 0) if (worklist.length () > 0)
{ {
FOR_EACH_VEC_ELT (worklist, i, bprime) FOR_EACH_VEC_ELT (worklist, i, e)
{ {
unsigned int i; unsigned int i;
bitmap_iterator bi; 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, bitmap_value_insert_into_set (PA_OUT,
expression_for_id (i)); 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 (); 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) FOR_EACH_EXPR_ID_IN_SET (pa_in, i, bi)
bitmap_value_insert_into_set (PA_OUT, bitmap_value_insert_into_set (PA_OUT,
expression_for_id (i)); expression_for_id (i));
bitmap_set_free (pa_in); bitmap_set_free (pa_in);
} }
else 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, bitmap_value_insert_into_set (PA_OUT,
expression_for_id (i)); expression_for_id (i));
} }
...@@ -3158,8 +3177,7 @@ do_pre_regular_insertion (basic_block block, basic_block dom) ...@@ -3158,8 +3177,7 @@ do_pre_regular_insertion (basic_block block, basic_block dom)
gcc_assert (!(pred->flags & EDGE_FAKE)); gcc_assert (!(pred->flags & EDGE_FAKE));
bprime = pred->src; bprime = pred->src;
/* We are looking at ANTIC_OUT of bprime. */ /* We are looking at ANTIC_OUT of bprime. */
eprime = phi_translate (expr, ANTIC_IN (block), NULL, eprime = phi_translate (expr, ANTIC_IN (block), NULL, pred);
bprime, block);
/* eprime will generally only be NULL if the /* eprime will generally only be NULL if the
value of the expression, translated value of the expression, translated
...@@ -3315,8 +3333,7 @@ do_pre_partial_partial_insertion (basic_block block, basic_block dom) ...@@ -3315,8 +3333,7 @@ do_pre_partial_partial_insertion (basic_block block, basic_block dom)
gcc_assert (!(pred->flags & EDGE_FAKE)); gcc_assert (!(pred->flags & EDGE_FAKE));
bprime = pred->src; bprime = pred->src;
eprime = phi_translate (expr, ANTIC_IN (block), eprime = phi_translate (expr, ANTIC_IN (block),
PA_IN (block), PA_IN (block), pred);
bprime, block);
/* eprime will generally only be NULL if the /* eprime will generally only be NULL if the
value of the expression, translated value of the expression, translated
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment