diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index 3378923c22c36..d435d3ee69b76 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -1,39 +1,44 @@ -//! This module provides a pass to replacing the following statements with -//! [`Nop`]s +//! This module provides a pass that removes parts of MIR that are no longer relevant after +//! analysis phase and borrowck. In particular, it removes false edges, user type annotations and +//! replaces following statements with [`Nop`]s: //! //! - [`AscribeUserType`] //! - [`FakeRead`] //! - [`Assign`] statements with a [`Shallow`] borrow //! -//! The `CleanFakeReadsAndBorrows` "pass" is actually implemented as two -//! traversals (aka visits) of the input MIR. The first traversal, -//! `DeleteAndRecordFakeReads`, deletes the fake reads and finds the -//! temporaries read by [`ForMatchGuard`] reads, and `DeleteFakeBorrows` -//! deletes the initialization of those temporaries. -//! //! [`AscribeUserType`]: rustc_middle::mir::StatementKind::AscribeUserType -//! [`Shallow`]: rustc_middle::mir::BorrowKind::Shallow -//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead //! [`Assign`]: rustc_middle::mir::StatementKind::Assign -//! [`ForMatchGuard`]: rustc_middle::mir::FakeReadCause::ForMatchGuard +//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead //! [`Nop`]: rustc_middle::mir::StatementKind::Nop +//! [`Shallow`]: rustc_middle::mir::BorrowKind::Shallow use crate::MirPass; -use rustc_middle::mir::visit::MutVisitor; -use rustc_middle::mir::{Body, BorrowKind, Location, Rvalue}; -use rustc_middle::mir::{Statement, StatementKind}; +use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind}; use rustc_middle::ty::TyCtxt; -pub struct CleanupNonCodegenStatements; +pub struct CleanupPostBorrowck; -pub struct DeleteNonCodegenStatements<'tcx> { - tcx: TyCtxt<'tcx>, -} +impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck { + fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + for basic_block in body.basic_blocks.as_mut() { + for statement in basic_block.statements.iter_mut() { + match statement.kind { + StatementKind::AscribeUserType(..) + | StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Shallow, _))) + | StatementKind::FakeRead(..) => statement.make_nop(), + _ => (), + } + } + let terminator = basic_block.terminator_mut(); + match terminator.kind { + TerminatorKind::FalseEdge { real_target, .. } + | TerminatorKind::FalseUnwind { real_target, .. } => { + terminator.kind = TerminatorKind::Goto { target: real_target }; + } + _ => {} + } + } -impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements { - fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - let mut delete = DeleteNonCodegenStatements { tcx }; - delete.visit_body_preserves_cfg(body); body.user_type_annotations.raw.clear(); for decl in &mut body.local_decls { @@ -41,19 +46,3 @@ impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements { } } } - -impl<'tcx> MutVisitor<'tcx> for DeleteNonCodegenStatements<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Location) { - match statement.kind { - StatementKind::AscribeUserType(..) - | StatementKind::Assign(box (_, Rvalue::Ref(_, BorrowKind::Shallow, _))) - | StatementKind::FakeRead(..) => statement.make_nop(), - _ => (), - } - self.super_statement(statement, location); - } -} diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 93200b28830f0..aba5a8580f194 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -77,8 +77,6 @@ mod match_branches; mod multiple_return_terminators; mod normalize_array_len; mod nrvo; -// This pass is public to allow external drivers to perform MIR cleanup -pub mod remove_false_edges; mod remove_noop_landing_pads; mod remove_storage_markers; mod remove_uninit_drops; @@ -494,10 +492,9 @@ fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx> /// After this series of passes, no lifetime analysis based on borrowing can be done. fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let passes: &[&dyn MirPass<'tcx>] = &[ - &remove_false_edges::RemoveFalseEdges, + &cleanup_post_borrowck::CleanupPostBorrowck, &simplify_branches::SimplifyConstCondition::new("initial"), &remove_noop_landing_pads::RemoveNoopLandingPads, - &cleanup_post_borrowck::CleanupNonCodegenStatements, &simplify::SimplifyCfg::new("early-opt"), &deref_separator::Derefer, ]; diff --git a/compiler/rustc_mir_transform/src/remove_false_edges.rs b/compiler/rustc_mir_transform/src/remove_false_edges.rs deleted file mode 100644 index 71f5ccf7e2465..0000000000000 --- a/compiler/rustc_mir_transform/src/remove_false_edges.rs +++ /dev/null @@ -1,29 +0,0 @@ -use rustc_middle::mir::{Body, TerminatorKind}; -use rustc_middle::ty::TyCtxt; - -use crate::MirPass; - -/// Removes `FalseEdge` and `FalseUnwind` terminators from the MIR. -/// -/// These are only needed for borrow checking, and can be removed afterwards. -/// -/// FIXME: This should probably have its own MIR phase. -pub struct RemoveFalseEdges; - -impl<'tcx> MirPass<'tcx> for RemoveFalseEdges { - fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - for block in body.basic_blocks_mut() { - let terminator = block.terminator_mut(); - terminator.kind = match terminator.kind { - TerminatorKind::FalseEdge { real_target, .. } => { - TerminatorKind::Goto { target: real_target } - } - TerminatorKind::FalseUnwind { real_target, .. } => { - TerminatorKind::Goto { target: real_target } - } - - _ => continue, - } - } - } -} diff --git a/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff similarity index 90% rename from src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff rename to src/test/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff index bb5920b28ca94..0b3da98a5a192 100644 --- a/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff +++ b/src/test/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.diff @@ -1,5 +1,5 @@ -- // MIR for `match_guard` before CleanupNonCodegenStatements -+ // MIR for `match_guard` after CleanupNonCodegenStatements +- // MIR for `match_guard` before CleanupPostBorrowck ++ // MIR for `match_guard` after CleanupPostBorrowck fn match_guard(_1: Option<&&i32>, _2: bool) -> i32 { debug x => _1; // in scope 0 at $DIR/remove_fake_borrows.rs:+0:16: +0:17 @@ -29,7 +29,8 @@ } bb3: { - goto -> bb4; // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16 +- falseEdge -> [real: bb4, imaginary: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16 ++ goto -> bb4; // scope 0 at $DIR/remove_fake_borrows.rs:+2:9: +2:16 } bb4: { @@ -62,15 +63,12 @@ bb6: { StorageDead(_8); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 - goto -> bb1; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 +- falseEdge -> [real: bb1, imaginary: bb1]; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 ++ goto -> bb1; // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21 } bb7: { return; // scope 0 at $DIR/remove_fake_borrows.rs:+5:2: +5:2 } - - bb8 (cleanup): { - resume; // scope 0 at $DIR/remove_fake_borrows.rs:+0:1: +5:2 - } } diff --git a/src/test/mir-opt/remove_fake_borrows.rs b/src/test/mir-opt/remove_fake_borrows.rs index a980f386b6963..d26c6f5d7e51b 100644 --- a/src/test/mir-opt/remove_fake_borrows.rs +++ b/src/test/mir-opt/remove_fake_borrows.rs @@ -2,7 +2,7 @@ // ignore-wasm32-bare compiled with panic=abort by default -// EMIT_MIR remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff +// EMIT_MIR remove_fake_borrows.match_guard.CleanupPostBorrowck.diff fn match_guard(x: Option<&&i32>, c: bool) -> i32 { match x { Some(0) if c => 0,