1
Fork 0

librustc: Add a new nop statement to the MIR.

This is useful when passes want to remove statements without affecting
`Location`s.
This commit is contained in:
Patrick Walton 2016-09-15 18:17:58 -07:00
parent 5f6f838448
commit 2e6a91812c
9 changed files with 33 additions and 5 deletions

View file

@ -187,6 +187,14 @@ impl<'tcx> Mir<'tcx> {
self.var_decls.len() + self.var_decls.len() +
self.temp_decls.len() + 1 self.temp_decls.len() + 1
} }
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids
/// invalidating statement indices in `Location`s.
pub fn make_statement_nop(&mut self, location: Location) {
let block = &mut self[location.block];
debug_assert!(location.statement_index < block.statements.len());
block.statements[location.statement_index].make_nop()
}
} }
impl<'tcx> Index<BasicBlock> for Mir<'tcx> { impl<'tcx> Index<BasicBlock> for Mir<'tcx> {
@ -686,6 +694,14 @@ pub struct Statement<'tcx> {
pub kind: StatementKind<'tcx>, pub kind: StatementKind<'tcx>,
} }
impl<'tcx> Statement<'tcx> {
/// Changes a statement to a nop. This is both faster than deleting instructions and avoids
/// invalidating statement indices in `Location`s.
pub fn make_nop(&mut self) {
self.kind = StatementKind::Nop
}
}
#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] #[derive(Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum StatementKind<'tcx> { pub enum StatementKind<'tcx> {
/// Write the RHS Rvalue to the LHS Lvalue. /// Write the RHS Rvalue to the LHS Lvalue.
@ -699,6 +715,9 @@ pub enum StatementKind<'tcx> {
/// End the current live range for the storage of the local. /// End the current live range for the storage of the local.
StorageDead(Lvalue<'tcx>), StorageDead(Lvalue<'tcx>),
/// No-op. Useful for deleting instructions without affecting statement indices.
Nop,
} }
impl<'tcx> Debug for Statement<'tcx> { impl<'tcx> Debug for Statement<'tcx> {
@ -711,6 +730,7 @@ impl<'tcx> Debug for Statement<'tcx> {
SetDiscriminant{lvalue: ref lv, variant_index: index} => { SetDiscriminant{lvalue: ref lv, variant_index: index} => {
write!(fmt, "discriminant({:?}) = {:?}", lv, index) write!(fmt, "discriminant({:?}) = {:?}", lv, index)
} }
Nop => write!(fmt, "nop"),
} }
} }
} }

View file

@ -346,6 +346,7 @@ macro_rules! make_mir_visitor {
StatementKind::StorageDead(ref $($mutability)* lvalue) => { StatementKind::StorageDead(ref $($mutability)* lvalue) => {
self.visit_lvalue(lvalue, LvalueContext::StorageDead, location); self.visit_lvalue(lvalue, LvalueContext::StorageDead, location);
} }
StatementKind::Nop => {}
} }
} }

View file

@ -455,7 +455,8 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
}); });
} }
repr::StatementKind::StorageLive(_) | repr::StatementKind::StorageLive(_) |
repr::StatementKind::StorageDead(_) => {} repr::StatementKind::StorageDead(_) |
repr::StatementKind::Nop => {}
} }
} }

View file

@ -105,7 +105,8 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
(lvalue, rvalue) (lvalue, rvalue)
} }
repr::StatementKind::StorageLive(_) | repr::StatementKind::StorageLive(_) |
repr::StatementKind::StorageDead(_) => continue, repr::StatementKind::StorageDead(_) |
repr::StatementKind::Nop => continue,
repr::StatementKind::SetDiscriminant{ .. } => repr::StatementKind::SetDiscriminant{ .. } =>
span_bug!(stmt.source_info.span, span_bug!(stmt.source_info.span,
"sanity_check should run before Deaggregator inserts SetDiscriminant"), "sanity_check should run before Deaggregator inserts SetDiscriminant"),

View file

@ -389,7 +389,8 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>(
|moi| callback(moi, DropFlagState::Present)) |moi| callback(moi, DropFlagState::Present))
} }
repr::StatementKind::StorageLive(_) | repr::StatementKind::StorageLive(_) |
repr::StatementKind::StorageDead(_) => {} repr::StatementKind::StorageDead(_) |
repr::StatementKind::Nop => {}
}, },
None => { None => {
debug!("drop_flag_effects: replace {:?}", block.terminator()); debug!("drop_flag_effects: replace {:?}", block.terminator());

View file

@ -910,7 +910,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
} }
StatementKind::SetDiscriminant { .. } | StatementKind::SetDiscriminant { .. } |
StatementKind::StorageLive(_) | StatementKind::StorageLive(_) |
StatementKind::StorageDead(_) => {} StatementKind::StorageDead(_) |
StatementKind::Nop => {}
} }
}); });
} }

View file

@ -385,6 +385,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
} }
} }
} }
StatementKind::Nop => {}
} }
} }

View file

@ -292,7 +292,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
} }
} }
mir::StatementKind::StorageLive(_) | mir::StatementKind::StorageLive(_) |
mir::StatementKind::StorageDead(_) => {} mir::StatementKind::StorageDead(_) |
mir::StatementKind::Nop => {}
mir::StatementKind::SetDiscriminant{ .. } => { mir::StatementKind::SetDiscriminant{ .. } => {
span_bug!(span, "SetDiscriminant should not appear in constants?"); span_bug!(span, "SetDiscriminant should not appear in constants?");
} }

View file

@ -78,6 +78,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
mir::StatementKind::StorageDead(ref lvalue) => { mir::StatementKind::StorageDead(ref lvalue) => {
self.trans_storage_liveness(bcx, lvalue, base::Lifetime::End) self.trans_storage_liveness(bcx, lvalue, base::Lifetime::End)
} }
mir::StatementKind::Nop => bcx,
} }
} }