summaryrefslogtreecommitdiffstats
path: root/llvm/lib/IR/LLVMContextImpl.h
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2017-02-06 21:23:03 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2017-02-06 21:23:03 +0000
commite69e73c7b82f8c43c7890f1602760e2b61feacb6 (patch)
tree2f6443ac26afc6577b18ed1486c434bb7fa8f971 /llvm/lib/IR/LLVMContextImpl.h
parentc24ec3237027f5dc8331ba4a73484d2aef41a012 (diff)
downloadbcm5719-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.h14
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();
}
};
OpenPOWER on IntegriCloud