Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a MIR pass manager #77665

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,7 @@ fn test_debugging_options_tracking_hash() {
tracked!(link_only, true);
tracked!(merge_functions, Some(MergeFunctions::Disabled));
tracked!(mir_emit_retag, true);
tracked!(mir_opt_skip_pass, vec!["ConstProp".to_owned()]);
tracked!(mir_opt_level, 3);
tracked!(mutable_noalias, true);
tracked!(new_llvm_pass_manager, true);
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ extern crate tracing;
#[macro_use]
extern crate rustc_middle;

#[macro_use]
pub mod transform;

mod borrow_check;
pub mod const_eval;
pub mod dataflow;
pub mod interpret;
pub mod monomorphize;
mod shim;
pub mod transform;
pub mod util;

use rustc_middle::ty::query::Providers;
Expand Down
23 changes: 10 additions & 13 deletions compiler/rustc_mir/src/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use std::iter;

use crate::transform::{
add_call_guards, add_moves_for_packed_drops, no_landing_pads, remove_noop_landing_pads,
run_passes, simplify,
simplify, PassManager,
};
use crate::util::elaborate_drops::{self, DropElaborator, DropFlagMode, DropStyle};
use crate::util::expand_aggregate;
Expand Down Expand Up @@ -75,18 +75,15 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
};
debug!("make_shim({:?}) = untransformed {:?}", instance, result);

run_passes(
tcx,
&mut result,
MirPhase::Const,
&[&[
&add_moves_for_packed_drops::AddMovesForPackedDrops,
&no_landing_pads::NoLandingPads::new(tcx),
&remove_noop_landing_pads::RemoveNoopLandingPads,
&simplify::SimplifyCfg::new("make_shim"),
&add_call_guards::CriticalCallEdges,
]],
);
if result.phase < MirPhase::Const {
run_passes!(PassManager::new(tcx, &mut result, MirPhase::Const) => [
add_moves_for_packed_drops::AddMovesForPackedDrops,
no_landing_pads::NoLandingPads::new(tcx),
remove_noop_landing_pads::RemoveNoopLandingPads,
simplify::SimplifyCfg::new("make_shim"),
add_call_guards::CriticalCallEdges,
]);
}

debug!("make_shim({:?}) = {:?}", instance, result);

Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir/src/transform/add_call_guards.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::transform::MirPass;
use crate::transform::{MirPass, OptLevel};
use rustc_index::vec::{Idx, IndexVec};
use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
Expand Down Expand Up @@ -31,6 +31,8 @@ pub use self::AddCallGuards::*;
*/

