Skip to content

Commit 65b9e51

Browse files
committed
Feat: added caching schema for debuginfo type names
1 parent 0132f82 commit 65b9e51

File tree

1 file changed

+51
-10
lines changed

1 file changed

+51
-10
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ pub struct TypeMap<'ll, 'tcx> {
152152
type_to_metadata: FxHashMap<Ty<'tcx>, &'ll DIType>,
153153
/// A map from types to `UniqueTypeId`. This is an N:1 mapping.
154154
type_to_unique_id: FxHashMap<Ty<'tcx>, UniqueTypeId>,
155+
/// A map from `UniqueTypeId` to it's type-name string.
156+
unique_id_to_type_name: FxHashMap<UniqueTypeId, String>,
155157
}
156158

157159
impl TypeMap<'ll, 'tcx> {
@@ -201,6 +203,21 @@ impl TypeMap<'ll, 'tcx> {
201203
}
202204
}
203205

206+
/// Adds a `UniqueTypeId` to type-name mapping to the `TypeMap`. The
207+
/// method will fail if the mapping already exists.
208+
fn register_unique_id_with_type_name(
209+
&mut self,
210+
unique_type_id: UniqueTypeId,
211+
type_name: String
212+
) {
213+
if self.unique_id_to_type_name.insert(unique_type_id, type_name).is_some() {
214+
bug!(
215+
"type name for unique ID '{}' is already in the `TypeMap`!",
216+
self.get_unique_type_id_as_string(unique_type_id)
217+
);
218+
}
219+
}
220+
204221
fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option<&'ll DIType> {
205222
self.type_to_metadata.get(&type_).cloned()
206223
}
@@ -209,6 +226,10 @@ impl TypeMap<'ll, 'tcx> {
209226
self.unique_id_to_metadata.get(&unique_type_id).cloned()
210227
}
211228

229+
fn find_type_name_for_unique_id(&self, unique_type_id: UniqueTypeId) -> Option<String> {
230+
self.unique_id_to_type_name.get(&unique_type_id).cloned()
231+
}
232+
212233
/// Gets the string representation of a `UniqueTypeId`. This method will fail if
213234
/// the ID is unknown.
214235
fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> &str {
@@ -374,6 +395,26 @@ macro_rules! return_if_metadata_created_in_meantime {
374395
};
375396
}
376397

