Skip to content

Commit cdc3876

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)
1 parent 28dfa53 commit cdc3876

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

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

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

11091108
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
@@ -1787,17 +1787,16 @@ TEST_F(DIBasicTypeTest, get) {
17871787
26, 7, 100, DINode::FlagZero));
17881788

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

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

0 commit comments

Comments
 (0)