Skip to content

Commit e410658

Browse files
committed
Replace on-the-fly llvm field index calculation with cache
1 parent 60a523d commit e410658

File tree

2 files changed

+14
-17
lines changed

2 files changed

+14
-17
lines changed

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ pub struct CodegenCx<'ll, 'tcx> {
7979
pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,
8080
pub isize_ty: &'ll Type,
8181

82+
/// Cache for the mapping from source index to llvm index for struct fields,
83+
/// necessary because the mapping depends on padding and thus depens on
84+
/// TyAndLayout.
85+
pub field_projection_cache: RefCell<FxHashMap<TyAndLayout<'tcx>, Vec<u32>>>,
86+
8287
pub coverage_cx: Option<coverageinfo::CrateCoverageContext<'ll, 'tcx>>,
8388
pub dbg_cx: Option<debuginfo::CrateDebugContext<'ll, 'tcx>>,
8489

@@ -308,6 +313,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
308313
scalar_lltypes: Default::default(),
309314
pointee_infos: Default::default(),
310315
isize_ty,
316+
field_projection_cache: Default::default(),
311317
coverage_cx,
312318
dbg_cx,
313319
eh_personality: Cell::new(None),

compiler/rustc_codegen_llvm/src/type_of.rs

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ fn struct_llfields<'a, 'tcx>(
9898
let mut offset = Size::ZERO;
9999
let mut prev_effective_align = layout.align.abi;
100100
let mut result: Vec<_> = Vec::with_capacity(1 + field_count * 2);
101+
let mut projection = vec![0; field_count];
101102
for i in layout.fields.index_by_increasing_offset() {
102103
let target_offset = layout.fields.offset(i as usize);
103104
let field = layout.field(cx, i);
@@ -122,6 +123,7 @@ fn struct_llfields<'a, 'tcx>(
122123
result.push(cx.type_padding_filler(padding, padding_align));
123124
debug!(" padding before: {:?}", padding);
124125
}
126+
projection[i] = result.len() as u32;
125127
result.push(field.llvm_type(cx));
126128
offset = target_offset + field.size;
127129
prev_effective_align = effective_field_align;
@@ -143,6 +145,7 @@ fn struct_llfields<'a, 'tcx>(
143145
} else {
144146
debug!("struct_llfields: offset: {:?} stride: {:?}", offset, layout.size);
145147
}
148+
cx.field_projection_cache.borrow_mut().insert(layout, projection);
146149

147150
(result, packed)
148151
}
@@ -356,24 +359,12 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
356359

357360
FieldsShape::Array { .. } => index as u64,
358361

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)
374366
}
375-
bug!("TyAndLayout::llvm_field_index({:?}): index {} out of range", self, index)
376-
}
367+
},
377368
}
378369
}
379370

0 commit comments

Comments
 (0)