From 2a8513d221cfeb76c284a47e972961d22bdf65ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 17 Dec 2022 00:00:00 +0000 Subject: [PATCH 1/4] Replace visitor with a loop over blocks and statements --- .../src/cleanup_post_borrowck.rs | 39 +++++++------------ 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index 3378923c22c36..c33d72179ad19 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -19,21 +19,24 @@ //! [`Nop`]: rustc_middle::mir::StatementKind::Nop 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}; use rustc_middle::ty::TyCtxt; pub struct CleanupNonCodegenStatements; -pub struct DeleteNonCodegenStatements<'tcx> { - tcx: TyCtxt<'tcx>, -} - 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); + fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { + for basic_block in body.basic_blocks.as_mut_preserves_cfg() { + 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(), + _ => (), + } + } + } + body.user_type_annotations.raw.clear(); for decl in &mut body.local_decls { @@ -41,19 +44,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); - } -} From 4c3efc7f1b2dc4a815d3690c6995bed5a8c63ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 17 Dec 2022 00:00:00 +0000 Subject: [PATCH 2/4] Rename CleanupNonCodegenStatements to CleanupPostBorrowck --- compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs | 4 ++-- compiler/rustc_mir_transform/src/lib.rs | 2 +- src/test/mir-opt/remove_fake_borrows.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index c33d72179ad19..fe5295afaced7 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -22,9 +22,9 @@ use crate::MirPass; use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind}; use rustc_middle::ty::TyCtxt; -pub struct CleanupNonCodegenStatements; +pub struct CleanupPostBorrowck; -impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements { +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_preserves_cfg() { for statement in basic_block.statements.iter_mut() { diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 93200b28830f0..e28406ce67ea6 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -497,7 +497,7 @@ fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { &remove_false_edges::RemoveFalseEdges, &simplify_branches::SimplifyConstCondition::new("initial"), &remove_noop_landing_pads::RemoveNoopLandingPads, - &cleanup_post_borrowck::CleanupNonCodegenStatements, + &cleanup_post_borrowck::CleanupPostBorrowck, &simplify::SimplifyCfg::new("early-opt"), &deref_separator::Derefer, ]; 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, From 62f9084dfa58cfb395606128bc5d33ef483d1c8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 17 Dec 2022 00:00:00 +0000 Subject: [PATCH 3/4] Remove false edges in CleanupPostBorrowck --- .../src/cleanup_post_borrowck.rs | 28 +++++++++--------- compiler/rustc_mir_transform/src/lib.rs | 5 +--- .../src/remove_false_edges.rs | 29 ------------------- 3 files changed, 16 insertions(+), 46 deletions(-) delete mode 100644 compiler/rustc_mir_transform/src/remove_false_edges.rs diff --git a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs index fe5295afaced7..d435d3ee69b76 100644 --- a/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs +++ b/compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs @@ -1,32 +1,26 @@ -//! 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::{Body, BorrowKind, Rvalue, StatementKind}; +use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind}; use rustc_middle::ty::TyCtxt; pub struct CleanupPostBorrowck; 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_preserves_cfg() { + for basic_block in body.basic_blocks.as_mut() { for statement in basic_block.statements.iter_mut() { match statement.kind { StatementKind::AscribeUserType(..) @@ -35,6 +29,14 @@ impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck { _ => (), } } + let terminator = basic_block.terminator_mut(); + match terminator.kind { + TerminatorKind::FalseEdge { real_target, .. } + | TerminatorKind::FalseUnwind { real_target, .. } => { + terminator.kind = TerminatorKind::Goto { target: real_target }; + } + _ => {} + } } body.user_type_annotations.raw.clear(); diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index e28406ce67ea6..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::CleanupPostBorrowck, &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, - } - } - } -} From acaa2c1235080aa1dc66133f840f7b5aa37dd016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Sat, 17 Dec 2022 00:00:00 +0000 Subject: [PATCH 4/4] ./x.py test --bless --- ...e_borrows.match_guard.CleanupPostBorrowck.diff} | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) rename src/test/mir-opt/{remove_fake_borrows.match_guard.CleanupNonCodegenStatements.diff => remove_fake_borrows.match_guard.CleanupPostBorrowck.diff} (90%) 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 - } }