1
Fork 0

simplify-locals: Change RemoveStatements visitor into a function

No functionl changes intended.
This commit is contained in:
Tomasz Miąsko 2020-10-22 00:00:00 +00:00
parent a6b64be8b5
commit e1e48ae29b

View file

@ -330,14 +330,7 @@ impl<'tcx> MirPass<'tcx> for SimplifyLocals {
// count. For example, if we removed `_2 = discriminant(_1)`, then we'll subtract one from // count. For example, if we removed `_2 = discriminant(_1)`, then we'll subtract one from
// `use_counts[_1]`. That in turn might make `_1` unused, so we loop until we hit a // `use_counts[_1]`. That in turn might make `_1` unused, so we loop until we hit a
// fixedpoint where there are no more unused locals. // fixedpoint where there are no more unused locals.
loop { remove_unused_definitions(&mut used_locals, body);
let mut remove_statements = RemoveStatements::new(&mut used_locals, tcx);
remove_statements.visit_body(body);
if !remove_statements.modified {
break;
}
}
// Finally, we'll actually do the work of shrinking `body.local_decls` and remapping the `Local`s. // Finally, we'll actually do the work of shrinking `body.local_decls` and remapping the `Local`s.
let map = make_local_map(&mut body.local_decls, &used_locals); let map = make_local_map(&mut body.local_decls, &used_locals);
@ -487,44 +480,40 @@ impl Visitor<'_> for UsedLocals {
} }
} }
struct RemoveStatements<'a, 'tcx> { /// Removes unused definitions. Updates the used locals to reflect the changes made.
fn remove_unused_definitions<'a, 'tcx>(
used_locals: &'a mut UsedLocals, used_locals: &'a mut UsedLocals,
tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>,
modified: bool, ) {
} // The use counts are updated as we remove the statements. A local might become unused
// during the retain operation, leading to a temporary inconsistency (storage statements or
// definitions referencing the local might remain). For correctness it is crucial that this
// computation reaches a fixed point.
impl<'a, 'tcx> RemoveStatements<'a, 'tcx> { let mut modified = true;
fn new(used_locals: &'a mut UsedLocals, tcx: TyCtxt<'tcx>) -> Self { while modified {
Self { used_locals, tcx, modified: false } modified = false;
}
}
impl<'a, 'tcx> MutVisitor<'tcx> for RemoveStatements<'a, 'tcx> { for data in body.basic_blocks_mut() {
fn tcx(&self) -> TyCtxt<'tcx> { // Remove unnecessary StorageLive and StorageDead annotations.
self.tcx data.statements.retain(|statement| {
} let keep = match &statement.kind {
StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => {
used_locals.is_used(*local)
}
StatementKind::Assign(box (place, _)) => used_locals.is_used(place.local),
_ => true,
};
fn visit_basic_block_data(&mut self, block: BasicBlock, data: &mut BasicBlockData<'tcx>) { if !keep {
// Remove unnecessary StorageLive and StorageDead annotations. trace!("removing statement {:?}", statement);
data.statements.retain(|statement| { modified = true;
let keep = match &statement.kind { used_locals.statement_removed(statement);
StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => {
self.used_locals.is_used(*local)
} }
StatementKind::Assign(box (place, _)) => self.used_locals.is_used(place.local),
_ => true,
};
if !keep { keep
trace!("removing statement {:?}", statement); });
self.modified = true; }
self.used_locals.statement_removed(statement);
}
keep
});
self.super_basic_block_data(block, data);
} }
} }