398+
fn check_type_name_cache(
399+
cx: &CodegenCx<'ll, 'tcx>,
400+
ty: Ty<'tcx>,
401+
qualified: bool,
402+
) -> String {
403+
let mut type_map = debug_context(cx).type_map.borrow_mut();
404+
let unique_type_id = type_map.get_unique_type_id_of_type(cx, ty);
405+
match type_map.find_type_name_for_unique_id(unique_type_id) {
406+
Some(type_name) => { type_name },
407+
None => {
408+
let type_name = compute_debuginfo_type_name(cx.tcx, ty, qualified);
409+
type_map.register_unique_id_with_type_name(
410+
unique_type_id,
411+
type_name.clone(),
412+
);
413+
type_name
414+
},
415+
}
416+
}
417+
377418
fn fixed_vec_metadata(
378419
cx: &CodegenCx<'ll, 'tcx>,
379420
unique_type_id: UniqueTypeId,
@@ -422,7 +463,7 @@ fn vec_slice_metadata(
422463

423464
return_if_metadata_created_in_meantime!(cx, unique_type_id);
424465

425-
let slice_type_name = compute_debuginfo_type_name(cx.tcx, slice_ptr_type, true);
466+
let slice_type_name = check_type_name_cache(cx, slice_ptr_type, true);
426467

427468
let (pointer_size, pointer_align) = cx.size_and_align_of(data_ptr_type);
428469
let (usize_size, usize_align) = cx.size_and_align_of(cx.tcx.types.usize);
@@ -520,10 +561,10 @@ fn trait_pointer_metadata(
520561
Some(trait_object_type) => match trait_object_type.kind() {
521562
ty::Adt(def, _) => (
522563
Some(get_namespace_for_item(cx, def.did)),
523-
compute_debuginfo_type_name(cx.tcx, trait_object_type, false),
564+
check_type_name_cache(cx, trait_object_type, false),
524565
),
525566
ty::RawPtr(_) | ty::Ref(..) => {
526-
(NO_SCOPE_METADATA, compute_debuginfo_type_name(cx.tcx, trait_object_type, true))
567+
(NO_SCOPE_METADATA, check_type_name_cache(cx, trait_object_type, true))
527568
}
528569
_ => {
529570
bug!(
@@ -536,7 +577,7 @@ fn trait_pointer_metadata(
536577

537578
// No object type, use the trait type directly (no scope here since the type
538579
// will be wrapped in the dyn$ synthetic type).
539-
None => (NO_SCOPE_METADATA, compute_debuginfo_type_name(cx.tcx, trait_type, true)),
580+
None => (NO_SCOPE_METADATA, check_type_name_cache(cx, trait_type, true)),
540581
};
541582

542583
let file_metadata = unknown_file_metadata(cx);
@@ -987,7 +1028,7 @@ fn foreign_type_metadata(
9871028
) -> &'ll DIType {
9881029
debug!("foreign_type_metadata: {:?}", t);
9891030

990-
let name = compute_debuginfo_type_name(cx.tcx, t, false);
1031+
let name = check_type_name_cache(cx, t, false);
9911032
create_struct_stub(cx, t, &name, unique_type_id, NO_SCOPE_METADATA, DIFlags::FlagZero)
9921033
}
9931034

@@ -997,7 +1038,7 @@ fn pointer_type_metadata(
9971038
pointee_type_metadata: &'ll DIType,
9981039
) -> &'ll DIType {
9991040
let (pointer_size, pointer_align) = cx.size_and_align_of(pointer_type);
1000-
let name = compute_debuginfo_type_name(cx.tcx, pointer_type, false);
1041+
let name = check_type_name_cache(cx, pointer_type, false);
10011042
unsafe {
10021043
llvm::LLVMRustDIBuilderCreatePointerType(
10031044
DIB(cx),
@@ -1300,7 +1341,7 @@ fn prepare_struct_metadata(
13001341
unique_type_id: UniqueTypeId,
13011342
span: Span,
13021343
) -> RecursiveTypeDescription<'ll, 'tcx> {
1303-
let struct_name = compute_debuginfo_type_name(cx.tcx, struct_type, false);
1344+
let struct_name = check_type_name_cache(cx, struct_type, false);
13041345

13051346
let (struct_def_id, variant) = match struct_type.kind() {
13061347
ty::Adt(def, _) => (def.did, def.non_enum_variant()),
@@ -1406,7 +1447,7 @@ fn prepare_tuple_metadata(
14061447
span: Span,
14071448
containing_scope: Option<&'ll DIScope>,
14081449
) -> RecursiveTypeDescription<'ll, 'tcx> {
1409-
let tuple_name = compute_debuginfo_type_name(cx.tcx, tuple_type, false);
1450+
let tuple_name = check_type_name_cache(cx, tuple_type, false);
14101451

14111452
let struct_stub = create_struct_stub(
14121453
cx,
@@ -1470,7 +1511,7 @@ fn prepare_union_metadata(
14701511
unique_type_id: UniqueTypeId,
14711512
span: Span,
14721513
) -> RecursiveTypeDescription<'ll, 'tcx> {
1473-
let union_name = compute_debuginfo_type_name(cx.tcx, union_type, false);
1514+
let union_name = check_type_name_cache(cx, union_type, false);
14741515

14751516
let (union_def_id, variant) = match union_type.kind() {
14761517
ty::Adt(def, _) => (def.did, def.non_enum_variant()),
@@ -2025,7 +2066,7 @@ fn prepare_enum_metadata(
20252066
outer_field_tys: Vec<Ty<'tcx>>,
20262067
) -> RecursiveTypeDescription<'ll, 'tcx> {
20272068
let tcx = cx.tcx;
2028-
let enum_name = compute_debuginfo_type_name(tcx, enum_type, false);
2069+
let enum_name = check_type_name_cache(cx, enum_type, false);
20292070

20302071
let containing_scope = get_namespace_for_item(cx, enum_def_id);
20312072
// FIXME: This should emit actual file metadata for the enum, but we

0 commit comments

Comments
 (0)