Skip to content

Commit 9ba00e0

Browse files
committed
Auto merge of #144543 - scottmcm:more-sroa, r=cjgillot
Allow more MIR SROA This removes some guards on SROA that are no longer needed: - With rust-lang/compiler-team#838 it no longer needs to check for SIMD - With rust-lang/compiler-team#807 it no longer needs to check for niches - This means that `Wrapper(char)` and `Pin<&mut T>` can get SRoA'd now, where previously they weren't because the check was banning SRaA for anything with a niche -- not just things with `#[rustc_layout_scalar_valid_range_*]`. - Technically #133652 isn't complete yet, but `NonZero` and `NonNull` have already moved over, so this is fine. At worst this will mean that LLVM gets less `!range` metadata on something that wasn't already fixed by #133651 or #135236, but that's still sound, and unblocking general SRoA is worth that tradeoff.
2 parents 65b6cdb + 47bfa84 commit 9ba00e0

File tree

3 files changed

+40
-68
lines changed

3 files changed

+40
-68
lines changed

compiler/rustc_mir_transform/src/sroa.rs

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_abi::{FIRST_VARIANT, FieldIdx};
1+
use rustc_abi::FieldIdx;
22
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
33
use rustc_hir::LangItem;
44
use rustc_index::IndexVec;
@@ -32,7 +32,7 @@ impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates {
3232
let typing_env = body.typing_env(tcx);
3333
loop {
3434
debug!(?excluded);
35-
let escaping = escaping_locals(tcx, typing_env, &excluded, body);
35+
let escaping = escaping_locals(tcx, &excluded, body);
3636
debug!(?escaping);
3737
let replacements = compute_flattening(tcx, typing_env, body, escaping);
3838
debug!(?replacements);
@@ -64,39 +64,19 @@ impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates {
6464
/// client code.
6565
fn escaping_locals<'tcx>(
6666
tcx: TyCtxt<'tcx>,
67-
typing_env: ty::TypingEnv<'tcx>,
6867
excluded: &DenseBitSet<Local>,
6968
body: &Body<'tcx>,
7069
) -> DenseBitSet<Local> {
7170
let is_excluded_ty = |ty: Ty<'tcx>| {
7271
if ty.is_union() || ty.is_enum() {
7372
return true;
7473
}
75-
if let ty::Adt(def, _args) = ty.kind() {
76-
if def.repr().simd() {
77-
// Exclude #[repr(simd)] types so that they are not de-optimized into an array
78-
return true;
79-
}
80-
if tcx.is_lang_item(def.did(), LangItem::DynMetadata) {
81-
// codegen wants to see the `DynMetadata<T>`,
82-
// not the inner reference-to-opaque-type.
83-
return true;
84-
}
85-
// We already excluded unions and enums, so this ADT must have one variant
86-
let variant = def.variant(FIRST_VARIANT);
87-
if variant.fields.len() > 1 {
88-
// If this has more than one field, it cannot be a wrapper that only provides a
89-
// niche, so we do not want to automatically exclude it.
90-
return false;
91-
}
92-
let Ok(layout) = tcx.layout_of(typing_env.as_query_input(ty)) else {
93-
// We can't get the layout
94-
return true;
95-
};
96-
if layout.layout.largest_niche().is_some() {
97-
// This type has a niche
98-
return true;
99-
}
74+
if let ty::Adt(def, _args) = ty.kind()
75+
&& tcx.is_lang_item(def.did(), LangItem::DynMetadata)
76+
{
77+
// codegen wants to see the `DynMetadata<T>`,
78+
// not the inner reference-to-opaque-type.
79+
return true;
10080
}
10181
// Default for non-ADTs
10282
false

tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,8 @@
6464
+ let mut _45: &mut std::future::Ready<()>;
6565
+ let mut _46: &mut std::pin::Pin<&mut std::future::Ready<()>>;
6666
+ scope 14 (inlined <Pin<&mut std::future::Ready<()>> as DerefMut>::deref_mut) {
67-
+ let mut _47: std::pin::Pin<&mut std::future::Ready<()>>;
6867
+ scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) {
69-
+ let mut _48: &mut &mut std::future::Ready<()>;
68+
+ let mut _47: &mut &mut std::future::Ready<()>;
7069
+ scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
7170
+ }
7271
+ scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) {
@@ -76,15 +75,15 @@
7675
+ }
7776
+ }
7877
+ scope 19 (inlined Option::<()>::take) {
79-
+ let mut _49: std::option::Option<()>;
78+
+ let mut _48: std::option::Option<()>;
8079
+ scope 20 (inlined std::mem::replace::<Option<()>>) {
8180
+ scope 21 {
8281
+ }
8382
+ }
8483
+ }
8584
+ scope 22 (inlined #[track_caller] Option::<()>::expect) {
86-
+ let mut _50: isize;
87-
+ let mut _51: !;
85+
+ let mut _49: isize;
86+
+ let mut _50: !;
8887
+ scope 23 {
8988
+ }
9089
+ }
@@ -229,28 +228,25 @@
229228
+ StorageDead(_24);
230229
+ StorageLive(_45);
231230
+ StorageLive(_46);
232-
+ StorageLive(_51);
231+
+ StorageLive(_50);
233232
+ StorageLive(_42);
234233
+ StorageLive(_43);
235234
+ StorageLive(_44);
236235
+ _46 = &mut _19;
237236
+ StorageLive(_47);
238-
+ StorageLive(_48);
239-
+ _48 = &mut (_19.0: &mut std::future::Ready<()>);
237+
+ _47 = &mut (_19.0: &mut std::future::Ready<()>);
240238
+ _45 = copy (_19.0: &mut std::future::Ready<()>);
241-
+ StorageDead(_48);
242-
+ _47 = Pin::<&mut std::future::Ready<()>> { pointer: copy _45 };
243239
+ StorageDead(_47);
244240
+ _44 = &mut ((*_45).0: std::option::Option<()>);
245-
+ StorageLive(_49);
246-
+ _49 = Option::<()>::None;
241+
+ StorageLive(_48);
242+
+ _48 = Option::<()>::None;
247243
+ _43 = copy ((*_45).0: std::option::Option<()>);
248-
+ ((*_45).0: std::option::Option<()>) = copy _49;
249-
+ StorageDead(_49);
244+
+ ((*_45).0: std::option::Option<()>) = copy _48;
245+
+ StorageDead(_48);
250246
+ StorageDead(_44);
251-
+ StorageLive(_50);
252-
+ _50 = discriminant(_43);
253-
+ switchInt(move _50) -> [0: bb11, 1: bb12, otherwise: bb5];
247+
+ StorageLive(_49);
248+
+ _49 = discriminant(_43);
249+
+ switchInt(move _49) -> [0: bb11, 1: bb12, otherwise: bb5];
254250
}
255251
+
256252
+ bb5: {
@@ -313,16 +309,16 @@
313309
+ }
314310
+
315311
+ bb11: {
316-
+ _51 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable;
312+
+ _50 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable;
317313
+ }
318314
+
319315
+ bb12: {
320316
+ _42 = move ((_43 as Some).0: ());
321-
+ StorageDead(_50);
317+
+ StorageDead(_49);
322318
+ StorageDead(_43);
323319
+ _18 = Poll::<()>::Ready(move _42);
324320
+ StorageDead(_42);
325-
+ StorageDead(_51);
321+
+ StorageDead(_50);
326322
+ StorageDead(_46);
327323
+ StorageDead(_45);
328324
+ StorageDead(_22);

tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,8 @@
6666
+ let mut _47: &mut std::future::Ready<()>;
6767
+ let mut _48: &mut std::pin::Pin<&mut std::future::Ready<()>>;
6868
+ scope 14 (inlined <Pin<&mut std::future::Ready<()>> as DerefMut>::deref_mut) {
69-
+ let mut _49: std::pin::Pin<&mut std::future::Ready<()>>;
7069
+ scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) {
71-
+ let mut _50: &mut &mut std::future::Ready<()>;
70+
+ let mut _49: &mut &mut std::future::Ready<()>;
7271
+ scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
7372
+ }
7473
+ scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) {
@@ -78,15 +77,15 @@
7877
+ }
7978
+ }
8079
+ scope 19 (inlined Option::<()>::take) {
81-
+ let mut _51: std::option::Option<()>;
80+
+ let mut _50: std::option::Option<()>;
8281
+ scope 20 (inlined std::mem::replace::<Option<()>>) {
8382
+ scope 21 {
8483
+ }
8584
+ }
8685
+ }
8786
+ scope 22 (inlined #[track_caller] Option::<()>::expect) {
88-
+ let mut _52: isize;
89-
+ let mut _53: !;
87+
+ let mut _51: isize;
88+
+ let mut _52: !;
9089
+ scope 23 {
9190
+ }
9291
+ }
@@ -246,28 +245,25 @@
246245
+ StorageDead(_24);
247246
+ StorageLive(_47);
248247
+ StorageLive(_48);
249-
+ StorageLive(_53);
248+
+ StorageLive(_52);
250249
+ StorageLive(_44);
251250
+ StorageLive(_45);
252251
+ StorageLive(_46);
253252
+ _48 = &mut _19;
254253
+ StorageLive(_49);
255-
+ StorageLive(_50);
256-
+ _50 = &mut (_19.0: &mut std::future::Ready<()>);
254+
+ _49 = &mut (_19.0: &mut std::future::Ready<()>);
257255
+ _47 = copy (_19.0: &mut std::future::Ready<()>);
258-
+ StorageDead(_50);
259-
+ _49 = Pin::<&mut std::future::Ready<()>> { pointer: copy _47 };
260256
+ StorageDead(_49);
261257
+ _46 = &mut ((*_47).0: std::option::Option<()>);
262-
+ StorageLive(_51);
263-
+ _51 = Option::<()>::None;
258+
+ StorageLive(_50);
259+
+ _50 = Option::<()>::None;
264260
+ _45 = copy ((*_47).0: std::option::Option<()>);
265-
+ ((*_47).0: std::option::Option<()>) = copy _51;
266-
+ StorageDead(_51);
261+
+ ((*_47).0: std::option::Option<()>) = copy _50;
262+
+ StorageDead(_50);
267263
+ StorageDead(_46);
268-
+ StorageLive(_52);
269-
+ _52 = discriminant(_45);
270-
+ switchInt(move _52) -> [0: bb16, 1: bb17, otherwise: bb7];
264+
+ StorageLive(_51);
265+
+ _51 = discriminant(_45);
266+
+ switchInt(move _51) -> [0: bb16, 1: bb17, otherwise: bb7];
271267
}
272268

273269
- bb6 (cleanup): {
@@ -354,16 +350,16 @@
354350
+ }
355351
+
356352
+ bb16: {
357-
+ _53 = option::expect_failed(const "`Ready` polled after completion") -> bb11;
353+
+ _52 = option::expect_failed(const "`Ready` polled after completion") -> bb11;
358354
+ }
359355
+
360356
+ bb17: {
361357
+ _44 = move ((_45 as Some).0: ());
362-
+ StorageDead(_52);
358+
+ StorageDead(_51);
363359
+ StorageDead(_45);
364360
+ _18 = Poll::<()>::Ready(move _44);
365361
+ StorageDead(_44);
366-
+ StorageDead(_53);
362+
+ StorageDead(_52);
367363
+ StorageDead(_48);
368364
+ StorageDead(_47);
369365
+ StorageDead(_22);

0 commit comments

Comments
 (0)