From 9d2f019fb63e80bfa9d50229b1f6213ccd11368a Mon Sep 17 00:00:00 2001 From: Adrian Prantl Date: Wed, 26 Apr 2017 23:59:52 +0000 Subject: [PATCH] Turn DISubprogram into a variable-length node. DISubprogram currently has 10 pointer operands, several of which are often nullptr. This patch reduces the amount of memory allocated by DISubprogram by rearranging the operands such that containing type, template params, and thrown types come last, and are only allocated when they are non-null (or followed by non-null operands). This patch also eliminates the entirely unused DisplayName operand. This saves up to 4 pointer operands per DISubprogram. (I tried measuring the effect on peak memory usage on an LTO link of an X86 llc, but the results were very noisy). This reapplies r301498 with an attempted workaround for g++. Differential Revision: https://reviews.llvm.org/D32560 llvm-svn: 301501 --- llvm/include/llvm/IR/DebugInfoMetadata.h | 30 +++++++++++-------- llvm/lib/Bitcode/Reader/MetadataLoader.cpp | 4 +-- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 +- llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 8 ++--- llvm/lib/IR/DebugInfoMetadata.cpp | 27 ++++++++++++----- llvm/tools/opt/BreakpointPrinter.cpp | 2 +- 6 files changed, 45 insertions(+), 28 deletions(-) diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h index ae11181f791c..67f51ccdeb38 100644 --- a/llvm/include/llvm/IR/DebugInfoMetadata.h +++ b/llvm/include/llvm/IR/DebugInfoMetadata.h @@ -1614,11 +1614,7 @@ public: DIScopeRef getScope() const { return DIScopeRef(getRawScope()); } StringRef getName() const { return getStringOperand(2); } - StringRef getDisplayName() const { return getStringOperand(3); } - StringRef getLinkageName() const { return getStringOperand(4); } - - MDString *getRawName() const { return getOperandAs(2); } - MDString *getRawLinkageName() const { return getOperandAs(4); } + StringRef getLinkageName() const { return getStringOperand(3); } DISubroutineType *getType() const { return cast_or_null(getRawType()); @@ -1630,7 +1626,7 @@ public: DICompileUnit *getUnit() const { return cast_or_null(getRawUnit()); } - void replaceUnit(DICompileUnit *CU) { replaceOperandWith(7, CU); } + void replaceUnit(DICompileUnit *CU) { replaceOperandWith(5, CU); } DITemplateParameterArray getTemplateParams() const { return cast_or_null(getRawTemplateParams()); } @@ -1645,13 +1641,21 @@ public: } Metadata *getRawScope() const { return getOperand(1); } - Metadata *getRawType() const { return getOperand(5); } - Metadata *getRawContainingType() const { return getOperand(6); } - Metadata *getRawUnit() const { return getOperand(7); } - Metadata *getRawTemplateParams() const { return getOperand(8); } - Metadata *getRawDeclaration() const { return getOperand(9); } - Metadata *getRawVariables() const { return getOperand(10); } - Metadata *getRawThrownTypes() const { return getOperand(11); } + MDString *getRawName() const { return getOperandAs(2); } + MDString *getRawLinkageName() const { return getOperandAs(3); } + Metadata *getRawType() const { return getOperand(4); } + Metadata *getRawUnit() const { return getOperand(5); } + Metadata *getRawDeclaration() const { return getOperand(6); } + Metadata *getRawVariables() const { return getOperand(7); } + Metadata *getRawContainingType() const { + return getNumOperands() > 8 ? getOperandAs(8) : nullptr; + } + Metadata *getRawTemplateParams() const { + return getNumOperands() > 9 ? getOperandAs(9) : nullptr; + } + Metadata *getRawThrownTypes() const { + return getNumOperands() > 10 ? getOperandAs(10) : nullptr; + } /// Check if this subprogram describes the given function. /// diff --git a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp index 7ca2e167da0b..24fdca33c232 100644 --- a/llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ b/llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -474,8 +474,8 @@ class MetadataLoader::MetadataLoaderImpl { for (auto CU_SP : CUSubprograms) if (auto *SPs = dyn_cast_or_null(CU_SP.second)) for (auto &Op : SPs->operands()) - if (auto *SP = dyn_cast_or_null(Op)) - SP->replaceOperandWith(7, CU_SP.first); + if (auto *SP = dyn_cast_or_null(Op)) + SP->replaceUnit(CU_SP.first); CUSubprograms.clear(); } diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index d99065b1b67a..b11e30c359b3 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -820,7 +820,7 @@ static bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) { const DILocalVariable *V = MI->getDebugVariable(); if (auto *SP = dyn_cast(V->getScope())) { - StringRef Name = SP->getDisplayName(); + StringRef Name = SP->getName(); if (!Name.empty()) OS << Name << ":"; } diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index 2571f6869651..665dbc0b6144 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -237,7 +237,7 @@ TypeIndex CodeViewDebug::getFuncIdForSubprogram(const DISubprogram *SP) { // The display name includes function template arguments. Drop them to match // MSVC. - StringRef DisplayName = SP->getDisplayName().split('<').first; + StringRef DisplayName = SP->getName().split('<').first; const DIScope *Scope = SP->getScope().resolve(); TypeIndex TI; @@ -657,7 +657,7 @@ void CodeViewDebug::emitInlineeLinesSubsection() { OS.AddBlankLine(); unsigned FileId = maybeRecordFile(SP->getFile()); - OS.AddComment("Inlined function " + SP->getDisplayName() + " starts at " + + OS.AddComment("Inlined function " + SP->getName() + " starts at " + SP->getFilename() + Twine(':') + Twine(SP->getLine())); OS.AddBlankLine(); // The filechecksum table uses 8 byte entries for now, and file ids start at @@ -759,9 +759,9 @@ void CodeViewDebug::emitDebugInfoForFunction(const Function *GV, // If we have a display name, build the fully qualified name by walking the // chain of scopes. - if (!SP->getDisplayName().empty()) + if (!SP->getName().empty()) FuncName = - getFullyQualifiedName(SP->getScope().resolve(), SP->getDisplayName()); + getFullyQualifiedName(SP->getScope().resolve(), SP->getName()); // If our DISubprogram name is empty, use the mangled name. if (FuncName.empty()) diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 498617c44600..3db9a3de92ee 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -214,6 +214,10 @@ void GenericDINode::recalculateHash() { #define DEFINE_GETIMPL_STORE_NO_CONSTRUCTOR_ARGS(CLASS, OPS) \ return storeImpl(new (array_lengthof(OPS)) CLASS(Context, Storage, OPS), \ Storage, Context.pImpl->CLASS##s) +#define DEFINE_GETIMPL_STORE_N(CLASS, ARGS, OPS, NUM_OPS) \ + return storeImpl(new (NUM_OPS) \ + CLASS(Context, Storage, UNWRAP_ARGS(ARGS), OPS), \ + Storage, Context.pImpl->CLASS##s) DISubrange *DISubrange::getImpl(LLVMContext &Context, int64_t Count, int64_t Lo, StorageType Storage, bool ShouldCreate) { @@ -449,13 +453,22 @@ DISubprogram *DISubprogram::getImpl( IsDefinition, ScopeLine, ContainingType, Virtuality, VirtualIndex, ThisAdjustment, Flags, IsOptimized, Unit, TemplateParams, Declaration, Variables, ThrownTypes)); - Metadata *Ops[] = {File, Scope, Name, Name, - LinkageName, Type, ContainingType, Unit, - TemplateParams, Declaration, Variables, ThrownTypes}; - DEFINE_GETIMPL_STORE(DISubprogram, (Line, ScopeLine, Virtuality, VirtualIndex, - ThisAdjustment, Flags, IsLocalToUnit, - IsDefinition, IsOptimized), - Ops); + SmallVector Ops = { + File, Scope, Name, LinkageName, Type, Unit, + Declaration, Variables, ContainingType, TemplateParams, ThrownTypes}; + if (!ThrownTypes) { + Ops.pop_back(); + if (!TemplateParams) { + Ops.pop_back(); + if (!ContainingType) + Ops.pop_back(); + } + } + DEFINE_GETIMPL_STORE_N(DISubprogram, + (Line, ScopeLine, Virtuality, VirtualIndex, + ThisAdjustment, Flags, IsLocalToUnit, IsDefinition, + IsOptimized), + Ops, Ops.size()); } bool DISubprogram::describes(const Function *F) const { diff --git a/llvm/tools/opt/BreakpointPrinter.cpp b/llvm/tools/opt/BreakpointPrinter.cpp index 33b3edcd1237..e5614ed061e3 100644 --- a/llvm/tools/opt/BreakpointPrinter.cpp +++ b/llvm/tools/opt/BreakpointPrinter.cpp @@ -51,7 +51,7 @@ struct BreakpointPrinter : public ModulePass { if (!SP) continue; getContextName(SP->getScope().resolve(), Name); - Name = Name + SP->getDisplayName().str(); + Name = Name + SP->getName().str(); if (!Name.empty() && Processed.insert(Name).second) { Out << Name << "\n"; }