about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2024-08-29 16:53:07 +0200
committerRalf Jung <post@ralfj.de>2024-08-29 16:53:14 +0200
commitde34a9135069a559e3a2249b481fe551a5c1a8dd (patch)
treeda6e6095802e95da1e474c0a3affba3bf0875aa9
parent6cf068db566de080dfa7ed24a216ea3aed2b98ce (diff)
downloadrust-de34a9135069a559e3a2249b481fe551a5c1a8dd.tar.gz
rust-de34a9135069a559e3a2249b481fe551a5c1a8dd.zip
interpret/visitor: make memory order iteration slightly more efficient
-rw-r--r--compiler/rustc_const_eval/src/interpret/visitor.rs19
-rw-r--r--src/tools/miri/src/helpers.rs13
2 files changed, 15 insertions, 17 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/visitor.rs b/compiler/rustc_const_eval/src/interpret/visitor.rs
index fd649d608c6..b02f12e3c7f 100644
--- a/compiler/rustc_const_eval/src/interpret/visitor.rs
+++ b/compiler/rustc_const_eval/src/interpret/visitor.rs
@@ -25,14 +25,15 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
     }
 
     /// This function provides the chance to reorder the order in which fields are visited for
-    /// `FieldsShape::Aggregate`: The order of fields will be
-    /// `(0..num_fields).map(aggregate_field_order)`.
+    /// `FieldsShape::Aggregate`.
     ///
-    /// The default means we iterate in source declaration order; alternative this can do an inverse
-    /// lookup in `memory_index` to use memory field order instead.
+    /// The default means we iterate in source declaration order; alternatively this can do some
+    /// work with `memory_index` to iterate in memory order.
     #[inline(always)]
-    fn aggregate_field_order(_memory_index: &IndexVec<FieldIdx, u32>, idx: usize) -> usize {
-        idx
+    fn aggregate_field_iter(
+        memory_index: &IndexVec<FieldIdx, u32>,
+    ) -> impl Iterator<Item = FieldIdx> + 'static {
+        memory_index.indices()
     }
 
     // Recursive actions, ready to be overloaded.
@@ -172,9 +173,9 @@ pub trait ValueVisitor<'tcx, M: Machine<'tcx>>: Sized {
             &FieldsShape::Union(fields) => {
                 self.visit_union(v, fields)?;
             }
-            FieldsShape::Arbitrary { offsets, memory_index } => {
-                for idx in 0..offsets.len() {
-                    let idx = Self::aggregate_field_order(memory_index, idx);
+            FieldsShape::Arbitrary { memory_index, .. } => {
+                for idx in Self::aggregate_field_iter(memory_index) {
+                    let idx = idx.as_usize();
                     let field = self.ecx().project_field(v, idx)?;
                     self.visit_field(v, idx, &field)?;
                 }
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 04837456212..a546ad20fef 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -630,14 +630,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 self.ecx
             }
 
-            fn aggregate_field_order(memory_index: &IndexVec<FieldIdx, u32>, idx: usize) -> usize {
-                // We need to do an *inverse* lookup: find the field that has position `idx` in memory order.
-                for (src_field, &mem_pos) in memory_index.iter_enumerated() {
-                    if mem_pos as usize == idx {
-                        return src_field.as_usize();
-                    }
-                }
-                panic!("invalid `memory_index`, could not find {}-th field in memory order", idx);
+            fn aggregate_field_iter(
+                memory_index: &IndexVec<FieldIdx, u32>,
+            ) -> impl Iterator<Item = FieldIdx> + 'static {
+                let inverse_memory_index = memory_index.invert_bijective_mapping();
+                inverse_memory_index.into_iter()
             }
 
             // Hook to detect `UnsafeCell`.