From 2e6a91812c64a507e3d2ab727824ff9cda8449fc Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 15 Sep 2016 18:17:58 -0700 Subject: [PATCH] librustc: Add a new nop statement to the MIR. This is useful when passes want to remove statements without affecting `Location`s. --- src/librustc/mir/repr.rs | 20 +++++++++++++++++++ src/librustc/mir/visit.rs | 1 + .../borrowck/mir/dataflow/impls.rs | 3 ++- .../borrowck/mir/dataflow/sanity_check.rs | 3 ++- src/librustc_borrowck/borrowck/mir/mod.rs | 3 ++- src/librustc_mir/transform/qualify_consts.rs | 3 ++- src/librustc_mir/transform/type_check.rs | 1 + src/librustc_trans/mir/constant.rs | 3 ++- src/librustc_trans/mir/statement.rs | 1 + 9 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs index 53b6ccdbd530a..3ab8ed5bce292 100644 --- a/src/librustc/mir/repr.rs +++ b/src/librustc/mir/repr.rs @@ -187,6 +187,14 @@ impl<'tcx> Mir<'tcx> { self.var_decls.len() + 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 for Mir<'tcx> { @@ -686,6 +694,14 @@ pub struct Statement<'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)] pub enum StatementKind<'tcx> { /// 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. StorageDead(Lvalue<'tcx>), + + /// No-op. Useful for deleting instructions without affecting statement indices. + Nop, } impl<'tcx> Debug for Statement<'tcx> { @@ -711,6 +730,7 @@ impl<'tcx> Debug for Statement<'tcx> { SetDiscriminant{lvalue: ref lv, variant_index: index} => { write!(fmt, "discriminant({:?}) = {:?}", lv, index) } + Nop => write!(fmt, "nop"), } } } diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs index 16e0b376f4b53..072faf795220a 100644 --- a/src/librustc/mir/visit.rs +++ b/src/librustc/mir/visit.rs @@ -346,6 +346,7 @@ macro_rules! make_mir_visitor { StatementKind::StorageDead(ref $($mutability)* lvalue) => { self.visit_lvalue(lvalue, LvalueContext::StorageDead, location); } + StatementKind::Nop => {} } } diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs b/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs index 8ac59c60396f6..55dda8eda3a4a 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs @@ -455,7 +455,8 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> { }); } repr::StatementKind::StorageLive(_) | - repr::StatementKind::StorageDead(_) => {} + repr::StatementKind::StorageDead(_) | + repr::StatementKind::Nop => {} } } diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs index 88f6d5fef562d..aeb91f06a9aa4 100644 --- a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs +++ b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs @@ -105,7 +105,8 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>, (lvalue, rvalue) } repr::StatementKind::StorageLive(_) | - repr::StatementKind::StorageDead(_) => continue, + repr::StatementKind::StorageDead(_) | + repr::StatementKind::Nop => continue, repr::StatementKind::SetDiscriminant{ .. } => span_bug!(stmt.source_info.span, "sanity_check should run before Deaggregator inserts SetDiscriminant"), diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs index 5b5d782bc83a2..f26afdc2b8572 100644 --- a/src/librustc_borrowck/borrowck/mir/mod.rs +++ b/src/librustc_borrowck/borrowck/mir/mod.rs @@ -389,7 +389,8 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>( |moi| callback(moi, DropFlagState::Present)) } repr::StatementKind::StorageLive(_) | - repr::StatementKind::StorageDead(_) => {} + repr::StatementKind::StorageDead(_) | + repr::StatementKind::Nop => {} }, None => { debug!("drop_flag_effects: replace {:?}", block.terminator()); diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index a3f8f7a63eeab..9f162aabe0c2f 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -910,7 +910,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { } StatementKind::SetDiscriminant { .. } | StatementKind::StorageLive(_) | - StatementKind::StorageDead(_) => {} + StatementKind::StorageDead(_) | + StatementKind::Nop => {} } }); } diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs index 7fda658185e07..412759cd5b2d3 100644 --- a/src/librustc_mir/transform/type_check.rs +++ b/src/librustc_mir/transform/type_check.rs @@ -385,6 +385,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { } } } + StatementKind::Nop => {} } } diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index e9f324c0b08f0..70d0a61840475 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -292,7 +292,8 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { } } mir::StatementKind::StorageLive(_) | - mir::StatementKind::StorageDead(_) => {} + mir::StatementKind::StorageDead(_) | + mir::StatementKind::Nop => {} mir::StatementKind::SetDiscriminant{ .. } => { span_bug!(span, "SetDiscriminant should not appear in constants?"); } diff --git a/src/librustc_trans/mir/statement.rs b/src/librustc_trans/mir/statement.rs index 1167208955368..325bd655266c1 100644 --- a/src/librustc_trans/mir/statement.rs +++ b/src/librustc_trans/mir/statement.rs @@ -78,6 +78,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { mir::StatementKind::StorageDead(ref lvalue) => { self.trans_storage_liveness(bcx, lvalue, base::Lifetime::End) } + mir::StatementKind::Nop => bcx, } }