// pending clobbers into actual definitions.
//
// POS gives the final position of INSN, which hasn't yet been moved into
-// place.
+// place. Keep track of any newly-created set_infos being added with this
+// change by adding them to NEW_SETS.
void
-function_info::finalize_new_accesses (insn_change &change, insn_info *pos)
+function_info::finalize_new_accesses (insn_change &change, insn_info *pos,
+ hash_set<def_info *> &new_sets)
{
insn_info *insn = change.insn ();
// later in case we see a second write to the same resource.
def_info *perm_def = allocate<set_info> (change.insn (),
def->resource ());
+
+ // Keep track of the new set so we remember to add it to the
+ // def chain later.
+ if (new_sets.add (perm_def))
+ gcc_unreachable (); // We shouldn't see duplicates here.
+
def->set_last_def (perm_def);
def = perm_def;
}
}
// Copy information from CHANGE to its underlying insn_info, given that
-// the insn_info has already been placed appropriately.
+// the insn_info has already been placed appropriately. NEW_SETS contains the
+// new set_infos that are being added as part of this change (as opposed to
+// being moved or repurposed from existing instructions).
void
-function_info::apply_changes_to_insn (insn_change &change)
+function_info::apply_changes_to_insn (insn_change &change,
+ hash_set<def_info *> &new_sets)
{
insn_info *insn = change.insn ();
if (change.is_deletion ())
// Copy the cost.
insn->set_cost (change.new_cost);
- // Add all clobbers. Sets and call clobbers never move relative to
- // other definitions, so are OK as-is.
+ // Add all clobbers and newly-created sets. Existing sets and call
+ // clobbers never move relative to other definitions, so are OK as-is.
for (def_info *def : change.new_defs)
- if (is_a<clobber_info *> (def) && !def->is_call_clobber ())
+ if ((is_a<clobber_info *> (def) && !def->is_call_clobber ())
+ || (is_a<set_info *> (def) && new_sets.contains (def)))
add_def (def);
// Add all uses, now that their position is final.
placeholders[i] = placeholder;
}
+ // We need to keep track of newly-added sets as these need adding to
+ // the def chain later.
+ hash_set<def_info *> new_sets;
+
// Finalize the new list of accesses for each change. Don't install them yet,
// so that we still have access to the old lists below.
//
insn_info *placeholder = placeholders[i];
if (!change.is_deletion ())
finalize_new_accesses (change,
- placeholder ? placeholder : change.insn ());
+ placeholder ? placeholder : change.insn (),
+ new_sets);
}
// Remove all definitions that are no longer needed. After the above,
// Apply the changes to the underlying insn_infos.
for (insn_change *change : changes)
- apply_changes_to_insn (*change);
+ apply_changes_to_insn (*change, new_sets);
// Now that the insns and accesses are up to date, add any REG_UNUSED notes.
for (insn_change *change : changes)
void process_uses_of_deleted_def (set_info *);
insn_info *add_placeholder_after (insn_info *);
void possibly_queue_changes (insn_change &);
- void finalize_new_accesses (insn_change &, insn_info *);
- void apply_changes_to_insn (insn_change &);
+ void finalize_new_accesses (insn_change &, insn_info *,
+ hash_set<def_info *> &);
+ void apply_changes_to_insn (insn_change &,
+ hash_set<def_info *> &);
void init_function_data ();
void calculate_potential_phi_regs (build_info &);