Skip to content
4 changes: 4 additions & 0 deletions compiler/rustc_const_eval/src/transform/promote_consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ pub struct PromoteTemps<'tcx> {
}

impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
fn phase_change(&self) -> Option<MirPhase> {
Some(MirPhase::ConstPromotion)
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// There's not really any point in promoting errorful MIR.
//
Expand Down
15 changes: 15 additions & 0 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ use rustc_hir::def::{CtorKind, Namespace};
use rustc_hir::def_id::{DefId, CRATE_DEF_INDEX};
use rustc_hir::{self, GeneratorKind};
use rustc_hir::{self as hir, HirId};
use rustc_session::Session;
use rustc_target::abi::{Size, VariantIdx};

use polonius_engine::Atom;
Expand Down Expand Up @@ -99,7 +100,21 @@ pub trait MirPass<'tcx> {
}
}

/// Returns `true` if this pass is enabled with the current combination of compiler flags.
fn is_enabled(&self, _sess: &Session) -> bool {
true
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>);

/// If this pass causes the MIR to enter a new phase, return that phase.
fn phase_change(&self) -> Option<MirPhase> {
None
}

fn is_mir_dump_enabled(&self) -> bool {
true
}
}

/// The various "big phases" that MIR goes through.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_dataflow/src/rustc_peek.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use crate::{Analysis, JoinSemiLattice, Results, ResultsCursor};

pub struct SanityCheck;

