Skip to content

Do partial SsaLocals analysis in unoptimized builds #134051

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

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/add_retag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b
}

impl<'tcx> crate::MirPass<'tcx> for AddRetag {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.opts.unstable_opts.mir_emit_retag
fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
tcx.sess.opts.unstable_opts.mir_emit_retag
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
7 changes: 3 additions & 4 deletions compiler/rustc_mir_transform/src/check_alignment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@ 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::check_pointers::{BorrowCheckMode, PointerCheck, check_pointers};

pub(super) struct CheckAlignment;

impl<'tcx> crate::MirPass<'tcx> for CheckAlignment {
fn is_enabled(&self, sess: &Session) -> bool {
fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
// FIXME(#112480) MSVC and rustc disagree on minimum stack alignment on x86 Windows
if sess.target.llvm_target == "i686-pc-windows-msvc" {
if tcx.sess.target.llvm_target == "i686-pc-windows-msvc" {
return false;
}
sess.ub_checks()
tcx.sess.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 @@ -2,15 +2,14 @@ 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::check_pointers::{BorrowCheckMode, PointerCheck, check_pointers};

pub(super) struct CheckNull;

impl<'tcx> crate::MirPass<'tcx> for CheckNull {
fn is_enabled(&self, sess: &Session) -> bool {
sess.ub_checks()
fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
tcx.sess.ub_checks()
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
31 changes: 26 additions & 5 deletions compiler/rustc_mir_transform/src/copy_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
use tracing::{debug, instrument};

use crate::ssa::SsaLocals;
use crate::pass_manager as pm;
use crate::ssa::{SsaAnalysis, SsaLocals};

/// Unify locals that copy each other.
///
Expand All @@ -17,19 +18,39 @@ use crate::ssa::SsaLocals;
/// where each of the locals is only assigned once.
///
/// We want to replace all those locals by `_a`, either copied or moved.
pub(super) struct CopyProp;
pub(super) enum CopyProp {
Partial,
Full,
}

impl<'tcx> crate::MirPass<'tcx> for CopyProp {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 1
fn name(&self) -> &'static str {
match self {
CopyProp::Partial => "CopyProp-partial",
CopyProp::Full => "CopyProp",
}
}

fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
match self {
CopyProp::Partial => {
tcx.sess.mir_opt_level() == 1
&& !pm::should_run_pass(tcx, &CopyProp::Full, pm::Optimizations::Allowed)
}
CopyProp::Full => tcx.sess.mir_opt_level() >= 2,
}
}

#[instrument(level = "trace", skip(self, tcx, body))]
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
debug!(def_id = ?body.source.def_id());

let typing_env = body.typing_env(tcx);
let ssa = SsaLocals::new(tcx, body, typing_env);
let ssa_analysis = match self {
CopyProp::Partial => SsaAnalysis::Partial,
CopyProp::Full => SsaAnalysis::Full,
};
let ssa = SsaLocals::new(tcx, body, typing_env, ssa_analysis);

let fully_moved = fully_moved_locals(&ssa, body);
debug!(?fully_moved);
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 @@ -30,8 +30,8 @@ use crate::coverage::mappings::ExtractedMappings;
pub(super) struct InstrumentCoverage;

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

fn run_pass(&self, tcx: TyCtxt<'tcx>, mir_body: &mut mir::Body<'tcx>) {
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 @@ -35,8 +35,8 @@ const PLACE_LIMIT: usize = 100;
pub(super) struct DataflowConstProp;

impl<'tcx> crate::MirPass<'tcx> for DataflowConstProp {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 3
fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
tcx.sess.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 @@ -140,8 +140,8 @@ impl<'tcx> crate::MirPass<'tcx> for DeadStoreElimination {
}
}

fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 2
fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
tcx.sess.mir_opt_level() >= 2
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
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 @@ -149,7 +149,7 @@ use tracing::{debug, trace};
pub(super) struct DestinationPropagation;

impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
// For now, only run at MIR opt level 3. Two things need to be changed before this can be
// turned on by default:
// 1. Because of the overeager removal of storage statements, this can cause stack space
Expand All @@ -158,7 +158,7 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
// 2. Despite being an overall perf improvement, this still causes a 30% regression in
// keccak. We can temporarily fix this by bounding function size, but in the long term
// we should fix this by being smarter about invalidating analysis results.
sess.mir_opt_level() >= 3
tcx.sess.mir_opt_level() >= 3
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
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 @@ -93,8 +93,8 @@ use crate::patch::MirPatch;
pub(super) struct EarlyOtherwiseBranch;

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

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
31 changes: 26 additions & 5 deletions compiler/rustc_mir_transform/src/gvn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,21 +109,42 @@ use rustc_span::def_id::DefId;
use smallvec::SmallVec;
use tracing::{debug, instrument, trace};

use crate::ssa::SsaLocals;
use crate::pass_manager as pm;
use crate::ssa::{SsaAnalysis, SsaLocals};

pub(super) struct GVN;
pub(super) enum GVN {
Partial,
Full,
}

impl<'tcx> crate::MirPass<'tcx> for GVN {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
sess.mir_opt_level() >= 2
fn name(&self) -> &'static str {
match self {
GVN::Partial => "GVN-partial",
GVN::Full => "GVN",
}
}

fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
match self {
GVN::Partial => {
tcx.sess.mir_opt_level() == 1
&& !pm::should_run_pass(tcx, &GVN::Full, pm::Optimizations::Allowed)
}
GVN::Full => tcx.sess.mir_opt_level() >= 2,
}
}

#[instrument(level = "trace", skip(self, tcx, body))]
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
debug!(def_id = ?body.source.def_id());

let typing_env = body.typing_env(tcx);
let ssa = SsaLocals::new(tcx, body, typing_env);
let ssa_analysis = match self {
GVN::Partial => SsaAnalysis::Partial,
GVN::Full => SsaAnalysis::Full,
};
let ssa = SsaLocals::new(tcx, body, typing_env, ssa_analysis);
// Clone dominators because we need them while mutating the body.
let dominators = body.basic_blocks.dominators().clone();

Expand Down
13 changes: 7 additions & 6 deletions compiler/rustc_mir_transform/src/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,16 +43,17 @@ struct CallSite<'tcx> {
pub struct Inline;

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

match sess.mir_opt_level() {
match tcx.sess.mir_opt_level() {
0 | 1 => false,
2 => {
(sess.opts.optimize == OptLevel::More || sess.opts.optimize == OptLevel::Aggressive)
&& sess.opts.incremental == None
(opts.optimize == OptLevel::More || opts.optimize == OptLevel::Aggressive)
&& opts.incremental == None
}
_ => true,
}
Expand Down Expand Up @@ -82,7 +83,7 @@ impl ForceInline {
}

impl<'tcx> crate::MirPass<'tcx> for ForceInline {
fn is_enabled(&self, _: &rustc_session::Session) -> bool {
fn is_enabled(&self, _tcx: TyCtxt<'tcx>) -> bool {
true
}

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 @@ -25,8 +25,8 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
}
}

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

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/jump_threading.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ const MAX_COST: usize = 100;
const MAX_PLACES: usize = 100;

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

#[instrument(skip_all level = "debug")]
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_mir_transform/src/large_enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,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::patch::MirPatch;

Expand All @@ -29,11 +28,11 @@ pub(super) struct EnumSizeOpt {
}

impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt {
fn is_enabled(&self, sess: &Session) -> bool {
fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
// 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/pull/85158#issuecomment-1101836457
sess.opts.unstable_opts.unsound_mir_opts || sess.mir_opt_level() >= 3
tcx.sess.opts.unstable_opts.unsound_mir_opts || tcx.sess.mir_opt_level() >= 3
}

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
16 changes: 12 additions & 4 deletions compiler/rustc_mir_transform/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,10 @@ declare_passes! {
// This pass is public to allow external drivers to perform MIR cleanup
pub mod cleanup_post_borrowck : CleanupPostBorrowck;

mod copy_prop : CopyProp;
mod copy_prop : CopyProp {
Partial,
Full
};
mod coroutine : StateTransform;
mod coverage : InstrumentCoverage;
mod ctfe_limit : CtfeLimit;
Expand All @@ -145,7 +148,10 @@ declare_passes! {
mod elaborate_box_derefs : ElaborateBoxDerefs;
mod elaborate_drops : ElaborateDrops;
mod function_item_references : FunctionItemReferences;
mod gvn : GVN;
mod gvn : GVN {
Partial,
Full
};
// Made public so that `mir_drops_elaborated_and_const_checked` can be overridden
// by custom rustc drivers, running all the steps by themselves. See #114628.
pub mod inline : Inline, ForceInline;
Expand Down Expand Up @@ -708,7 +714,8 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
&instsimplify::InstSimplify::AfterSimplifyCfg,
&simplify::SimplifyLocals::BeforeConstProp,
&dead_store_elimination::DeadStoreElimination::Initial,
&gvn::GVN,
&gvn::GVN::Full,
&gvn::GVN::Partial,
&simplify::SimplifyLocals::AfterGVN,
&dataflow_const_prop::DataflowConstProp,
&single_use_consts::SingleUseConsts,
Expand All @@ -722,7 +729,8 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
&o1(simplify::SimplifyCfg::Final),
// After the last SimplifyCfg, because this wants one-block functions.
&strip_debuginfo::StripDebugInfo,
&copy_prop::CopyProp,
&copy_prop::CopyProp::Full,
&copy_prop::CopyProp::Partial,
&dead_store_elimination::DeadStoreElimination::Final,
&nrvo::RenameReturnPlace,
&simplify::SimplifyLocals::Final,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/lower_slice_len.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use rustc_middle::ty::TyCtxt;
pub(super) struct LowerSliceLenCalls;

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

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/match_branches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use crate::patch::MirPatch;
pub(super) struct MatchBranchSimplification;

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

fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_mir_transform/src/mentioned_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ use rustc_middle::mir::visit::Visitor;
use rustc_middle::mir::{self, Location, MentionedItem};
use rustc_middle::ty::adjustment::PointerCoercion;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::Session;
use rustc_span::source_map::Spanned;

pub(super) struct MentionedItems;
Expand All @@ -14,7 +13,7 @@ struct MentionedItemsVisitor<'a, 'tcx> {
}

impl<'tcx> crate::MirPass<'tcx> for MentionedItems {
fn is_enabled(&self, _sess: &Session) -> bool {
fn is_enabled(&self, _tcx: TyCtxt<'tcx>) -> 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
// of anything, but that still seems fragile. Furthermore, even debug builds use level 1, so
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use crate::simplify;
pub(super) struct MultipleReturnTerminators;

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

fn run_pass(&self, _: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_mir_transform/src/nrvo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ use tracing::{debug, trace};
pub(super) struct RenameReturnPlace;

impl<'tcx> crate::MirPass<'tcx> for RenameReturnPlace {
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
// unsound: #111005
sess.mir_opt_level() > 0 && sess.opts.unstable_opts.unsound_mir_opts
tcx.sess.mir_opt_level() > 0 && tcx.sess.opts.unstable_opts.unsound_mir_opts
}

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