Skip to content

Commit 4a4e9e3

Browse files
committed
Store field remapping information together with the LLVM type in a new TypeLowering struct instead of an extra cache.
1 parent 7dbc568 commit 4a4e9e3

File tree

2 files changed

+50
-26
lines changed

2 files changed

+50
-26
lines changed

compiler/rustc_codegen_llvm/src/context.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,15 @@ pub struct CodegenCx<'ll, 'tcx> {
7474
/// See <https://llvm.org/docs/LangRef.html#the-llvm-used-global-variable> for details
7575
pub used_statics: RefCell<Vec<&'ll Value>>,
7676

77-
pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<VariantIdx>), &'ll Type>>,
77+
/// Mapping of non-scalar types to llvm types and field remapping if needed.
78+
pub type_lowering: RefCell<FxHashMap<(Ty<'tcx>, Option<VariantIdx>), TypeLowering<'ll>>>,
79+
80+
/// Mapping of scalar types to llvm types.
7881
pub scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, &'ll Type>>,
82+
7983
pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,
8084
pub isize_ty: &'ll Type,
8185

82-
/// Cache for the mapping from source index to llvm index for struct fields,
83-
/// only present if synthetic fields are inserted for padding.
84-
pub field_projection_cache: RefCell<FxHashMap<TyAndLayout<'tcx>, Vec<u32>>>,
85-
8686
pub coverage_cx: Option<coverageinfo::CrateCoverageContext<'ll, 'tcx>>,
8787
pub dbg_cx: Option<debuginfo::CrateDebugContext<'ll, 'tcx>>,
8888

@@ -96,6 +96,15 @@ pub struct CodegenCx<'ll, 'tcx> {
9696
local_gen_sym_counter: Cell<usize>,
9797
}
9898

99+
pub struct TypeLowering<'ll> {
100+
/// Associated LLVM type
101+
pub lltype: &'ll Type,
102+
103+
/// If padding is used the slice maps fields from source order
104+
/// to llvm order.
105+
pub field_remapping: Option<Box<[u32]>>,
106+
}
107+
99108
fn to_llvm_tls_model(tls_model: TlsModel) -> llvm::ThreadLocalMode {
100109
match tls_model {
101110
TlsModel::GeneralDynamic => llvm::ThreadLocalMode::GeneralDynamic,
@@ -308,11 +317,10 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
308317
const_globals: Default::default(),
309318
statics_to_rauw: RefCell::new(Vec::new()),
310319
used_statics: RefCell::new(Vec::new()),
311-
lltypes: Default::default(),
320+
type_lowering: Default::default(),
312321
scalar_lltypes: Default::default(),
313322
pointee_infos: Default::default(),
314323
isize_ty,
315-
field_projection_cache: Default::default(),
316324
coverage_cx,
317325
dbg_cx,
318326
eh_personality: Cell::new(None),

compiler/rustc_codegen_llvm/src/type_of.rs

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use crate::abi::FnAbi;
22
use crate::common::*;
3+
use crate::context::TypeLowering;
34
use crate::type_::Type;
45
use rustc_codegen_ssa::traits::*;
56
use rustc_middle::bug;
@@ -17,6 +18,7 @@ fn uncached_llvm_type<'a, 'tcx>(
1718
cx: &CodegenCx<'a, 'tcx>,
1819
layout: TyAndLayout<'tcx>,
1920
defer: &mut Option<(&'a Type, TyAndLayout<'tcx>)>,
21+
field_remapping: &mut Option<Box<[u32]>>,
2022
) -> &'a Type {
2123
match layout.abi {
2224
Abi::Scalar(_) => bug!("handled elsewhere"),
@@ -75,7 +77,8 @@ fn uncached_llvm_type<'a, 'tcx>(
7577
FieldsShape::Array { count, .. } => cx.type_array(layout.field(cx, 0).llvm_type(cx), count),
7678
FieldsShape::Arbitrary { .. } => match name {
7779
None => {
78-
let (llfields, packed) = struct_llfields(cx, layout);
80+
let (llfields, packed, new_field_remapping) = struct_llfields(cx, layout);
81+
*field_remapping = new_field_remapping;
7982
cx.type_struct(&llfields, packed)
8083
}
8184
Some(ref name) => {
@@ -90,7 +93,7 @@ fn uncached_llvm_type<'a, 'tcx>(
9093
fn struct_llfields<'a, 'tcx>(
9194
cx: &CodegenCx<'a, 'tcx>,
9295
layout: TyAndLayout<'tcx>,
93-
) -> (Vec<&'a Type>, bool) {
96+
) -> (Vec<&'a Type>, bool, Option<Box<[u32]>>) {
9497
debug!("struct_llfields: {:#?}", layout);
9598
let field_count = layout.fields.count();
9699

@@ -147,11 +150,8 @@ fn struct_llfields<'a, 'tcx>(
147150
} else {
148151
debug!("struct_llfields: offset: {:?} stride: {:?}", offset, layout.size);
149152
}
150-
if padding_used {
151-
cx.field_projection_cache.borrow_mut().insert(layout, projection);
152-
}
153153

154-
(result, packed)
154+
(result, packed, padding_used.then_some(projection.into_boxed_slice()))
155155
}
156156

157157
impl<'a, 'tcx> CodegenCx<'a, 'tcx> {
@@ -243,8 +243,8 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
243243
Variants::Single { index } => Some(index),
244244
_ => None,
245245
};
246-
if let Some(&llty) = cx.lltypes.borrow().get(&(self.ty, variant_index)) {
247-
return llty;
246+
if let Some(ref llty) = cx.type_lowering.borrow().get(&(self.ty, variant_index)) {
247+
return llty.lltype;
248248
}
249249

250250
debug!("llvm_type({:#?})", self);
@@ -256,24 +256,29 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
256256
let normal_ty = cx.tcx.erase_regions(self.ty);
257257

258258
let mut defer = None;
259+
let mut field_remapping = None;
259260
let llty = if self.ty != normal_ty {
260261
let mut layout = cx.layout_of(normal_ty);
261262
if let Some(v) = variant_index {
262263
layout = layout.for_variant(cx, v);
263264
}
264265
layout.llvm_type(cx)
265266
} else {
266-
uncached_llvm_type(cx, *self, &mut defer)
267+
uncached_llvm_type(cx, *self, &mut defer, &mut field_remapping)
267268
};
268269
debug!("--> mapped {:#?} to llty={:?}", self, llty);
269270

270-
cx.lltypes.borrow_mut().insert((self.ty, variant_index), llty);
271+
cx.type_lowering
272+
.borrow_mut()
273+
.insert((self.ty, variant_index), TypeLowering { lltype: llty, field_remapping: None });
271274

272275
if let Some((llty, layout)) = defer {
273-
let (llfields, packed) = struct_llfields(cx, layout);
274-
cx.set_struct_body(llty, &llfields, packed)
276+
let (llfields, packed, new_field_remapping) = struct_llfields(cx, layout);
277+
cx.set_struct_body(llty, &llfields, packed);
278+
field_remapping = new_field_remapping;
275279
}
276-
280+
cx.type_lowering.borrow_mut().get_mut(&(self.ty, variant_index)).unwrap().field_remapping =
281+
field_remapping;
277282
llty
278283
}
279284

@@ -363,12 +368,23 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {
363368

364369
FieldsShape::Array { .. } => index as u64,
365370

366-
// Look up llvm field index in projection cache if present. If no projection cache
367-
// is present no padding is used and the llvm field index matches the memory index.
368-
FieldsShape::Arbitrary { .. } => match cx.field_projection_cache.borrow().get(self) {
369-
Some(projection) => projection[index] as u64,
370-
None => self.fields.memory_index(index) as u64,
371-
},
371+
FieldsShape::Arbitrary { .. } => {
372+
let variant_index = match self.variants {
373+
Variants::Single { index } => Some(index),
374+
_ => None,
375+
};
376+
377+
// Look up llvm field if indexes do not match memory order due to padding. If
378+
// `field_remapping` is `None` no padding was used and the llvm field index
379+
// matches the memory index.
380+
match cx.type_lowering.borrow().get(&(self.ty, variant_index)) {
381+
Some(TypeLowering { field_remapping: Some(ref prj), .. }) => prj[index] as u64,
382+
Some(_) => self.fields.memory_index(index) as u64,
383+
None => {
384+
bug!("TyAndLayout::llvm_field_index({:?}): type info not found", self)
385+
}
386+
}
387+
}
372388
}
373389
}
374390

0 commit comments

Comments
 (0)