about summary refs log tree commit diff
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2025-07-27 13:21:06 -0700
committerScott McMurray <scottmcm@users.noreply.github.com>2025-07-27 13:21:06 -0700
commit47bfa846f37cf053471656b572a35d2bfca16715 (patch)
tree157ae92f4dbb0aec744ca5e693bc5960ff2bd9aa
parentedc3841c5d28e0f54c6d3c7e906ad083129f3903 (diff)
downloadrust-47bfa846f37cf053471656b572a35d2bfca16715.tar.gz
rust-47bfa846f37cf053471656b572a35d2bfca16715.zip
Allow more MIR SROA
-rw-r--r--compiler/rustc_mir_transform/src/sroa.rs36
-rw-r--r--tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff36
-rw-r--r--tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff36
3 files changed, 40 insertions, 68 deletions
diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs
index 7c6ccc89c4f..80c4b58a574 100644
--- a/compiler/rustc_mir_transform/src/sroa.rs
+++ b/compiler/rustc_mir_transform/src/sroa.rs
@@ -1,4 +1,4 @@
-use rustc_abi::{FIRST_VARIANT, FieldIdx};
+use rustc_abi::FieldIdx;
 use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
 use rustc_hir::LangItem;
 use rustc_index::IndexVec;
@@ -32,7 +32,7 @@ impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates {
         let typing_env = body.typing_env(tcx);
         loop {
             debug!(?excluded);
-            let escaping = escaping_locals(tcx, typing_env, &excluded, body);
+            let escaping = escaping_locals(tcx, &excluded, body);
             debug!(?escaping);
             let replacements = compute_flattening(tcx, typing_env, body, escaping);
             debug!(?replacements);
@@ -64,7 +64,6 @@ impl<'tcx> crate::MirPass<'tcx> for ScalarReplacementOfAggregates {
 ///   client code.
 fn escaping_locals<'tcx>(
     tcx: TyCtxt<'tcx>,
-    typing_env: ty::TypingEnv<'tcx>,
     excluded: &DenseBitSet<Local>,
     body: &Body<'tcx>,
 ) -> DenseBitSet<Local> {
@@ -72,31 +71,12 @@ fn escaping_locals<'tcx>(
         if ty.is_union() || ty.is_enum() {
             return true;
         }
-        if let ty::Adt(def, _args) = ty.kind() {
-            if def.repr().simd() {
-                // Exclude #[repr(simd)] types so that they are not de-optimized into an array
-                return true;
-            }
-            if tcx.is_lang_item(def.did(), LangItem::DynMetadata) {
-                // codegen wants to see the `DynMetadata<T>`,
-                // not the inner reference-to-opaque-type.
-                return true;
-            }
-            // We already excluded unions and enums, so this ADT must have one variant
-            let variant = def.variant(FIRST_VARIANT);
-            if variant.fields.len() > 1 {
-                // If this has more than one field, it cannot be a wrapper that only provides a
-                // niche, so we do not want to automatically exclude it.
-                return false;
-            }
-            let Ok(layout) = tcx.layout_of(typing_env.as_query_input(ty)) else {
-                // We can't get the layout
-                return true;
-            };
-            if layout.layout.largest_niche().is_some() {
-                // This type has a niche
-                return true;
-            }
+        if let ty::Adt(def, _args) = ty.kind()
+            && tcx.is_lang_item(def.did(), LangItem::DynMetadata)
+        {
+            // codegen wants to see the `DynMetadata<T>`,
+            // not the inner reference-to-opaque-type.
+            return true;
         }
         // Default for non-ADTs
         false
diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff
index 169a6768448..22e6ea722dd 100644
--- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff
@@ -64,9 +64,8 @@
 +                             let mut _45: &mut std::future::Ready<()>;
 +                             let mut _46: &mut std::pin::Pin<&mut std::future::Ready<()>>;
 +                             scope 14 (inlined <Pin<&mut std::future::Ready<()>> as DerefMut>::deref_mut) {
-+                                 let mut _47: std::pin::Pin<&mut std::future::Ready<()>>;
 +                                 scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) {
-+                                     let mut _48: &mut &mut std::future::Ready<()>;
++                                     let mut _47: &mut &mut std::future::Ready<()>;
 +                                     scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
 +                                     }
 +                                     scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) {
@@ -76,15 +75,15 @@
 +                                 }
 +                             }
 +                             scope 19 (inlined Option::<()>::take) {
-+                                 let mut _49: std::option::Option<()>;
++                                 let mut _48: std::option::Option<()>;
 +                                 scope 20 (inlined std::mem::replace::<Option<()>>) {
 +                                     scope 21 {
 +                                     }
 +                                 }
 +                             }
 +                             scope 22 (inlined #[track_caller] Option::<()>::expect) {
-+                                 let mut _50: isize;
-+                                 let mut _51: !;
++                                 let mut _49: isize;
++                                 let mut _50: !;
 +                                 scope 23 {
 +                                 }
 +                             }
@@ -229,28 +228,25 @@
 +         StorageDead(_24);
 +         StorageLive(_45);
 +         StorageLive(_46);
-+         StorageLive(_51);
++         StorageLive(_50);
 +         StorageLive(_42);
 +         StorageLive(_43);
 +         StorageLive(_44);
 +         _46 = &mut _19;
 +         StorageLive(_47);
-+         StorageLive(_48);
-+         _48 = &mut (_19.0: &mut std::future::Ready<()>);
++         _47 = &mut (_19.0: &mut std::future::Ready<()>);
 +         _45 = copy (_19.0: &mut std::future::Ready<()>);
-+         StorageDead(_48);
-+         _47 = Pin::<&mut std::future::Ready<()>> { pointer: copy _45 };
 +         StorageDead(_47);
 +         _44 = &mut ((*_45).0: std::option::Option<()>);
-+         StorageLive(_49);
-+         _49 = Option::<()>::None;
++         StorageLive(_48);
++         _48 = Option::<()>::None;
 +         _43 = copy ((*_45).0: std::option::Option<()>);
-+         ((*_45).0: std::option::Option<()>) = copy _49;
-+         StorageDead(_49);
++         ((*_45).0: std::option::Option<()>) = copy _48;
++         StorageDead(_48);
 +         StorageDead(_44);
-+         StorageLive(_50);
-+         _50 = discriminant(_43);
-+         switchInt(move _50) -> [0: bb11, 1: bb12, otherwise: bb5];
++         StorageLive(_49);
++         _49 = discriminant(_43);
++         switchInt(move _49) -> [0: bb11, 1: bb12, otherwise: bb5];
       }
 + 
 +     bb5: {
@@ -313,16 +309,16 @@
 +     }
 + 
 +     bb11: {
-+         _51 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable;
++         _50 = option::expect_failed(const "`Ready` polled after completion") -> unwind unreachable;
 +     }
 + 
 +     bb12: {
 +         _42 = move ((_43 as Some).0: ());
-+         StorageDead(_50);
++         StorageDead(_49);
 +         StorageDead(_43);
 +         _18 = Poll::<()>::Ready(move _42);
 +         StorageDead(_42);
-+         StorageDead(_51);
++         StorageDead(_50);
 +         StorageDead(_46);
 +         StorageDead(_45);
 +         StorageDead(_22);
diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff
index 14ba3311d2d..8b027e988b8 100644
--- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff
@@ -66,9 +66,8 @@
 +                             let mut _47: &mut std::future::Ready<()>;
 +                             let mut _48: &mut std::pin::Pin<&mut std::future::Ready<()>>;
 +                             scope 14 (inlined <Pin<&mut std::future::Ready<()>> as DerefMut>::deref_mut) {
-+                                 let mut _49: std::pin::Pin<&mut std::future::Ready<()>>;
 +                                 scope 15 (inlined Pin::<&mut std::future::Ready<()>>::as_mut) {
-+                                     let mut _50: &mut &mut std::future::Ready<()>;
++                                     let mut _49: &mut &mut std::future::Ready<()>;
 +                                     scope 16 (inlined Pin::<&mut std::future::Ready<()>>::new_unchecked) {
 +                                     }
 +                                     scope 18 (inlined <&mut std::future::Ready<()> as DerefMut>::deref_mut) {
@@ -78,15 +77,15 @@
 +                                 }
 +                             }
 +                             scope 19 (inlined Option::<()>::take) {
-+                                 let mut _51: std::option::Option<()>;
++                                 let mut _50: std::option::Option<()>;
 +                                 scope 20 (inlined std::mem::replace::<Option<()>>) {
 +                                     scope 21 {
 +                                     }
 +                                 }
 +                             }
 +                             scope 22 (inlined #[track_caller] Option::<()>::expect) {
-+                                 let mut _52: isize;
-+                                 let mut _53: !;
++                                 let mut _51: isize;
++                                 let mut _52: !;
 +                                 scope 23 {
 +                                 }
 +                             }
@@ -246,28 +245,25 @@
 +         StorageDead(_24);
 +         StorageLive(_47);
 +         StorageLive(_48);
-+         StorageLive(_53);
++         StorageLive(_52);
 +         StorageLive(_44);
 +         StorageLive(_45);
 +         StorageLive(_46);
 +         _48 = &mut _19;
 +         StorageLive(_49);
-+         StorageLive(_50);
-+         _50 = &mut (_19.0: &mut std::future::Ready<()>);
++         _49 = &mut (_19.0: &mut std::future::Ready<()>);
 +         _47 = copy (_19.0: &mut std::future::Ready<()>);
-+         StorageDead(_50);
-+         _49 = Pin::<&mut std::future::Ready<()>> { pointer: copy _47 };
 +         StorageDead(_49);
 +         _46 = &mut ((*_47).0: std::option::Option<()>);
-+         StorageLive(_51);
-+         _51 = Option::<()>::None;
++         StorageLive(_50);
++         _50 = Option::<()>::None;
 +         _45 = copy ((*_47).0: std::option::Option<()>);
-+         ((*_47).0: std::option::Option<()>) = copy _51;
-+         StorageDead(_51);
++         ((*_47).0: std::option::Option<()>) = copy _50;
++         StorageDead(_50);
 +         StorageDead(_46);
-+         StorageLive(_52);
-+         _52 = discriminant(_45);
-+         switchInt(move _52) -> [0: bb16, 1: bb17, otherwise: bb7];
++         StorageLive(_51);
++         _51 = discriminant(_45);
++         switchInt(move _51) -> [0: bb16, 1: bb17, otherwise: bb7];
       }
   
 -     bb6 (cleanup): {
@@ -354,16 +350,16 @@
 +     }
 + 
 +     bb16: {
-+         _53 = option::expect_failed(const "`Ready` polled after completion") -> bb11;
++         _52 = option::expect_failed(const "`Ready` polled after completion") -> bb11;
 +     }
 + 
 +     bb17: {
 +         _44 = move ((_45 as Some).0: ());
-+         StorageDead(_52);
++         StorageDead(_51);
 +         StorageDead(_45);
 +         _18 = Poll::<()>::Ready(move _44);
 +         StorageDead(_44);
-+         StorageDead(_53);
++         StorageDead(_52);
 +         StorageDead(_48);
 +         StorageDead(_47);
 +         StorageDead(_22);