Rollup merge of #105835 - tmiasko:cleanup-post-borrowck, r=JakobDegen
Refactor post borrowck cleanup passes
This commit is contained in:
commit
52fe5a1cc1
5 changed files with 35 additions and 80 deletions
|
@ -1,39 +1,44 @@
|
||||||
//! This module provides a pass to replacing the following statements with
|
//! This module provides a pass that removes parts of MIR that are no longer relevant after
|
||||||
//! [`Nop`]s
|
//! analysis phase and borrowck. In particular, it removes false edges, user type annotations and
|
||||||
|
//! replaces following statements with [`Nop`]s:
|
||||||
//!
|
//!
|
||||||
//! - [`AscribeUserType`]
|
//! - [`AscribeUserType`]
|
||||||
//! - [`FakeRead`]
|
//! - [`FakeRead`]
|
||||||
//! - [`Assign`] statements with a [`Shallow`] borrow
|
//! - [`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
|
//! [`AscribeUserType`]: rustc_middle::mir::StatementKind::AscribeUserType
|
||||||
//! [`Shallow`]: rustc_middle::mir::BorrowKind::Shallow
|
|
||||||
//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead
|
|
||||||
//! [`Assign`]: rustc_middle::mir::StatementKind::Assign
|
//! [`Assign`]: rustc_middle::mir::StatementKind::Assign
|
||||||
//! [`ForMatchGuard`]: rustc_middle::mir::FakeReadCause::ForMatchGuard
|
//! [`FakeRead`]: rustc_middle::mir::StatementKind::FakeRead
|
||||||
//! [`Nop`]: rustc_middle::mir::StatementKind::Nop
|
//! [`Nop`]: rustc_middle::mir::StatementKind::Nop
|
||||||
|
//! [`Shallow`]: rustc_middle::mir::BorrowKind::Shallow
|
||||||
|
|
||||||
use crate::MirPass;
|
use crate::MirPass;
|
||||||
use rustc_middle::mir::visit::MutVisitor;
|
use rustc_middle::mir::{Body, BorrowKind, Rvalue, StatementKind, TerminatorKind};
|
||||||
use rustc_middle::mir::{Body, BorrowKind, Location, Rvalue};
|
|
||||||
use rustc_middle::mir::{Statement, StatementKind};
|
|
||||||
use rustc_middle::ty::TyCtxt;
|
use rustc_middle::ty::TyCtxt;
|
||||||
|
|
||||||
pub struct CleanupNonCodegenStatements;
|
pub struct CleanupPostBorrowck;
|
||||||
|
|
||||||
pub struct DeleteNonCodegenStatements<'tcx> {
|
impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck {
|
||||||
tcx: TyCtxt<'tcx>,
|
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();
|
body.user_type_annotations.raw.clear();
|
||||||
|
|
||||||
for decl in &mut body.local_decls {
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -77,8 +77,6 @@ mod match_branches;
|
||||||
mod multiple_return_terminators;
|
mod multiple_return_terminators;
|
||||||
mod normalize_array_len;
|
mod normalize_array_len;
|
||||||
mod nrvo;
|
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_noop_landing_pads;
|
||||||
mod remove_storage_markers;
|
mod remove_storage_markers;
|
||||||
mod remove_uninit_drops;
|
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.
|
/// 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>) {
|
fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
|
||||||
let passes: &[&dyn MirPass<'tcx>] = &[
|
let passes: &[&dyn MirPass<'tcx>] = &[
|
||||||
&remove_false_edges::RemoveFalseEdges,
|
&cleanup_post_borrowck::CleanupPostBorrowck,
|
||||||
&simplify_branches::SimplifyConstCondition::new("initial"),
|
&simplify_branches::SimplifyConstCondition::new("initial"),
|
||||||
&remove_noop_landing_pads::RemoveNoopLandingPads,
|
&remove_noop_landing_pads::RemoveNoopLandingPads,
|
||||||
&cleanup_post_borrowck::CleanupNonCodegenStatements,
|
|
||||||
&simplify::SimplifyCfg::new("early-opt"),
|
&simplify::SimplifyCfg::new("early-opt"),
|
||||||
&deref_separator::Derefer,
|
&deref_separator::Derefer,
|
||||||
];
|
];
|
||||||
|
|
|
@ -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,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,5 @@
|
||||||
- // MIR for `match_guard` before CleanupNonCodegenStatements
|
- // MIR for `match_guard` before CleanupPostBorrowck
|
||||||
+ // MIR for `match_guard` after CleanupNonCodegenStatements
|
+ // MIR for `match_guard` after CleanupPostBorrowck
|
||||||
|
|
||||||
fn match_guard(_1: Option<&&i32>, _2: bool) -> i32 {
|
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
|
debug x => _1; // in scope 0 at $DIR/remove_fake_borrows.rs:+0:16: +0:17
|
||||||
|
@ -29,7 +29,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
bb3: {
|
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: {
|
bb4: {
|
||||||
|
@ -62,15 +63,12 @@
|
||||||
|
|
||||||
bb6: {
|
bb6: {
|
||||||
StorageDead(_8); // scope 0 at $DIR/remove_fake_borrows.rs:+2:20: +2:21
|
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: {
|
bb7: {
|
||||||
return; // scope 0 at $DIR/remove_fake_borrows.rs:+5:2: +5:2
|
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
// ignore-wasm32-bare compiled with panic=abort by default
|
// 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 {
|
fn match_guard(x: Option<&&i32>, c: bool) -> i32 {
|
||||||
match x {
|
match x {
|
||||||
Some(0) if c => 0,
|
Some(0) if c => 0,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue