Index: include/llvm/ADT/SetVector.h =================================================================== --- include/llvm/ADT/SetVector.h +++ include/llvm/ADT/SetVector.h @@ -110,6 +110,11 @@ return vector_.rend(); } + /// Get underlying set container of the SetVector. + const set_type &set() const { + return set_; + } + /// \brief Return the last element of the SetVector. const T &back() const { assert(!empty() && "Cannot call back() on empty SetVector!"); Index: include/llvm/IR/Metadata.def =================================================================== --- include/llvm/IR/Metadata.def +++ include/llvm/IR/Metadata.def @@ -13,7 +13,9 @@ #if !(defined HANDLE_METADATA || defined HANDLE_METADATA_LEAF || \ defined HANDLE_METADATA_BRANCH || defined HANDLE_MDNODE_LEAF || \ - defined HANDLE_MDNODE_LEAF_UNIQUABLE || defined HANDLE_MDNODE_BRANCH || \ + defined HANDLE_MDNODE_LEAF_UNIQUABLE || \ + defined HANDLE_MDNODE_LEAF_UNIQUABLE_VECTOR || \ + defined HANDLE_MDNODE_BRANCH || \ defined HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE || \ defined HANDLE_SPECIALIZED_MDNODE_LEAF || \ defined HANDLE_SPECIALIZED_MDNODE_BRANCH) @@ -53,6 +55,21 @@ #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) HANDLE_MDNODE_LEAF(CLASS) #endif +#ifndef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE_VECTOR +#ifdef HANDLE_MDNODE_LEAF_UNIQUABLE_VECTOR +#define HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE_VECTOR(CLASS) \ + HANDLE_MDNODE_LEAF_UNIQUABLE_VECTOR(CLASS) +#else +#define HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE_VECTOR(CLASS) \ + HANDLE_SPECIALIZED_MDNODE_LEAF(CLASS) +#endif +#endif + +// Handler for leaf nodes under MDNode. +#ifndef HANDLE_MDNODE_LEAF_UNIQUABLE_VECTOR +#define HANDLE_MDNODE_LEAF_UNIQUABLE_VECTOR(CLASS) HANDLE_MDNODE_LEAF(CLASS) +#endif + // Handler for leaf nodes under MDNode. #ifndef HANDLE_MDNODE_LEAF #define HANDLE_MDNODE_LEAF(CLASS) HANDLE_METADATA_LEAF(CLASS) @@ -107,7 +124,7 @@ HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIGlobalVariable) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DILocalVariable) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIObjCProperty) -HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIImportedEntity) +HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE_VECTOR(DIImportedEntity) HANDLE_SPECIALIZED_MDNODE_BRANCH(DIMacroNode) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacro) HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE(DIMacroFile) @@ -117,7 +134,9 @@ #undef HANDLE_METADATA_BRANCH #undef HANDLE_MDNODE_LEAF #undef HANDLE_MDNODE_LEAF_UNIQUABLE +#undef HANDLE_MDNODE_LEAF_UNIQUABLE_VECTOR #undef HANDLE_MDNODE_BRANCH #undef HANDLE_SPECIALIZED_MDNODE_LEAF #undef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE +#undef HANDLE_SPECIALIZED_MDNODE_LEAF_UNIQUABLE_VECTOR #undef HANDLE_SPECIALIZED_MDNODE_BRANCH Index: lib/IR/DIBuilder.cpp =================================================================== --- lib/IR/DIBuilder.cpp +++ lib/IR/DIBuilder.cpp @@ -19,6 +19,7 @@ #include "llvm/IR/Module.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Dwarf.h" +#include "LLVMContextImpl.h" using namespace llvm; using namespace llvm::dwarf; @@ -110,10 +111,11 @@ if (!AllGVs.empty()) CUNode->replaceGlobalVariables(MDTuple::get(VMContext, AllGVs)); - if (!AllImportedModules.empty()) + if (!VMContext.pImpl->DIImportedEntitys.empty()) CUNode->replaceImportedEntities(MDTuple::get( - VMContext, SmallVector(AllImportedModules.begin(), - AllImportedModules.end()))); + VMContext, SmallVector( + VMContext.pImpl->DIImportedEntitys.begin(), + VMContext.pImpl->DIImportedEntitys.end()))); // Now that all temp nodes have been replaced or deleted, resolve remaining // cycles. @@ -166,10 +168,8 @@ static DIImportedEntity * createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope *Context, - Metadata *NS, unsigned Line, StringRef Name, - SmallVectorImpl &AllImportedModules) { + Metadata *NS, unsigned Line, StringRef Name) { auto *M = DIImportedEntity::get(C, Tag, Context, DINodeRef(NS), Line, Name); - AllImportedModules.emplace_back(M); return M; } @@ -177,20 +177,20 @@ DINamespace *NS, unsigned Line) { return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, - Context, NS, Line, StringRef(), AllImportedModules); + Context, NS, Line, StringRef()); } DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DIImportedEntity *NS, unsigned Line) { return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, - Context, NS, Line, StringRef(), AllImportedModules); + Context, NS, Line, StringRef()); } DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DIModule *M, unsigned Line) { return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module, - Context, M, Line, StringRef(), AllImportedModules); + Context, M, Line, StringRef()); } DIImportedEntity *DIBuilder::createImportedDeclaration(DIScope *Context, @@ -200,8 +200,7 @@ // Make sure to use the unique identifier based metadata reference for // types that have one. return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration, - Context, DINodeRef::get(Decl), Line, Name, - AllImportedModules); + Context, DINodeRef::get(Decl), Line, Name); } DIFile *DIBuilder::createFile(StringRef Filename, StringRef Directory) { Index: lib/IR/LLVMContextImpl.h =================================================================== --- lib/IR/LLVMContextImpl.h +++ lib/IR/LLVMContextImpl.h @@ -24,6 +24,7 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/Hashing.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringMap.h" #include "llvm/IR/Constants.h" @@ -933,6 +934,9 @@ #define HANDLE_MDNODE_LEAF_UNIQUABLE(CLASS) \ DenseSet CLASS##s; +#define HANDLE_MDNODE_LEAF_UNIQUABLE_VECTOR(CLASS) \ + SetVector, DenseSet > \ + CLASS##s; #include "llvm/IR/Metadata.def" // MDNodes may be uniqued or not uniqued. When they're not uniqued, they Index: lib/IR/Metadata.cpp =================================================================== --- lib/IR/Metadata.cpp +++ lib/IR/Metadata.cpp @@ -705,6 +705,15 @@ return N; } +template +static T *uniquifyImpl(T *N, SetVector < T *, std::vector, + DenseSet> &Store) { + if (T *U = getUniqued(Store, N)) + return U; + Store.insert(N); + return N; +} + template struct MDNode::HasCachedHash { typedef char Yes[1]; typedef char No[2]; @@ -732,6 +741,14 @@ dispatchRecalculateHash(SubclassThis, ShouldRecalculateHash); \ return uniquifyImpl(SubclassThis, getContext().pImpl->CLASS##s); \ } +#define HANDLE_MDNODE_LEAF_UNIQUABLE_VECTOR(CLASS) \ + case CLASS##Kind: { \ + CLASS *SubclassThis = cast(this); \ + std::integral_constant::value> \ + ShouldRecalculateHash; \ + dispatchRecalculateHash(SubclassThis, ShouldRecalculateHash); \ + return uniquifyImpl(SubclassThis, getContext().pImpl->CLASS##s); \ + } #include "llvm/IR/Metadata.def" } } @@ -744,6 +761,10 @@ case CLASS##Kind: \ getContext().pImpl->CLASS##s.erase(cast(this)); \ break; +#define HANDLE_MDNODE_LEAF_UNIQUABLE_VECTOR(CLASS) \ + case CLASS##Kind: \ + getContext().pImpl->CLASS##s.remove(cast(this)); \ + break; #include "llvm/IR/Metadata.def" } } Index: lib/IR/MetadataImpl.h =================================================================== --- lib/IR/MetadataImpl.h +++ lib/IR/MetadataImpl.h @@ -26,6 +26,14 @@ return I == Store.end() ? nullptr : *I; } +template +static T * +getUniqued(SetVector, DenseSet> &Store, +const typename InfoT::KeyTy &Key) { + auto I = Store.set().find_as(Key); + return I == Store.set().end() ? nullptr : *I; +} + template T *MDNode::storeImpl(T *N, StorageType Storage) { switch (Storage) { case Uniqued: Index: unittests/IR/IRBuilderTest.cpp =================================================================== --- unittests/IR/IRBuilderTest.cpp +++ unittests/IR/IRBuilderTest.cpp @@ -418,4 +418,19 @@ DIB.finalize(); } + +TEST_F(IRBuilderTest, DIImportedEntity) { + IRBuilder<> Builder(BB); + DIBuilder DIB(*M); + auto File = DIB.createFile("F.CBL", "/"); + auto CU = DIB.createCompileUnit(dwarf::DW_LANG_Cobol74, "F.CBL", "/", + "llvm-cobol74", true, "", 0); + auto IE1 = DIB.createImportedDeclaration(CU, nullptr, 1); + auto IE2 = DIB.createImportedDeclaration(CU, nullptr, 1); + auto IE3 = DIB.createImportedModule(CU, (DIImportedEntity*)nullptr, 2); + auto IE4 = DIB.createImportedModule(CU, (DIImportedEntity*)nullptr, 2); + DIB.finalize(); + EXPECT_TRUE(verifyModule(*M)); + EXPECT_TRUE(CU->getImportedEntities().size() == 2); +} }