@@ -98,6 +98,7 @@ fn struct_llfields<'a, 'tcx>(
98
98
let mut offset = Size :: ZERO ;
99
99
let mut prev_effective_align = layout. align . abi ;
100
100
let mut result: Vec < _ > = Vec :: with_capacity ( 1 + field_count * 2 ) ;
101
+ let mut projection = vec ! [ 0 ; field_count] ;
101
102
for i in layout. fields . index_by_increasing_offset ( ) {
102
103
let target_offset = layout. fields . offset ( i as usize ) ;
103
104
let field = layout. field ( cx, i) ;
@@ -122,6 +123,7 @@ fn struct_llfields<'a, 'tcx>(
122
123
result. push ( cx. type_padding_filler ( padding, padding_align) ) ;
123
124
debug ! ( " padding before: {:?}" , padding) ;
124
125
}
126
+ projection[ i] = result. len ( ) as u32 ;
125
127
result. push ( field. llvm_type ( cx) ) ;
126
128
offset = target_offset + field. size ;
127
129
prev_effective_align = effective_field_align;
@@ -143,6 +145,7 @@ fn struct_llfields<'a, 'tcx>(
143
145
} else {
144
146
debug ! ( "struct_llfields: offset: {:?} stride: {:?}" , offset, layout. size) ;
145
147
}
148
+ cx. field_projection_cache . borrow_mut ( ) . insert ( layout, projection) ;
146
149
147
150
( result, packed)
148
151
}
@@ -356,24 +359,12 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
356
359
357
360
FieldsShape :: Array { .. } => index as u64 ,
358
361
359
- FieldsShape :: Arbitrary { .. } => {
360
- let mut llvm_index = 0 ;
361
- let mut offset = Size :: ZERO ;
362
- for i in self . fields . index_by_increasing_offset ( ) {
363
- let target_offset = self . fields . offset ( i as usize ) ;
364
- let field = self . field ( cx, i) ;
365
- let padding = target_offset - offset;
366
- if padding != Size :: ZERO {
367
- llvm_index += 1 ;
368
- }
369
- if i == index {
370
- return llvm_index;
371
- }
372
- offset = target_offset + field. size ;
373
- llvm_index += 1 ;
362
+ FieldsShape :: Arbitrary { .. } => match cx. field_projection_cache . borrow ( ) . get ( self ) {
363
+ Some ( projection) => projection[ index] as u64 ,
364
+ None => {
365
+ bug ! ( "TyAndLayout::llvm_field_index({:?}): field projection not cached" , self )
374
366
}
375
- bug ! ( "TyAndLayout::llvm_field_index({:?}): index {} out of range" , self , index)
376
- }
367
+ } ,
377
368
}
378
369
}
379
370
0 commit comments