Skip to content

Commit 102f7fc

Browse files
[llvm] Reduce memory footprint of Debug metadata nodes (#71227)
Using a combination of reordering fields and using empty SubclassData32 / SubclassData1, it's possible to improve the size of data structures used to store debug info in the IR: Before: DILexicalBlock: 24 DILexicalBlockFile: 24 DIModule: 24 DITemplateParameter: 24 DICommonBlock: 24 DIMacro: 24 DICompileUnit: 56 DIType: 48 DINamespace: 24 DIVariable: 24 DIGlobalVariable: 32 DILocalVariable: 32 DILabel: 24 After: DILexicalBlock: 24 DILexicalBlockFile: 16 DIModule: 16 DITemplateParameter: 16 DICommonBlock: 16 DIMacro: 16 DICompileUnit: 48 DIType: 40 DINamespace: 16 DIVariable: 24 DIGlobalVariable: 24 DILocalVariable: 32 DILabel: 16
1 parent ae623d1 commit 102f7fc

File tree

2 files changed

+90
-58
lines changed

2 files changed

+90
-58
lines changed

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 70 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ class DITypeRefArray {
128128
/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
129129
/// defined in llvm/BinaryFormat/Dwarf.h). Called \a DINode because it's
130130
/// potentially used for non-DWARF output.
131+
///
132+
/// Uses the SubclassData16 Metadata slot.
131133
class DINode : public MDNode {
132134
friend class LLVMContextImpl;
133135
friend class MDNode;
@@ -227,6 +229,8 @@ class DINode : public MDNode {
227229
/// (possibly empty) null-separated \a MDString header that contains arbitrary
228230
/// fields. The remaining operands are \a dwarf_operands(), and are pointers
229231
/// to other metadata.
232+
///
233+
/// Uses the SubclassData32 Metadata slot.
230234
class GenericDINode : public DINode {
231235
friend class LLVMContextImpl;
232236
friend class MDNode;
@@ -695,12 +699,13 @@ std::optional<StringRef> DIScope::getSource() const {
695699
/// TODO: Remove the hardcoded name and context, since many types don't use
696700
/// them.
697701
/// TODO: Split up flags.
702+
///
703+
/// Uses the SubclassData32 Metadata slot.
698704
class DIType : public DIScope {
699705
unsigned Line;
700706
DIFlags Flags;
701707
uint64_t SizeInBits;
702708
uint64_t OffsetInBits;
703-
uint32_t AlignInBits;
704709

705710
protected:
706711
DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
@@ -716,7 +721,7 @@ class DIType : public DIScope {
716721
this->Line = Line;
717722
this->Flags = Flags;
718723
this->SizeInBits = SizeInBits;
719-
this->AlignInBits = AlignInBits;
724+
this->SubclassData32 = AlignInBits;
720725
this->OffsetInBits = OffsetInBits;
721726
}
722727

@@ -735,7 +740,7 @@ class DIType : public DIScope {
735740

736741
unsigned getLine() const { return Line; }
737742
uint64_t getSizeInBits() const { return SizeInBits; }
738-
uint32_t getAlignInBits() const { return AlignInBits; }
743+
uint32_t getAlignInBits() const { return SubclassData32; }
739744
uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
740745
uint64_t getOffsetInBits() const { return OffsetInBits; }
741746
DIFlags getFlags() const { return Flags; }
@@ -1389,13 +1394,13 @@ class DICompileUnit : public DIScope {
13891394

13901395
private:
13911396
unsigned SourceLanguage;
1392-
bool IsOptimized;
13931397
unsigned RuntimeVersion;
1394-
unsigned EmissionKind;
13951398
uint64_t DWOId;
1399+
unsigned EmissionKind;
1400+
unsigned NameTableKind;
1401+
bool IsOptimized;
13961402
bool SplitDebugInlining;
13971403
bool DebugInfoForProfiling;
1398-
unsigned NameTableKind;
13991404
bool RangesBaseAddress;
14001405

14011406
DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
@@ -1876,6 +1881,10 @@ class DISubprogram : public DILocalScope {
18761881
/// Debug location.
18771882
///
18781883
/// A debug location in source code, used for debug info and otherwise.
1884+
///
1885+
/// Uses the SubclassData1, SubclassData16 and SubclassData32
1886+
/// Metadata slots.
1887+
18791888
class DILocation : public MDNode {
18801889
friend class LLVMContextImpl;
18811890
friend class MDNode;
@@ -2161,17 +2170,20 @@ class DILexicalBlockBase : public DILocalScope {
21612170
}
21622171
};
21632172

2173+
/// Debug lexical block.
2174+
///
2175+
/// Uses the SubclassData32 Metadata slot.
21642176
class DILexicalBlock : public DILexicalBlockBase {
21652177
friend class LLVMContextImpl;
21662178
friend class MDNode;
21672179

2168-
unsigned Line;
21692180
uint16_t Column;
21702181

21712182
DILexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line,
21722183
unsigned Column, ArrayRef<Metadata *> Ops)
2173-
: DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops), Line(Line),
2184+
: DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops),
21742185
Column(Column) {
2186+
SubclassData32 = Line;
21752187
assert(Column < (1u << 16) && "Expected 16-bit column");
21762188
}
21772189
~DILexicalBlock() = default;
@@ -2206,7 +2218,7 @@ class DILexicalBlock : public DILexicalBlockBase {
22062218

22072219
TempDILexicalBlock clone() const { return cloneImpl(); }
22082220

2209-
unsigned getLine() const { return Line; }
2221+
unsigned getLine() const { return SubclassData32; }
22102222
unsigned getColumn() const { return Column; }
22112223

22122224
static bool classof(const Metadata *MD) {
@@ -2218,12 +2230,11 @@ class DILexicalBlockFile : public DILexicalBlockBase {
22182230
friend class LLVMContextImpl;
22192231
friend class MDNode;
22202232

2221-
unsigned Discriminator;
2222-
22232233
DILexicalBlockFile(LLVMContext &C, StorageType Storage,
22242234
unsigned Discriminator, ArrayRef<Metadata *> Ops)
2225-
: DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops),
2226-
Discriminator(Discriminator) {}
2235+
: DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops) {
2236+
SubclassData32 = Discriminator;
2237+
}
22272238
~DILexicalBlockFile() = default;
22282239

22292240
static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope,
@@ -2255,7 +2266,7 @@ class DILexicalBlockFile : public DILexicalBlockBase {
22552266
(Scope, File, Discriminator))
22562267

22572268
TempDILexicalBlockFile clone() const { return cloneImpl(); }
2258-
unsigned getDiscriminator() const { return Discriminator; }
2269+
unsigned getDiscriminator() const { return SubclassData32; }
22592270

22602271
static bool classof(const Metadata *MD) {
22612272
return MD->getMetadataID() == DILexicalBlockFileKind;
@@ -2338,12 +2349,13 @@ DILocation::cloneByMultiplyingDuplicationFactor(unsigned DF) const {
23382349
return std::nullopt;
23392350
}
23402351

2352+
/// Debug lexical block.
2353+
///
2354+
/// Uses the SubclassData1 Metadata slot.
23412355
class DINamespace : public DIScope {
23422356
friend class LLVMContextImpl;
23432357
friend class MDNode;
23442358

2345-
unsigned ExportSymbols : 1;
2346-
23472359
DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols,
23482360
ArrayRef<Metadata *> Ops);
23492361
~DINamespace() = default;
@@ -2373,7 +2385,7 @@ class DINamespace : public DIScope {
23732385

23742386
TempDINamespace clone() const { return cloneImpl(); }
23752387

2376-
bool getExportSymbols() const { return ExportSymbols; }
2388+
bool getExportSymbols() const { return SubclassData1; }
23772389
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
23782390
StringRef getName() const { return getStringOperand(2); }
23792391

@@ -2387,11 +2399,11 @@ class DINamespace : public DIScope {
23872399

23882400
/// Represents a module in the programming language, for example, a Clang
23892401
/// module, or a Fortran module.
2402+
///
2403+
/// Uses the SubclassData1 and SubclassData32 Metadata slots.
23902404
class DIModule : public DIScope {
23912405
friend class LLVMContextImpl;
23922406
friend class MDNode;
2393-
unsigned LineNo;
2394-
bool IsDecl;
23952407

23962408
DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
23972409
bool IsDecl, ArrayRef<Metadata *> Ops);
@@ -2443,8 +2455,8 @@ class DIModule : public DIScope {
24432455
StringRef getConfigurationMacros() const { return getStringOperand(3); }
24442456
StringRef getIncludePath() const { return getStringOperand(4); }
24452457
StringRef getAPINotesFile() const { return getStringOperand(5); }
2446-
unsigned getLineNo() const { return LineNo; }
2447-
bool getIsDecl() const { return IsDecl; }
2458+
unsigned getLineNo() const { return SubclassData32; }
2459+
bool getIsDecl() const { return SubclassData1; }
24482460

24492461
Metadata *getRawScope() const { return getOperand(1); }
24502462
MDString *getRawName() const { return getOperandAs<MDString>(2); }
@@ -2460,13 +2472,15 @@ class DIModule : public DIScope {
24602472
};
24612473

24622474
/// Base class for template parameters.
2475+
///
2476+
/// Uses the SubclassData1 Metadata slot.
24632477
class DITemplateParameter : public DINode {
24642478
protected:
2465-
bool IsDefault;
2466-
24672479
DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
24682480
unsigned Tag, bool IsDefault, ArrayRef<Metadata *> Ops)
2469-
: DINode(Context, ID, Storage, Tag, Ops), IsDefault(IsDefault) {}
2481+
: DINode(Context, ID, Storage, Tag, Ops) {
2482+
SubclassData1 = IsDefault;
2483+
}
24702484
~DITemplateParameter() = default;
24712485

24722486
public:
@@ -2475,7 +2489,7 @@ class DITemplateParameter : public DINode {
24752489

24762490
MDString *getRawName() const { return getOperandAs<MDString>(0); }
24772491
Metadata *getRawType() const { return getOperand(1); }
2478-
bool isDefault() const { return IsDefault; }
2492+
bool isDefault() const { return SubclassData1; }
24792493

24802494
static bool classof(const Metadata *MD) {
24812495
return MD->getMetadataID() == DITemplateTypeParameterKind ||
@@ -2572,9 +2586,10 @@ class DITemplateValueParameter : public DITemplateParameter {
25722586
};
25732587

25742588
/// Base class for variables.
2589+
///
2590+
/// Uses the SubclassData32 Metadata slot.
25752591
class DIVariable : public DINode {
25762592
unsigned Line;
2577-
uint32_t AlignInBits;
25782593

25792594
protected:
25802595
DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, signed Line,
@@ -2587,7 +2602,7 @@ class DIVariable : public DINode {
25872602
StringRef getName() const { return getStringOperand(1); }
25882603
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
25892604
DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
2590-
uint32_t getAlignInBits() const { return AlignInBits; }
2605+
uint32_t getAlignInBits() const { return SubclassData32; }
25912606
uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
25922607
/// Determines the size of the variable's type.
25932608
std::optional<uint64_t> getSizeInBits() const;
@@ -3161,9 +3176,10 @@ class DIGlobalVariable : public DIVariable {
31613176
}
31623177
};
31633178

3179+
/// Debug common block.
3180+
///
3181+
/// Uses the SubclassData32 Metadata slot.
31643182
class DICommonBlock : public DIScope {
3165-
unsigned LineNo;
3166-
31673183
friend class LLVMContextImpl;
31683184
friend class MDNode;
31693185

@@ -3205,7 +3221,7 @@ class DICommonBlock : public DIScope {
32053221
}
32063222
StringRef getName() const { return getStringOperand(2); }
32073223
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
3208-
unsigned getLineNo() const { return LineNo; }
3224+
unsigned getLineNo() const { return SubclassData32; }
32093225

32103226
Metadata *getRawScope() const { return getOperand(0); }
32113227
Metadata *getRawDecl() const { return getOperand(1); }
@@ -3310,12 +3326,11 @@ class DILocalVariable : public DIVariable {
33103326

33113327
/// Label.
33123328
///
3329+
/// Uses the SubclassData32 Metadata slot.
33133330
class DILabel : public DINode {
33143331
friend class LLVMContextImpl;
33153332
friend class MDNode;
33163333

3317-
unsigned Line;
3318-
33193334
DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
33203335
ArrayRef<Metadata *> Ops);
33213336
~DILabel() = default;
@@ -3353,7 +3368,7 @@ class DILabel : public DINode {
33533368
DILocalScope *getScope() const {
33543369
return cast_or_null<DILocalScope>(getRawScope());
33553370
}
3356-
unsigned getLine() const { return Line; }
3371+
unsigned getLine() const { return SubclassData32; }
33573372
StringRef getName() const { return getStringOperand(1); }
33583373
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
33593374

@@ -3455,15 +3470,17 @@ class DIObjCProperty : public DINode {
34553470
};
34563471

34573472
/// An imported module (C++ using directive or similar).
3473+
///
3474+
/// Uses the SubclassData32 Metadata slot.
34583475
class DIImportedEntity : public DINode {
34593476
friend class LLVMContextImpl;
34603477
friend class MDNode;
34613478

3462-
unsigned Line;
3463-
34643479
DIImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
34653480
unsigned Line, ArrayRef<Metadata *> Ops)
3466-
: DINode(C, DIImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
3481+
: DINode(C, DIImportedEntityKind, Storage, Tag, Ops) {
3482+
SubclassData32 = Line;
3483+
}
34673484
~DIImportedEntity() = default;
34683485

34693486
static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
@@ -3499,7 +3516,7 @@ class DIImportedEntity : public DINode {
34993516

35003517
TempDIImportedEntity clone() const { return cloneImpl(); }
35013518

3502-
unsigned getLine() const { return Line; }
3519+
unsigned getLine() const { return SubclassData32; }
35033520
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
35043521
DINode *getEntity() const { return cast_or_null<DINode>(getRawEntity()); }
35053522
StringRef getName() const { return getStringOperand(2); }
@@ -3567,6 +3584,8 @@ class DIGlobalVariableExpression : public MDNode {
35673584
/// \c DW_MACINFO_*, defined in llvm/BinaryFormat/Dwarf.h). Called \a
35683585
/// DIMacroNode
35693586
/// because it's potentially used for non-DWARF output.
3587+
///
3588+
/// Uses the SubclassData16 Metadata slot.
35703589
class DIMacroNode : public MDNode {
35713590
friend class LLVMContextImpl;
35723591
friend class MDNode;
@@ -3611,15 +3630,18 @@ class DIMacroNode : public MDNode {
36113630
}
36123631
};
36133632

3633+
/// Macro
3634+
///
3635+
/// Uses the SubclassData32 Metadata slot.
36143636
class DIMacro : public DIMacroNode {
36153637
friend class LLVMContextImpl;
36163638
friend class MDNode;
36173639

3618-
unsigned Line;
3619-
36203640
DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line,
36213641
ArrayRef<Metadata *> Ops)
3622-
: DIMacroNode(C, DIMacroKind, Storage, MIType, Ops), Line(Line) {}
3642+
: DIMacroNode(C, DIMacroKind, Storage, MIType, Ops) {
3643+
SubclassData32 = Line;
3644+
}
36233645
~DIMacro() = default;
36243646

36253647
static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
@@ -3649,7 +3671,7 @@ class DIMacro : public DIMacroNode {
36493671

36503672
TempDIMacro clone() const { return cloneImpl(); }
36513673

3652-
unsigned getLine() const { return Line; }
3674+
unsigned getLine() const { return SubclassData32; }
36533675

36543676
StringRef getName() const { return getStringOperand(0); }
36553677
StringRef getValue() const { return getStringOperand(1); }
@@ -3662,15 +3684,18 @@ class DIMacro : public DIMacroNode {
36623684
}
36633685
};
36643686

3687+
/// Macro file
3688+
///
3689+
/// Uses the SubclassData32 Metadata slot.
36653690
class DIMacroFile : public DIMacroNode {
36663691
friend class LLVMContextImpl;
36673692
friend class MDNode;
36683693

3669-
unsigned Line;
3670-
36713694
DIMacroFile(LLVMContext &C, StorageType Storage, unsigned MIType,
36723695
unsigned Line, ArrayRef<Metadata *> Ops)
3673-
: DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops), Line(Line) {}
3696+
: DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops) {
3697+
SubclassData32 = Line;
3698+
}
36743699
~DIMacroFile() = default;
36753700

36763701
static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
@@ -3711,7 +3736,7 @@ class DIMacroFile : public DIMacroNode {
37113736
replaceOperandWith(1, Elements.get());
37123737
}
37133738

3714-
unsigned getLine() const { return Line; }
3739+
unsigned getLine() const { return SubclassData32; }
37153740
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
37163741

37173742
DIMacroNodeArray getElements() const {

0 commit comments

Comments
 (0)