Skip to content

Commit c32f395

Browse files
committed
Do partial SsaLocals analysis in unoptimized builds
1 parent f7b4354 commit c32f395

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+337
-288
lines changed

compiler/rustc_mir_transform/src/add_retag.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b
4949
}
5050

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

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

compiler/rustc_mir_transform/src/check_alignment.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,18 @@ use rustc_middle::mir::interpret::Scalar;
33
use rustc_middle::mir::visit::PlaceContext;
44
use rustc_middle::mir::*;
55
use rustc_middle::ty::{Ty, TyCtxt};
6-
use rustc_session::Session;
76

87
use crate::check_pointers::{BorrowCheckMode, PointerCheck, check_pointers};
98

109
pub(super) struct CheckAlignment;
1110

1211
impl<'tcx> crate::MirPass<'tcx> for CheckAlignment {
13-
fn is_enabled(&self, sess: &Session) -> bool {
12+
fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
1413
// FIXME(#112480) MSVC and rustc disagree on minimum stack alignment on x86 Windows
15-
if sess.target.llvm_target == "i686-pc-windows-msvc" {
14+
if tcx.sess.target.llvm_target == "i686-pc-windows-msvc" {
1615
return false;
1716
}
18-
sess.ub_checks()
17+
tcx.sess.ub_checks()
1918
}
2019

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

compiler/rustc_mir_transform/src/check_null.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@ use rustc_index::IndexVec;
22
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext};
33
use rustc_middle::mir::*;
44
use rustc_middle::ty::{Ty, TyCtxt};
5-
use rustc_session::Session;
65

76
use crate::check_pointers::{BorrowCheckMode, PointerCheck, check_pointers};
87

98
pub(super) struct CheckNull;
109

1110
impl<'tcx> crate::MirPass<'tcx> for CheckNull {
12-
fn is_enabled(&self, sess: &Session) -> bool {
13-
sess.ub_checks()
11+
fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
12+
tcx.sess.ub_checks()
1413
}
1514

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

compiler/rustc_mir_transform/src/copy_prop.rs

+26-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use rustc_middle::mir::*;
55
use rustc_middle::ty::TyCtxt;
66
use tracing::{debug, instrument};
77

8-
use crate::ssa::SsaLocals;
8+
use crate::pass_manager as pm;
9+
use crate::ssa::{SsaAnalysis, SsaLocals};
910

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

2226
impl<'tcx> crate::MirPass<'tcx> for CopyProp {
23-
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
24-
sess.mir_opt_level() >= 1
27+
fn name(&self) -> &'static str {
28+
match self {
29+
CopyProp::Partial => "CopyProp-partial",
30+
CopyProp::Full => "CopyProp",
31+
}
32+
}
33+
34+
fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
35+
match self {
36+
CopyProp::Partial => {
37+
tcx.sess.mir_opt_level() == 1
38+
&& !pm::should_run_pass(tcx, &CopyProp::Full, pm::Optimizations::Allowed)
39+
}
40+
CopyProp::Full => tcx.sess.mir_opt_level() >= 2,
41+
}
2542
}
2643

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

3148
let typing_env = body.typing_env(tcx);
32-
let ssa = SsaLocals::new(tcx, body, typing_env);
49+
let ssa_analysis = match self {
50+
CopyProp::Partial => SsaAnalysis::Partial,
51+
CopyProp::Full => SsaAnalysis::Full,
52+
};
53+
let ssa = SsaLocals::new(tcx, body, typing_env, ssa_analysis);
3354

3455
let fully_moved = fully_moved_locals(&ssa, body);
3556
debug!(?fully_moved);

compiler/rustc_mir_transform/src/coverage/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ use crate::coverage::mappings::ExtractedMappings;
3030
pub(super) struct InstrumentCoverage;
3131

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

3737
fn run_pass(&self, tcx: TyCtxt<'tcx>, mir_body: &mut mir::Body<'tcx>) {

compiler/rustc_mir_transform/src/dataflow_const_prop.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ const PLACE_LIMIT: usize = 100;
3535
pub(super) struct DataflowConstProp;
3636

3737
impl<'tcx> crate::MirPass<'tcx> for DataflowConstProp {
38-
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
39-
sess.mir_opt_level() >= 3
38+
fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
39+
tcx.sess.mir_opt_level() >= 3
4040
}
4141

4242
#[instrument(skip_all level = "debug")]

compiler/rustc_mir_transform/src/dead_store_elimination.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,8 @@ impl<'tcx> crate::MirPass<'tcx> for DeadStoreElimination {
140140
}
141141
}
142142

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

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

compiler/rustc_mir_transform/src/dest_prop.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ use tracing::{debug, trace};
149149
pub(super) struct DestinationPropagation;
150150

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

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

compiler/rustc_mir_transform/src/early_otherwise_branch.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ use crate::patch::MirPatch;
9393
pub(super) struct EarlyOtherwiseBranch;
9494

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

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

compiler/rustc_mir_transform/src/gvn.rs

+26-5
Original file line numberDiff line numberDiff line change
@@ -107,21 +107,42 @@ use rustc_span::def_id::DefId;
107107
use smallvec::SmallVec;
108108
use tracing::{debug, instrument, trace};
109109

110-
use crate::ssa::{AssignedValue, SsaLocals};
110+
use crate::pass_manager as pm;
111+
use crate::ssa::{AssignedValue, SsaAnalysis, SsaLocals};
111112

112-
pub(super) struct GVN;
113+
pub(super) enum GVN {
114+
Partial,
115+
Full,
116+
}
113117

114118
impl<'tcx> crate::MirPass<'tcx> for GVN {
115-
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
116-
sess.mir_opt_level() >= 2
119+
fn name(&self) -> &'static str {
120+
match self {
121+
GVN::Partial => "GVN-partial",
122+
GVN::Full => "GVN",
123+
}
124+
}
125+
126+
fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
127+
match self {
128+
GVN::Partial => {
129+
tcx.sess.mir_opt_level() == 1
130+
&& !pm::should_run_pass(tcx, &GVN::Full, pm::Optimizations::Allowed)
131+
}
132+
GVN::Full => tcx.sess.mir_opt_level() >= 2,
133+
}
117134
}
118135

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

