Skip to content

Commit

Permalink
Auto merge of #51870 - nnethercote:reuse-DefsUsesVisitor, r=nikomatsakis
Browse files Browse the repository at this point in the history
Reuse the `DefsUsesVisitor` in `simulate_block()`.

This avoids a bunch of allocations for the bitsets within it,
speeding up a number of NLL benchmarks, the best by 1%.

r? @nikomatsakis
  • Loading branch information
bors committed Jul 4, 2018
2 parents a22bcd8 + b0c7812 commit eded1aa
Showing 1 changed file with 34 additions and 24 deletions.
58 changes: 34 additions & 24 deletions src/librustc_mir/util/liveness.rs
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

0 comments on commit eded1aa

Please sign in to comment.