Skip to content

Commit d441ee7

Browse files
committed
[DebugInfo] Add num_extra_inhabitants to debug info (llvm#112590)
An extra inhabitant is a bit pattern that does not represent a valid value for instances of a given type. The number of extra inhabitants is the number of those bit configurations. This is used by Swift to save space when composing types. For example, because Bool only needs 2 bit patterns to represent all of its values (true and false), an Optional<Bool> only occupies 1 byte in memory by using a bit configuration that is unused by Bool. Which bit patterns are unused are part of the ABI of the language. Since Swift generics are not monomorphized, by using dynamic libraries you can have generic types whose size, alignment, etc, are known only at runtime (which is why this feature is needed). This patch adds num_extra_inhabitants to LLVM-IR debug info and in DWARF as an Apple extension. (cherry picked from commit f6617d6) (cherry picked from commit cdc3876)
1 parent f49c61d commit d441ee7

File tree

9 files changed

+55
-33
lines changed

9 files changed

+55
-33
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -318,7 +318,7 @@ DWARFASTParserSwift::getBuiltinTypeDescriptor(
318318
unsigned stride = ((byte_size + alignment - 1) & ~(alignment - 1));
319319

320320
auto num_extra_inhabitants =
321-
die.GetAttributeValueAsUnsigned(DW_AT_APPLE_num_extra_inhabitants, 0);
321+
die.GetAttributeValueAsUnsigned(DW_AT_LLVM_num_extra_inhabitants, 0);
322322

323323
auto is_bitwise_takable = true; // TODO: encode it in DWARF
324324

llvm/include/llvm/BinaryFormat/Dwarf.def

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@ HANDLE_DW_AT(0x3e07, LLVM_apinotes, 0, APPLE)
617617
HANDLE_DW_AT(0x3e08, LLVM_ptrauth_isa_pointer, 0, LLVM)
618618
HANDLE_DW_AT(0x3e09, LLVM_ptrauth_authenticates_null_values, 0, LLVM)
619619
HANDLE_DW_AT(0x3e0a, LLVM_ptrauth_authentication_mode, 0, LLVM)
620+
HANDLE_DW_AT(0x3e0b, LLVM_num_extra_inhabitants, 0, LLVM)
620621

621622
// Apple extensions.
622623
HANDLE_DW_AT(0x3fe1, APPLE_optimized, 0, APPLE)
@@ -635,7 +636,6 @@ HANDLE_DW_AT(0x3fed, APPLE_property, 0, APPLE)
635636
HANDLE_DW_AT(0x3fee, APPLE_objc_direct, 0, APPLE)
636637
HANDLE_DW_AT(0x3fef, APPLE_sdk, 0, APPLE)
637638
HANDLE_DW_AT(0x3ff0, APPLE_origin, 0, APPLE)
638-
HANDLE_DW_AT(0x3ff1, APPLE_num_extra_inhabitants, 0, APPLE)
639639

640640
// Attribute form encodings.
641641
HANDLE_DW_FORM(0x01, addr, 2, DWARF)

llvm/include/llvm/IR/DIBuilder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ namespace llvm {
227227
/// \param Flags Optional DWARF attributes, e.g., DW_AT_endianity.
228228
/// \param NumExtraInhabitants The number of extra inhabitants of the type.
229229
/// An extra inhabitant is a bit pattern that does not represent a valid
230-
/// value for objects of a given type.
230+
/// value for instances of a given type. This is used by the Swift language.
231231
DIBasicType *createBasicType(StringRef Name, uint64_t SizeInBits,
232232
unsigned Encoding,
233233
DINode::DIFlags Flags = DINode::FlagZero,
@@ -493,7 +493,7 @@ namespace llvm {
493493
/// template parameters have been substituted in.
494494
/// \param NumExtraInhabitants The number of extra inhabitants of the type.
495495
/// An extra inhabitant is a bit pattern that does not represent a valid
496-
/// value for objects of a given type.
496+
/// value for instances of a given type.
497497
DICompositeType *createStructType(
498498
DIScope *Scope, StringRef Name, DIFile *File, unsigned LineNumber,
499499
uint64_t SizeInBits, uint32_t AlignInBits, DINode::DIFlags Flags,

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -739,10 +739,12 @@ class DIType : public DIScope {
739739

740740
/// Change fields in place.
741741
void mutate(unsigned Tag, unsigned Line, uint64_t SizeInBits,
742-
uint32_t AlignInBits, uint64_t OffsetInBits, uint32_t NumExtraInhabitants, DIFlags Flags) {
742+
uint32_t AlignInBits, uint64_t OffsetInBits,
743+
uint32_t NumExtraInhabitants, DIFlags Flags) {
743744
assert(isDistinct() && "Only distinct nodes can mutate");
744745
setTag(Tag);
745-
init(Line, SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants, Flags);
746+
init(Line, SizeInBits, AlignInBits, OffsetInBits, NumExtraInhabitants,
747+
Flags);
746748
}
747749

748750
public:
@@ -838,8 +840,7 @@ class DIBasicType : public DIType {
838840
StringRef Name, uint64_t SizeInBits,
839841
uint32_t AlignInBits, unsigned Encoding,
840842
uint32_t NumExtraInhabitants, DIFlags Flags,
841-
StorageType Storage,
842-
bool ShouldCreate = true) {
843+
StorageType Storage, bool ShouldCreate = true) {
843844
return getImpl(Context, Tag, getCanonicalMDString(Context, Name),
844845
SizeInBits, AlignInBits, Encoding, NumExtraInhabitants,
845846
Flags, Storage, ShouldCreate);
@@ -865,6 +866,14 @@ class DIBasicType : public DIType {
865866
DEFINE_MDNODE_GET(DIBasicType,
866867
(unsigned Tag, MDString *Name, uint64_t SizeInBits),
867868
(Tag, Name, SizeInBits, 0, 0, 0, FlagZero))
869+
DEFINE_MDNODE_GET(DIBasicType,
870+
(unsigned Tag, StringRef Name, uint64_t SizeInBits,
871+
uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
872+
(Tag, Name, SizeInBits, AlignInBits, Encoding, 0, Flags))
873+
DEFINE_MDNODE_GET(DIBasicType,
874+
(unsigned Tag, MDString *Name, uint64_t SizeInBits,
875+
uint32_t AlignInBits, unsigned Encoding, DIFlags Flags),
876+
(Tag, Name, SizeInBits, AlignInBits, Encoding, 0, Flags))
868877
DEFINE_MDNODE_GET(DIBasicType,
869878
(unsigned Tag, StringRef Name, uint64_t SizeInBits,
870879
uint32_t AlignInBits, unsigned Encoding,
@@ -1033,8 +1042,7 @@ class DIDerivedType : public DIType {
10331042
std::optional<PtrAuthData> PtrAuthData, DIFlags Flags,
10341043
ArrayRef<Metadata *> Ops)
10351044
: DIType(C, DIDerivedTypeKind, Storage, Tag, Line, SizeInBits,
1036-
AlignInBits, OffsetInBits, /*NumExtraInhabitants=*/0, Flags,
1037-
Ops),
1045+
AlignInBits, OffsetInBits, /*NumExtraInhabitants=*/0, Flags, Ops),
10381046
DWARFAddressSpace(DWARFAddressSpace) {
10391047
if (PtrAuthData)
10401048
SubclassData32 = PtrAuthData->RawData;

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -737,7 +737,7 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DIBasicType *BTy) {
737737
addUInt(Buffer, dwarf::DW_AT_endianity, std::nullopt, dwarf::DW_END_little);
738738

739739
if (uint32_t NumExtraInhabitants = BTy->getNumExtraInhabitants())
740-
addUInt(Buffer, dwarf::DW_AT_APPLE_num_extra_inhabitants, std::nullopt,
740+
addUInt(Buffer, dwarf::DW_AT_LLVM_num_extra_inhabitants, std::nullopt,
741741
NumExtraInhabitants);
742742
}
743743

@@ -1101,10 +1101,9 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
11011101
AlignInBytes);
11021102

11031103
if (uint32_t NumExtraInhabitants = CTy->getNumExtraInhabitants())
1104-
addUInt(Buffer, dwarf::DW_AT_APPLE_num_extra_inhabitants,
1105-
std::nullopt, NumExtraInhabitants);
1106-
1107-
}
1104+
addUInt(Buffer, dwarf::DW_AT_LLVM_num_extra_inhabitants, std::nullopt,
1105+
NumExtraInhabitants);
1106+
}
11081107
}
11091108

11101109
void DwarfUnit::constructTemplateTypeParameterDIE(

llvm/lib/IR/DebugInfoMetadata.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,8 +664,7 @@ DIBasicType *DIBasicType::getImpl(LLVMContext &Context, unsigned Tag,
664664
MDString *Name, uint64_t SizeInBits,
665665
uint32_t AlignInBits, unsigned Encoding,
666666
uint32_t NumExtraInhabitants, DIFlags Flags,
667-
StorageType Storage,
668-
bool ShouldCreate) {
667+
StorageType Storage, bool ShouldCreate) {
669668
assert(isCanonical(Name) && "Expected canonical MDString");
670669
DEFINE_GETIMPL_LOOKUP(DIBasicType, (Tag, Name, SizeInBits, AlignInBits,
671670
Encoding, NumExtraInhabitants, Flags));

llvm/test/Assembler/debug-info.ll

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
22
; RUN: verify-uselistorder %s
33

4-
; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43}
5-
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46}
4+
; CHECK: !named = !{!0, !0, !1, !2, !3, !4, !5, !6, !7, !8, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45}
5+
!named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9, !10, !11, !12, !13, !14, !15, !16, !17, !18, !19, !20, !21, !22, !23, !24, !25, !26, !27, !28, !29, !30, !31, !32, !33, !34, !35, !36, !37, !38, !39, !40, !41, !42, !43, !44, !45, !46, !47, !48}
66

77
; CHECK: !0 = !DISubrange(count: 3, lowerBound: 0)
88
; CHECK-NEXT: !1 = !DISubrange(count: 3, lowerBound: 4)
@@ -111,3 +111,9 @@
111111

112112
; CHECK: !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !13, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: true, ptrAuthAuthenticatesNullValues: true)
113113
!46 = !DIDerivedType(tag: DW_TAG_LLVM_ptrauth_type, baseType: !15, ptrAuthKey: 2, ptrAuthIsAddressDiscriminated: true, ptrAuthExtraDiscriminator: 1234, ptrAuthIsaPointer: true, ptrAuthAuthenticatesNullValues: true)
114+
115+
; CHECK: !DIBasicType(name: "ExtraInhabitantBasicType", size: 1, encoding: DW_ATE_unsigned, num_extra_inhabitants: 254)
116+
!47 = !DIBasicType(name: "ExtraInhabitantBasicType", size: 1, encoding: DW_ATE_unsigned, num_extra_inhabitants: 254)
117+
118+
;CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "ExtraInhabitantCompositeType", file: !10, size: 64, num_extra_inhabitants: 66, identifier: "MangledExtraInhabitantCompositeType")
119+
!48 = !DICompositeType(tag: DW_TAG_structure_type, name: "ExtraInhabitantCompositeType", file: !12, size: 64, num_extra_inhabitants: 66, identifier: "MangledExtraInhabitantCompositeType")

llvm/test/DebugInfo/AArch64/num_extra_inhabitants.ll

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,40 @@
22
; RUN: | llvm-dwarfdump - | FileCheck %s
33

44
; CHECK: DW_TAG_base_type
5-
; CHECK: DW_AT_APPLE_num_extra_inhabitants (0xfe)
5+
; CHECK: DW_AT_name ("ExtraInhabitantBasicType")
6+
; CHECK: DW_AT_LLVM_num_extra_inhabitants (0xfe)
67

78
; CHECK: DW_TAG_structure_type
8-
; CHECK: DW_AT_APPLE_num_extra_inhabitants (0x42)
9+
; CHECK: DW_AT_name ("ExtraInhabitantCompositeType")
10+
; CHECK: DW_AT_LLVM_num_extra_inhabitants (0x42)
11+
12+
; CHECK: DW_TAG_structure_type
13+
; CHECK: DW_AT_name ("NoExtraInhabitantType")
14+
; CHECK-NOT: DW_AT_LLVM_num_extra_inhabitants
15+
916
target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
1017

11-
@p = common global i8* null, align 8, !dbg !0
12-
@q = common global i8* null, align 8, !dbg !8
18+
@p = common global i8* null, align 8, !dbg !100
19+
@q = common global i8* null, align 8, !dbg !102
20+
@r = common global i8* null, align 8, !dbg !105
1321

1422
!llvm.dbg.cu = !{!2}
1523
!llvm.module.flags = !{!6, !7}
1624

17-
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
18-
!1 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 1, type: !10, isLocal: false, isDefinition: true)
1925
!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug, globals: !5)
2026
!3 = !DIFile(filename: "/tmp/p.c", directory: "/")
2127
!4 = !{}
22-
!5 = !{!0, !8}
28+
!5 = !{!100, !102, !105}
2329
!6 = !{i32 2, !"Dwarf Version", i32 4}
2430
!7 = !{i32 2, !"Debug Info Version", i32 3}
2531

26-
!8 = !DIGlobalVariableExpression(var: !9, expr: !DIExpression())
27-
!9 = distinct !DIGlobalVariable(name: "q", scope: !2, file: !3, line: 1, type: !11, isLocal: false, isDefinition: true)
2832
!10 = !DIBasicType(name: "ExtraInhabitantBasicType", size: 1, encoding: DW_ATE_unsigned, num_extra_inhabitants: 254)
2933
!11 = !DICompositeType(tag: DW_TAG_structure_type, name: "ExtraInhabitantCompositeType", file: !3, size: 64, num_extra_inhabitants: 66, identifier: "MangledExtraInhabitantCompositeType")
34+
!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "NoExtraInhabitantType", file: !3, size: 64, identifier: "MangledNoExtraInhabitantType")
3035

36+
!100 = !DIGlobalVariableExpression(var: !101, expr: !DIExpression())
37+
!101 = distinct !DIGlobalVariable(name: "p", scope: !2, file: !3, line: 1, type: !10, isLocal: false, isDefinition: true)
38+
!102 = !DIGlobalVariableExpression(var: !103, expr: !DIExpression())
39+
!103 = distinct !DIGlobalVariable(name: "q", scope: !2, file: !3, line: 1, type: !11, isLocal: false, isDefinition: true)
40+
!104 = distinct !DIGlobalVariable(name: "r", scope: !2, file: !3, line: 1, type: !12, isLocal: false, isDefinition: true)
41+
!105 = !DIGlobalVariableExpression(var: !104, expr: !DIExpression())

llvm/unittests/IR/MetadataTest.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1786,17 +1786,16 @@ TEST_F(DIBasicTypeTest, get) {
17861786
26, 7, 100, DINode::FlagZero));
17871787

17881788
EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type,
1789-
"special", 33, 26, 7,100, DINode::FlagZero));
1790-
EXPECT_NE(N,
1791-
DIBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26, 7, 100,
1792-
DINode::FlagZero));
1789+
"special", 33, 26, 7, 100, DINode::FlagZero));
1790+
EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "s", 33, 26,
1791+
7, 100, DINode::FlagZero));
17931792
EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 32,
17941793
26, 7, 100, DINode::FlagZero));
17951794
EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
17961795
25, 7, 100, DINode::FlagZero));
17971796

17981797
EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
1799-
26, 7, 99, DINode::FlagZero));
1798+
26, 7, 99, DINode::FlagZero));
18001799
EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,
18011800
26, 6, 100, DINode::FlagZero));
18021801
EXPECT_NE(N, DIBasicType::get(Context, dwarf::DW_TAG_base_type, "special", 33,

0 commit comments

Comments
 (0)