123140
let typing_env = body.typing_env(tcx);
124-
let ssa = SsaLocals::new(tcx, body, typing_env);
141+
let ssa_analysis = match self {
142+
GVN::Partial => SsaAnalysis::Partial,
143+
GVN::Full => SsaAnalysis::Full,
144+
};
145+
let ssa = SsaLocals::new(tcx, body, typing_env, ssa_analysis);
125146
// Clone dominators because we need them while mutating the body.
126147
let dominators = body.basic_blocks.dominators().clone();
127148

compiler/rustc_mir_transform/src/inline.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,17 @@ struct CallSite<'tcx> {
4343
pub struct Inline;
4444

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

51-
match sess.mir_opt_level() {
52+
match tcx.sess.mir_opt_level() {
5253
0 | 1 => false,
5354
2 => {
54-
(sess.opts.optimize == OptLevel::More || sess.opts.optimize == OptLevel::Aggressive)
55-
&& sess.opts.incremental == None
55+
(opts.optimize == OptLevel::More || opts.optimize == OptLevel::Aggressive)
56+
&& opts.incremental == None
5657
}
5758
_ => true,
5859
}
@@ -82,7 +83,7 @@ impl ForceInline {
8283
}
8384

8485
impl<'tcx> crate::MirPass<'tcx> for ForceInline {
85-
fn is_enabled(&self, _: &rustc_session::Session) -> bool {
86+
fn is_enabled(&self, _tcx: TyCtxt<'tcx>) -> bool {
8687
true
8788
}
8889

compiler/rustc_mir_transform/src/instsimplify.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
2525
}
2626
}
2727

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

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

compiler/rustc_mir_transform/src/jump_threading.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ const MAX_COST: usize = 100;
6161
const MAX_PLACES: usize = 100;
6262

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

6868
#[instrument(skip_all level = "debug")]

compiler/rustc_mir_transform/src/large_enums.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ use rustc_middle::mir::interpret::AllocId;
44
use rustc_middle::mir::*;
55
use rustc_middle::ty::util::IntTypeExt;
66
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
7-
use rustc_session::Session;
87

98
use crate::patch::MirPatch;
109

@@ -29,11 +28,11 @@ pub(super) struct EnumSizeOpt {
2928
}
3029

3130
impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt {
32-
fn is_enabled(&self, sess: &Session) -> bool {
31+
fn is_enabled(&self, tcx: TyCtxt<'tcx>) -> bool {
3332
// There are some differences in behavior on wasm and ARM that are not properly
3433
// understood, so we conservatively treat this optimization as unsound:
3534
// https://github.com/rust-lang/rust/pull/85158#issuecomment-1101836457
36-
sess.opts.unstable_opts.unsound_mir_opts || sess.mir_opt_level() >= 3
35+
tcx.sess.opts.unstable_opts.unsound_mir_opts || tcx.sess.mir_opt_level() >= 3
3736
}
3837

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

compiler/rustc_mir_transform/src/lib.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,10 @@ declare_passes! {
128128
// This pass is public to allow external drivers to perform MIR cleanup
129129
pub mod cleanup_post_borrowck : CleanupPostBorrowck;
130130

131-
mod copy_prop : CopyProp;
131+
mod copy_prop : CopyProp {
132+
Partial,
133+
Full
134+
};
132135
mod coroutine : StateTransform;
133136
mod coverage : InstrumentCoverage;
134137
mod ctfe_limit : CtfeLimit;
@@ -144,7 +147,10 @@ declare_passes! {
144147
mod elaborate_box_derefs : ElaborateBoxDerefs;
145148
mod elaborate_drops : ElaborateDrops;
146149
mod function_item_references : FunctionItemReferences;
147-
mod gvn : GVN;
150+
mod gvn : GVN {
151+
Partial,
152+
Full
153+
};
148154
// Made public so that `mir_drops_elaborated_and_const_checked` can be overridden
149155
// by custom rustc drivers, running all the steps by themselves. See #114628.
150156
pub mod inline : Inline, ForceInline;
@@ -704,7 +710,8 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
704710
&instsimplify::InstSimplify::AfterSimplifyCfg,
705711
&simplify::SimplifyLocals::BeforeConstProp,
706712
&dead_store_elimination::DeadStoreElimination::Initial,
707-
&gvn::GVN,
713+
&gvn::GVN::Full,
714+
&gvn::GVN::Partial,
708715
&simplify::SimplifyLocals::AfterGVN,
709716
&dataflow_const_prop::DataflowConstProp,
710717
&single_use_consts::SingleUseConsts,
@@ -718,7 +725,8 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
718725
&o1(simplify::SimplifyCfg::Final),
719726
// After the last SimplifyCfg, because this wants one-block functions.
720727
&strip_debuginfo::StripDebugInfo,
721-
&copy_prop::CopyProp,
728+
&copy_prop::CopyProp::Full,
729+
&copy_prop::CopyProp::Partial,
722730
&dead_store_elimination::DeadStoreElimination::Final,
723731
&nrvo::RenameReturnPlace,
724732
&simplify::SimplifyLocals::Final,

compiler/rustc_mir_transform/src/lower_slice_len.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ use rustc_middle::ty::TyCtxt;
88
pub(super) struct LowerSliceLenCalls;
99

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

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

compiler/rustc_mir_transform/src/match_branches.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use crate::patch::MirPatch;
1414
pub(super) struct MatchBranchSimplification;
1515

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

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

compiler/rustc_mir_transform/src/mentioned_items.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ use rustc_middle::mir::visit::Visitor;
22
use rustc_middle::mir::{self, Location, MentionedItem};
33
use rustc_middle::ty::adjustment::PointerCoercion;
44
use rustc_middle::ty::{self, TyCtxt};
5-
use rustc_session::Session;
65
use rustc_span::source_map::Spanned;
76

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

1615
impl<'tcx> crate::MirPass<'tcx> for MentionedItems {
17-
fn is_enabled(&self, _sess: &Session) -> bool {
16+
fn is_enabled(&self, _tcx: TyCtxt<'tcx>) -> bool {
1817
// If this pass is skipped the collector assume that nothing got mentioned! We could
1918
// potentially skip it in opt-level 0 if we are sure that opt-level will never *remove* uses
2019
// of anything, but that still seems fragile. Furthermore, even debug builds use level 1, so

compiler/rustc_mir_transform/src/multiple_return_terminators.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ use crate::simplify;
1010
pub(super) struct MultipleReturnTerminators;
1111

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

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

compiler/rustc_mir_transform/src/nrvo.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ use tracing::{debug, trace};
3333
pub(super) struct RenameReturnPlace;
3434

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

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

0 commit comments

Comments
 (0)