Move MirPass to rustc_mir_transform.

Because that's now the only crate that uses it.

Moving stuff out of `rustc_middle` is always welcome.

I chose to use `impl crate::MirPass`/`impl crate::MirLint` (with
explicit `crate::`) everywhere because that's the only mention of
`MirPass`/`MirLint` used in all of these files. (Prior to this change,
`MirPass` was mostly imported via `use rustc_middle::mir::*` items.)
This commit is contained in:
Nicholas Nethercote 2024-09-03 15:45:27 +10:00
parent 5410900aaa
commit 2aae619edb
58 changed files with 143 additions and 162 deletions

View File

@ -3,8 +3,6 @@
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
use std::borrow::Cow;
use std::cell::RefCell;
use std::collections::hash_map::Entry;
use std::fmt::{self, Debug, Formatter};
use std::ops::{Index, IndexMut};
use std::{iter, mem};
@ -26,7 +24,6 @@ use rustc_index::bit_set::BitSet;
use rustc_index::{Idx, IndexSlice, IndexVec};
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
use rustc_serialize::{Decodable, Encodable};
use rustc_session::Session;
use rustc_span::source_map::Spanned;
use rustc_span::symbol::Symbol;
use rustc_span::{Span, DUMMY_SP};
@ -106,65 +103,6 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> {
}
}
thread_local! {
static PASS_NAMES: RefCell<FxHashMap<&'static str, &'static str>> = {
RefCell::new(FxHashMap::default())
};
}
/// Converts a MIR pass name into a snake case form to match the profiling naming style.
fn to_profiler_name(type_name: &'static str) -> &'static str {
PASS_NAMES.with(|names| match names.borrow_mut().entry(type_name) {
Entry::Occupied(e) => *e.get(),
Entry::Vacant(e) => {
let snake_case: String = type_name
.chars()
.flat_map(|c| {
if c.is_ascii_uppercase() {
vec!['_', c.to_ascii_lowercase()]
} else if c == '-' {
vec!['_']
} else {
vec![c]
}
})
.collect();
let result = &*String::leak(format!("mir_pass{}", snake_case));
e.insert(result);
result
}
})
}
/// A streamlined trait that you can implement to create a pass; the
/// pass will be named after the type, and it will consist of a main
/// loop that goes over each available MIR and applies `run_pass`.
pub trait MirPass<'tcx> {
fn name(&self) -> &'static str {
// FIXME Simplify the implementation once more `str` methods get const-stable.
// See copypaste in `MirLint`
const {
let name = std::any::type_name::<Self>();
crate::util::common::c_name(name)
}
}
fn profiler_name(&self) -> &'static str {
to_profiler_name(self.name())
}
/// 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>);
fn is_mir_dump_enabled(&self) -> bool {
true
}
}
impl MirPhase {
/// Gets the index of the current MirPhase within the set of all `MirPhase`s.
///

View File

@ -20,19 +20,3 @@ pub fn to_readable_str(mut val: usize) -> String {
groups.join("_")
}
// const wrapper for `if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }`
pub const fn c_name(name: &'static str) -> &'static str {
// FIXME Simplify the implementation once more `str` methods get const-stable.
// and inline into call site
let bytes = name.as_bytes();
let mut i = bytes.len();
while i > 0 && bytes[i - 1] != b':' {
i = i - 1;
}
let (_, bytes) = bytes.split_at(i);
match std::str::from_utf8(bytes) {
Ok(name) => name,
Err(_) => name,
}
}

View File

@ -22,7 +22,7 @@ use rustc_target::spec::PanicStrategy;
#[derive(PartialEq)]
pub struct AbortUnwindingCalls;
impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls {
impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let def_id = body.source.def_id();
let kind = tcx.def_kind(def_id);

View File

@ -30,7 +30,7 @@ pub use self::AddCallGuards::*;
*
*/
impl<'tcx> MirPass<'tcx> for AddCallGuards {
impl<'tcx> crate::MirPass<'tcx> for AddCallGuards {
fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
self.add_call_guards(body);
}

View File

@ -37,7 +37,7 @@ use crate::util;
/// blowup.
pub struct AddMovesForPackedDrops;
impl<'tcx> MirPass<'tcx> for AddMovesForPackedDrops {
impl<'tcx> crate::MirPass<'tcx> for AddMovesForPackedDrops {
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);

View File

@ -48,7 +48,7 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b
}
}
impl<'tcx> MirPass<'tcx> for AddRetag {
impl<'tcx> crate::MirPass<'tcx> for AddRetag {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.opts.unstable_opts.mir_emit_retag
}

View File

@ -62,7 +62,7 @@ pub fn subtype_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
checker.patcher.apply(body);
}
impl<'tcx> MirPass<'tcx> for Subtyper {
impl<'tcx> crate::MirPass<'tcx> for Subtyper {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
subtype_finder(tcx, body);
}

View File

@ -9,7 +9,7 @@ use tracing::{debug, trace};
pub struct CheckAlignment;
impl<'tcx> MirPass<'tcx> for CheckAlignment {
impl<'tcx> crate::MirPass<'tcx> for CheckAlignment {
fn is_enabled(&self, sess: &Session) -> bool {
// FIXME(#112480) MSVC and rustc disagree on minimum stack alignment on x86 Windows
if sess.target.llvm_target == "i686-pc-windows-msvc" {

View File

@ -6,11 +6,11 @@ use rustc_session::lint::builtin::CONST_ITEM_MUTATION;
use rustc_span::def_id::DefId;
use rustc_span::Span;
use crate::{errors, MirLint};
use crate::errors;
pub struct CheckConstItemMutation;
impl<'tcx> MirLint<'tcx> for CheckConstItemMutation {
impl<'tcx> crate::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);

View File

@ -3,11 +3,11 @@ use rustc_middle::mir::*;
use rustc_middle::span_bug;
use rustc_middle::ty::{self, TyCtxt};
use crate::{errors, util, MirLint};
use crate::{errors, util};
pub struct CheckPackedRef;
impl<'tcx> MirLint<'tcx> for CheckPackedRef {
impl<'tcx> crate::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);

View File

@ -21,11 +21,9 @@ use rustc_middle::mir::{Body, BorrowKind, CastKind, Rvalue, StatementKind, Termi
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::TyCtxt;
use crate::MirPass;
pub struct CleanupPostBorrowck;
impl<'tcx> MirPass<'tcx> for CleanupPostBorrowck {
impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck {
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() {

View File

@ -19,7 +19,7 @@ use crate::ssa::SsaLocals;
/// We want to replace all those locals by `_a`, either copied or moved.
pub struct CopyProp;
impl<'tcx> MirPass<'tcx> for CopyProp {
impl<'tcx> crate::MirPass<'tcx> for CopyProp {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 1
}

View File

@ -1535,7 +1535,7 @@ fn check_field_tys_sized<'tcx>(
}
}
impl<'tcx> MirPass<'tcx> for StateTransform {
impl<'tcx> crate::MirPass<'tcx> for StateTransform {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let Some(old_yield_ty) = body.yield_ty() else {
// This only applies to coroutines

View File

@ -28,14 +28,13 @@ use tracing::{debug, debug_span, instrument, trace};
use crate::coverage::counters::{CounterIncrementSite, CoverageCounters};
use crate::coverage::graph::CoverageGraph;
use crate::coverage::mappings::ExtractedMappings;
use crate::MirPass;
/// Inserts `StatementKind::Coverage` statements that either instrument the binary with injected
/// counters, via intrinsic `llvm.instrprof.increment`, and/or inject metadata used during codegen
/// to construct the coverage map.
pub struct InstrumentCoverage;
impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
impl<'tcx> crate::MirPass<'tcx> for InstrumentCoverage {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.instrument_coverage()
}

View File

@ -8,11 +8,9 @@ use rustc_middle::mir::{
use rustc_middle::ty::TyCtxt;
use tracing::instrument;
use crate::MirPass;
pub struct CtfeLimit;
impl<'tcx> MirPass<'tcx> for CtfeLimit {
impl<'tcx> crate::MirPass<'tcx> for CtfeLimit {
#[instrument(skip(self, _tcx, body))]
fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let doms = body.basic_blocks.dominators();

View File

@ -28,7 +28,7 @@ const PLACE_LIMIT: usize = 100;
pub struct DataflowConstProp;
impl<'tcx> MirPass<'tcx> for DataflowConstProp {
impl<'tcx> crate::MirPass<'tcx> for DataflowConstProp {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 3
}

View File

@ -132,7 +132,7 @@ pub enum DeadStoreElimination {
Final,
}
impl<'tcx> MirPass<'tcx> for DeadStoreElimination {
impl<'tcx> crate::MirPass<'tcx> for DeadStoreElimination {
fn name(&self) -> &'static str {
match self {
DeadStoreElimination::Initial => "DeadStoreElimination-initial",

View File

@ -15,7 +15,7 @@ use super::simplify::simplify_cfg;
pub struct DeduplicateBlocks;
impl<'tcx> MirPass<'tcx> for DeduplicateBlocks {
impl<'tcx> crate::MirPass<'tcx> for DeduplicateBlocks {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 4
}

View File

@ -78,7 +78,7 @@ pub fn deref_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
checker.patcher.apply(body);
}
impl<'tcx> MirPass<'tcx> for Derefer {
impl<'tcx> crate::MirPass<'tcx> for Derefer {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
deref_finder(tcx, body);
}

View File

@ -146,11 +146,9 @@ use rustc_mir_dataflow::points::{save_as_intervals, DenseLocationMap, PointIndex
use rustc_mir_dataflow::Analysis;
use tracing::{debug, trace};
use crate::MirPass;
pub struct DestinationPropagation;
impl<'tcx> MirPass<'tcx> for DestinationPropagation {
impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
// For now, only run at MIR opt level 3. Two things need to be changed before this can be
// turned on by default:

View File

@ -7,11 +7,9 @@ use rustc_middle::mir::{write_mir_pretty, Body};
use rustc_middle::ty::TyCtxt;
use rustc_session::config::{OutFileName, OutputType};
use crate::MirPass;
pub struct Marker(pub &'static str);
impl<'tcx> MirPass<'tcx> for Marker {
impl<'tcx> crate::MirPass<'tcx> for Marker {
fn name(&self) -> &'static str {
self.0
}

View File

@ -92,7 +92,7 @@ use super::simplify::simplify_cfg;
/// ```
pub struct EarlyOtherwiseBranch;
impl<'tcx> MirPass<'tcx> for EarlyOtherwiseBranch {
impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 2
}

View File

@ -88,7 +88,7 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
pub struct ElaborateBoxDerefs;
impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
impl<'tcx> crate::MirPass<'tcx> for ElaborateBoxDerefs {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
if let Some(def_id) = tcx.lang_items().owned_box() {
let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::ZERO].did;

View File

@ -49,7 +49,7 @@ use crate::deref_separator::deref_finder;
/// ```
pub struct ElaborateDrops;
impl<'tcx> MirPass<'tcx> for ElaborateDrops {
impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops {
#[instrument(level = "trace", skip(self, tcx, body))]
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
debug!("elaborate_drops({:?} @ {:?})", body.source, body.span);

View File

@ -9,11 +9,11 @@ use rustc_span::symbol::sym;
use rustc_span::Span;
use rustc_target::spec::abi::Abi;
use crate::{errors, MirLint};
use crate::errors;
pub struct FunctionItemReferences;
impl<'tcx> MirLint<'tcx> for FunctionItemReferences {
impl<'tcx> crate::MirLint<'tcx> for FunctionItemReferences {
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
let mut checker = FunctionItemRefChecker { tcx, body };
checker.visit_body(body);

View File

@ -111,7 +111,7 @@ use crate::ssa::{AssignedValue, SsaLocals};
pub struct GVN;
impl<'tcx> MirPass<'tcx> for GVN {
impl<'tcx> crate::MirPass<'tcx> for GVN {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 2
}

View File

@ -42,7 +42,7 @@ struct CallSite<'tcx> {
source_info: SourceInfo,
}
impl<'tcx> MirPass<'tcx> for Inline {
impl<'tcx> crate::MirPass<'tcx> for Inline {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
// FIXME(#127234): Coverage instrumentation currently doesn't handle inlined
// MIR correctly when Modified Condition/Decision Coverage is enabled.

View File

@ -27,7 +27,7 @@ impl InstSimplify {
}
}
impl<'tcx> MirPass<'tcx> for InstSimplify {
impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
fn name(&self) -> &'static str {
self.name()
}

View File

@ -61,7 +61,7 @@ const MAX_BACKTRACK: usize = 5;
const MAX_COST: usize = 100;
const MAX_PLACES: usize = 100;
impl<'tcx> MirPass<'tcx> for JumpThreading {
impl<'tcx> crate::MirPass<'tcx> for JumpThreading {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 2
}

View File

@ -25,11 +25,10 @@ use rustc_target::abi::{Abi, FieldIdx, HasDataLayout, Size, TargetDataLayout, Va
use tracing::{debug, instrument, trace};
use crate::errors::{AssertLint, AssertLintKind};
use crate::MirLint;
pub struct KnownPanicsLint;
impl<'tcx> MirLint<'tcx> for KnownPanicsLint {
impl<'tcx> crate::MirLint<'tcx> for KnownPanicsLint {
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
if body.tainted_by_errors.is_some() {
return;

View File

@ -27,7 +27,7 @@ pub struct EnumSizeOpt {
pub(crate) discrepancy: u64,
}
impl<'tcx> MirPass<'tcx> for EnumSizeOpt {
impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt {
fn is_enabled(&self, sess: &Session) -> bool {
// There are some differences in behavior on wasm and ARM that are not properly
// understood, so we conservatively treat this optimization as unsound:

View File

@ -26,7 +26,7 @@ use rustc_hir::intravisit::{self, Visitor};
use rustc_index::IndexVec;
use rustc_middle::mir::{
AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstOperand, ConstQualifs, LocalDecl,
MirPass, MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
MirPhase, Operand, Place, ProjectionElem, Promoted, RuntimePhase, Rvalue, SourceInfo,
Statement, StatementKind, TerminatorKind, START_BLOCK,
};
use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
@ -40,7 +40,7 @@ use tracing::{debug, trace};
#[macro_use]
mod pass_manager;
use pass_manager::{self as pm, Lint, MirLint, WithMinOptLevel};
use pass_manager::{self as pm, Lint, MirLint, MirPass, WithMinOptLevel};
mod abort_unwinding_calls;
mod add_call_guards;

View File

@ -9,7 +9,7 @@ use crate::take_array;
pub struct LowerIntrinsics;
impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
impl<'tcx> crate::MirPass<'tcx> for LowerIntrinsics {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let local_decls = &body.local_decls;
for block in body.basic_blocks.as_mut() {

View File

@ -7,7 +7,7 @@ use rustc_middle::ty::TyCtxt;
pub struct LowerSliceLenCalls;
impl<'tcx> MirPass<'tcx> for LowerSliceLenCalls {
impl<'tcx> crate::MirPass<'tcx> for LowerSliceLenCalls {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() > 0
}

View File

@ -12,7 +12,7 @@ use super::simplify::simplify_cfg;
pub struct MatchBranchSimplification;
impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 1
}

View File

@ -1,5 +1,5 @@
use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{self, Location, MentionedItem, MirPass};
use rustc_middle::mir::{self, Location, MentionedItem};
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::Session;
@ -13,7 +13,7 @@ struct MentionedItemsVisitor<'a, 'tcx> {
mentioned_items: &'a mut Vec<Spanned<MentionedItem<'tcx>>>,
}
impl<'tcx> MirPass<'tcx> for MentionedItems {
impl<'tcx> crate::MirPass<'tcx> for MentionedItems {
fn is_enabled(&self, _sess: &Session) -> bool {
// If this pass is skipped the collector assume that nothing got mentioned! We could
// potentially skip it in opt-level 0 if we are sure that opt-level will never *remove* uses

View File

@ -9,7 +9,7 @@ use crate::simplify;
pub struct MultipleReturnTerminators;
impl<'tcx> MirPass<'tcx> for MultipleReturnTerminators {
impl<'tcx> crate::MirPass<'tcx> for MultipleReturnTerminators {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 4
}

View File

@ -8,8 +8,6 @@ use rustc_middle::mir::{self, BasicBlock, Local, Location};
use rustc_middle::ty::TyCtxt;
use tracing::{debug, trace};
use crate::MirPass;
/// This pass looks for MIR that always copies the same local into the return place and eliminates
/// the copy by renaming all uses of that local to `_0`.
///
@ -34,7 +32,7 @@ use crate::MirPass;
/// [#71003]: https://github.com/rust-lang/rust/pull/71003
pub struct RenameReturnPlace;
impl<'tcx> MirPass<'tcx> for RenameReturnPlace {
impl<'tcx> crate::MirPass<'tcx> for RenameReturnPlace {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
// unsound: #111005
sess.mir_opt_level() > 0 && sess.opts.unstable_opts.unsound_mir_opts

View File

@ -1,10 +1,89 @@
use std::cell::RefCell;
use std::collections::hash_map::Entry;
use rustc_data_structures::fx::FxHashMap;
use rustc_middle::mir::{self, Body, MirPhase, RuntimePhase};
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use tracing::trace;
use crate::lint::lint_body;
use crate::{validate, MirPass};
use crate::validate;
thread_local! {
static PASS_NAMES: RefCell<FxHashMap<&'static str, &'static str>> = {
RefCell::new(FxHashMap::default())
};
}
/// Converts a MIR pass name into a snake case form to match the profiling naming style.
fn to_profiler_name(type_name: &'static str) -> &'static str {
PASS_NAMES.with(|names| match names.borrow_mut().entry(type_name) {
Entry::Occupied(e) => *e.get(),
Entry::Vacant(e) => {
let snake_case: String = type_name
.chars()
.flat_map(|c| {
if c.is_ascii_uppercase() {
vec!['_', c.to_ascii_lowercase()]
} else if c == '-' {
vec!['_']
} else {
vec![c]
}
})
.collect();
let result = &*String::leak(format!("mir_pass{}", snake_case));
e.insert(result);
result
}
})
}
// const wrapper for `if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }`
const fn c_name(name: &'static str) -> &'static str {
// FIXME Simplify the implementation once more `str` methods get const-stable.
// and inline into call site
let bytes = name.as_bytes();
let mut i = bytes.len();
while i > 0 && bytes[i - 1] != b':' {
i = i - 1;
}
let (_, bytes) = bytes.split_at(i);
match std::str::from_utf8(bytes) {
Ok(name) => name,
Err(_) => name,
}
}
/// A streamlined trait that you can implement to create a pass; the
/// pass will be named after the type, and it will consist of a main
/// loop that goes over each available MIR and applies `run_pass`.
pub trait MirPass<'tcx> {
fn name(&self) -> &'static str {
// FIXME Simplify the implementation once more `str` methods get const-stable.
// See copypaste in `MirLint`
const {
let name = std::any::type_name::<Self>();
c_name(name)
}
}
fn profiler_name(&self) -> &'static str {
to_profiler_name(self.name())
}
/// 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>);
fn is_mir_dump_enabled(&self) -> bool {
true
}
}
/// Just like `MirPass`, except it cannot mutate `Body`.
pub trait MirLint<'tcx> {
@ -13,7 +92,7 @@ pub trait MirLint<'tcx> {
// See copypaste in `MirPass`
const {
let name = std::any::type_name::<Self>();
rustc_middle::util::common::c_name(name)
c_name(name)
}
}

View File

@ -17,7 +17,7 @@ use rustc_session::Session;
/// `IndexVec`, unless that successor is a back-edge (such as from a loop).
pub struct ReorderBasicBlocks;
impl<'tcx> MirPass<'tcx> for ReorderBasicBlocks {
impl<'tcx> crate::MirPass<'tcx> for ReorderBasicBlocks {
fn is_enabled(&self, _session: &Session) -> bool {
false
}
@ -45,7 +45,7 @@ impl<'tcx> MirPass<'tcx> for ReorderBasicBlocks {
/// (Does not reorder arguments nor the [`RETURN_PLACE`].)
pub struct ReorderLocals;
impl<'tcx> MirPass<'tcx> for ReorderLocals {
impl<'tcx> crate::MirPass<'tcx> for ReorderLocals {
fn is_enabled(&self, _session: &Session) -> bool {
false
}

View File

@ -41,7 +41,7 @@ pub struct PromoteTemps<'tcx> {
pub promoted_fragments: Cell<IndexVec<Promoted, Body<'tcx>>>,
}
impl<'tcx> MirPass<'tcx> for PromoteTemps<'tcx> {
impl<'tcx> crate::MirPass<'tcx> for PromoteTemps<'tcx> {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// There's not really any point in promoting errorful MIR.
//

View File

@ -72,7 +72,7 @@ use crate::ssa::{SsaLocals, StorageLiveLocals};
/// so we perform all the possible instantiations without removing the `_1 = &_2` statement.
pub struct ReferencePropagation;
impl<'tcx> MirPass<'tcx> for ReferencePropagation {
impl<'tcx> crate::MirPass<'tcx> for ReferencePropagation {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 2
}

View File

@ -10,7 +10,7 @@ use tracing::debug;
/// terrible code for these.
pub struct RemoveNoopLandingPads;
impl<'tcx> MirPass<'tcx> for RemoveNoopLandingPads {
impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.panic_strategy() != PanicStrategy::Abort
}

View File

@ -6,7 +6,7 @@ use tracing::trace;
pub struct RemovePlaceMention;
impl<'tcx> MirPass<'tcx> for RemovePlaceMention {
impl<'tcx> crate::MirPass<'tcx> for RemovePlaceMention {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
!sess.opts.unstable_opts.mir_keep_place_mention
}

View File

@ -6,7 +6,7 @@ use tracing::trace;
pub struct RemoveStorageMarkers;
impl<'tcx> MirPass<'tcx> for RemoveStorageMarkers {
impl<'tcx> crate::MirPass<'tcx> for RemoveStorageMarkers {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() > 0 && !sess.emit_lifetime_markers()
}

View File

@ -6,8 +6,6 @@ use rustc_mir_dataflow::move_paths::{LookupResult, MoveData, MovePathIndex};
use rustc_mir_dataflow::{move_path_children_matching, Analysis, MaybeReachable};
use rustc_target::abi::FieldIdx;
use crate::MirPass;
/// Removes `Drop` terminators whose target is known to be uninitialized at
/// that point.
///
@ -18,7 +16,7 @@ use crate::MirPass;
/// [#90770]: https://github.com/rust-lang/rust/issues/90770
pub struct RemoveUninitDrops;
impl<'tcx> MirPass<'tcx> for RemoveUninitDrops {
impl<'tcx> crate::MirPass<'tcx> for RemoveUninitDrops {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let param_env = tcx.param_env(body.source.def_id());
let move_data =

View File

@ -12,7 +12,7 @@ use super::simplify::simplify_cfg;
pub struct RemoveUnneededDrops;
impl<'tcx> MirPass<'tcx> for RemoveUnneededDrops {
impl<'tcx> crate::MirPass<'tcx> for RemoveUnneededDrops {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
trace!("Running RemoveUnneededDrops on {:?}", body.source);

View File

@ -6,7 +6,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
pub struct RemoveZsts;
impl<'tcx> MirPass<'tcx> for RemoveZsts {
impl<'tcx> crate::MirPass<'tcx> for RemoveZsts {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() > 0
}

View File

@ -6,7 +6,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
pub struct RevealAll;
impl<'tcx> MirPass<'tcx> for RevealAll {
impl<'tcx> crate::MirPass<'tcx> for RevealAll {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body);

View File

@ -2,11 +2,9 @@ use rustc_middle::mir::Body;
use rustc_middle::ty::TyCtxt;
use rustc_mir_dataflow::rustc_peek::sanity_check;
use crate::MirLint;
pub(super) struct SanityCheck;
impl<'tcx> MirLint<'tcx> for SanityCheck {
impl<'tcx> crate::MirLint<'tcx> for SanityCheck {
fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
sanity_check(tcx, body);
}

View File

@ -74,7 +74,7 @@ pub(crate) fn simplify_cfg(body: &mut Body<'_>) {
body.basic_blocks_mut().raw.shrink_to_fit();
}
impl<'tcx> MirPass<'tcx> for SimplifyCfg {
impl<'tcx> crate::MirPass<'tcx> for SimplifyCfg {
fn name(&self) -> &'static str {
self.name()
}
@ -366,7 +366,7 @@ pub enum SimplifyLocals {
Final,
}
impl<'tcx> MirPass<'tcx> for SimplifyLocals {
impl<'tcx> crate::MirPass<'tcx> for SimplifyLocals {
fn name(&self) -> &'static str {
match &self {
SimplifyLocals::BeforeConstProp => "SimplifyLocals-before-const-prop",

View File

@ -7,7 +7,7 @@ pub enum SimplifyConstCondition {
Final,
}
/// A pass that replaces a branch with a goto when its condition is known.
impl<'tcx> MirPass<'tcx> for SimplifyConstCondition {
impl<'tcx> crate::MirPass<'tcx> for SimplifyConstCondition {
fn name(&self) -> &'static str {
match self {
SimplifyConstCondition::AfterConstProp => "SimplifyConstCondition-after-const-prop",

View File

@ -9,8 +9,6 @@ use rustc_middle::mir::{
use rustc_middle::ty::{Ty, TyCtxt};
use tracing::trace;
use super::MirPass;
/// Pass to convert `if` conditions on integrals into switches on the integral.
/// For an example, it turns something like
///
@ -27,7 +25,7 @@ use super::MirPass;
/// ```
pub struct SimplifyComparisonIntegral;
impl<'tcx> MirPass<'tcx> for SimplifyComparisonIntegral {
impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() > 0
}

View File

@ -21,7 +21,7 @@ use rustc_middle::ty::TyCtxt;
/// needed to do that too, including updating the debug info.
pub struct SingleUseConsts;
impl<'tcx> MirPass<'tcx> for SingleUseConsts {
impl<'tcx> crate::MirPass<'tcx> for SingleUseConsts {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() > 0
}

View File

@ -13,7 +13,7 @@ use tracing::{debug, instrument};
pub struct ScalarReplacementOfAggregates;
impl<'tcx> MirPass<'tcx> for ScalarReplacementOfAggregates {
impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 2
}

View File

@ -12,8 +12,6 @@ use rustc_middle::ty::{Ty, TyCtxt};
use rustc_target::abi::{Abi, Variants};
use tracing::trace;
use crate::MirPass;
pub struct UnreachableEnumBranching;
fn get_discriminant_local(terminator: &TerminatorKind<'_>) -> Option<Local> {
@ -74,7 +72,7 @@ fn variant_discriminants<'tcx>(
}
}
impl<'tcx> MirPass<'tcx> for UnreachableEnumBranching {
impl<'tcx> crate::MirPass<'tcx> for UnreachableEnumBranching {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() > 0
}

View File

@ -12,7 +12,7 @@ use rustc_target::abi::Size;
pub struct UnreachablePropagation;
impl MirPass<'_> for UnreachablePropagation {
impl crate::MirPass<'_> for UnreachablePropagation {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
// Enable only under -Zmir-opt-level=2 as this can make programs less debuggable.
sess.mir_opt_level() >= 2

View File

@ -36,7 +36,7 @@ pub struct Validator {
pub mir_phase: MirPhase,
}
impl<'tcx> MirPass<'tcx> for Validator {
impl<'tcx> crate::MirPass<'tcx> for Validator {
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
// FIXME(JakobDegen): These bodies never instantiated in codegend anyway, so it's not
// terribly important that they pass the validator. However, I think other passes might