Skip to content

Reuse the DefsUsesVisitor in simulate_block(). #51870

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 4, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 34 additions & 24 deletions src/librustc_mir/util/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,27 +179,6 @@ impl LivenessResult {
block,
statement_index,
};
let terminator_defs_uses = self.defs_uses(mir, terminator_location, &data.terminator);
terminator_defs_uses.apply(&mut bits);
callback(terminator_location, &bits);

// Compute liveness before each statement (in rev order) and invoke callback.
for statement in data.statements.iter().rev() {
statement_index -= 1;
let statement_location = Location {
block,
statement_index,
};
let statement_defs_uses = self.defs_uses(mir, statement_location, statement);
statement_defs_uses.apply(&mut bits);
callback(statement_location, &bits);
}
}

fn defs_uses<'tcx, V>(&self, mir: &Mir<'tcx>, location: Location, thing: &V) -> DefsUses
where
V: MirVisitable<'tcx>,
{
let locals = mir.local_decls.len();
let mut visitor = DefsUsesVisitor {
mode: self.mode,
Expand All @@ -208,12 +187,22 @@ impl LivenessResult {
uses: LocalSet::new_empty(locals),
},
};

// Visit the various parts of the basic block in reverse. If we go
// forward, the logic in `add_def` and `add_use` would be wrong.
thing.apply(location, &mut visitor);
visitor.update_bits_and_do_callback(terminator_location, &data.terminator, &mut bits,
&mut callback);

visitor.defs_uses
// Compute liveness before each statement (in rev order) and invoke callback.
for statement in data.statements.iter().rev() {
statement_index -= 1;
let statement_location = Location {
block,
statement_index,
};
visitor.defs_uses.clear();
visitor.update_bits_and_do_callback(statement_location, statement, &mut bits,
&mut callback);
}
}
}

Expand Down Expand Up @@ -304,6 +293,11 @@ struct DefsUses {
}

impl DefsUses {
fn clear(&mut self) {
self.uses.clear();
self.defs.clear();
}

fn apply(&self, bits: &mut LocalSet) -> bool {
bits.subtract(&self.defs) | bits.union(&self.uses)
}
Expand Down Expand Up @@ -338,6 +332,22 @@ impl DefsUses {
}
}

impl DefsUsesVisitor {
/// Update `bits` with the effects of `value` and call `callback`. We
/// should always visit in reverse order. This method assumes that we have
/// not visited anything before; if you have, clear `bits` first.
fn update_bits_and_do_callback<'tcx, OP>(&mut self, location: Location,
value: &impl MirVisitable<'tcx>, bits: &mut LocalSet,
callback: &mut OP)
where
OP: FnMut(Location, &LocalSet),
{
value.apply(location, self);
self.defs_uses.apply(bits);
callback(location, bits);
}
}

impl<'tcx> Visitor<'tcx> for DefsUsesVisitor {
fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
match categorize(context, self.mode) {
Expand Down