summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-04-17 03:58:21 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-04-17 03:58:21 +0000
commit5ab2be094e9b1e75a91b214a214d07e58aacef53 (patch)
treef95cbcc8b7e39181f9ae9e9983c5bed8c5f49496 /llvm/lib
parent05ebfd09382b8dc8cd26eaf8fb91fb73ce48290e (diff)
downloadbcm5719-llvm-5ab2be094e9b1e75a91b214a214d07e58aacef53.tar.gz
bcm5719-llvm-5ab2be094e9b1e75a91b214a214d07e58aacef53.zip
IR: Use an explicit map for debug info type uniquing
Rather than relying on the structural equivalence of DICompositeType to merge type definitions, use an explicit map on the LLVMContext that LLParser and BitcodeReader consult when constructing new nodes. Each non-forward-declaration DICompositeType with a non-empty 'identifier:' field is stored/loaded from the type map, and the first definiton will "win". This map is opt-in: clients that expect ODR types from different modules to be merged must call LLVMContext::ensureDITypeMap. - Clients that just happen to load more than one Module in the same LLVMContext won't magically merge types. - Clients (like LTO) that want to continue to merge types based on ODR identifiers should opt-in immediately. I have updated LTOCodeGenerator.cpp, the two "linking" spots in gold-plugin.cpp, and llvm-link (unless -disable-debug-info-type-map) to set this. With this in place, it will be straightforward to remove the DITypeRef concept (i.e., referencing types by their 'identifier:' string rather than pointing at them directly). llvm-svn: 266549
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp14
-rw-r--r--llvm/lib/Bitcode/Reader/BitcodeReader.cpp33
-rw-r--r--llvm/lib/IR/DebugInfoMetadata.cpp1
-rw-r--r--llvm/lib/IR/LLVMContext.cpp17
-rw-r--r--llvm/lib/IR/LLVMContextImpl.h3
-rw-r--r--llvm/lib/LTO/LTOCodeGenerator.cpp1
-rw-r--r--llvm/lib/Transforms/Utils/ValueMapper.cpp1
7 files changed, 60 insertions, 10 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index c72b7196195..34f7ec4469b 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -3839,11 +3839,25 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
+ // If this isn't a forward declaration and it has a UUID, check for it in the
+ // type map in the context.
+ DIType **MappedT = nullptr;
+ if (!(flags.Val & DINode::FlagFwdDecl) && identifier.Val &&
+ (MappedT = Context.getOrInsertDITypeMapping(*identifier.Val)) &&
+ *MappedT) {
+ Result = *MappedT;
+ return false;
+ }
+
+ // Create a new node, and save it in the context if it belongs in the type
+ // map.
Result = GET_OR_DISTINCT(
DICompositeType,
(Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val));
+ if (MappedT)
+ *MappedT = cast<DIType>(Result);
return false;
}
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
index ad14cbc998d..18386ed0727 100644
--- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
+++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp
@@ -2188,16 +2188,29 @@ std::error_code BitcodeReader::parseMetadata(bool ModuleLevel) {
if (Record.size() != 16)
return error("Invalid record");
- MetadataList.assignValue(
- GET_OR_DISTINCT(DICompositeType, Record[0],
- (Context, Record[1], getMDString(Record[2]),
- getMDOrNull(Record[3]), Record[4],
- getMDOrNull(Record[5]), getMDOrNull(Record[6]),
- Record[7], Record[8], Record[9], Record[10],
- getMDOrNull(Record[11]), Record[12],
- getMDOrNull(Record[13]), getMDOrNull(Record[14]),
- getMDString(Record[15]))),
- NextMetadataNo++);
+ // If we have a UUID and this is not a forward declaration, lookup the
+ // mapping.
+ unsigned Flags = Record[10];
+ auto *Identifier = getMDString(Record[15]);
+ DIType **MappedT = nullptr;
+ if (!(Flags & DINode::FlagFwdDecl) && Identifier)
+ MappedT = Context.getOrInsertDITypeMapping(*Identifier);
+
+ // Use the mapped type node, or create a new one if necessary.
+ DIType *CT = MappedT ? *MappedT : nullptr;
+ if (!CT) {
+ CT = GET_OR_DISTINCT(
+ DICompositeType, Record[0],
+ (Context, Record[1], getMDString(Record[2]), getMDOrNull(Record[3]),
+ Record[4], getMDOrNull(Record[5]), getMDOrNull(Record[6]),
+ Record[7], Record[8], Record[9], Flags, getMDOrNull(Record[11]),
+ Record[12], getMDOrNull(Record[13]), getMDOrNull(Record[14]),
+ Identifier));
+ if (MappedT)
+ *MappedT = CT;
+ }
+
+ MetadataList.assignValue(CT, NextMetadataNo++);
break;
}
case bitc::METADATA_SUBROUTINE_TYPE: {
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index 80c83140ee3..3e6400785fd 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -254,6 +254,7 @@ DICompositeType *DICompositeType::getImpl(
Metadata *TemplateParams, MDString *Identifier, StorageType Storage,
bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
+
DEFINE_GETIMPL_LOOKUP(
DICompositeType, (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
diff --git a/llvm/lib/IR/LLVMContext.cpp b/llvm/lib/IR/LLVMContext.cpp
index 0e8d3e826aa..3fc79ed03c3 100644
--- a/llvm/lib/IR/LLVMContext.cpp
+++ b/llvm/lib/IR/LLVMContext.cpp
@@ -311,6 +311,23 @@ bool LLVMContext::shouldDiscardValueNames() const {
return pImpl->DiscardValueNames;
}
+bool LLVMContext::hasDITypeMap() const { return !!pImpl->DITypeMap; }
+
+void LLVMContext::ensureDITypeMap() {
+ if (pImpl->DITypeMap)
+ return;
+
+ pImpl->DITypeMap = llvm::make_unique<DenseMap<const MDString *, DIType *>>();
+}
+
+void LLVMContext::destroyDITypeMap() { pImpl->DITypeMap.reset(); }
+
+DIType **LLVMContext::getOrInsertDITypeMapping(const MDString &S) {
+ if (!hasDITypeMap())
+ return nullptr;
+ return &(*pImpl->DITypeMap)[&S];
+}
+
void LLVMContext::setDiscardValueNames(bool Discard) {
pImpl->DiscardValueNames = Discard;
}
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 8a2c43909b4..a535a19d653 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -1022,6 +1022,9 @@ public:
DenseSet<CLASS *, CLASS##Info> CLASS##s;
#include "llvm/IR/Metadata.def"
+ // Optional map for looking up composite types by identifier.
+ std::unique_ptr<DenseMap<const MDString *, DIType *>> DITypeMap;
+
// MDNodes may be uniqued or not uniqued. When they're not uniqued, they
// aren't in the MDNodeSet, but they're still shared between objects, so no
// one object can destroy them. This set allows us to at least destroy them
diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp
index bc500085a72..4f779d4390b 100644
--- a/llvm/lib/LTO/LTOCodeGenerator.cpp
+++ b/llvm/lib/LTO/LTOCodeGenerator.cpp
@@ -84,6 +84,7 @@ LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context)
: Context(Context), MergedModule(new Module("ld-temp.o", Context)),
TheLinker(new Linker(*MergedModule)) {
Context.setDiscardValueNames(LTODiscardValueNames);
+ Context.ensureDITypeMap();
initializeLTOPasses();
}
diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp
index a58b98bb9fb..f8fa61329e2 100644
--- a/llvm/lib/Transforms/Utils/ValueMapper.cpp
+++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp
@@ -15,6 +15,7 @@
#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/IR/CallSite.h"
#include "llvm/IR/Constants.h"
+#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalAlias.h"
#include "llvm/IR/GlobalVariable.h"
OpenPOWER on IntegriCloud