Replace on-the-fly llvm field index calculation with cache
This commit is contained in:
parent
60a523de92
commit
e4106581de
2 changed files with 14 additions and 17 deletions
|
@ -79,6 +79,11 @@ pub struct CodegenCx<'ll, 'tcx> {
|
||||||
pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,
|
pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,
|
||||||
pub isize_ty: &'ll Type,
|
pub isize_ty: &'ll Type,
|
||||||
|
|
||||||
|
/// Cache for the mapping from source index to llvm index for struct fields,
|
||||||
|
/// necessary because the mapping depends on padding and thus depens on
|
||||||
|
/// TyAndLayout.
|
||||||
|
pub field_projection_cache: RefCell<FxHashMap<TyAndLayout<'tcx>, Vec<u32>>>,
|
||||||
|
|
||||||
pub coverage_cx: Option<coverageinfo::CrateCoverageContext<'ll, 'tcx>>,
|
pub coverage_cx: Option<coverageinfo::CrateCoverageContext<'ll, 'tcx>>,
|
||||||
pub dbg_cx: Option<debuginfo::CrateDebugContext<'ll, 'tcx>>,
|
pub dbg_cx: Option<debuginfo::CrateDebugContext<'ll, 'tcx>>,
|
||||||
|
|
||||||
|
@ -308,6 +313,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
||||||
scalar_lltypes: Default::default(),
|
scalar_lltypes: Default::default(),
|
||||||
pointee_infos: Default::default(),
|
pointee_infos: Default::default(),
|
||||||
isize_ty,
|
isize_ty,
|
||||||
|
field_projection_cache: Default::default(),
|
||||||
coverage_cx,
|
coverage_cx,
|
||||||
dbg_cx,
|
dbg_cx,
|
||||||
eh_personality: Cell::new(None),
|
eh_personality: Cell::new(None),
|
||||||
|
|
|
@ -98,6 +98,7 @@ fn struct_llfields<'a, 'tcx>(
|
||||||
let mut offset = Size::ZERO;
|
let mut offset = Size::ZERO;
|
||||||
let mut prev_effective_align = layout.align.abi;
|
let mut prev_effective_align = layout.align.abi;
|
||||||
let mut result: Vec<_> = Vec::with_capacity(1 + field_count * 2);
|
let mut result: Vec<_> = Vec::with_capacity(1 + field_count * 2);
|
||||||
|
let mut projection = vec![0; field_count];
|
||||||
for i in layout.fields.index_by_increasing_offset() {
|
for i in layout.fields.index_by_increasing_offset() {
|
||||||
let target_offset = layout.fields.offset(i as usize);
|
let target_offset = layout.fields.offset(i as usize);
|
||||||
let field = layout.field(cx, i);
|
let field = layout.field(cx, i);
|
||||||
|
@ -122,6 +123,7 @@ fn struct_llfields<'a, 'tcx>(
|
||||||
result.push(cx.type_padding_filler(padding, padding_align));
|
result.push(cx.type_padding_filler(padding, padding_align));
|
||||||
debug!(" padding before: {:?}", padding);
|
debug!(" padding before: {:?}", padding);
|
||||||
}
|
}
|
||||||
|
projection[i] = result.len() as u32;
|
||||||
result.push(field.llvm_type(cx));
|
result.push(field.llvm_type(cx));
|
||||||
offset = target_offset + field.size;
|
offset = target_offset + field.size;
|
||||||
prev_effective_align = effective_field_align;
|
prev_effective_align = effective_field_align;
|
||||||
|
@ -143,6 +145,7 @@ fn struct_llfields<'a, 'tcx>(
|
||||||
} else {
|
} else {
|
||||||
debug!("struct_llfields: offset: {:?} stride: {:?}", offset, layout.size);
|
debug!("struct_llfields: offset: {:?} stride: {:?}", offset, layout.size);
|
||||||
}
|
}
|
||||||
|
cx.field_projection_cache.borrow_mut().insert(layout, projection);
|
||||||
|
|
||||||
(result, packed)
|
(result, packed)
|
||||||
}
|
}
|
||||||
|
@ -356,24 +359,12 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
|
||||||
|
|
||||||
FieldsShape::Array { .. } => index as u64,
|
FieldsShape::Array { .. } => index as u64,
|
||||||
|
|
||||||
FieldsShape::Arbitrary { .. } => {
|
FieldsShape::Arbitrary { .. } => match cx.field_projection_cache.borrow().get(self) {
|
||||||
let mut llvm_index = 0;
|
Some(projection) => projection[index] as u64,
|
||||||
let mut offset = Size::ZERO;
|
None => {
|
||||||
for i in self.fields.index_by_increasing_offset() {
|
bug!("TyAndLayout::llvm_field_index({:?}): field projection not cached", self)
|
||||||
let target_offset = self.fields.offset(i as usize);
|
|
||||||
let field = self.field(cx, i);
|
|
||||||
let padding = target_offset - offset;
|
|
||||||
if padding != Size::ZERO {
|
|
||||||
llvm_index += 1;
|
|
||||||
}
|
|
||||||
if i == index {
|
|
||||||
return llvm_index;
|
|
||||||
}
|
|
||||||
offset = target_offset + field.size;
|
|
||||||
llvm_index += 1;
|
|
||||||
}
|
}
|
||||||
bug!("TyAndLayout::llvm_field_index({:?}): index {} out of range", self, index)
|
},
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue