Skip to content

Commit 41a4db1

Browse files
authored
[lldb/DWARF] Optimize DIEToType handling (llvm#96308)
- move type insertion from individual parse methods into ParseTypeFromDWARF - optimize sentinel (TYPE_IS_BEING_PARSED) insertion to avoid double map lookup - as this requires the map to not have nullptr values, I've replaced all `operator[]` queries with calls to `lookup`.
1 parent 689c5c4 commit 41a4db1

File tree

1 file changed

+74
-104
lines changed

1 file changed

+74
-104
lines changed

lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp

Lines changed: 74 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromClangModule(const SymbolContext &sc,
223223
nullptr, LLDB_INVALID_UID, Type::eEncodingInvalid,
224224
&pcm_type_sp->GetDeclaration(), type, Type::ResolveState::Forward,
225225
TypePayloadClang(GetOwningClangModule(die)));
226-
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
227226
clang::TagDecl *tag_decl = TypeSystemClang::GetAsTagDecl(type);
228227
if (tag_decl) {
229228
LinkDeclContextToDIE(tag_decl, die);
@@ -458,90 +457,78 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
458457
DW_TAG_value_to_name(die.Tag()), die.Tag(), die.GetName());
459458
}
460459

461-
Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
462-
if (type_ptr == DIE_IS_BEING_PARSED)
463-
return nullptr;
464-
if (type_ptr)
465-
return type_ptr->shared_from_this();
466460
// Set a bit that lets us know that we are currently parsing this
467-
dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
461+
if (auto [it, inserted] =
462+
dwarf->GetDIEToType().try_emplace(die.GetDIE(), DIE_IS_BEING_PARSED);
463+
!inserted) {
464+
if (it->getSecond() == nullptr || it->getSecond() == DIE_IS_BEING_PARSED)
465+
return nullptr;
466+
return it->getSecond()->shared_from_this();
467+
}
468468

469469
ParsedDWARFTypeAttributes attrs(die);
470470

