return set;
}
+// Make USE's definition available at USE, if it isn't already. Assume that
+// the caller has properly used make_use_available to check that this is
+// possible.
+void
+function_info::commit_make_use_available (use_info *use)
+{
+ // We only need to handle single dominating definitions here.
+ // Other cases are handled by degenerate phis, with create_degenerate_phi
+ // creating any necessary live-out uses.
+ set_info *def = use->def ();
+ if (def
+ && use->is_reg ()
+ && is_single_dominating_def (def)
+ && use->ebb () != def->ebb ())
+ {
+ // If USE's EBB has DEF's EBB as its single predecessor, it's enough
+ // to add a live-out use to the former's predecessor block. Otherwise,
+ // conservatively add a live-out use at the end of DEF's block, so that
+ // DEF cannot move further down. Doing a minimal yet accurate update
+ // would be an O(n.log(n)) operation in the worst case.
+ auto ebb_cfg_bb = def->ebb ()->first_bb ()->cfg_bb ();
+ if (single_pred_p (ebb_cfg_bb))
+ {
+ bb_info *pred_bb = this->bb (single_pred (ebb_cfg_bb));
+ if (pred_bb->ebb () == def->ebb ())
+ {
+ add_live_out_use (pred_bb, def);
+ return;
+ }
+ }
+ add_live_out_use (def->bb (), def);
+ return;
+ }
+}
+
// Add PHI to EBB and enter it into the function's hash table.
void
function_info::append_phi (ebb_info *ebb, phi_info *phi)
// Add all uses, now that their position is final.
for (use_info *use : change.new_uses)
- add_use (use);
+ {
+ if (use->def ())
+ commit_make_use_available (use);
+ add_use (use);
+ }
// Copy the uses and definitions.
unsigned int num_defs = change.new_defs.size ();
void add_live_out_use (bb_info *, set_info *);
set_info *live_out_value (bb_info *, set_info *);
+ void commit_make_use_available (use_info *);
void append_phi (ebb_info *, phi_info *);
void remove_phi (phi_info *);