Skip to content
Open
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
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/abort_unwinding_calls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ impl<'tcx> crate::MirPass<'tcx> for AbortUnwindingCalls {
super::simplify::remove_dead_blocks(body);
}

fn policy(&self, _sess: &rustc_session::Session) -> PassPolicy {
fn policy(&self, _ctx: &crate::PassCtx<'_>) -> PassPolicy {
// Implements part of MIR semantics, turning effectively implicit aborts into explicit
// ones.
PassPolicy::Required
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/add_call_guards.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards {
basic_blocks.extend(new_blocks);
}

fn policy(&self, _sess: &rustc_session::Session) -> PassPolicy {
fn policy(&self, _ctx: &crate::PassCtx<'_>) -> PassPolicy {
// Breaks critical edges so codegen can place edge-specific actions without affecting
// other control-flow edges.
PassPolicy::Required
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ impl<'tcx> crate::MirPass<'tcx> for AddMovesForPackedDrops {
patch.apply(body);
}

fn policy(&self, _sess: &rustc_session::Session) -> PassPolicy {
fn policy(&self, _ctx: &crate::PassCtx<'_>) -> PassPolicy {
// Implements part of MIR semantics by making implicit packed-drop handling explicit.
PassPolicy::Required
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ impl<'tcx> crate::MirPass<'tcx> for Subtyper {
checker.patcher.apply(body);
}

fn policy(&self, _sess: &rustc_session::Session) -> PassPolicy {
fn policy(&self, _ctx: &crate::PassCtx<'_>) -> PassPolicy {
// Later MIR phases expect all subtyping to be explicit.
PassPolicy::Required
}
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_mir_transform/src/check_alignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@ use rustc_middle::mir::interpret::Scalar;
use rustc_middle::mir::visit::PlaceContext;
use rustc_middle::mir::*;
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_session::Session;

use crate::PassPolicy;
use crate::check_pointers::{BorrowedFieldProjectionMode, PointerCheck, check_pointers};

pub(super) struct CheckAlignment;

impl<'tcx> crate::MirPass<'tcx> for CheckAlignment {
fn policy(&self, sess: &Session) -> PassPolicy {
fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy {
// When UB checks are enabled this is part of their semantics, not an optimization.
PassPolicy::optional_non_optimization(sess.ub_checks())
PassPolicy::optional(ctx.ub_checks())
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_mir_transform/src/check_enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::*;
use rustc_middle::ty::layout::PrimitiveExt;
use rustc_middle::ty::{self, Ty, TyCtxt, TypingEnv};
use rustc_session::Session;
use tracing::debug;

use crate::PassPolicy;
Expand All @@ -18,9 +17,9 @@ use crate::PassPolicy;
pub(super) struct CheckEnums;

impl<'tcx> crate::MirPass<'tcx> for CheckEnums {
fn policy(&self, sess: &Session) -> PassPolicy {
fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy {
// When UB checks are enabled this is part of their semantics, not an optimization.
PassPolicy::optional_non_optimization(sess.ub_checks())
PassPolicy::optional(ctx.ub_checks())
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_mir_transform/src/check_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,16 @@ use rustc_index::IndexVec;
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext};
use rustc_middle::mir::*;
use rustc_middle::ty::{Ty, TyCtxt};
use rustc_session::Session;

use crate::PassPolicy;
use crate::check_pointers::{BorrowedFieldProjectionMode, PointerCheck, check_pointers};

pub(super) struct CheckNull;

impl<'tcx> crate::MirPass<'tcx> for CheckNull {
fn policy(&self, sess: &Session) -> PassPolicy {
fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy {
// When UB checks are enabled this is part of their semantics, not an optimization.
PassPolicy::optional_non_optimization(sess.ub_checks())
PassPolicy::optional(ctx.ub_checks())
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/cleanup_post_borrowck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl<'tcx> crate::MirPass<'tcx> for CleanupPostBorrowck {
}
}

fn policy(&self, _sess: &rustc_session::Session) -> PassPolicy {
fn policy(&self, _ctx: &crate::PassCtx<'_>) -> PassPolicy {
// Removes administrative MIR instructions that later passes must never see.
PassPolicy::Required
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/copy_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ use crate::ssa::{MaybeUninitializedLocals, SsaLocals};
pub(super) struct CopyProp;

impl<'tcx> crate::MirPass<'tcx> for CopyProp {
fn policy(&self, sess: &rustc_session::Session) -> PassPolicy {
PassPolicy::optimization(sess.mir_opt_level() >= 1)
fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy {
PassPolicy::optional(ctx.mir_opt_level() >= 1)
}

#[instrument(level = "trace", skip(self, tcx, body))]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/coroutine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1219,7 +1219,7 @@ impl<'tcx> crate::MirPass<'tcx> for StateTransform {
create_coroutine_resume_function(tcx, transform, body, can_return, can_unwind);
}

fn policy(&self, _sess: &rustc_session::Session) -> PassPolicy {
fn policy(&self, _ctx: &crate::PassCtx<'_>) -> PassPolicy {
// Implements coroutine semantics by lowering the coroutine body to a state machine.
PassPolicy::Required
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/coverage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ mod tests;
pub(super) struct InstrumentCoverage;

impl<'tcx> crate::MirPass<'tcx> for InstrumentCoverage {
fn policy(&self, sess: &rustc_session::Session) -> PassPolicy {
PassPolicy::optional_non_optimization(sess.instrument_coverage())
fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy {
PassPolicy::optional(ctx.instrument_coverage())
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, mir_body: &mut mir::Body<'tcx>) {
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_mir_transform/src/cross_crate_inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,9 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
// Don't do any inference if codegen optimizations are disabled and also MIR inlining is not
// enabled. This ensures that we do inference even if someone only passes -Zinline-mir,
// which is less confusing than having to also enable -Copt-level=1.
let inliner_will_run = pm::should_run_pass(tcx, &inline::Inline, pm::Optimizations::Allowed)
|| inline::ForceInline::should_run_pass_for_callee(tcx, def_id.to_def_id());
let inliner_will_run =
pm::should_run_pass(&inline::Inline, &pm::PassCtx::for_body(tcx, def_id.to_def_id()))
|| inline::ForceInline::should_run_pass_for_callee(tcx, def_id.to_def_id());
if matches!(tcx.sess.opts.optimize, OptLevel::No) && !inliner_will_run {
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/ctfe_limit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ impl<'tcx> crate::MirPass<'tcx> for CtfeLimit {
}
}

fn policy(&self, _sess: &rustc_session::Session) -> PassPolicy {
fn policy(&self, _ctx: &crate::PassCtx<'_>) -> PassPolicy {
// This is part of CTFE diagnostics rather than an optimization.
PassPolicy::optional_non_optimization(true)
PassPolicy::optional(true)
}
}

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/dataflow_const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ const PLACE_LIMIT: usize = 100;
pub(super) struct DataflowConstProp;

impl<'tcx> crate::MirPass<'tcx> for DataflowConstProp {
fn policy(&self, sess: &rustc_session::Session) -> PassPolicy {
PassPolicy::optimization(sess.mir_opt_level() >= 3)
fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy {
PassPolicy::optional(ctx.mir_opt_level() >= 3)
}

#[instrument(skip_all level = "debug")]
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/dead_store_elimination.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,8 @@ impl<'tcx> crate::MirPass<'tcx> for DeadStoreElimination {
}
}

fn policy(&self, sess: &rustc_session::Session) -> PassPolicy {
PassPolicy::optimization(sess.mir_opt_level() >= 2)
fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy {
PassPolicy::optional(ctx.mir_opt_level() >= 2)
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/deref_separator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ impl<'tcx> crate::MirPass<'tcx> for Derefer {
deref_finder(tcx, body, true);
}

fn policy(&self, _sess: &rustc_session::Session) -> PassPolicy {
fn policy(&self, _ctx: &crate::PassCtx<'_>) -> PassPolicy {
// Later MIR stages expect derefs to only appear as the first place projection.
PassPolicy::Required
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/dest_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ use crate::PassPolicy;
pub(super) struct DestinationPropagation;

impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
fn policy(&self, sess: &rustc_session::Session) -> PassPolicy {
PassPolicy::optimization(sess.mir_opt_level() >= 2)
fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy {
PassPolicy::optional(ctx.mir_opt_level() >= 2)
}

#[tracing::instrument(level = "trace", skip(self, tcx, body))]
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/early_otherwise_branch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ use crate::patch::MirPatch;
pub(super) struct EarlyOtherwiseBranch;

impl<'tcx> crate::MirPass<'tcx> for EarlyOtherwiseBranch {
fn policy(&self, sess: &rustc_session::Session) -> PassPolicy {
PassPolicy::optimization(sess.mir_opt_level() >= 2)
fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy {
PassPolicy::optional(ctx.mir_opt_level() >= 2)
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateBoxDerefs {
}
}

fn policy(&self, _sess: &rustc_session::Session) -> PassPolicy {
fn policy(&self, _ctx: &crate::PassCtx<'_>) -> PassPolicy {
// Implements Box dereference semantics so backends and Miri do not have to handle them.
PassPolicy::Required
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/elaborate_drops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateDrops {
elaborate_patch.apply(body);
}

fn policy(&self, _sess: &rustc_session::Session) -> PassPolicy {
fn policy(&self, _ctx: &crate::PassCtx<'_>) -> PassPolicy {
// Implements MIR drop semantics.
PassPolicy::Required
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/erase_deref_temps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl<'tcx> crate::MirPass<'tcx> for EraseDerefTemps {
EraseDerefTempsVisitor { tcx }.visit_body_preserves_cfg(body);
}

fn policy(&self, _sess: &rustc_session::Session) -> PassPolicy {
fn policy(&self, _ctx: &crate::PassCtx<'_>) -> PassPolicy {
// Later MIR stages assume that CopyForDeref is gone.
PassPolicy::Required
}
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/gvn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@ use crate::ssa::{MaybeUninitializedLocals, SsaLocals};
pub(super) struct GVN;

impl<'tcx> crate::MirPass<'tcx> for GVN {
fn policy(&self, sess: &rustc_session::Session) -> PassPolicy {
PassPolicy::optimization(sess.mir_opt_level() >= 2)
fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy {
PassPolicy::optional(ctx.mir_opt_level() >= 2)
}

#[instrument(level = "trace", skip(self, tcx, body))]
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/impossible_clauses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ impl<'tcx> MirPass<'tcx> for ImpossibleClauses {
}
}

fn policy(&self, _sess: &rustc_session::Session) -> PassPolicy {
fn policy(&self, _ctx: &crate::PassCtx<'_>) -> PassPolicy {
// This can only replace code proven unreachable with immediate UB, so it cannot remove UB.
PassPolicy::optional_non_optimization(true)
PassPolicy::optional(true)
}
}
33 changes: 21 additions & 12 deletions compiler/rustc_mir_transform/src/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use rustc_span::Spanned;
use tracing::{debug, instrument, trace, trace_span};

use crate::cost_checker::{CostChecker, is_call_like};
use crate::pass_manager::BodyMirOptLevel;
use crate::simplify::{UsedInStmtLocals, simplify_cfg};
use crate::validate::validate_types;
use crate::{PassPolicy, check_inline, util};
Expand All @@ -45,18 +46,26 @@ struct CallSite<'tcx> {
pub struct Inline;

impl<'tcx> crate::MirPass<'tcx> for Inline {
fn policy(&self, sess: &rustc_session::Session) -> PassPolicy {
let enabled_by_default =
sess.opts.unstable_opts.inline_mir.unwrap_or_else(|| match sess.mir_opt_level() {
0 | 1 => false,
2 => {
(sess.opts.optimize == OptLevel::More
|| sess.opts.optimize == OptLevel::Aggressive)
&& sess.opts.incremental == None
fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy {
match ctx.opts.unstable_opts.inline_mir {
Some(enabled) => PassPolicy::optional(enabled),
None => PassPolicy::optional({
let source = ctx.mir_opt_level_source();
match source.level() {
0 | 1 => false,
3.. => true,
// If level 2 has been inferred from opt-level=1/s/z, we don't want to enable inlining.
// However, if `optimize(speed)` has been set, we want to inline irrespective of global opt level.
2 if matches!(ctx.opts.optimize, OptLevel::More | OptLevel::Aggressive)
|| matches!(source, BodyMirOptLevel::Overridden(_)) =>
{
// Inlining reduces incremental effectiveness.
ctx.opts.incremental.is_none()
}
_ => false,
}
_ => true,
});
PassPolicy::optimization(enabled_by_default)
}),

@RalfJung RalfJung Aug 21, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this, we won't do MIR inlining with optimize(speed) if the global opt level is 0 or 1 which seems wrong. The inliner kind of introduces a mir-opt-level 1.5 here, it's the only MIR opt that dintinguishes -Copt-level=1 from -Copt-level=2. It seems like it has done this ever since #91743. @cjgillot @wesleywiser @oli-obk what is the reason this was done and do you have ideas for how it could be handled with the per-function attribute? We use ctx to communicate the intended opt level for the function this pass runs on, but that needs to reflected -Zmir-opt-level so it is expressed as a MIR opt level and therefore can't capture the logic here that depends on both mir-opt-level and -Copt-level. The easiest fix it to stop doing this odd special case but that would mean the MIR inliner would kick in at -Copt-level=1. IMO if we don't want that we shouldn't map -Copt-level=1 and -Copt-level=2 to the same MIR opt level.

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pushed an approach which records the source for the body-opt-level to at least retain the behaviour; this is kind of overkill (we could just have a local_override: bool flag or something on PassCtx), but having this information around might be useful.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Urgh :/

I'd rather "free up" mir-opt-level 3 so that we can map -Copt-level=1 to a different mir-opt-level. Or decide that the inliner doesn't need to be that special. The -Copt-levels other than 0 and 3 are not widely used anyway I assume...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense; this is the lowest impact fix I can think of to immediately get things working, but I can wait for opinions from others on the inliner.

}
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand All @@ -78,7 +87,7 @@ impl ForceInline {
}

impl<'tcx> crate::MirPass<'tcx> for ForceInline {
fn policy(&self, _sess: &rustc_session::Session) -> PassPolicy {
fn policy(&self, _ctx: &crate::PassCtx<'_>) -> PassPolicy {
// Forced inlining is part of MIR semantics.
PassPolicy::Required
}
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_mir_transform/src/inline/cycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,10 @@ fn should_recurse<'tcx>(tcx: TyCtxt<'tcx>, callee: ty::Instance<'tcx>) -> bool {
}
}

crate::pm::should_run_pass(tcx, &crate::inline::Inline, crate::pm::Optimizations::Allowed)
|| crate::inline::ForceInline::should_run_pass_for_callee(tcx, callee.def.def_id())
crate::pm::should_run_pass(
&crate::inline::Inline,
&crate::pm::PassCtx::for_body(tcx, callee.def_id()),
) || crate::inline::ForceInline::should_run_pass_for_callee(tcx, callee.def.def_id())
}

#[instrument(
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/instsimplify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
}
}

fn policy(&self, sess: &rustc_session::Session) -> PassPolicy {
PassPolicy::optimization(sess.mir_opt_level() > 0)
fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy {
PassPolicy::optional(ctx.mir_opt_level() >= 1)
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
19 changes: 7 additions & 12 deletions compiler/rustc_mir_transform/src/jump_threading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,18 +76,13 @@ pub(super) struct JumpThreading;
const MAX_COST: u8 = 100;

impl<'tcx> crate::MirPass<'tcx> for JumpThreading {
fn policy(&self, sess: &rustc_session::Session) -> PassPolicy {
let enabled_by_default = if sess.target.is_like_gpu {
// Jump threading can duplicate calls in control-flow.
// This leads to incorrect code when done for so called "convergent" operations on GPU
// targets, similar to how inline assembly cannot be duplicated on all targets.
// Conservatively prevent this by disabling the pass.
// See also issue #137086.
false
} else {
sess.mir_opt_level() >= 2
};
PassPolicy::optimization(enabled_by_default)
fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy {
// Jump threading can duplicate calls in control-flow.
// This leads to incorrect code when done for so called "convergent" operations on GPU
// targets, similar to how inline assembly cannot be duplicated on all targets.
// Conservatively prevent this by disabling the pass.
// See also issue #137086.
PassPolicy::optional(ctx.mir_opt_level() >= 2 && !ctx.target.is_like_gpu)
}

#[instrument(skip_all level = "debug")]
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_mir_transform/src/large_enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ use rustc_middle::mir::interpret::AllocId;
use rustc_middle::mir::*;
use rustc_middle::ty::util::IntTypeExt;
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
use rustc_session::Session;

use crate::PassPolicy;
use crate::patch::MirPatch;
Expand All @@ -32,13 +31,11 @@ pub(super) struct EnumSizeOpt {
}

impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt {
fn policy(&self, sess: &Session) -> PassPolicy {
fn policy(&self, ctx: &crate::PassCtx<'_>) -> PassPolicy {
// There are some differences in behavior on wasm and ARM that are not properly
// understood, so we conservatively treat this optimization as unsound:
// https://github.com/rust-lang/rust/issues/154413
PassPolicy::optimization(
sess.opts.unstable_opts.unsound_mir_opts && sess.mir_opt_level() >= 3,
)
PassPolicy::optional(ctx.mir_opt_level() >= 3 && ctx.opts.unstable_opts.unsound_mir_opts)
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
Loading
Loading