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 (Taylor's Version) #91475

Merged
merged 9 commits into from
Dec 5, 2021
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