// FIXME: This should be a `MirLint`, but it needs to be moved back to `rustc_mir_transform` first.
impl<'tcx> MirPass<'tcx> for SanityCheck {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
use crate::has_rustc_mir_with;
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_mir_transform/src/add_retag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,11 @@ fn may_be_reference(ty: Ty<'tcx>) -> bool {
}

impl<'tcx> MirPass<'tcx> for AddRetag {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if !tcx.sess.opts.debugging_opts.mir_emit_retag {
return;
}
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.opts.debugging_opts.mir_emit_retag
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// We need an `AllCallEdges` pass before we can do any work.
super::add_call_guards::AllCallEdges.run_pass(tcx, body);

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_mir_transform/src/check_const_item_mutation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::CONST_ITEM_MUTATION;
use rustc_span::def_id::DefId;

use crate::MirPass;
use crate::MirLint;

pub struct CheckConstItemMutation;

impl<'tcx> MirPass<'tcx> for CheckConstItemMutation {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
impl<'tcx> MirLint<'tcx> for CheckConstItemMutation {
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
let mut checker = ConstMutationChecker { body, tcx, target_local: None };
checker.visit_body(&body);
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_mir_transform/src/check_packed_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,16 @@ use rustc_session::lint::builtin::UNALIGNED_REFERENCES;
use rustc_span::symbol::sym;

use crate::util;
use crate::MirPass;
use crate::MirLint;

pub(crate) fn provide(providers: &mut Providers) {
*providers = Providers { unsafe_derive_on_repr_packed, ..*providers };
}

pub struct CheckPackedRef;

impl<'tcx> MirPass<'tcx> for CheckPackedRef {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
impl<'tcx> MirLint<'tcx> for CheckPackedRef {
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
let param_env = tcx.param_env(body.source.def_id());
let source_info = SourceInfo::outermost(body.span);
let mut checker = PackedRefChecker { body, tcx, param_env, source_info };
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_mir_transform/src/const_debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ use rustc_index::{bit_set::BitSet, vec::IndexVec};
pub struct ConstDebugInfo;

impl<'tcx> MirPass<'tcx> for ConstDebugInfo {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if !tcx.sess.opts.debugging_opts.unsound_mir_opts {
return;
}
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.opts.debugging_opts.unsound_mir_opts && sess.mir_opt_level() > 0
}

fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
trace!("running ConstDebugInfo on {:?}", body.source);

for (local, constant) in find_optimization_oportunities(body) {
Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_mir_transform/src/const_goto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ use super::simplify::{simplify_cfg, simplify_locals};
pub struct ConstGoto;

impl<'tcx> MirPass<'tcx> for ConstGoto {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 4
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.mir_opt_level() < 4 {
return;
}
trace!("Running ConstGoto on {:?}", body.source);
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
let mut opt_finder =
Expand Down
7 changes: 7 additions & 0 deletions compiler/rustc_mir_transform/src/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,13 @@ macro_rules! throw_machine_stop_str {
pub struct ConstProp;

impl<'tcx> MirPass<'tcx> for ConstProp {
fn is_enabled(&self, _sess: &rustc_session::Session) -> bool {
// FIXME(#70073): Unlike the other passes in "optimizations", this one emits errors, so it
// runs even when MIR optimizations are disabled. We should separate the lint out from the
// transform and move the lint as early in the pipeline as possible.
true
}

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
4 changes: 4 additions & 0 deletions compiler/rustc_mir_transform/src/coverage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ impl Error {
pub struct InstrumentCoverage;

impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.instrument_coverage()
}

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

Expand Down
7 changes: 4 additions & 3 deletions compiler/rustc_mir_transform/src/deduplicate_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ use super::simplify::simplify_cfg;
pub struct DeduplicateBlocks;

impl<'tcx> MirPass<'tcx> for DeduplicateBlocks {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 4
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if tcx.sess.mir_opt_level() < 4 {
return;
}
debug!("Running DeduplicateBlocks on `{:?}`", body.source);
let duplicates = find_duplicates(body);
let has_opts_to_apply = !duplicates.is_empty();
Expand Down
15 changes: 6 additions & 9 deletions compiler/rustc_mir_transform/src/dest_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -124,18 +124,15 @@ 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>) {
// FIXME(#79191, #82678)
if !tcx.sess.opts.debugging_opts.unsound_mir_opts {
return;
}

fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
// FIXME(#79191, #82678): This is unsound.
//
// Only run at mir-opt-level=3 or higher for now (we don't fix up debuginfo and remove
// storage statements at the moment).
if tcx.sess.mir_opt_level() < 3 {
return;
}
sess.opts.debugging_opts.unsound_mir_opts && sess.mir_opt_level() >= 3
}

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
12 changes: 5 additions & 7 deletions compiler/rustc_mir_transform/src/early_otherwise_branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,14 @@ use super::simplify::simplify_cfg;
pub struct EarlyOtherwiseBranch;

impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
// FIXME(#78496)
if !tcx.sess.opts.debugging_opts.unsound_mir_opts {
return;
}
sess.opts.debugging_opts.unsound_mir_opts && sess.mir_opt_level() >= 3
}

if tcx.sess.mir_opt_level() < 3 {
return;
}
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
trace!("running EarlyOtherwiseBranch on {:?}", body.source);

// we are only interested in this bb if the terminator is a switchInt
let bbs_with_switch =
body.basic_blocks().iter_enumerated().filter(|(_, bb)| is_switch(bb.terminator()));
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_mir_transform/src/elaborate_drops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ use std::fmt;
pub struct ElaborateDrops;

impl<'tcx> MirPass<'tcx> for ElaborateDrops {
fn phase_change(&self) -> Option<MirPhase> {
Some(MirPhase::DropLowering)
}

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

Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_mir_transform/src/function_item_references.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ use rustc_session::lint::builtin::FUNCTION_ITEM_REFERENCES;
use rustc_span::{symbol::sym, Span};
use rustc_target::spec::abi::Abi;

use crate::MirPass;
use crate::MirLint;

pub struct FunctionItemReferences;

impl<'tcx> MirPass<'tcx> for FunctionItemReferences {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
impl<'tcx> MirLint<'tcx> for FunctionItemReferences {
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
let mut checker = FunctionItemRefChecker { tcx, body };
checker.visit_body(&body);
}
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_mir_transform/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,10 @@ fn create_cases<'tcx>(
}

impl<'tcx> MirPass<'tcx> for StateTransform {
fn phase_change(&self) -> Option<MirPhase> {
Some(MirPhase::GeneratorLowering)
}

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
19 changes: 7 additions & 12 deletions compiler/rustc_mir_transform/src/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,16 @@ struct CallSite<'tcx> {
source_info: SourceInfo,
}

/// Returns true if MIR inlining is enabled in the current compilation session.
crate fn is_enabled(tcx: TyCtxt<'_>) -> bool {
if let Some(enabled) = tcx.sess.opts.debugging_opts.inline_mir {
return enabled;
}

tcx.sess.mir_opt_level() >= 3
}

impl<'tcx> MirPass<'tcx> for Inline {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if !is_enabled(tcx) {
return;
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
if let Some(enabled) = sess.opts.debugging_opts.inline_mir {
return enabled;
}

sess.opts.mir_opt_level() >= 3
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let span = trace_span!("inline", body = %tcx.def_path_str(body.source.def_id()));
let _guard = span.enter();
if inline(tcx, body) {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_mir_transform/src/instcombine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ use rustc_middle::ty::{self, TyCtxt};
pub struct InstCombine;

impl<'tcx> MirPass<'tcx> for InstCombine {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() > 0
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let (basic_blocks, local_decls) = body.basic_blocks_and_local_decls_mut();
let ctx = InstCombineContext { tcx, local_decls };
Expand Down
Loading