diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-04-19 18:00:19 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-04-19 18:00:19 +0000 |
commit | 9738602869dda75509a0f3782cd6639f9e3927c4 (patch) | |
tree | 7930467116f656492380f6cef7c78a9f8aa3f1b7 /llvm/lib/IR/DebugInfoMetadata.cpp | |
parent | 40a34c2e2af8eaabfac246c9801af09a4e478dc1 (diff) | |
download | bcm5719-llvm-9738602869dda75509a0f3782cd6639f9e3927c4.tar.gz bcm5719-llvm-9738602869dda75509a0f3782cd6639f9e3927c4.zip |
IR: Enable debug info type ODR uniquing for forward decls
Add a new method, DICompositeType::buildODRType, that will create or
mutate the DICompositeType for a given ODR identifier, and use it in
LLParser and BitcodeReader instead of DICompositeType::getODRType.
The logic is as follows:
- If there's no node, create one with the given arguments.
- Else, if the current node is a forward declaration and the new
arguments would create a definition, mutate the node to match the
new arguments.
- Else, return the old node.
This adds a missing feature supported by the current DITypeIdentifierMap
(which I'm slowly making redudant). The only remaining difference is
that the DITypeIdentifierMap has a "the-last-one-wins" rule, whereas
DICompositeType::buildODRType has a "the-first-one-wins" rule.
For now I'm leaving behind DICompositeType::getODRType since it has
obvious, low-level semantics that are convenient for unit testing.
llvm-svn: 266786
Diffstat (limited to 'llvm/lib/IR/DebugInfoMetadata.cpp')
-rw-r--r-- | llvm/lib/IR/DebugInfoMetadata.cpp | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp index 37986f73ab1..c2ecd4e5fc8 100644 --- a/llvm/lib/IR/DebugInfoMetadata.cpp +++ b/llvm/lib/IR/DebugInfoMetadata.cpp @@ -255,6 +255,7 @@ DICompositeType *DICompositeType::getImpl( bool ShouldCreate) { assert(isCanonical(Name) && "Expected canonical MDString"); + // Keep this in sync with buildODRType. DEFINE_GETIMPL_LOOKUP( DICompositeType, (Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, @@ -266,6 +267,40 @@ DICompositeType *DICompositeType::getImpl( Ops); } +DICompositeType *DICompositeType::buildODRType( + LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, + Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, + uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, + unsigned Flags, Metadata *Elements, unsigned RuntimeLang, + Metadata *VTableHolder, Metadata *TemplateParams) { + assert(!Identifier.getString().empty() && "Expected valid identifier"); + if (!Context.isODRUniquingDebugTypes()) + return nullptr; + auto *&CT = (*Context.pImpl->DITypeMap)[&Identifier]; + if (!CT) + return CT = DICompositeType::getDistinct( + Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, + AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, + VTableHolder, TemplateParams, &Identifier); + + // Only mutate CT if it's a forward declaration and the new operands aren't. + assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?"); + if (!CT->isForwardDecl() || (Flags & DINode::FlagFwdDecl)) + return CT; + + // Mutate CT in place. Keep this in sync with getImpl. + CT->mutate(Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits, + Flags); + Metadata *Ops[] = {File, Scope, Name, BaseType, + Elements, VTableHolder, TemplateParams, &Identifier}; + assert(std::end(Ops) - std::begin(Ops) == CT->getNumOperands() && + "Mismatched number of operands"); + for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I) + if (Ops[I] != CT->getOperand(I)) + CT->setOperand(I, Ops[I]); + return CT; +} + DICompositeType *DICompositeType::getODRType( LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name, Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType, |