* 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. Index: ifcvt.c =================================================================== --- ifcvt.c (revision 158513) +++ ifcvt.c (working copy) @@ -3990,7 +3990,7 @@ dead_or_predicable (basic_block test_bb, 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; @@ -4026,11 +4026,14 @@ dead_or_predicable (basic_block test_bb, /* 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); @@ -4047,13 +4050,8 @@ dead_or_predicable (basic_block test_bb, { 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); } } @@ -4061,7 +4059,7 @@ dead_or_predicable (basic_block test_bb, 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] @@ -4081,7 +4079,7 @@ dead_or_predicable (basic_block test_bb, { 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); @@ -4090,16 +4088,19 @@ dead_or_predicable (basic_block test_bb, } /* 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); Index: df.h =================================================================== --- df.h (revision 158513) +++ df.h (working copy) @@ -978,6 +978,7 @@ extern void df_note_add_problem (void); 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); Index: df-problems.c =================================================================== --- df-problems.c (revision 158513) +++ df-problems.c (working copy) @@ -3745,9 +3745,22 @@ df_simulate_find_defs (rtx insn, bitmap 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)); } } @@ -3939,7 +3952,7 @@ df_simulate_one_insn_forwards (basic_blo 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))