Skip to content

Commit 482aedc

Browse files
committed
Added cache argument for compute_debuginfo_type_name
1 parent 2e01bf1 commit 482aedc

File tree

2 files changed

+88
-52
lines changed

2 files changed

+88
-52
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,6 @@ 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>,
157155
}
158156

159157
impl TypeMap<'ll, 'tcx> {
@@ -203,21 +201,6 @@ impl TypeMap<'ll, 'tcx> {
203201
}
204202
}
205203

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-
221204
fn find_metadata_for_type(&self, type_: Ty<'tcx>) -> Option<&'ll DIType> {
222205
self.type_to_metadata.get(&type_).cloned()
223206
}
@@ -226,10 +209,6 @@ impl TypeMap<'ll, 'tcx> {
226209
self.unique_id_to_metadata.get(&unique_type_id).cloned()
227210
}
228211

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-
233212
/// Gets the string representation of a `UniqueTypeId`. This method will fail if
234213
/// the ID is unknown.
235214
fn get_unique_type_id_as_string(&self, unique_type_id: UniqueTypeId) -> &str {
@@ -396,16 +375,8 @@ macro_rules! return_if_metadata_created_in_meantime {
396375
}
397376

398377
fn check_type_name_cache(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>, qualified: bool) -> String {
399-
let mut type_map = debug_context(cx).type_map.borrow_mut();
400-
let unique_type_id = type_map.get_unique_type_id_of_type(cx, ty);
401-
match type_map.find_type_name_for_unique_id(unique_type_id) {
402-
Some(type_name) => type_name,
403-
None => {
404-
let type_name = compute_debuginfo_type_name(cx.tcx, ty, qualified);
405-
type_map.register_unique_id_with_type_name(unique_type_id, type_name.clone());
406-
type_name
407-
}
408-
}
378+
let type_name_cache = &mut *debug_context(cx).type_name_cache.borrow_mut();
379+
compute_debuginfo_type_name(cx.tcx, ty, qualified, type_name_cache)
409380
}
410381

411382
fn fixed_vec_metadata(

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

Lines changed: 86 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// within the brackets).
1212
// * `"` is treated as the start of a string.
1313

14-
use rustc_data_structures::fx::FxHashSet;
14+
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
1515
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
1616
use rustc_hir as hir;
1717
use rustc_hir::def_id::DefId;
@@ -33,12 +33,18 @@ pub fn compute_debuginfo_type_name<'tcx>(
3333
tcx: TyCtxt<'tcx>,
3434
t: Ty<'tcx>,
3535
qualified: bool,
36+
type_name_cache: &mut FxHashMap<(Ty<'tcx>, bool), String>,
3637
) -> String {
3738
let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name");
3839

40+
// Check if we have seen this type and qualifier before.
41+
if let Some(type_name) = type_name_cache.get(&(&t, qualified)) {
42+
return type_name.clone();
43+
}
44+
3945
let mut result = String::with_capacity(64);
4046
let mut visited = FxHashSet::default();
41-
push_debuginfo_type_name(tcx, t, qualified, &mut result, &mut visited);
47+
push_debuginfo_type_name(tcx, t, qualified, &mut result, &mut visited, type_name_cache);
4248
result
4349
}
4450

@@ -50,6 +56,7 @@ fn push_debuginfo_type_name<'tcx>(
5056
qualified: bool,
5157
output: &mut String,
5258
visited: &mut FxHashSet<Ty<'tcx>>,
59+
type_name_cache: &mut FxHashMap<(Ty<'tcx>, bool), String>,
5360
) {
5461
// When targeting MSVC, emit C++ style type names for compatibility with
5562
// .natvis visualizers (and perhaps other existing native debuggers?)
@@ -72,10 +79,10 @@ fn push_debuginfo_type_name<'tcx>(
7279
ty::Foreign(def_id) => push_item_name(tcx, def_id, qualified, output),
7380
ty::Adt(def, substs) => {
7481
if def.is_enum() && cpp_like_names {
75-
msvc_enum_fallback(tcx, t, def, substs, output, visited);
82+
msvc_enum_fallback(tcx, t, def, substs, output, visited, type_name_cache);
7683
} else {
7784
push_item_name(tcx, def.did, qualified, output);
78-
push_generic_params_internal(tcx, substs, output, visited);
85+
push_generic_params_internal(tcx, substs, output, visited, type_name_cache);
7986
}
8087
}
8188
ty::Tuple(component_types) => {
@@ -86,7 +93,14 @@ fn push_debuginfo_type_name<'tcx>(
8693
}
8794

8895
for component_type in component_types {
89-
push_debuginfo_type_name(tcx, component_type.expect_ty(), true, output, visited);
96+
push_debuginfo_type_name(
97+
tcx,
98+
component_type.expect_ty(),
99+
true,
100+
output,
101+
visited,
102+
type_name_cache,
103+
);
90104
push_arg_separator(cpp_like_names, output);
91105
}
92106
if !component_types.is_empty() {
@@ -113,7 +127,7 @@ fn push_debuginfo_type_name<'tcx>(
113127
}
114128
}
115129

116-
push_debuginfo_type_name(tcx, inner_type, qualified, output, visited);
130+
push_debuginfo_type_name(tcx, inner_type, qualified, output, visited, type_name_cache);
117131

118132
if cpp_like_names {
119133
push_close_angle_bracket(cpp_like_names, output);
@@ -139,7 +153,7 @@ fn push_debuginfo_type_name<'tcx>(
139153
}
140154
}
141155

142-
push_debuginfo_type_name(tcx, inner_type, qualified, output, visited);
156+
push_debuginfo_type_name(tcx, inner_type, qualified, output, visited, type_name_cache);
143157

144158
if cpp_like_names && !is_slice_or_str {
145159
push_close_angle_bracket(cpp_like_names, output);
@@ -148,15 +162,15 @@ fn push_debuginfo_type_name<'tcx>(
148162
ty::Array(inner_type, len) => {
149163
if cpp_like_names {
150164
output.push_str("array$<");
151-
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
165+
push_debuginfo_type_name(tcx, inner_type, true, output, visited, type_name_cache);
152166
match len.val {
153167
ty::ConstKind::Param(param) => write!(output, ",{}>", param.name).unwrap(),
154168
_ => write!(output, ",{}>", len.eval_usize(tcx, ty::ParamEnv::reveal_all()))
155169
.unwrap(),
156170
}
157171
} else {
158172
output.push('[');
159-
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
173+
push_debuginfo_type_name(tcx, inner_type, true, output, visited, type_name_cache);
160174
match len.val {
161175
ty::ConstKind::Param(param) => write!(output, "; {}]", param.name).unwrap(),
162176
_ => write!(output, "; {}]", len.eval_usize(tcx, ty::ParamEnv::reveal_all()))
@@ -171,7 +185,7 @@ fn push_debuginfo_type_name<'tcx>(
171185
output.push('[');
172186
}
173187

174-
push_debuginfo_type_name(tcx, inner_type, true, output, visited);
188+
push_debuginfo_type_name(tcx, inner_type, true, output, visited, type_name_cache);
175189

176190
if cpp_like_names {
177191
push_close_angle_bracket(cpp_like_names, output);
@@ -200,8 +214,13 @@ fn push_debuginfo_type_name<'tcx>(
200214
let principal =
201215
tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), principal);
202216
push_item_name(tcx, principal.def_id, qualified, output);
203-
let principal_has_generic_params =
204-
push_generic_params_internal(tcx, principal.substs, output, visited);
217+
let principal_has_generic_params = push_generic_params_internal(
218+
tcx,
219+
principal.substs,
220+
output,
221+
visited,
222+
type_name_cache,
223+
);
205224

206225
let projection_bounds: SmallVec<[_; 4]> = trait_data
207226
.projection_bounds()
@@ -225,12 +244,26 @@ fn push_debuginfo_type_name<'tcx>(
225244
output.push_str("assoc$<");
226245
push_item_name(tcx, item_def_id, false, output);
227246
push_arg_separator(cpp_like_names, output);
228-
push_debuginfo_type_name(tcx, ty, true, output, visited);
247+
push_debuginfo_type_name(
248+
tcx,
249+
ty,
250+
true,
251+
output,
252+
visited,
253+
type_name_cache,
254+
);
229255
push_close_angle_bracket(cpp_like_names, output);
230256
} else {
231257
push_item_name(tcx, item_def_id, false, output);
232258
output.push('=');
233-
push_debuginfo_type_name(tcx, ty, true, output, visited);
259+
push_debuginfo_type_name(
260+
tcx,
261+
ty,
262+
true,
263+
output,
264+
visited,
265+
type_name_cache,
266+
);
234267
}
235268
}
236269

@@ -298,7 +331,14 @@ fn push_debuginfo_type_name<'tcx>(
298331
if sig.output().is_unit() {
299332
output.push_str("void");
300333
} else {
301-
push_debuginfo_type_name(tcx, sig.output(), true, output, visited);
334+
push_debuginfo_type_name(
335+
tcx,
336+
sig.output(),
337+
true,
338+
output,
339+
visited,
340+
type_name_cache,
341+
);
302342
}
303343
output.push_str(" (*)(");
304344
} else {
@@ -315,7 +355,14 @@ fn push_debuginfo_type_name<'tcx>(
315355

316356
if !sig.inputs().is_empty() {
317357
for &parameter_type in sig.inputs() {
318-
push_debuginfo_type_name(tcx, parameter_type, true, output, visited);
358+
push_debuginfo_type_name(
359+
tcx,
360+
parameter_type,
361+
true,
362+
output,
363+
visited,
364+
type_name_cache,
365+
);
319366
push_arg_separator(cpp_like_names, output);
320367
}
321368
pop_arg_separator(output);
@@ -333,7 +380,7 @@ fn push_debuginfo_type_name<'tcx>(
333380

334381
if !cpp_like_names && !sig.output().is_unit() {
335382
output.push_str(" -> ");
336-
push_debuginfo_type_name(tcx, sig.output(), true, output, visited);
383+
push_debuginfo_type_name(tcx, sig.output(), true, output, visited, type_name_cache);
337384
}
338385

339386
// We only keep the type in 'visited'
@@ -375,6 +422,10 @@ fn push_debuginfo_type_name<'tcx>(
375422
}
376423
}
377424

425+
if type_name_cache.insert((&t, qualified), output.clone()).is_some() {
426+
bug!("type name is already in the type name cache!");
427+
}
428+
378429
/// MSVC names enums differently than other platforms so that the debugging visualization
379430
// format (natvis) is able to understand enums and render the active variant correctly in the
380431
// debugger. For more information, look in `src/etc/natvis/intrinsic.natvis` and
@@ -386,12 +437,13 @@ fn push_debuginfo_type_name<'tcx>(
386437
substs: SubstsRef<'tcx>,
387438
output: &mut String,
388439
visited: &mut FxHashSet<Ty<'tcx>>,
440+
type_name_cache: &mut FxHashMap<(Ty<'tcx>, bool), String>,
389441
) {
390442
let layout = tcx.layout_of(tcx.param_env(def.did).and(ty)).expect("layout error");
391443

392444
output.push_str("enum$<");
393445
push_item_name(tcx, def.did, true, output);
394-
push_generic_params_internal(tcx, substs, output, visited);
446+
push_generic_params_internal(tcx, substs, output, visited, type_name_cache);
395447

396448
if let Variants::Multiple {
397449
tag_encoding: TagEncoding::Niche { dataful_variant, .. },
@@ -503,6 +555,7 @@ fn push_generic_params_internal<'tcx>(
503555
substs: SubstsRef<'tcx>,
504556
output: &mut String,
505557
visited: &mut FxHashSet<Ty<'tcx>>,
558+
type_name_cache: &mut FxHashMap<(Ty<'tcx>, bool), String>,
506559
) -> bool {
507560
if substs.non_erasable_generics().next().is_none() {
508561
return false;
@@ -517,7 +570,14 @@ fn push_generic_params_internal<'tcx>(
517570
for type_parameter in substs.non_erasable_generics() {
518571
match type_parameter {
519572
GenericArgKind::Type(type_parameter) => {
520-
push_debuginfo_type_name(tcx, type_parameter, true, output, visited);
573+
push_debuginfo_type_name(
574+
tcx,
575+
type_parameter,
576+
true,
577+
output,
578+
visited,
579+
type_name_cache,
580+
);
521581
}
522582
GenericArgKind::Const(ct) => {
523583
push_const_param(tcx, ct, output);
@@ -578,10 +638,15 @@ fn push_const_param<'tcx>(tcx: TyCtxt<'tcx>, ct: &'tcx ty::Const<'tcx>, output:
578638
.unwrap();
579639
}
580640

581-
pub fn push_generic_params<'tcx>(tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, output: &mut String) {
641+
pub fn push_generic_params<'tcx>(
642+
tcx: TyCtxt<'tcx>,
643+
substs: SubstsRef<'tcx>,
644+
output: &mut String,
645+
type_name_cache: &mut FxHashMap<(Ty<'tcx>, bool), String>,
646+
) {
582647
let _prof = tcx.prof.generic_activity("compute_debuginfo_type_name");
583648
let mut visited = FxHashSet::default();
584-
push_generic_params_internal(tcx, substs, output, &mut visited);
649+
push_generic_params_internal(tcx, substs, output, &mut visited, type_name_cache);
585650
}
586651

587652
fn push_close_angle_bracket(cpp_like_names: bool, output: &mut String) {

0 commit comments

Comments
 (0)