+2010-04-22 Bernd Schmidt <bernds@codesourcery.com>
+
+ * ifcvt.c (dead_or_predicable): Use df_simulate_find_defs and
+ df_simulate_find_noclobber_defs as appropriate. Keep track of an
+ extra set merge_set_noclobber, and use it to relax the final test
+ slightly.
+ * df.h (df_simulate_find_noclobber_defs): Declare.
+ * df-problems.c (df_simulate_find_defs): Don't ignore partial or
+ conditional defs.
+ (df_simulate_find_noclobber_defs): New function.
+
2010-04-22 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md: Use {} around multi-line preparation statements.
for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
{
df_ref def = *def_rec;
- /* If the def is to only part of the reg, it does
- not kill the other defs that reach here. */
- if (!(DF_REF_FLAGS (def) & (DF_REF_PARTIAL | DF_REF_CONDITIONAL)))
+ bitmap_set_bit (defs, DF_REF_REGNO (def));
+ }
+}
+
+/* Find the set of real DEFs, which are not clobbers, for INSN. */
+
+void
+df_simulate_find_noclobber_defs (rtx insn, bitmap defs)
+{
+ df_ref *def_rec;
+ unsigned int uid = INSN_UID (insn);
+
+ for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
+ {
+ df_ref def = *def_rec;
+ if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
bitmap_set_bit (defs, DF_REF_REGNO (def));
}
}
while here the scan is performed forwards! So, first assume that the
def is live, and if this is not true REG_UNUSED notes will rectify the
situation. */
- df_simulate_find_defs (insn, live);
+ df_simulate_find_noclobber_defs (insn, live);
/* Clear all of the registers that go dead. */
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
extern void df_md_add_problem (void);
extern void df_md_simulate_artificial_defs_at_top (basic_block, bitmap);
extern void df_md_simulate_one_insn (basic_block, rtx, bitmap);
+extern void df_simulate_find_noclobber_defs (rtx, bitmap);
extern void df_simulate_find_defs (rtx, bitmap);
extern void df_simulate_defs (rtx, bitmap);
extern void df_simulate_uses (rtx, bitmap);
that any registers modified are dead at the branch site. */
rtx insn, cond, prev;
- bitmap merge_set, test_live, test_set;
+ bitmap merge_set, merge_set_noclobber, test_live, test_set;
unsigned i, fail = 0;
bitmap_iterator bi;
/* Collect:
MERGE_SET = set of registers set in MERGE_BB
+ MERGE_SET_NOCLOBBER = like MERGE_SET, but only includes registers
+ that are really set, not just clobbered.
TEST_LIVE = set of registers live at EARLIEST
- TEST_SET = set of registers set between EARLIEST and the
- end of the block. */
+ TEST_SET = set of registers set between EARLIEST and the
+ end of the block. */
merge_set = BITMAP_ALLOC (®_obstack);
+ merge_set_noclobber = BITMAP_ALLOC (®_obstack);
test_live = BITMAP_ALLOC (®_obstack);
test_set = BITMAP_ALLOC (®_obstack);
{
if (NONDEBUG_INSN_P (insn))
{
- unsigned int uid = INSN_UID (insn);
- df_ref *def_rec;
- for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
- {
- df_ref def = *def_rec;
- bitmap_set_bit (merge_set, DF_REF_REGNO (def));
- }
+ df_simulate_find_defs (insn, merge_set);
+ df_simulate_find_noclobber_defs (insn, merge_set_noclobber);
}
}
hard registers before reload. */
if (SMALL_REGISTER_CLASSES && ! reload_completed)
{
- EXECUTE_IF_SET_IN_BITMAP (merge_set, 0, i, bi)
+ EXECUTE_IF_SET_IN_BITMAP (merge_set_noclobber, 0, i, bi)
{
if (i < FIRST_PSEUDO_REGISTER
&& ! fixed_regs[i]
{
if (INSN_P (insn))
{
- df_simulate_find_defs (insn, test_set);
+ df_simulate_find_noclobber_defs (insn, test_set);
df_simulate_one_insn_backwards (test_bb, insn, test_live);
}
prev = PREV_INSN (insn);
}
/* We can perform the transformation if
- MERGE_SET & (TEST_SET | TEST_LIVE)
+ MERGE_SET_NOCLOBBER & TEST_SET
+ and
+ MERGE_SET & TEST_LIVE)
and
TEST_SET & DF_LIVE_IN (merge_bb)
are empty. */
- if (bitmap_intersect_p (test_set, merge_set)
+ if (bitmap_intersect_p (test_set, merge_set_noclobber)
|| bitmap_intersect_p (test_live, merge_set)
|| bitmap_intersect_p (test_set, df_get_live_in (merge_bb)))
fail = 1;
+ BITMAP_FREE (merge_set_noclobber);
BITMAP_FREE (merge_set);
BITMAP_FREE (test_live);
BITMAP_FREE (test_set);