summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-04-17 02:30:20 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-04-17 02:30:20 +0000
commit05ebfd09382b8dc8cd26eaf8fb91fb73ce48290e (patch)
tree92e6efb5cab9251fd4ec1425cf2bc3be61340af2 /llvm/lib
parent25fd344aa4d69b18b1328c0a8b89dc539506a582 (diff)
downloadbcm5719-llvm-05ebfd09382b8dc8cd26eaf8fb91fb73ce48290e.tar.gz
bcm5719-llvm-05ebfd09382b8dc8cd26eaf8fb91fb73ce48290e.zip
IR: Use ODR to unique DICompositeType members
Merge members that are describing the same member of the same ODR type, even if other bits differ. If the file or line differ, we don't care; if anything else differs, it's an ODR violation (and we still don't really care). For DISubprogram declarations, this looks at the LinkageName and Scope. For DW_TAG_member instances of DIDerivedType, this looks at the Name and Scope. In both cases, we know that the Scope follows ODR rules if it has a non-empty identifier. llvm-svn: 266548
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h64
1 files changed, 64 insertions, 0 deletions
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index bd61648264d..8a2c43909b4 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -32,6 +32,7 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/ValueHandle.h"
+#include "llvm/Support/Dwarf.h"
#include <vector>
namespace llvm {
@@ -376,6 +377,12 @@ template <> struct MDNodeKeyImpl<DIDerivedType> {
ExtraData == RHS->getRawExtraData();
}
unsigned getHashValue() const {
+ // If this is a member inside an ODR type, only hash the type and the name.
+ // Otherwise the hash will be stronger than
+ // MDNodeSubsetEqualImpl::isODRMember().
+ if (Tag == dwarf::DW_TAG_member && Name && Scope && isa<MDString>(Scope))
+ return hash_combine(Name, Scope);
+
// Intentionally computes the hash on a subset of the operands for
// performance reason. The subset has to be significant enough to avoid
// collision "most of the time". There is no correctness issue in case of
@@ -384,6 +391,30 @@ template <> struct MDNodeKeyImpl<DIDerivedType> {
}
};
+template <> struct MDNodeSubsetEqualImpl<DIDerivedType> {
+ typedef MDNodeKeyImpl<DIDerivedType> KeyTy;
+ static bool isSubsetEqual(const KeyTy &LHS, const DIDerivedType *RHS) {
+ return isODRMember(LHS.Tag, LHS.Scope, LHS.Name, RHS);
+ }
+ static bool isSubsetEqual(const DIDerivedType *LHS, const DIDerivedType *RHS) {
+ return isODRMember(LHS->getTag(), LHS->getRawScope(), LHS->getRawName(),
+ RHS);
+ }
+
+ /// Subprograms compare equal if they declare the same function in an ODR
+ /// type.
+ static bool isODRMember(unsigned Tag, const Metadata *Scope,
+ const MDString *Name, const DIDerivedType *RHS) {
+ // Check whether the LHS is eligible.
+ if (Tag != dwarf::DW_TAG_member || !Name || !Scope || !isa<MDString>(Scope))
+ return false;
+
+ // Compare to the RHS.
+ return Tag == RHS->getTag() && Name == RHS->getRawName() &&
+ Scope == RHS->getRawScope();
+ }
+};
+
template <> struct MDNodeKeyImpl<DICompositeType> {
unsigned Tag;
MDString *Name;
@@ -537,6 +568,12 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
Variables == RHS->getRawVariables();
}
unsigned getHashValue() const {
+ // If this is a declaration inside an ODR type, only hash the type and the
+ // name. Otherwise the hash will be stronger than
+ // MDNodeSubsetEqualImpl::isDeclarationOfODRMember().
+ if (!IsDefinition && LinkageName && Scope && isa<MDString>(Scope))
+ return hash_combine(LinkageName, Scope);
+
// Intentionally computes the hash on a subset of the operands for
// performance reason. The subset has to be significant enough to avoid
// collision "most of the time". There is no correctness issue in case of
@@ -545,6 +582,33 @@ template <> struct MDNodeKeyImpl<DISubprogram> {
}
};
+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);
+ }
+ static bool isSubsetEqual(const DISubprogram *LHS, const DISubprogram *RHS) {
+ return isDeclarationOfODRMember(LHS->isDefinition(), LHS->getRawScope(),
+ LHS->getRawLinkageName(), 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 DISubprogram *RHS) {
+ // Check whether the LHS is eligible.
+ if (IsDefinition || !Scope || !LinkageName || !Scope ||
+ !isa<MDString>(Scope))
+ return false;
+
+ // Compare to the RHS.
+ return IsDefinition == RHS->isDefinition() && Scope == RHS->getRawScope() &&
+ LinkageName == RHS->getRawLinkageName();
+ }
+};
+
template <> struct MDNodeKeyImpl<DILexicalBlock> {
Metadata *Scope;
Metadata *File;
OpenPOWER on IntegriCloud