471+
TypeSP type_sp;
471472
if (DWARFDIE signature_die = attrs.signature.Reference()) {
472-
if (TypeSP type_sp =
473-
ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr)) {
474-
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
473+
type_sp = ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr);
474+
if (type_sp) {
475475
if (clang::DeclContext *decl_ctx =
476476
GetCachedClangDeclContextForDIE(signature_die))
477477
LinkDeclContextToDIE(decl_ctx, die);
478-
return type_sp;
479478
}
480-
return nullptr;
481-
}
482-
483-
if (type_is_new_ptr)
484-
*type_is_new_ptr = true;
485-
486-
const dw_tag_t tag = die.Tag();
487-
488-
TypeSP type_sp;
489-
490-
switch (tag) {
491-
case DW_TAG_typedef:
492-
case DW_TAG_base_type:
493-
case DW_TAG_pointer_type:
494-
case DW_TAG_reference_type:
495-
case DW_TAG_rvalue_reference_type:
496-
case DW_TAG_const_type:
497-
case DW_TAG_restrict_type:
498-
case DW_TAG_volatile_type:
499-
case DW_TAG_LLVM_ptrauth_type:
500-
case DW_TAG_atomic_type:
501-
case DW_TAG_unspecified_type: {
502-
type_sp = ParseTypeModifier(sc, die, attrs);
503-
break;
504-
}
505-
506-
case DW_TAG_structure_type:
507-
case DW_TAG_union_type:
508-
case DW_TAG_class_type: {
509-
type_sp = ParseStructureLikeDIE(sc, die, attrs);
510-
break;
511-
}
479+
} else {
480+
if (type_is_new_ptr)
481+
*type_is_new_ptr = true;
512482

513-
case DW_TAG_enumeration_type: {
514-
type_sp = ParseEnum(sc, die, attrs);
515-
break;
516-
}
483+
const dw_tag_t tag = die.Tag();
517484

518-
case DW_TAG_inlined_subroutine:
519-
case DW_TAG_subprogram:
520-
case DW_TAG_subroutine_type: {
521-
type_sp = ParseSubroutine(die, attrs);
522-
break;
523-
}
524-
case DW_TAG_array_type: {
525-
type_sp = ParseArrayType(die, attrs);
526-
break;
527-
}
528-
case DW_TAG_ptr_to_member_type: {
529-
type_sp = ParsePointerToMemberType(die, attrs);
530-
break;
485+
switch (tag) {
486+
case DW_TAG_typedef:
487+
case DW_TAG_base_type:
488+
case DW_TAG_pointer_type:
489+
case DW_TAG_reference_type:
490+
case DW_TAG_rvalue_reference_type:
491+
case DW_TAG_const_type:
492+
case DW_TAG_restrict_type:
493+
case DW_TAG_volatile_type:
494+
case DW_TAG_LLVM_ptrauth_type:
495+
case DW_TAG_atomic_type:
496+
case DW_TAG_unspecified_type:
497+
type_sp = ParseTypeModifier(sc, die, attrs);
498+
break;
499+
case DW_TAG_structure_type:
500+
case DW_TAG_union_type:
501+
case DW_TAG_class_type:
502+
type_sp = ParseStructureLikeDIE(sc, die, attrs);
503+
break;
504+
case DW_TAG_enumeration_type:
505+
type_sp = ParseEnum(sc, die, attrs);
506+
break;
507+
case DW_TAG_inlined_subroutine:
508+
case DW_TAG_subprogram:
509+
case DW_TAG_subroutine_type:
510+
type_sp = ParseSubroutine(die, attrs);
511+
break;
512+
case DW_TAG_array_type:
513+
type_sp = ParseArrayType(die, attrs);
514+
break;
515+
case DW_TAG_ptr_to_member_type:
516+
type_sp = ParsePointerToMemberType(die, attrs);
517+
break;
518+
default:
519+
dwarf->GetObjectFile()->GetModule()->ReportError(
520+
"[{0:x16}]: unhandled type tag {1:x4} ({2}), "
521+
"please file a bug and "
522+
"attach the file at the start of this error message",
523+
die.GetOffset(), tag, DW_TAG_value_to_name(tag));
524+
break;
525+
}
526+
UpdateSymbolContextScopeForType(sc, die, type_sp);
531527
}
532-
default:
533-
dwarf->GetObjectFile()->GetModule()->ReportError(
534-
"[{0:x16}]: unhandled type tag {1:x4} ({2}), "
535-
"please file a bug and "
536-
"attach the file at the start of this error message",
537-
die.GetOffset(), tag, DW_TAG_value_to_name(tag));
538-
break;
528+
if (type_sp) {
529+
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
539530
}
540-
541-
// TODO: We should consider making the switch above exhaustive to simplify
542-
// control flow in ParseTypeFromDWARF. Then, we could simply replace this
543-
// return statement with a call to llvm_unreachable.
544-
return UpdateSymbolContextScopeForType(sc, die, type_sp);
531+
return type_sp;
545532
}
546533

547534
static std::optional<uint32_t>
@@ -830,12 +817,9 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc,
830817
}
831818
}
832819

833-
type_sp = dwarf->MakeType(die.GetID(), attrs.name, attrs.byte_size, nullptr,
834-
attrs.type.Reference().GetID(), encoding_data_type,
835-
&attrs.decl, clang_type, resolve_state, payload);
836-
837-
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
838-
return type_sp;
820+
return dwarf->MakeType(die.GetID(), attrs.name, attrs.byte_size, nullptr,
821+
attrs.type.Reference().GetID(), encoding_data_type,
822+
&attrs.decl, clang_type, resolve_state, payload);
839823
}
840824

841825
std::string
@@ -885,13 +869,10 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
885869
type_sp->GetID());
886870
}
887871

