diff options
author | serge-sans-paille <sguelton@mozilla.com> | 2023-11-16 21:55:43 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-16 21:55:43 +0000 |
commit | 102f7fce8d8251655be5bf6955af33e55bea9c9e (patch) | |
tree | c0ffcd2240f0b0b6868a4ef7aca5b0abd565588b | |
parent | ae623d16d50c9f12de7ae7ac1aa11c9d6857e081 (diff) | |
download | llvm-102f7fce8d8251655be5bf6955af33e55bea9c9e.zip llvm-102f7fce8d8251655be5bf6955af33e55bea9c9e.tar.gz llvm-102f7fce8d8251655be5bf6955af33e55bea9c9e.tar.bz2 |
[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
-rw-r--r-- | llvm/include/llvm/IR/DebugInfoMetadata.h | 115 | ||||
-rw-r--r-- | llvm/lib/IR/DebugInfoMetadata.cpp | 33 |
2 files changed, 90 insertions, 58 deletions
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index 1fe0543..3d9ee1c 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -128,6 +128,8 @@ public: /// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*, /// defined in llvm/BinaryFormat/Dwarf.h). Called \a DINode because it's /// potentially used for non-DWARF output. +/// +/// Uses the SubclassData16 Metadata slot. class DINode : public MDNode { friend class LLVMContextImpl; friend class MDNode; @@ -227,6 +229,8 @@ public: /// (possibly empty) null-separated \a MDString header that contains arbitrary /// fields. The remaining operands are \a dwarf_operands(), and are pointers /// to other metadata. +/// +/// Uses the SubclassData32 Metadata slot. class GenericDINode : public DINode { friend class LLVMContextImpl; friend class MDNode; @@ -695,12 +699,13 @@ std::optional<StringRef> DIScope::getSource() const { /// TODO: Remove the hardcoded name and context, since many types don't use /// them. /// TODO: Split up flags. +/// +/// Uses the SubclassData32 Metadata slot. class DIType : public DIScope { unsigned Line; DIFlags Flags; uint64_t SizeInBits; uint64_t OffsetInBits; - uint32_t AlignInBits; protected: DIType(LLVMContext &C, unsigned ID, StorageType Storage, unsigned Tag, @@ -716,7 +721,7 @@ protected: this->Line = Line; this->Flags = Flags; this->SizeInBits = SizeInBits; - this->AlignInBits = AlignInBits; + this->SubclassData32 = AlignInBits; this->OffsetInBits = OffsetInBits; } @@ -735,7 +740,7 @@ public: 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 +1394,13 @@ public: 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, @@ -1876,6 +1881,10 @@ public: /// Debug location. /// /// A debug location in source code, used for debug info and otherwise. +/// +/// Uses the SubclassData1, SubclassData16 and SubclassData32 +/// Metadata slots. + class DILocation : public MDNode { friend class LLVMContextImpl; friend class MDNode; @@ -2161,17 +2170,20 @@ public: } }; +/// Debug lexical block. +/// +/// Uses the SubclassData32 Metadata slot. 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 +2218,7 @@ public: 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 +2230,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 +2266,7 @@ public: (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; @@ -2338,12 +2349,13 @@ DILocation::cloneByMultiplyingDuplicationFactor(unsigned DF) const { return std::nullopt; } +/// Debug lexical block. +/// +/// Uses the SubclassData1 Metadata slot. 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 +2385,7 @@ public: 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); } @@ -2387,11 +2399,11 @@ public: /// Represents a module in the programming language, for example, a Clang /// module, or a Fortran module. +/// +/// Uses the SubclassData1 and SubclassData32 Metadata slots. 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 +2455,8 @@ public: 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); } @@ -2460,13 +2472,15 @@ public: }; /// Base class for template parameters. +/// +/// Uses the SubclassData1 Metadata slot. 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 +2489,7 @@ public: 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 || @@ -2572,9 +2586,10 @@ public: }; /// Base class for variables. +/// +/// Uses the SubclassData32 Metadata slot. class DIVariable : public DINode { unsigned Line; - uint32_t AlignInBits; protected: DIVariable(LLVMContext &C, unsigned ID, StorageType Storage, signed Line, @@ -2587,7 +2602,7 @@ public: 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; @@ -3161,9 +3176,10 @@ public: } }; +/// Debug common block. +/// +/// Uses the SubclassData32 Metadata slot. class DICommonBlock : public DIScope { - unsigned LineNo; - friend class LLVMContextImpl; friend class MDNode; @@ -3205,7 +3221,7 @@ public: } 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); } @@ -3310,12 +3326,11 @@ public: /// Label. /// +/// Uses the SubclassData32 Metadata slot. 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 +3368,7 @@ public: 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()); } @@ -3455,15 +3470,17 @@ public: }; /// An imported module (C++ using directive or similar). +/// +/// Uses the SubclassData32 Metadata slot. 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 +3516,7 @@ public: 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); } @@ -3567,6 +3584,8 @@ public: /// \c DW_MACINFO_*, defined in llvm/BinaryFormat/Dwarf.h). Called \a /// DIMacroNode /// because it's potentially used for non-DWARF output. +/// +/// Uses the SubclassData16 Metadata slot. class DIMacroNode : public MDNode { friend class LLVMContextImpl; friend class MDNode; @@ -3611,15 +3630,18 @@ public: } }; +/// Macro +/// +/// Uses the SubclassData32 Metadata slot. 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 +3671,7 @@ public: 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); } @@ -3662,15 +3684,18 @@ public: } }; +/// Macro file +/// +/// Uses the SubclassData32 Metadata slot. 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 +3736,7 @@ public: 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 943826c..927aefb 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -915,11 +915,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); } @@ -1181,8 +1181,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) { @@ -1196,8 +1197,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, @@ -1211,8 +1213,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, @@ -1301,8 +1305,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(); @@ -1328,7 +1333,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) { |