Skip to content

Commit

Permalink
librustc: Add a new nop statement to the MIR.
Browse files Browse the repository at this point in the history
This is useful when passes want to remove statements without affecting
`Location`s.
  • Loading branch information
pcwalton committed Sep 19, 2016
1 parent 5f6f838 commit 2e6a918
Show file tree
Hide file tree
Showing 9 changed files with 33 additions and 5 deletions.
20 changes: 20 additions & 0 deletions src/librustc/mir/repr.rs
Expand Up @@ -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<BasicBlock> for Mir<'tcx> {
Expand Down Expand Up @@ -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.
Expand All @@ -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> {
Expand All @@ -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"),
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc/mir/visit.rs
Expand Up @@ -346,6 +346,7 @@ macro_rules! make_mir_visitor {
StatementKind::StorageDead(ref $($mutability)* lvalue) => {
self.visit_lvalue(lvalue, LvalueContext::StorageDead, location);
}
StatementKind::Nop => {}
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
Expand Up @@ -455,7 +455,8 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
});
}
repr::StatementKind::StorageLive(_) |
repr::StatementKind::StorageDead(_) => {}
repr::StatementKind::StorageDead(_) |
repr::StatementKind::Nop => {}
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs
Expand Up @@ -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"),
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_borrowck/borrowck/mir/mod.rs
Expand Up @@ -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());
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_mir/transform/qualify_consts.rs
Expand Up @@ -910,7 +910,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
}
StatementKind::SetDiscriminant { .. } |
StatementKind::StorageLive(_) |
StatementKind::StorageDead(_) => {}
StatementKind::StorageDead(_) |
StatementKind::Nop => {}
}
});
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_mir/transform/type_check.rs
Expand Up @@ -385,6 +385,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
}
}
}
StatementKind::Nop => {}
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/librustc_trans/mir/constant.rs
Expand Up @@ -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?");
}
Expand Down
1 change: 1 addition & 0 deletions src/librustc_trans/mir/statement.rs
Expand Up @@ -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,
}
}

Expand Down

0 comments on commit 2e6a918

Please sign in to comment.