diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2017-02-06 21:23:03 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2017-02-06 21:23:03 +0000 |
commit | e69e73c7b82f8c43c7890f1602760e2b61feacb6 (patch) | |
tree | 2f6443ac26afc6577b18ed1486c434bb7fa8f971 /llvm/lib/IR/LLVMContextImpl.h | |
parent | c24ec3237027f5dc8331ba4a73484d2aef41a012 (diff) | |
download | bcm5719-llvm-e69e73c7b82f8c43c7890f1602760e2b61feacb6.tar.gz bcm5719-llvm-e69e73c7b82f8c43c7890f1602760e2b61feacb6.zip |
IR: Consider two DISubprograms to be odr-equal if they have the same template parameters.
In ValueMapper we create new operands for MDNodes and
rely on MDNode::replaceWithUniqued to create a new MDNode
with the specified operands. However this doesn't always
actually happen correctly for DISubprograms because when we
uniquify the new node, we only odr-compare it with existing nodes
(MDNodeSubsetEqualImpl<DISubprogram>::isDeclarationOfODRMember). Although
the TemplateParameters field can refer to a distinct DICompileUnit via
DITemplateTypeParameter::type -> DICompositeType::scope -> DISubprogram::unit,
it is not currently included in the odr comparison. As a result, we can end
up getting our original DISubprogram back, which means we will have a cloned
module referring to the DICompileUnit in the original module, which causes
a verification error.
The fix I implemented was to consider TemplateParameters to be one of the
odr-equal properties. But I'm a little uncomfortable with this. In general it
seems unsound to rely on distinct MDNodes never being reachable from nodes
which we only check odr-equality of. My only long term suggestion would be
to separate odr-uniquing from full uniquing.
Differential Revision: https://reviews.llvm.org/D29240
llvm-svn: 294240
Diffstat (limited to 'llvm/lib/IR/LLVMContextImpl.h')
-rw-r--r-- | llvm/lib/IR/LLVMContextImpl.h | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h index 850c81cfabb..79bd2e12a35 100644 --- a/llvm/lib/IR/LLVMContextImpl.h +++ b/llvm/lib/IR/LLVMContextImpl.h @@ -612,17 +612,19 @@ template <> struct MDNodeSubsetEqualImpl<DISubprogram> { typedef MDNodeKeyImpl<DISubprogram> KeyTy; static bool isSubsetEqual(const KeyTy &LHS, const DISubprogram *RHS) { return isDeclarationOfODRMember(LHS.IsDefinition, LHS.Scope, - LHS.LinkageName, RHS); + LHS.LinkageName, LHS.TemplateParams, RHS); } static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) { return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(), - LHS->getRawLinkageName(), RHS); + LHS->getRawLinkageName(), + LHS->getRawTemplateParams(), RHS); } /// Subprograms compare equal if they declare the same function in an ODR /// type. static bool isDeclarationOfODRMember(bool IsDefinition, const Metadata *Scope, const MDString *LinkageName, + const Metadata *TemplateParams, const DISubprogram *RHS) { // Check whether the LHS is eligible. if (IsDefinition || !Scope || !LinkageName) @@ -633,8 +635,14 @@ template <> struct MDNodeSubsetEqualImpl<DISubprogram> { return false; // Compare to the RHS. + // FIXME: We need to compare template parameters here to avoid incorrect + // collisions in mapMetadata when RF_MoveDistinctMDs and a ODR-DISubprogram + // has a non-ODR template parameter (i.e., a DICompositeType that does not + // have an identifier). Eventually we should decouple ODR logic from + // uniquing logic. return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() && - LinkageName == RHS->getRawLinkageName(); + LinkageName == RHS->getRawLinkageName() && + TemplateParams == RHS->getRawTemplateParams(); } }; |