aboutsummaryrefslogtreecommitdiff
path: root/gcc/ifcvt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ifcvt.c')
-rw-r--r--gcc/ifcvt.c57
1 files changed, 38 insertions, 19 deletions
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index 58ee90c..c91bbbf 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -3998,6 +3998,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
basic_block other_bb, basic_block new_dest, int reversep)
{
rtx head, end, jump, earliest = NULL_RTX, old_dest, new_label = NULL_RTX;
+ bitmap merge_set = NULL, merge_set_noclobber = NULL;
/* Number of pending changes. */
int n_validated_changes = 0;
@@ -4086,6 +4087,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
earliest = jump;
}
#endif
+
/* Try the NCE path if the CE path did not result in any changes. */
if (n_validated_changes == 0)
{
@@ -4094,9 +4096,8 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
that any registers modified are dead at the branch site. */
rtx insn, cond, prev;
- bitmap merge_set, merge_set_noclobber, test_live, test_set;
- unsigned i, fail = 0;
- bitmap_iterator bi;
+ bitmap test_live, test_set;
+ bool intersect = false;
/* Check for no calls or trapping operations. */
for (insn = head; ; insn = NEXT_INSN (insn))
@@ -4138,12 +4139,7 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
merge_set = BITMAP_ALLOC (&reg_obstack);
merge_set_noclobber = BITMAP_ALLOC (&reg_obstack);
- test_live = BITMAP_ALLOC (&reg_obstack);
- test_set = BITMAP_ALLOC (&reg_obstack);
- /* ??? bb->local_set is only valid during calculate_global_regs_live,
- so we must recompute usage for MERGE_BB. Not so bad, I suppose,
- since we've already asserted that MERGE_BB is small. */
/* If we allocated new pseudos (e.g. in the conditional move
expander called from noce_emit_cmove), we must resize the
array first. */
@@ -4164,17 +4160,22 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
if (! reload_completed
&& targetm.small_register_classes_for_mode_p (VOIDmode))
{
+ unsigned i;
+ bitmap_iterator bi;
+
EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi)
{
if (i < FIRST_PSEUDO_REGISTER
&& ! fixed_regs[i]
&& ! global_regs[i])
- fail = 1;
+ goto fail;
}
}
/* For TEST, we're interested in a range of insns, not a whole block.
Moreover, we're interested in the insns live from OTHER_BB. */
+ test_live = BITMAP_ALLOC (&reg_obstack);
+ test_set = BITMAP_ALLOC (&reg_obstack);
/* The loop below takes the set of live registers
after JUMP, and calculates the live set before EARLIEST. */
@@ -4195,23 +4196,21 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
/* We can perform the transformation if
MERGE_SET_NOCLOBBER & TEST_SET
and
- MERGE_SET & TEST_LIVE)
+ MERGE_SET & TEST_LIVE
and
TEST_SET & DF_LIVE_IN (merge_bb)
are empty. */
- if (bitmap_intersect_p (test_set, merge_set_noclobber)
- || bitmap_intersect_p (test_live, merge_set)
+ if (bitmap_intersect_p (merge_set_noclobber, test_set)
+ || bitmap_intersect_p (merge_set, test_live)
|| bitmap_intersect_p (test_set, df_get_live_in (merge_bb)))
- fail = 1;
+ intersect = true;
- BITMAP_FREE (merge_set_noclobber);
- BITMAP_FREE (merge_set);
BITMAP_FREE (test_live);
BITMAP_FREE (test_set);
- if (fail)
- return FALSE;
+ if (intersect)
+ goto fail;
}
no_body:
@@ -4261,8 +4260,8 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
if (end == BB_END (merge_bb))
BB_END (merge_bb) = PREV_INSN (head);
- /* PR 21767: When moving insns above a conditional branch, REG_EQUAL
- notes might become invalid. */
+ /* PR 21767: when moving insns above a conditional branch, the REG_EQUAL
+ notes being moved might become invalid. */
insn = head;
do
{
@@ -4279,6 +4278,20 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
remove_note (insn, note);
} while (insn != end && (insn = NEXT_INSN (insn)));
+ /* PR46315: when moving insns above a conditional branch, the REG_EQUAL
+ notes referring to the registers being set might become invalid. */
+ if (merge_set)
+ {
+ unsigned i;
+ bitmap_iterator bi;
+
+ EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi)
+ remove_reg_equal_equiv_notes_for_regno (i);
+
+ BITMAP_FREE (merge_set);
+ BITMAP_FREE (merge_set_noclobber);
+ }
+
reorder_insns (head, end, PREV_INSN (earliest));
}
@@ -4295,6 +4308,12 @@ dead_or_predicable (basic_block test_bb, basic_block merge_bb,
cancel:
cancel_changes (0);
+ fail:
+ if (merge_set)
+ {
+ BITMAP_FREE (merge_set);
+ BITMAP_FREE (merge_set_noclobber);
+ }
return FALSE;
}