<div dir="ltr">Looks like this should also be done for ThinLTO, and your changes to gold-plugin and llvm-link cover the ThinLTO case through those tools. I think to cover the rest of the ThinLTO cases we need to call <span style="font-size:12.8px">ensureDITypeMap() in these cases:</span><div><span style="font-size:12.8px">1) For libLTO via ThinLTOCodeGenerator.cpp: where the backend threads are creat</span>ed with new contexts in ThinLTOCodeGenerator::run</div><div>2) For opt, which can add the function import pass (maybe the same way you have this done in llvm-link, by default with an option to disable?).</div><div>3) When launching backend threads in separate processes for distributed builds, via the clang -fthinlto-index= option. I think we would call your new routine in BackendUtil.cpp where it checks if CodeGenOpts.ThinLTOIndexFile.empty and if so build the index.</div><div><br></div><div>Let me know if that sounds right, I can add the calls.</div><div><br></div><div>Thanks,</div><div>Teresa</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Apr 16, 2016 at 8:58 PM, Duncan P. N. Exon Smith via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dexonsmith<br>
Date: Sat Apr 16 22:58:21 2016<br>
New Revision: 266549<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=266549&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=266549&view=rev</a><br>
Log:<br>
IR: Use an explicit map for debug info type uniquing<br>
<br>
Rather than relying on the structural equivalence of DICompositeType to<br>
merge type definitions, use an explicit map on the LLVMContext that<br>
LLParser and BitcodeReader consult when constructing new nodes.<br>
Each non-forward-declaration DICompositeType with a non-empty<br>
'identifier:' field is stored/loaded from the type map, and the first<br>
definiton will "win".<br>
<br>
This map is opt-in: clients that expect ODR types from different modules<br>
to be merged must call LLVMContext::ensureDITypeMap.<br>
<br>
- Clients that just happen to load more than one Module in the same<br>
LLVMContext won't magically merge types.<br>
<br>
- Clients (like LTO) that want to continue to merge types based on ODR<br>
identifiers should opt-in immediately.<br>
<br>
I have updated LTOCodeGenerator.cpp, the two "linking" spots in<br>
gold-plugin.cpp, and llvm-link (unless -disable-debug-info-type-map) to<br>
set this.<br>
<br>
With this in place, it will be straightforward to remove the DITypeRef<br>
concept (i.e., referencing types by their 'identifier:' string rather<br>
than pointing at them directly).<br>
<br>
Added:<br>
llvm/trunk/test/Linker/Inputs/dicompositetype-unique.ll<br>
llvm/trunk/test/Linker/dicompositetype-unique.ll<br>
llvm/trunk/unittests/IR/LLVMContextTest.cpp<br>
Modified:<br>
llvm/trunk/docs/LangRef.rst<br>
llvm/trunk/include/llvm/IR/LLVMContext.h<br>
llvm/trunk/lib/AsmParser/LLParser.cpp<br>
llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp<br>
llvm/trunk/lib/IR/DebugInfoMetadata.cpp<br>
llvm/trunk/lib/IR/LLVMContext.cpp<br>
llvm/trunk/lib/IR/LLVMContextImpl.h<br>
llvm/trunk/lib/LTO/LTOCodeGenerator.cpp<br>
llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp<br>
llvm/trunk/tools/gold/gold-plugin.cpp<br>
llvm/trunk/tools/llvm-link/llvm-link.cpp<br>
llvm/trunk/unittests/IR/CMakeLists.txt<br>
<br>
Modified: llvm/trunk/docs/LangRef.rst<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=266549&r1=266548&r2=266549&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/LangRef.rst?rev=266549&r1=266548&r2=266549&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/docs/LangRef.rst (original)<br>
+++ llvm/trunk/docs/LangRef.rst Sat Apr 16 22:58:21 2016<br>
@@ -4006,6 +4006,11 @@ identifier used for type merging between<br>
can refer to composite types indirectly via a :ref:`metadata string<br>
<metadata-string>` that matches their identifier.<br>
<br>
+For a given ``identifier:``, there should only be a single composite type that<br>
+does not have ``flags: DIFlagFwdDecl`` set. LLVM tools that link modules<br>
+together will unique such definitions at parse time via the ``identifier:``<br>
+field, even if the nodes are ``distinct``.<br>
+<br>
.. code-block:: llvm<br>
<br>
!0 = !DIEnumerator(name: "SixKind", value: 7)<br>
<br>
Modified: llvm/trunk/include/llvm/IR/LLVMContext.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/LLVMContext.h?rev=266549&r1=266548&r2=266549&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/LLVMContext.h?rev=266549&r1=266548&r2=266549&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/LLVMContext.h (original)<br>
+++ llvm/trunk/include/llvm/IR/LLVMContext.h Sat Apr 16 22:58:21 2016<br>
@@ -25,6 +25,8 @@ class StringRef;<br>
class Twine;<br>
class Instruction;<br>
class Module;<br>
+class MDString;<br>
+class DIType;<br>
class SMDiagnostic;<br>
class DiagnosticInfo;<br>
template <typename T> class SmallVectorImpl;<br>
@@ -113,6 +115,23 @@ public:<br>
/// especially in release mode.<br>
void setDiscardValueNames(bool Discard);<br>
<br>
+ /// Whether there is a string map for uniquing debug info types with<br>
+ /// identifiers across the context. Off by default.<br>
+ bool hasDITypeMap() const;<br>
+ void ensureDITypeMap();<br>
+ void destroyDITypeMap();<br>
+<br>
+ /// Get or insert the DIType mapped to the given string.<br>
+ ///<br>
+ /// Returns the address of the current \a DIType pointer mapped to \c S,<br>
+ /// inserting a mapping to \c nullptr if \c S was not previously mapped.<br>
+ /// This method has no effect (and returns \c nullptr instead of a valid<br>
+ /// address) if \a hasDITypeMap() is \c false.<br>
+ ///<br>
+ /// \post If \a hasDITypeMap(), \c S will have a (possibly null) mapping.<br>
+ /// \note The returned address is only valid until the next call.<br>
+ DIType **getOrInsertDITypeMapping(const MDString &S);<br>
+<br>
typedef void (*InlineAsmDiagHandlerTy)(const SMDiagnostic&, void *Context,<br>
unsigned LocCookie);<br>
<br>
<br>
Modified: llvm/trunk/lib/AsmParser/LLParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=266549&r1=266548&r2=266549&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=266549&r1=266548&r2=266549&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)<br>
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Sat Apr 16 22:58:21 2016<br>
@@ -3839,11 +3839,25 @@ bool LLParser::ParseDICompositeType(MDNo<br>
PARSE_MD_FIELDS();<br>
#undef VISIT_MD_FIELDS<br>
<br>
+ // If this isn't a forward declaration and it has a UUID, check for it in the<br>
+ // type map in the context.<br>
+ DIType **MappedT = nullptr;<br>
+ if (!(flags.Val & DINode::FlagFwdDecl) && identifier.Val &&<br>
+ (MappedT = Context.getOrInsertDITypeMapping(*identifier.Val)) &&<br>
+ *MappedT) {<br>
+ Result = *MappedT;<br>
+ return false;<br>
+ }<br>
+<br>
+ // Create a new node, and save it in the context if it belongs in the type<br>
+ // map.<br>
Result = GET_OR_DISTINCT(<br>
DICompositeType,<br>
(Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,<br>
size.Val, align.Val, offset.Val, flags.Val, elements.Val,<br>
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val));<br>
+ if (MappedT)<br>
+ *MappedT = cast<DIType>(Result);<br>
return false;<br>
}<br>
<br>
<br>
Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=266549&r1=266548&r2=266549&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=266549&r1=266548&r2=266549&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)<br>
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Sat Apr 16 22:58:21 2016<br>
@@ -2188,16 +2188,29 @@ std::error_code BitcodeReader::parseMeta<br>
if (Record.size() != 16)<br>
return error("Invalid record");<br>
<br>
- MetadataList.assignValue(<br>
- GET_OR_DISTINCT(DICompositeType, Record[0],<br>
- (Context, Record[1], getMDString(Record[2]),<br>
- getMDOrNull(Record[3]), Record[4],<br>
- getMDOrNull(Record[5]), getMDOrNull(Record[6]),<br>
- Record[7], Record[8], Record[9], Record[10],<br>
- getMDOrNull(Record[11]), Record[12],<br>
- getMDOrNull(Record[13]), getMDOrNull(Record[14]),<br>
- getMDString(Record[15]))),<br>
- NextMetadataNo++);<br>
+ // If we have a UUID and this is not a forward declaration, lookup the<br>
+ // mapping.<br>
+ unsigned Flags = Record[10];<br>
+ auto *Identifier = getMDString(Record[15]);<br>
+ DIType **MappedT = nullptr;<br>
+ if (!(Flags & DINode::FlagFwdDecl) && Identifier)<br>
+ MappedT = Context.getOrInsertDITypeMapping(*Identifier);<br>
+<br>
+ // Use the mapped type node, or create a new one if necessary.<br>
+ DIType *CT = MappedT ? *MappedT : nullptr;<br>
+ if (!CT) {<br>
+ CT = GET_OR_DISTINCT(<br>
+ DICompositeType, Record[0],<br>
+ (Context, Record[1], getMDString(Record[2]), getMDOrNull(Record[3]),<br>
+ Record[4], getMDOrNull(Record[5]), getMDOrNull(Record[6]),<br>
+ Record[7], Record[8], Record[9], Flags, getMDOrNull(Record[11]),<br>
+ Record[12], getMDOrNull(Record[13]), getMDOrNull(Record[14]),<br>
+ Identifier));<br>
+ if (MappedT)<br>
+ *MappedT = CT;<br>
+ }<br>
+<br>
+ MetadataList.assignValue(CT, NextMetadataNo++);<br>
break;<br>
}<br>
case bitc::METADATA_SUBROUTINE_TYPE: {<br>
<br>
Modified: llvm/trunk/lib/IR/DebugInfoMetadata.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DebugInfoMetadata.cpp?rev=266549&r1=266548&r2=266549&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DebugInfoMetadata.cpp?rev=266549&r1=266548&r2=266549&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/DebugInfoMetadata.cpp (original)<br>
+++ llvm/trunk/lib/IR/DebugInfoMetadata.cpp Sat Apr 16 22:58:21 2016<br>
@@ -254,6 +254,7 @@ DICompositeType *DICompositeType::getImp<br>
Metadata *TemplateParams, MDString *Identifier, StorageType Storage,<br>
bool ShouldCreate) {<br>
assert(isCanonical(Name) && "Expected canonical MDString");<br>
+<br>
DEFINE_GETIMPL_LOOKUP(<br>
DICompositeType, (Tag, Name, File, Line, Scope, BaseType, SizeInBits,<br>
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,<br>
<br>
Modified: llvm/trunk/lib/IR/LLVMContext.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContext.cpp?rev=266549&r1=266548&r2=266549&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContext.cpp?rev=266549&r1=266548&r2=266549&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/LLVMContext.cpp (original)<br>
+++ llvm/trunk/lib/IR/LLVMContext.cpp Sat Apr 16 22:58:21 2016<br>
@@ -311,6 +311,23 @@ bool LLVMContext::shouldDiscardValueName<br>
return pImpl->DiscardValueNames;<br>
}<br>
<br>
+bool LLVMContext::hasDITypeMap() const { return !!pImpl->DITypeMap; }<br>
+<br>
+void LLVMContext::ensureDITypeMap() {<br>
+ if (pImpl->DITypeMap)<br>
+ return;<br>
+<br>
+ pImpl->DITypeMap = llvm::make_unique<DenseMap<const MDString *, DIType *>>();<br>
+}<br>
+<br>
+void LLVMContext::destroyDITypeMap() { pImpl->DITypeMap.reset(); }<br>
+<br>
+DIType **LLVMContext::getOrInsertDITypeMapping(const MDString &S) {<br>
+ if (!hasDITypeMap())<br>
+ return nullptr;<br>
+ return &(*pImpl->DITypeMap)[&S];<br>
+}<br>
+<br>
void LLVMContext::setDiscardValueNames(bool Discard) {<br>
pImpl->DiscardValueNames = Discard;<br>
}<br>
<br>
Modified: llvm/trunk/lib/IR/LLVMContextImpl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=266549&r1=266548&r2=266549&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=266549&r1=266548&r2=266549&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/LLVMContextImpl.h (original)<br>
+++ llvm/trunk/lib/IR/LLVMContextImpl.h Sat Apr 16 22:58:21 2016<br>
@@ -1022,6 +1022,9 @@ public:<br>
DenseSet<CLASS *, CLASS##Info> CLASS##s;<br>
#include "llvm/IR/Metadata.def"<br>
<br>
+ // Optional map for looking up composite types by identifier.<br>
+ std::unique_ptr<DenseMap<const MDString *, DIType *>> DITypeMap;<br>
+<br>
// MDNodes may be uniqued or not uniqued. When they're not uniqued, they<br>
// aren't in the MDNodeSet, but they're still shared between objects, so no<br>
// one object can destroy them. This set allows us to at least destroy them<br>
<br>
Modified: llvm/trunk/lib/LTO/LTOCodeGenerator.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=266549&r1=266548&r2=266549&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/LTO/LTOCodeGenerator.cpp?rev=266549&r1=266548&r2=266549&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/LTO/LTOCodeGenerator.cpp (original)<br>
+++ llvm/trunk/lib/LTO/LTOCodeGenerator.cpp Sat Apr 16 22:58:21 2016<br>
@@ -84,6 +84,7 @@ LTOCodeGenerator::LTOCodeGenerator(LLVMC<br>
: Context(Context), MergedModule(new Module("ld-temp.o", Context)),<br>
TheLinker(new Linker(*MergedModule)) {<br>
Context.setDiscardValueNames(LTODiscardValueNames);<br>
+ Context.ensureDITypeMap();<br>
initializeLTOPasses();<br>
}<br>
<br>
<br>
Modified: llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp?rev=266549&r1=266548&r2=266549&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp?rev=266549&r1=266548&r2=266549&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp Sat Apr 16 22:58:21 2016<br>
@@ -15,6 +15,7 @@<br>
#include "llvm/Transforms/Utils/ValueMapper.h"<br>
#include "llvm/IR/CallSite.h"<br>
#include "llvm/IR/Constants.h"<br>
+#include "llvm/IR/DebugInfoMetadata.h"<br>
#include "llvm/IR/Function.h"<br>
#include "llvm/IR/GlobalAlias.h"<br>
#include "llvm/IR/GlobalVariable.h"<br>
<br>
Added: llvm/trunk/test/Linker/Inputs/dicompositetype-unique.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/Inputs/dicompositetype-unique.ll?rev=266549&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/Inputs/dicompositetype-unique.ll?rev=266549&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/Linker/Inputs/dicompositetype-unique.ll (added)<br>
+++ llvm/trunk/test/Linker/Inputs/dicompositetype-unique.ll Sat Apr 16 22:58:21 2016<br>
@@ -0,0 +1,4 @@<br>
+!named = !{!0, !1}<br>
+<br>
+!0 = !DIFile(filename: "abc", directory: "/path/to")<br>
+!1 = !DICompositeType(tag: DW_TAG_class_type, name: "T2", identifier: "T", file: !0)<br>
<br>
Added: llvm/trunk/test/Linker/dicompositetype-unique.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/dicompositetype-unique.ll?rev=266549&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Linker/dicompositetype-unique.ll?rev=266549&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/test/Linker/dicompositetype-unique.ll (added)<br>
+++ llvm/trunk/test/Linker/dicompositetype-unique.ll Sat Apr 16 22:58:21 2016<br>
@@ -0,0 +1,42 @@<br>
+; RUN: llvm-link -S -o - %s %S/Inputs/dicompositetype-unique.ll \<br>
+; RUN: | FileCheck %s<br>
+; RUN: llvm-link -S -o - %S/Inputs/dicompositetype-unique.ll %s \<br>
+; RUN: | FileCheck %s -check-prefix REVERSE<br>
+; RUN: llvm-link -disable-debug-info-type-map -S -o - %s %S/Inputs/dicompositetype-unique.ll \<br>
+; RUN: | FileCheck %s -check-prefix NOMAP<br>
+<br>
+; Check that the bitcode reader handles this too.<br>
+; RUN: llvm-as -o %t1.bc <%s<br>
+; RUN: llvm-as -o %t2.bc <%S/Inputs/dicompositetype-unique.ll<br>
+; RUN: llvm-link -S -o - %t1.bc %t2.bc | FileCheck %s<br>
+; RUN: llvm-link -S -o - %t2.bc %t1.bc | FileCheck %s -check-prefix REVERSE<br>
+; RUN: llvm-link -disable-debug-info-type-map -S -o - %t1.bc %t2.bc \<br>
+; RUN: | FileCheck %s -check-prefix NOMAP<br>
+<br>
+; Check that the type map will unique two DICompositeTypes.<br>
+<br>
+; CHECK: !named = !{!0, !1, !0, !1}<br>
+; REVERSE: !named = !{!0, !1, !0, !1}<br>
+; NOMAP: !named = !{!0, !1, !0, !2}<br>
+!named = !{!0, !1}<br>
+<br>
+; Check both directions.<br>
+; CHECK: !1 = !DICompositeType(<br>
+; CHECK-SAME: name: "T1"<br>
+; CHECK-SAME: identifier: "T"<br>
+; CHECK-NOT: identifier: "T"<br>
+; REVERSE: !1 = !DICompositeType(<br>
+; REVERSE-SAME: name: "T2"<br>
+; REVERSE-SAME: identifier: "T"<br>
+; REVERSE-NOT: identifier: "T"<br>
+<br>
+; These types are different, so we should get both copies when there is no map.<br>
+; NOMAP: !1 = !DICompositeType(<br>
+; NOMAP-SAME: name: "T1"<br>
+; NOMAP-SAME: identifier: "T"<br>
+; NOMAP: !2 = !DICompositeType(<br>
+; NOMAP-SAME: name: "T2"<br>
+; NOMAP-SAME: identifier: "T"<br>
+; NOMAP-NOT: identifier: "T"<br>
+!0 = !DIFile(filename: "abc", directory: "/path/to")<br>
+!1 = !DICompositeType(tag: DW_TAG_class_type, name: "T1", identifier: "T", file: !0)<br>
<br>
Modified: llvm/trunk/tools/gold/gold-plugin.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/gold/gold-plugin.cpp?rev=266549&r1=266548&r2=266549&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/gold/gold-plugin.cpp?rev=266549&r1=266548&r2=266549&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/gold/gold-plugin.cpp (original)<br>
+++ llvm/trunk/tools/gold/gold-plugin.cpp Sat Apr 16 22:58:21 2016<br>
@@ -1110,6 +1110,7 @@ static void thinLTOBackendTask(claimed_f<br>
raw_fd_ostream *OS, unsigned TaskID) {<br>
// Need to use a separate context for each task<br>
LLVMContext Context;<br>
+ Context.ensureDITypeMap(); // Merge debug info types.<br>
Context.setDiagnosticHandler(diagnosticHandlerForContext, nullptr, true);<br>
<br>
std::unique_ptr<llvm::Module> NewModule(new llvm::Module(File.name, Context));<br>
@@ -1231,6 +1232,7 @@ static ld_plugin_status allSymbolsReadHo<br>
}<br>
<br>
LLVMContext Context;<br>
+ Context.ensureDITypeMap(); // Merge debug info types.<br>
Context.setDiagnosticHandler(diagnosticHandlerForContext, nullptr, true);<br>
<br>
std::unique_ptr<Module> Combined(new Module("ld-temp.o", Context));<br>
<br>
Modified: llvm/trunk/tools/llvm-link/llvm-link.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-link/llvm-link.cpp?rev=266549&r1=266548&r2=266549&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-link/llvm-link.cpp?rev=266549&r1=266548&r2=266549&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/llvm-link/llvm-link.cpp (original)<br>
+++ llvm/trunk/tools/llvm-link/llvm-link.cpp Sat Apr 16 22:58:21 2016<br>
@@ -71,6 +71,10 @@ static cl::opt<bool><br>
Internalize("internalize", cl::desc("Internalize linked symbols"));<br>
<br>
static cl::opt<bool><br>
+ DisableDITypeMap("disable-debug-info-type-map",<br>
+ cl::desc("Don't use a uniquing type map for debug info"));<br>
+<br>
+static cl::opt<bool><br>
OnlyNeeded("only-needed", cl::desc("Link only needed symbols"));<br>
<br>
static cl::opt<bool><br>
@@ -337,6 +341,9 @@ int main(int argc, char **argv) {<br>
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.<br>
cl::ParseCommandLineOptions(argc, argv, "llvm linker\n");<br>
<br>
+ if (!DisableDITypeMap)<br>
+ Context.ensureDITypeMap();<br>
+<br>
auto Composite = make_unique<Module>("llvm-link", Context);<br>
Linker L(*Composite);<br>
<br>
<br>
Modified: llvm/trunk/unittests/IR/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/CMakeLists.txt?rev=266549&r1=266548&r2=266549&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/CMakeLists.txt?rev=266549&r1=266548&r2=266549&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/IR/CMakeLists.txt (original)<br>
+++ llvm/trunk/unittests/IR/CMakeLists.txt Sat Apr 16 22:58:21 2016<br>
@@ -16,6 +16,7 @@ set(IRSources<br>
IRBuilderTest.cpp<br>
InstructionsTest.cpp<br>
IntrinsicsTest.cpp<br>
+ LLVMContextTest.cpp<br>
LegacyPassManagerTest.cpp<br>
MDBuilderTest.cpp<br>
MetadataTest.cpp<br>
<br>
Added: llvm/trunk/unittests/IR/LLVMContextTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/LLVMContextTest.cpp?rev=266549&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/IR/LLVMContextTest.cpp?rev=266549&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/IR/LLVMContextTest.cpp (added)<br>
+++ llvm/trunk/unittests/IR/LLVMContextTest.cpp Sat Apr 16 22:58:21 2016<br>
@@ -0,0 +1,57 @@<br>
+//===- LLVMContextTest.cpp - LLVMContext unit tests -----------------------===//<br>
+//<br>
+// The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/IR/LLVMContext.h"<br>
+#include "llvm/IR/DebugInfoMetadata.h"<br>
+#include "gtest/gtest.h"<br>
+using namespace llvm;<br>
+<br>
+namespace {<br>
+<br>
+TEST(LLVMContextTest, ensureDITypeMap) {<br>
+ LLVMContext Context;<br>
+ EXPECT_FALSE(Context.hasDITypeMap());<br>
+ Context.ensureDITypeMap();<br>
+ EXPECT_TRUE(Context.hasDITypeMap());<br>
+ Context.destroyDITypeMap();<br>
+ EXPECT_FALSE(Context.hasDITypeMap());<br>
+}<br>
+<br>
+TEST(LLVMContextTest, getOrInsertDITypeMapping) {<br>
+ LLVMContext Context;<br>
+ const MDString &S = *MDString::get(Context, "string");<br>
+<br>
+ // Without a type map, this should return null.<br>
+ EXPECT_FALSE(Context.getOrInsertDITypeMapping(S));<br>
+<br>
+ // Get the mapping.<br>
+ Context.ensureDITypeMap();<br>
+ DIType **Mapping = Context.getOrInsertDITypeMapping(S);<br>
+ ASSERT_TRUE(Mapping);<br>
+<br>
+ // Create some type and add it to the mapping.<br>
+ auto &BT =<br>
+ *DIBasicType::get(Context, dwarf::DW_TAG_unspecified_type, S.getString());<br>
+ *Mapping = &BT;<br>
+<br>
+ // Check that we get it back.<br>
+ Mapping = Context.getOrInsertDITypeMapping(S);<br>
+ ASSERT_TRUE(Mapping);<br>
+ EXPECT_EQ(&BT, *Mapping);<br>
+<br>
+ // Check that it's discarded with the type map.<br>
+ Context.destroyDITypeMap();<br>
+ EXPECT_FALSE(Context.getOrInsertDITypeMapping(S));<br>
+<br>
+ // And it shouldn't magically reappear...<br>
+ Context.ensureDITypeMap();<br>
+ EXPECT_FALSE(*Context.getOrInsertDITypeMapping(S));<br>
+}<br>
+<br>
+} // end namespace<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><span style="font-family:Times;font-size:medium"><table cellspacing="0" cellpadding="0"><tbody><tr style="color:rgb(85,85,85);font-family:sans-serif;font-size:small"><td nowrap style="border-top-style:solid;border-top-color:rgb(213,15,37);border-top-width:2px">Teresa Johnson |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(51,105,232);border-top-width:2px"> Software Engineer |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(0,153,57);border-top-width:2px"> <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(238,178,17);border-top-width:2px"> 408-460-2413</td></tr></tbody></table></span></div>
</div>