Skip to content

Commit 63ac52a

Browse files
committed
Auto merge of #125916 - tesuji:mir-opt-const-array-locals, r=<try>
[WIP] mir-opt: promoting const read-only arrays Modified from a copy of PromoteTemps. It's kind of a hack so nothing fancy or easy to follow and review. I'll to reuse structures from PromoteTemps when there is [consensus for this pass][zulip]. Compiler is doing more work now with this opt. So I don't think this pass improves compiler performance. But anyway, for statistics, can I get a perf run? cc #73825 r? ghost ### Current status - [ ] Waiting for [consensus][zulip]. - [ ] Maybe rewrite to [use GVN with mentor from oli][mentor] - [x] ~ICE on unstable feature: tests/assembly/simd-intrinsic-mask-load.rs#x86-avx512.~ In particular `Simd([literal array])` now transformed to `Simd(array_var)`. Maybe I should ignore array in constructor. - [x] *~Fail test on nested arrays~* [zulip]: https://rust-lang.zulipchat.com/#narrow/stream/136281-t-opsem/topic/Could.20const.20read-only.20arrays.20be.20const.20promoted.3F [mentor]: #125916 (comment)
2 parents 06194ca + dca7207 commit 63ac52a

File tree

6 files changed

+1339
-15
lines changed

6 files changed

+1339
-15
lines changed

compiler/rustc_mir_transform/src/lib.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ mod normalize_array_len;
9191
mod nrvo;
9292
mod prettify;
9393
mod promote_consts;
94+
mod promote_consts_local_arrays;
9495
mod ref_prop;
9596
mod remove_noop_landing_pads;
9697
mod remove_storage_markers;
@@ -342,14 +343,22 @@ fn mir_promoted(
342343

343344
// What we need to run borrowck etc.
344345
let promote_pass = promote_consts::PromoteTemps::default();
346+
let promote_array = promote_consts_local_arrays::PromoteArraysOpt::default();
345347
pm::run_passes(
346348
tcx,
347349
&mut body,
348-
&[&promote_pass, &simplify::SimplifyCfg::PromoteConsts, &coverage::InstrumentCoverage],
350+
&[
351+
&promote_pass,
352+
&promote_array,
353+
&simplify::SimplifyCfg::PromoteConsts,
354+
&coverage::InstrumentCoverage,
355+
],
349356
Some(MirPhase::Analysis(AnalysisPhase::Initial)),
350357
);
351358

352-
let promoted = promote_pass.promoted_fragments.into_inner();
359+
let mut promoted = promote_pass.promoted_fragments.into_inner();
360+
let array_promoted = promote_array.promoted_fragments.into_inner();
361+
promoted.extend(array_promoted);
353362
(tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
354363
}
355364

compiler/rustc_mir_transform/src/promote_consts.rs

+21-12
Original file line numberDiff line numberDiff line change
@@ -98,33 +98,36 @@ struct Collector<'a, 'tcx> {
9898
}
9999

100100
impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
101+
#[instrument(level = "debug", skip(self))]
101102
fn visit_local(&mut self, index: Local, context: PlaceContext, location: Location) {
102-
debug!("visit_local: index={:?} context={:?} location={:?}", index, context, location);
103103
// We're only interested in temporaries and the return place
104104
match self.ccx.body.local_kind(index) {
105105
LocalKind::Arg => return,
106-
LocalKind::Temp if self.ccx.body.local_decls[index].is_user_variable() => return,
106+
LocalKind::Temp
107+
if {
108+
let is_user_variable = self.ccx.body.local_decls[index].is_user_variable();
109+
debug!(?is_user_variable);
110+
is_user_variable
111+
} =>
112+
{
113+
return;
114+
}
107115
LocalKind::ReturnPointer | LocalKind::Temp => {}
108116
}
109117

110118
// Ignore drops, if the temp gets promoted,
111119
// then it's constant and thus drop is noop.
112120
// Non-uses are also irrelevant.
113121
if context.is_drop() || !context.is_use() {
114-
debug!(
115-
"visit_local: context.is_drop={:?} context.is_use={:?}",
116-
context.is_drop(),
117-
context.is_use(),
118-
);
122+
debug!(is_drop = context.is_drop(), is_use = context.is_use());
119123
return;
120124
}
121125

122126
let temp = &mut self.temps[index];
123-
debug!("visit_local: temp={:?}", temp);
127+
debug!(?temp);
124128
*temp = match *temp {
125129
TempState::Undefined => match context {
126-
PlaceContext::MutatingUse(MutatingUseContext::Store)
127-
| PlaceContext::MutatingUse(MutatingUseContext::Call) => {
130+
PlaceContext::MutatingUse(MutatingUseContext::Store | MutatingUseContext::Call) => {
128131
TempState::Defined { location, uses: 0, valid: Err(()) }
129132
}
130133
_ => TempState::Unpromotable,
@@ -137,7 +140,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
137140
| PlaceContext::NonMutatingUse(_) => true,
138141
PlaceContext::MutatingUse(_) | PlaceContext::NonUse(_) => false,
139142
};
140-
debug!("visit_local: allowed_use={:?}", allowed_use);
143+
debug!(?allowed_use);
141144
if allowed_use {
142145
*uses += 1;
143146
return;
@@ -146,6 +149,7 @@ impl<'tcx> Visitor<'tcx> for Collector<'_, 'tcx> {
146149
}
147150
TempState::Unpromotable | TempState::PromotedOut => TempState::Unpromotable,
148151
};
152+
debug!(?temp);
149153
}
150154

151155
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
@@ -972,7 +976,12 @@ fn promote_candidates<'tcx>(
972976
candidates: Vec<Candidate>,
973977
) -> IndexVec<Promoted, Body<'tcx>> {
974978
// Visit candidates in reverse, in case they're nested.
975-
debug!("promote_candidates({:?})", candidates);
979+
debug!(promote_candidates = ?candidates);
980+
981+
// eagerly fail fast
982+
if candidates.is_empty() {
983+
return IndexVec::new();
984+
}
976985

977986
let mut promotions = IndexVec::new();
978987

0 commit comments

Comments
 (0)