if (slots_filled < slots_to_fill)
{
+ /* If the flags register is dead after the insn, then we want to be
+ able to accept a candidate that clobbers it. For this purpose,
+ we need to filter the flags register during life analysis, so
+ that it doesn't create RAW and WAW dependencies, while still
+ creating the necessary WAR dependencies. */
+ bool filter_flags
+ = (slots_to_fill == 1
+ && targetm.flags_regnum != INVALID_REGNUM
+ && find_regno_note (insn, REG_DEAD, targetm.flags_regnum));
+ struct resources fset;
CLEAR_RESOURCE (&needed);
CLEAR_RESOURCE (&set);
mark_set_resources (insn, &set, 0, MARK_SRC_DEST);
+ if (filter_flags)
+ {
+ CLEAR_RESOURCE (&fset);
+ mark_set_resources (insn, &fset, 0, MARK_SRC_DEST);
+ }
mark_referenced_resources (insn, &needed, false);
for (trial = prev_nonnote_insn (insn); ! stop_search_p (trial, 1);
/* Check for resource conflict first, to avoid unnecessary
splitting. */
if (! insn_references_resource_p (trial, &set, true)
- && ! insn_sets_resource_p (trial, &set, true)
+ && ! insn_sets_resource_p (trial,
+ filter_flags ? &fset : &set,
+ true)
&& ! insn_sets_resource_p (trial, &needed, true)
#ifdef HAVE_cc0
/* Can't separate set of cc0 from its use. */
}
mark_set_resources (trial, &set, 0, MARK_SRC_DEST_CALL);
+ if (filter_flags)
+ {
+ mark_set_resources (trial, &fset, 0, MARK_SRC_DEST_CALL);
+ /* If the flags register is set, then it doesn't create RAW
+ dependencies any longer and it also doesn't create WAW
+ dependencies since it's dead after the original insn. */
+ if (TEST_HARD_REG_BIT (fset.regs, targetm.flags_regnum))
+ {
+ CLEAR_HARD_REG_BIT (needed.regs, targetm.flags_regnum);
+ CLEAR_HARD_REG_BIT (fset.regs, targetm.flags_regnum);
+ }
+ }
mark_referenced_resources (trial, &needed, true);
}
}