impl<'tcx> MirPass<'tcx> for AddCallGuards {
const LEVEL: OptLevel = OptLevel::ALWAYS;

fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
self.add_call_guards(body);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;

use crate::transform::MirPass;
use crate::transform::{MirPass, OptLevel};
use crate::util;
use crate::util::patch::MirPatch;

Expand Down Expand Up @@ -39,6 +39,8 @@ use crate::util::patch::MirPatch;
pub struct AddMovesForPackedDrops;

impl<'tcx> MirPass<'tcx> for AddMovesForPackedDrops {
const LEVEL: OptLevel = OptLevel::ALWAYS;

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
debug!("add_moves_for_packed_drops({:?} @ {:?})", body.source, body.span);
add_moves_for_packed_drops(tcx, body);
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir/src/transform/add_retag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! of MIR building, and only after this pass we think of the program has having the
//! normal MIR semantics.

use crate::transform::MirPass;
use crate::transform::{MirPass, OptLevel};
use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty, TyCtxt};

Expand Down Expand Up @@ -58,6 +58,8 @@ fn may_be_reference(ty: Ty<'tcx>) -> bool {
}

impl<'tcx> MirPass<'tcx> for AddRetag {
const LEVEL: OptLevel = OptLevel::ALWAYS;

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if !tcx.sess.opts.debugging_opts.mir_emit_retag {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::CONST_ITEM_MUTATION;
use rustc_span::def_id::DefId;

use crate::transform::MirPass;
use crate::transform::{MirPass, OptLevel};

// FIXME: This does not mutate the MIR, and should not be MIR pass.
pub struct CheckConstItemMutation;

impl<'tcx> MirPass<'tcx> for CheckConstItemMutation {
const LEVEL: OptLevel = OptLevel::ALWAYS;

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let mut checker = ConstMutationChecker { body, tcx, target_local: None };
checker.visit_body(&body);
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_mir/src/transform/check_packed_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ use rustc_middle::mir::*;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::lint::builtin::UNALIGNED_REFERENCES;

use crate::transform::MirPass;
use crate::transform::{MirPass, OptLevel};
use crate::util;

// FIXME: This does not mutate the MIR, and should not be `MirPass`.
pub struct CheckPackedRef;

impl<'tcx> MirPass<'tcx> for CheckPackedRef {
const LEVEL: OptLevel = OptLevel::ALWAYS;

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let param_env = tcx.param_env(body.source.def_id());
let source_info = SourceInfo::outermost(body.span);
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir/src/transform/cleanup_post_borrowck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//! [`ForMatchGuard`]: rustc_middle::mir::FakeReadCause::ForMatchGuard
//! [`Nop`]: rustc_middle::mir::StatementKind::Nop

use crate::transform::MirPass;
use crate::transform::{MirPass, OptLevel};
use rustc_middle::mir::visit::MutVisitor;
use rustc_middle::mir::{Body, BorrowKind, Location, Rvalue};
use rustc_middle::mir::{Statement, StatementKind};
Expand All @@ -31,6 +31,8 @@ pub struct DeleteNonCodegenStatements<'tcx> {
}

impl<'tcx> MirPass<'tcx> for CleanupNonCodegenStatements {
const LEVEL: OptLevel = OptLevel::ALWAYS;

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let mut delete = DeleteNonCodegenStatements { tcx };
delete.visit_body(body);
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_mir/src/transform/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use crate::interpret::{
InterpCx, LocalState, LocalValue, MemPlace, Memory, MemoryKind, OpTy, Operand as InterpOperand,
PlaceTy, Pointer, ScalarMaybeUninit, StackPopCleanup,
};
use crate::transform::MirPass;
use crate::transform::{MirPass, OptLevel};

/// The maximum number of bytes that we'll allocate space for a local or the return value.
/// Needed for #66397, because otherwise we eval into large places and that can cause OOM or just
Expand Down Expand Up @@ -60,6 +60,9 @@ macro_rules! throw_machine_stop_str {
pub struct ConstProp;

impl<'tcx> MirPass<'tcx> for ConstProp {
// FIXME(#70073): This pass is responsible for both optimization as well as some lints.
const LEVEL: OptLevel = OptLevel::ALWAYS;

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// will be evaluated by miri and produce its errors there
if body.source.promoted.is_some() {
Expand Down
14 changes: 5 additions & 9 deletions compiler/rustc_mir/src/transform/copy_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
//! (non-mutating) use of `SRC`. These restrictions are conservative and may be relaxed in the
//! future.

use crate::transform::MirPass;
use crate::transform::{MirPass, OptLevel};
use crate::util::def_use::DefUseAnalysis;
use rustc_middle::mir::visit::MutVisitor;
use rustc_middle::mir::{
Expand All @@ -30,15 +30,11 @@ use rustc_middle::ty::TyCtxt;
pub struct CopyPropagation;

impl<'tcx> MirPass<'tcx> for CopyPropagation {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let opts = &tcx.sess.opts.debugging_opts;
// We only run when the MIR optimization level is > 1.
// This avoids a slow pass, and messing up debug info.
// FIXME(76740): This optimization is buggy and can cause unsoundness.
if opts.mir_opt_level <= 1 || !opts.unsound_mir_opts {
return;
}
// This pass is slow and doesn't handle debug info. It shouldn't run by default.
// FIXME(76740): This optimization is buggy and can cause unsoundness.
const LEVEL: OptLevel = OptLevel::Unsound;

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let mut def_use_analysis = DefUseAnalysis::new(body);
loop {
def_use_analysis.analyze(body);
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir/src/transform/deaggregator.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
use crate::transform::MirPass;
use crate::transform::{MirPass, OptLevel};
use crate::util::expand_aggregate;
use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;

pub struct Deaggregator;

impl<'tcx> MirPass<'tcx> for Deaggregator {
const LEVEL: OptLevel = OptLevel::ALWAYS;

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
let local_decls = &*local_decls;
Expand Down
12 changes: 5 additions & 7 deletions compiler/rustc_mir/src/transform/dest_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
use crate::dataflow::impls::{MaybeInitializedLocals, MaybeLiveLocals};
use crate::dataflow::Analysis;
use crate::{
transform::MirPass,
transform::{MirPass, OptLevel},
util::{dump_mir, PassWhere},
};
use itertools::Itertools;
Expand All @@ -126,13 +126,11 @@ const MAX_BLOCKS: usize = 250;
pub struct DestinationPropagation;

impl<'tcx> MirPass<'tcx> for DestinationPropagation {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// Only run at mir-opt-level=2 or higher for now (we don't fix up debuginfo and remove
// storage statements at the moment).
if tcx.sess.opts.debugging_opts.mir_opt_level <= 1 {
return;
}
// Only run at mir-opt-level=2 or higher for now (we don't fix up debuginfo and remove
// storage statements at the moment).
const LEVEL: OptLevel = OptLevel::N(2);

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let def_id = body.source.def_id();

let candidates = find_candidates(tcx, body);
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir/src/transform/dump_mir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::fmt;
use std::fs::File;
use std::io;

use crate::transform::MirPass;
use crate::transform::{MirPass, OptLevel};
use crate::util as mir_util;
use rustc_middle::mir::Body;
use rustc_middle::ty::TyCtxt;
Expand All @@ -14,6 +14,8 @@ use rustc_session::config::{OutputFilenames, OutputType};
pub struct Marker(pub &'static str);

impl<'tcx> MirPass<'tcx> for Marker {
const LEVEL: OptLevel = OptLevel::ALWAYS;

fn name(&self) -> Cow<'_, str> {
Cow::Borrowed(self.0)
}
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_mir/src/transform/early_otherwise_branch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use crate::{transform::MirPass, util::patch::MirPatch};
use crate::transform::{MirPass, OptLevel};
use crate::util::patch::MirPatch;
use rustc_middle::mir::*;
use rustc_middle::ty::{Ty, TyCtxt};
use std::{borrow::Cow, fmt::Debug};
Expand All @@ -25,10 +26,9 @@ use super::simplify::simplify_cfg;
pub struct EarlyOtherwiseBranch;

impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
const LEVEL: OptLevel = OptLevel::N(2);

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level < 2 {
return;
}
trace!("running EarlyOtherwiseBranch on {:?}", body.source);
// we are only interested in this bb if the terminator is a switchInt
let bbs_with_switch =
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir/src/transform/elaborate_drops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::dataflow::on_lookup_result_bits;
use crate::dataflow::MoveDataParamEnv;
use crate::dataflow::{on_all_children_bits, on_all_drop_children_bits};
use crate::dataflow::{Analysis, ResultsCursor};
use crate::transform::MirPass;
use crate::transform::{MirPass, OptLevel};
use crate::util::elaborate_drops::{elaborate_drop, DropFlagState, Unwind};
use crate::util::elaborate_drops::{DropElaborator, DropFlagMode, DropStyle};
use crate::util::patch::MirPatch;
Expand All @@ -20,6 +20,8 @@ use std::fmt;
pub struct ElaborateDrops;

impl<'tcx> MirPass<'tcx> for ElaborateDrops {
const LEVEL: OptLevel = OptLevel::ALWAYS;

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
debug!("elaborate_drops({:?} @ {:?})", body.source, body.span);

Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_mir/src/transform/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ use crate::dataflow::impls::{
use crate::dataflow::{self, Analysis};
use crate::transform::no_landing_pads::no_landing_pads;
use crate::transform::simplify;
use crate::transform::MirPass;
use crate::transform::{MirPass, OptLevel};
use crate::util::dump_mir;
use crate::util::expand_aggregate;
use crate::util::storage;
Expand Down Expand Up @@ -1235,6 +1235,9 @@ fn create_cases<'tcx>(
}

impl<'tcx> MirPass<'tcx> for StateTransform {
// Even if we don't do optimizations, we still have to lower generators for codegen.
const LEVEL: OptLevel = OptLevel::ALWAYS;

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let yield_ty = if let Some(yield_ty) = body.yield_ty {
yield_ty
Expand Down
28 changes: 14 additions & 14 deletions compiler/rustc_mir/src/transform/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc_middle::ty::{self, ConstKind, Instance, InstanceDef, ParamEnv, Ty, TyC
use rustc_target::spec::abi::Abi;

use super::simplify::{remove_dead_blocks, CfgSimplifier};
use crate::transform::MirPass;
use crate::transform::{MirPass, OptLevel};
use std::collections::VecDeque;
use std::iter;

Expand All @@ -37,21 +37,21 @@ struct CallSite<'tcx> {
}

impl<'tcx> MirPass<'tcx> for Inline {
const LEVEL: OptLevel = OptLevel::N(2);

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
if tcx.sess.opts.debugging_opts.instrument_coverage {
// The current implementation of source code coverage injects code region counters
// into the MIR, and assumes a 1-to-1 correspondence between MIR and source-code-
// based function.
debug!("function inlining is disabled when compiling with `instrument_coverage`");
} else {
Inliner {
tcx,
param_env: tcx.param_env_reveal_all_normalized(body.source.def_id()),
codegen_fn_attrs: tcx.codegen_fn_attrs(body.source.def_id()),
}
.run_pass(body);
if tcx.sess.opts.debugging_opts.instrument_coverage {
// The current implementation of source code coverage injects code region counters
// into the MIR, and assumes a 1-to-1 correspondence between MIR and source-code-
// based function.
debug!("function inlining is disabled when compiling with `instrument_coverage`");
} else {
Inliner {
tcx,
param_env: tcx.param_env_reveal_all_normalized(body.source.def_id()),
codegen_fn_attrs: tcx.codegen_fn_attrs(body.source.def_id()),
}
.run_pass(body);
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir/src/transform/instcombine.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Performs various peephole optimizations.

use crate::transform::MirPass;
use crate::transform::{MirPass, OptLevel};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir::Mutability;
use rustc_index::vec::Idx;
Expand All @@ -19,6 +19,8 @@ use std::mem;
pub struct InstCombine;

impl<'tcx> MirPass<'tcx> for InstCombine {
const LEVEL: OptLevel = OptLevel::DEFAULT;

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// First, find optimization opportunities. This is done in a pre-pass to keep the MIR
// read-only so that we can do global analyses on the MIR in the process (e.g.
Expand Down
Loading