-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[llvm] Reduce memory footprint of Debug metadata nodes #71227
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[llvm] Reduce memory footprint of Debug metadata nodes #71227
Conversation
@llvm/pr-subscribers-debuginfo @llvm/pr-subscribers-llvm-ir Author: None (serge-sans-paille) ChangesUsing 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 After: DILexicalBlock: 24 Full diff: https://github.com/llvm/llvm-project/pull/71227.diff 2 Files Affected:
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index b347664883fd9f2..cdc0f56796658f9 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -700,7 +700,6 @@ class DIType : public DIScope {
DIFlags Flags;
uint64_t SizeInBits;
uint64_t OffsetInBits;
- uint32_t AlignInBits;
protected:
DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag,
@@ -716,7 +715,7 @@ class DIType : public DIScope {
this->Line = Line;
this->Flags = Flags;
this->SizeInBits = SizeInBits;
- this->AlignInBits = AlignInBits;
+ this->SubclassData32 = AlignInBits;
this->OffsetInBits = OffsetInBits;
}
@@ -735,7 +734,7 @@ class DIType : public DIScope {
unsigned getLine() const { return Line; }
uint64_t getSizeInBits() const { return SizeInBits; }
- uint32_t getAlignInBits() const { return AlignInBits; }
+ uint32_t getAlignInBits() const { return SubclassData32; }
uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
uint64_t getOffsetInBits() const { return OffsetInBits; }
DIFlags getFlags() const { return Flags; }
@@ -1389,13 +1388,13 @@ class DICompileUnit : public DIScope {
private:
unsigned SourceLanguage;
- bool IsOptimized;
unsigned RuntimeVersion;
- unsigned EmissionKind;
uint64_t DWOId;
+ unsigned EmissionKind;
+ unsigned NameTableKind;
+ bool IsOptimized;
bool SplitDebugInlining;
bool DebugInfoForProfiling;
- unsigned NameTableKind;
bool RangesBaseAddress;
DICompileUnit(LLVMContext &C, StorageType Storage, unsigned SourceLanguage,
@@ -2165,13 +2164,13 @@ class DILexicalBlock : public DILexicalBlockBase {
friend class LLVMContextImpl;
friend class MDNode;
- unsigned Line;
uint16_t Column;
DILexicalBlock(LLVMContext &C, StorageType Storage, unsigned Line,
unsigned Column, ArrayRef<Metadata *> Ops)
- : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops), Line(Line),
+ : DILexicalBlockBase(C, DILexicalBlockKind, Storage, Ops),
Column(Column) {
+ SubclassData32 = Line;
assert(Column < (1u << 16) && "Expected 16-bit column");
}
~DILexicalBlock() = default;
@@ -2206,7 +2205,7 @@ class DILexicalBlock : public DILexicalBlockBase {
TempDILexicalBlock clone() const { return cloneImpl(); }
- unsigned getLine() const { return Line; }
+ unsigned getLine() const { return SubclassData32; }
unsigned getColumn() const { return Column; }
static bool classof(const Metadata *MD) {
@@ -2218,12 +2217,11 @@ class DILexicalBlockFile : public DILexicalBlockBase {
friend class LLVMContextImpl;
friend class MDNode;
- unsigned Discriminator;
-
DILexicalBlockFile(LLVMContext &C, StorageType Storage,
unsigned Discriminator, ArrayRef<Metadata *> Ops)
- : DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops),
- Discriminator(Discriminator) {}
+ : DILexicalBlockBase(C, DILexicalBlockFileKind, Storage, Ops) {
+ SubclassData32 = Discriminator;
+ }
~DILexicalBlockFile() = default;
static DILexicalBlockFile *getImpl(LLVMContext &Context, DILocalScope *Scope,
@@ -2255,7 +2253,7 @@ class DILexicalBlockFile : public DILexicalBlockBase {
(Scope, File, Discriminator))
TempDILexicalBlockFile clone() const { return cloneImpl(); }
- unsigned getDiscriminator() const { return Discriminator; }
+ unsigned getDiscriminator() const { return SubclassData32; }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DILexicalBlockFileKind;
@@ -2342,8 +2340,6 @@ class DINamespace : public DIScope {
friend class LLVMContextImpl;
friend class MDNode;
- unsigned ExportSymbols : 1;
-
DINamespace(LLVMContext &Context, StorageType Storage, bool ExportSymbols,
ArrayRef<Metadata *> Ops);
~DINamespace() = default;
@@ -2373,7 +2369,7 @@ class DINamespace : public DIScope {
TempDINamespace clone() const { return cloneImpl(); }
- bool getExportSymbols() const { return ExportSymbols; }
+ bool getExportSymbols() const { return SubclassData1; }
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
StringRef getName() const { return getStringOperand(2); }
@@ -2390,8 +2386,6 @@ class DINamespace : public DIScope {
class DIModule : public DIScope {
friend class LLVMContextImpl;
friend class MDNode;
- unsigned LineNo;
- bool IsDecl;
DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
bool IsDecl, ArrayRef<Metadata *> Ops);
@@ -2443,8 +2437,8 @@ class DIModule : public DIScope {
StringRef getConfigurationMacros() const { return getStringOperand(3); }
StringRef getIncludePath() const { return getStringOperand(4); }
StringRef getAPINotesFile() const { return getStringOperand(5); }
- unsigned getLineNo() const { return LineNo; }
- bool getIsDecl() const { return IsDecl; }
+ unsigned getLineNo() const { return SubclassData32; }
+ bool getIsDecl() const { return SubclassData1; }
Metadata *getRawScope() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
@@ -2462,11 +2456,11 @@ class DIModule : public DIScope {
/// Base class for template parameters.
class DITemplateParameter : public DINode {
protected:
- bool IsDefault;
-
DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
unsigned Tag, bool IsDefault, ArrayRef<Metadata *> Ops)
- : DINode(Context, ID, Storage, Tag, Ops), IsDefault(IsDefault) {}
+ : DINode(Context, ID, Storage, Tag, Ops) {
+ SubclassData1 = IsDefault;
+ }
~DITemplateParameter() = default;
public:
@@ -2475,7 +2469,7 @@ class DITemplateParameter : public DINode {
MDString *getRawName() const { return getOperandAs<MDString>(0); }
Metadata *getRawType() const { return getOperand(1); }
- bool isDefault() const { return IsDefault; }
+ bool isDefault() const { return SubclassData1; }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DITemplateTypeParameterKind ||
@@ -2574,7 +2568,6 @@ class DITemplateValueParameter : public DITemplateParameter {
/// Base class for variables.
class DIVariable : public DINode {
unsigned Line;
- uint32_t AlignInBits;
protected:
DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, signed Line,
@@ -2587,7 +2580,7 @@ class DIVariable : public DINode {
StringRef getName() const { return getStringOperand(1); }
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
DIType *getType() const { return cast_or_null<DIType>(getRawType()); }
- uint32_t getAlignInBits() const { return AlignInBits; }
+ uint32_t getAlignInBits() const { return SubclassData32; }
uint32_t getAlignInBytes() const { return getAlignInBits() / CHAR_BIT; }
/// Determines the size of the variable's type.
std::optional<uint64_t> getSizeInBits() const;
@@ -3162,8 +3155,6 @@ class DIGlobalVariable : public DIVariable {
};
class DICommonBlock : public DIScope {
- unsigned LineNo;
-
friend class LLVMContextImpl;
friend class MDNode;
@@ -3205,7 +3196,7 @@ class DICommonBlock : public DIScope {
}
StringRef getName() const { return getStringOperand(2); }
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
- unsigned getLineNo() const { return LineNo; }
+ unsigned getLineNo() const { return SubclassData32; }
Metadata *getRawScope() const { return getOperand(0); }
Metadata *getRawDecl() const { return getOperand(1); }
@@ -3314,8 +3305,6 @@ class DILabel : public DINode {
friend class LLVMContextImpl;
friend class MDNode;
- unsigned Line;
-
DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
ArrayRef<Metadata *> Ops);
~DILabel() = default;
@@ -3353,7 +3342,7 @@ class DILabel : public DINode {
DILocalScope *getScope() const {
return cast_or_null<DILocalScope>(getRawScope());
}
- unsigned getLine() const { return Line; }
+ unsigned getLine() const { return SubclassData32; }
StringRef getName() const { return getStringOperand(1); }
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
@@ -3459,11 +3448,11 @@ class DIImportedEntity : public DINode {
friend class LLVMContextImpl;
friend class MDNode;
- unsigned Line;
-
DIImportedEntity(LLVMContext &C, StorageType Storage, unsigned Tag,
unsigned Line, ArrayRef<Metadata *> Ops)
- : DINode(C, DIImportedEntityKind, Storage, Tag, Ops), Line(Line) {}
+ : DINode(C, DIImportedEntityKind, Storage, Tag, Ops) {
+ SubclassData32 = Line;
+ }
~DIImportedEntity() = default;
static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
@@ -3499,7 +3488,7 @@ class DIImportedEntity : public DINode {
TempDIImportedEntity clone() const { return cloneImpl(); }
- unsigned getLine() const { return Line; }
+ unsigned getLine() const { return SubclassData32; }
DIScope *getScope() const { return cast_or_null<DIScope>(getRawScope()); }
DINode *getEntity() const { return cast_or_null<DINode>(getRawEntity()); }
StringRef getName() const { return getStringOperand(2); }
@@ -3615,11 +3604,11 @@ class DIMacro : public DIMacroNode {
friend class LLVMContextImpl;
friend class MDNode;
- unsigned Line;
-
DIMacro(LLVMContext &C, StorageType Storage, unsigned MIType, unsigned Line,
ArrayRef<Metadata *> Ops)
- : DIMacroNode(C, DIMacroKind, Storage, MIType, Ops), Line(Line) {}
+ : DIMacroNode(C, DIMacroKind, Storage, MIType, Ops) {
+ SubclassData32 = Line;
+ }
~DIMacro() = default;
static DIMacro *getImpl(LLVMContext &Context, unsigned MIType, unsigned Line,
@@ -3649,7 +3638,7 @@ class DIMacro : public DIMacroNode {
TempDIMacro clone() const { return cloneImpl(); }
- unsigned getLine() const { return Line; }
+ unsigned getLine() const { return SubclassData32; }
StringRef getName() const { return getStringOperand(0); }
StringRef getValue() const { return getStringOperand(1); }
@@ -3666,11 +3655,11 @@ class DIMacroFile : public DIMacroNode {
friend class LLVMContextImpl;
friend class MDNode;
- unsigned Line;
-
DIMacroFile(LLVMContext &C, StorageType Storage, unsigned MIType,
unsigned Line, ArrayRef<Metadata *> Ops)
- : DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops), Line(Line) {}
+ : DIMacroNode(C, DIMacroFileKind, Storage, MIType, Ops) {
+ SubclassData32 = Line;
+ }
~DIMacroFile() = default;
static DIMacroFile *getImpl(LLVMContext &Context, unsigned MIType,
@@ -3711,7 +3700,7 @@ class DIMacroFile : public DIMacroNode {
replaceOperandWith(1, Elements.get());
}
- unsigned getLine() const { return Line; }
+ unsigned getLine() const { return SubclassData32; }
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
DIMacroNodeArray getElements() const {
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index f7f36129ec8557c..37689cd1583e4df 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -914,11 +914,11 @@ DICompileUnit::DICompileUnit(LLVMContext &C, StorageType Storage,
bool DebugInfoForProfiling, unsigned NameTableKind,
bool RangesBaseAddress, ArrayRef<Metadata *> Ops)
: DIScope(C, DICompileUnitKind, Storage, dwarf::DW_TAG_compile_unit, Ops),
- SourceLanguage(SourceLanguage), IsOptimized(IsOptimized),
- RuntimeVersion(RuntimeVersion), EmissionKind(EmissionKind), DWOId(DWOId),
- SplitDebugInlining(SplitDebugInlining),
+ SourceLanguage(SourceLanguage), RuntimeVersion(RuntimeVersion),
+ DWOId(DWOId), EmissionKind(EmissionKind), NameTableKind(NameTableKind),
+ IsOptimized(IsOptimized), SplitDebugInlining(SplitDebugInlining),
DebugInfoForProfiling(DebugInfoForProfiling),
- NameTableKind(NameTableKind), RangesBaseAddress(RangesBaseAddress) {
+ RangesBaseAddress(RangesBaseAddress) {
assert(Storage != Uniqued);
}
@@ -1180,8 +1180,9 @@ DILexicalBlockFile *DILexicalBlockFile::getImpl(LLVMContext &Context,
DINamespace::DINamespace(LLVMContext &Context, StorageType Storage,
bool ExportSymbols, ArrayRef<Metadata *> Ops)
- : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops),
- ExportSymbols(ExportSymbols) {}
+ : DIScope(Context, DINamespaceKind, Storage, dwarf::DW_TAG_namespace, Ops) {
+ SubclassData1 = ExportSymbols;
+}
DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope,
MDString *Name, bool ExportSymbols,
StorageType Storage, bool ShouldCreate) {
@@ -1195,8 +1196,9 @@ DINamespace *DINamespace::getImpl(LLVMContext &Context, Metadata *Scope,
DICommonBlock::DICommonBlock(LLVMContext &Context, StorageType Storage,
unsigned LineNo, ArrayRef<Metadata *> Ops)
: DIScope(Context, DICommonBlockKind, Storage, dwarf::DW_TAG_common_block,
- Ops),
- LineNo(LineNo) {}
+ Ops) {
+ SubclassData32 = LineNo;
+}
DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope,
Metadata *Decl, MDString *Name,
Metadata *File, unsigned LineNo,
@@ -1210,8 +1212,10 @@ DICommonBlock *DICommonBlock::getImpl(LLVMContext &Context, Metadata *Scope,
DIModule::DIModule(LLVMContext &Context, StorageType Storage, unsigned LineNo,
bool IsDecl, ArrayRef<Metadata *> Ops)
- : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops),
- LineNo(LineNo), IsDecl(IsDecl) {}
+ : DIScope(Context, DIModuleKind, Storage, dwarf::DW_TAG_module, Ops) {
+ SubclassData1 = IsDecl;
+ SubclassData32 = LineNo;
+}
DIModule *DIModule::getImpl(LLVMContext &Context, Metadata *File,
Metadata *Scope, MDString *Name,
MDString *ConfigurationMacros,
@@ -1300,8 +1304,9 @@ DILocalVariable::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
DIVariable::DIVariable(LLVMContext &C, unsigned ID, StorageType Storage,
signed Line, ArrayRef<Metadata *> Ops,
uint32_t AlignInBits)
- : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line),
- AlignInBits(AlignInBits) {}
+ : DINode(C, ID, Storage, dwarf::DW_TAG_variable, Ops), Line(Line) {
+ SubclassData32 = AlignInBits;
+}
std::optional<uint64_t> DIVariable::getSizeInBits() const {
// This is used by the Verifier so be mindful of broken types.
const Metadata *RawType = getRawType();
@@ -1327,7 +1332,9 @@ std::optional<uint64_t> DIVariable::getSizeInBits() const {
DILabel::DILabel(LLVMContext &C, StorageType Storage, unsigned Line,
ArrayRef<Metadata *> Ops)
- : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops), Line(Line) {}
+ : DINode(C, DILabelKind, Storage, dwarf::DW_TAG_label, Ops) {
+ SubclassData32 = Line;
+}
DILabel *DILabel::getImpl(LLVMContext &Context, Metadata *Scope, MDString *Name,
Metadata *File, unsigned Line, StorageType Storage,
bool ShouldCreate) {
|
Please add @stevemerr and @bwyma from the DGI team as the reviewers. Also, you may want to consider making this change in the upstream directly. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a nice improvement! Is the use of SubclassData32
by each of the nodes documented somewhere?
No documentation, unfortunately :-/ |
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
163f6de
to
ed7a6c7
Compare
Let me rephrase that — could you document how SubclassData is used by the nodes you're changing in this patch? For example in the top-level doxygen comment of each DI* class you are modifying? |
done! |
@adrian-prantl : gentle ping :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
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
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
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