// If IGNORE_INSN is non-NULL, we should further ignore any hazards arising
// from that insn.
//
-// N.B. we ignore any defs/uses of memory here as we deal with that separately,
-// making use of alias disambiguation.
+// IS_LOAD_STORE is true if INSN is one of the loads or stores in the
+// candidate pair. We ignore any defs/uses of memory in such instructions
+// as we deal with that separately, making use of alias disambiguation.
static insn_info *
latest_hazard_before (insn_info *insn, rtx *ignore,
- insn_info *ignore_insn = nullptr)
+ insn_info *ignore_insn = nullptr,
+ bool is_load_store = true)
{
insn_info *result = nullptr;
&& find_reg_note (insn->rtl (), REG_EH_REGION, NULL_RTX))
return insn->prev_nondebug_insn ();
+ if (!is_load_store
+ && accesses_include_memory (insn->defs ()))
+ return insn->prev_nondebug_insn ();
+
// Return true if we registered the hazard.
auto hazard = [&](insn_info *h) -> bool
{
insns[0]->uid (), insns[1]->uid ());
};
- insn_info *hazard = latest_hazard_before (cand, nullptr, insns[1]);
+ insn_info *hazard = latest_hazard_before (cand, nullptr, insns[1], false);
if (!hazard || *hazard <= *pair_dst)
{
if (dump_file)
insn_info *insns[2] = { first, second };
auto_vec<insn_change *> changes;
- auto_vec<int, 2> tombstone_uids (2);
+ auto_vec<int, 3> tombstone_uids;
rtx pats[2] = {
PATTERN (first->rtl ()),
validate_change (rti, ®_NOTES (rti), reg_notes, true);
};
+ // Turn CHANGE into a memory definition tombstone.
+ auto make_tombstone = [&](insn_change *change)
+ {
+ tombstone_uids.quick_push (change->insn ()->uid ());
+ rtx_insn *rti = change->insn ()->rtl ();
+ validate_change (rti, &PATTERN (rti), gen_tombstone (), true);
+ validate_change (rti, ®_NOTES (rti), NULL_RTX, true);
+ change->new_uses = use_array ();
+ };
+
if (load_p)
{
changes.safe_push (make_delete (first));
}
case Action::TOMBSTONE:
{
- tombstone_uids.quick_push (change->insn ()->uid ());
- rtx_insn *rti = change->insn ()->rtl ();
- validate_change (rti, &PATTERN (rti), gen_tombstone (), true);
- validate_change (rti, ®_NOTES (rti), NULL_RTX, true);
- change->new_uses = use_array (nullptr, 0);
+ make_tombstone (change);
break;
}
case Action::INSERT:
}
if (trailing_add)
- changes.safe_push (make_delete (trailing_add));
+ {
+ if (auto *mem_def = memory_access (trailing_add->defs()))
+ {
+ auto *change = make_change (trailing_add);
+ change->new_defs = insert_access (attempt, mem_def, def_array ());
+ make_tombstone (change);
+ changes.safe_push (change);
+ }
+ else
+ changes.safe_push (make_delete (trailing_add));
+ }
else if ((writeback & 2) && !writeback_effect)
{
// The second insn initially had writeback but now the pair does not,
confirm_change_group ();
crtl->ssa->change_insns (changes);
- gcc_checking_assert (tombstone_uids.length () <= 2);
for (auto uid : tombstone_uids)
track_tombstone (uid);
--- /dev/null
+void h(long, long, long, long, long, long, long, long, long, long);
+long i(long, long, long, long, long, long, long, long, long, long);
+void f(long a0, long a1, long a2, long a3, long a4, long a5,
+ long a6, long a7, long a8, long a9) {
+ i(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9);
+ h(a0, 1, 1, 1, 1, 1, 1, 1, 0, 0);
+}