888-
// We found a real definition for this type elsewhere so lets use
889-
// it and cache the fact that we found a complete type for this
890-
// die
891-
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
892-
clang::DeclContext *defn_decl_ctx =
893-
GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
894-
if (defn_decl_ctx)
872+
// We found a real definition for this type elsewhere so must link its
873+
// DeclContext to this die.
874+
if (clang::DeclContext *defn_decl_ctx =
875+
GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID())))
895876
LinkDeclContextToDIE(defn_decl_ctx, die);
896877
return type_sp;
897878
}
@@ -1052,7 +1033,7 @@ std::pair<bool, TypeSP> DWARFASTParserClang::ParseCXXMethod(
10521033
// Unfortunately classes don't like having stuff added
10531034
// to them after their definitions are complete...
10541035

1055-
Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
1036+
Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
10561037
if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
10571038
return {true, type_ptr->shared_from_this()};
10581039
}
@@ -1164,7 +1145,7 @@ std::pair<bool, TypeSP> DWARFASTParserClang::ParseCXXMethod(
11641145
// we need to modify the dwarf->GetDIEToType() so it
11651146
// doesn't think we are trying to parse this DIE
11661147
// anymore...
1167-
dwarf->GetDIEToType()[die.GetDIE()] = NULL;
1148+
dwarf->GetDIEToType().erase(die.GetDIE());
11681149

11691150
// Now we get the full type to force our class type to
11701151
// complete itself using the clang::ExternalASTSource
@@ -1174,7 +1155,7 @@ std::pair<bool, TypeSP> DWARFASTParserClang::ParseCXXMethod(
11741155

11751156
// The type for this DIE should have been filled in the
11761157
// function call above.
1177-
Type *type_ptr = dwarf->GetDIEToType()[die.GetDIE()];
1158+
Type *type_ptr = dwarf->GetDIEToType().lookup(die.GetDIE());
11781159
if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
11791160
return {true, type_ptr->shared_from_this()};
11801161

@@ -1576,7 +1557,6 @@ TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
15761557
if (!type_sp)
15771558
return type_sp;
15781559

1579-
SymbolFileDWARF *dwarf = die.GetDWARF();
15801560
DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
15811561
dw_tag_t sc_parent_tag = sc_parent_die.Tag();
15821562

@@ -1595,8 +1575,6 @@ TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType(
15951575

15961576
if (symbol_context_scope != nullptr)
15971577
type_sp->SetSymbolContextScope(symbol_context_scope);
1598-
1599-
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
16001578
return type_sp;
16011579
}
16021580

@@ -1691,7 +1669,6 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
16911669
*unique_ast_entry_up)) {
16921670
type_sp = unique_ast_entry_up->m_type_sp;
16931671
if (type_sp) {
1694-
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
16951672
LinkDeclContextToDIE(
16961673
GetCachedClangDeclContextForDIE(unique_ast_entry_up->m_die), die);
16971674
return type_sp;
@@ -1763,11 +1740,6 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
17631740
DW_TAG_value_to_name(tag), tag, attrs.name.GetCString(),
17641741
type_sp->GetID());
17651742
}
1766-
1767-
// We found a real definition for this type elsewhere so lets use
1768-
// it and cache the fact that we found a complete type for this
1769-
// die
1770-
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
17711743
return type_sp;
17721744
}
17731745
}
@@ -1823,12 +1795,10 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
18231795
type_sp->GetID());
18241796
}
18251797

1826-
// We found a real definition for this type elsewhere so lets use
1827-
// it and cache the fact that we found a complete type for this die
1828-
dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get();
1829-
clang::DeclContext *defn_decl_ctx =
1830-
GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID()));
1831-
if (defn_decl_ctx)
1798+
// We found a real definition for this type elsewhere so must link its
1799+
// DeclContext to this die.
1800+
if (clang::DeclContext *defn_decl_ctx =
1801+
GetCachedClangDeclContextForDIE(dwarf->GetDIE(type_sp->GetID())))
18321802
LinkDeclContextToDIE(defn_decl_ctx, die);
18331803
return type_sp;
18341804
}
@@ -3809,7 +3779,7 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes(
38093779
if (dst_decl_ctx)
38103780
src_dwarf_ast_parser->LinkDeclContextToDIE(dst_decl_ctx, src);
38113781

3812-
if (Type *src_child_type = die_to_type[src.GetDIE()])
3782+
if (Type *src_child_type = die_to_type.lookup(src.GetDIE()))
38133783
die_to_type[dst.GetDIE()] = src_child_type;
38143784
};
38153785

0 commit comments

Comments
 (0)