diff --git a/llvm/include/llvm/IR/Module.h b/llvm/include/llvm/IR/Module.h --- a/llvm/include/llvm/IR/Module.h +++ b/llvm/include/llvm/IR/Module.h @@ -893,6 +893,12 @@ GlobalVariable *collectUsedGlobalVariables(const Module &M, SmallPtrSetImpl &Set, bool CompilerUsed); +/// Given "llvm.used" or "llvm.compiler.used" as a global name, collect the +/// initializer elements of that global in a SmallVector and return the global +/// itself. +GlobalVariable *collectUsedGlobalVariables(const Module &M, + SmallVectorImpl &Vec, + bool CompilerUsed); /// An raw_ostream inserter for modules. inline raw_ostream &operator<<(raw_ostream &O, const Module &M) { diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -658,6 +658,21 @@ return Result; } +GlobalVariable *llvm::collectUsedGlobalVariables( + const Module &M, SmallVectorImpl &Vec, bool CompilerUsed) { + const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used"; + GlobalVariable *GV = M.getGlobalVariable(Name); + if (!GV || !GV->hasInitializer()) + return GV; + + const ConstantArray *Init = cast(GV->getInitializer()); + for (Value *Op : Init->operands()) { + GlobalValue *G = cast(Op->stripPointerCasts()); + Vec.push_back(G); + } + return GV; +} + GlobalVariable *llvm::collectUsedGlobalVariables( const Module &M, SmallPtrSetImpl &Set, bool CompilerUsed) { const char *Name = CompilerUsed ? "llvm.compiler.used" : "llvm.used"; diff --git a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp --- a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp +++ b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp @@ -199,23 +199,20 @@ // values whose defs were cloned into that module. static void cloneUsedGlobalVariables(const Module &SrcM, Module &DestM, bool CompilerUsed) { - SmallPtrSet Used; - SmallPtrSet NewUsed; + SmallVector Used, NewUsed; // First collect those in the llvm[.compiler].used set. collectUsedGlobalVariables(SrcM, Used, CompilerUsed); // Next build a set of the equivalent values defined in DestM. for (auto *V : Used) { auto *GV = DestM.getNamedValue(V->getName()); if (GV && !GV->isDeclaration()) - NewUsed.insert(GV); + NewUsed.push_back(GV); } // Finally, add them to a llvm[.compiler].used variable in DestM. if (CompilerUsed) - appendToCompilerUsed( - DestM, std::vector(NewUsed.begin(), NewUsed.end())); + appendToCompilerUsed(DestM, NewUsed); else - appendToUsed(DestM, - std::vector(NewUsed.begin(), NewUsed.end())); + appendToUsed(DestM, NewUsed); } // If it's possible to split M into regular and thin LTO parts, do so and write