diff --git a/lib/ExecutionEngine/Orc/IndirectionUtils.cpp b/lib/ExecutionEngine/Orc/IndirectionUtils.cpp index bcf22f58266..ebeedef7eae 100644 --- a/lib/ExecutionEngine/Orc/IndirectionUtils.cpp +++ b/lib/ExecutionEngine/Orc/IndirectionUtils.cpp @@ -14,6 +14,7 @@ #include "llvm/IR/CallSite.h" #include "llvm/IR/IRBuilder.h" #include +#include namespace llvm { namespace orc { @@ -51,32 +52,69 @@ void makeStub(Function &F, GlobalVariable &ImplPointer) { Builder.CreateRet(Call); } +// Utility class for renaming global values and functions during partitioning. +class GlobalRenamer { +public: + + static bool needsRenaming(const Value &New) { + if (!New.hasName() || New.getName().startswith("\01L")) + return true; + return false; + } + + const std::string& getRename(const Value &Orig) { + // See if we have a name for this global. + { + auto I = Names.find(&Orig); + if (I != Names.end()) + return I->second; + } + + // Nope. Create a new one. + // FIXME: Use a more robust uniquing scheme. (This may blow up if the user + // writes a "__orc_anon[[:digit:]]* method). + unsigned ID = Names.size(); + std::ostringstream NameStream; + NameStream << "__orc_anon" << ID++; + auto I = Names.insert(std::make_pair(&Orig, NameStream.str())); + return I.first->second; + } +private: + DenseMap Names; +}; + void partition(Module &M, const ModulePartitionMap &PMap) { + GlobalRenamer Renamer; + for (auto &KVPair : PMap) { auto ExtractGlobalVars = [&](GlobalVariable &New, const GlobalVariable &Orig, ValueToValueMapTy &VMap) { - assert(Orig.hasName() && "Extracted globals must have names."); if (KVPair.second.count(&Orig)) { copyGVInitializer(New, Orig, VMap); } if (New.hasLocalLinkage()) { + if (Renamer.needsRenaming(New)) + New.setName(Renamer.getRename(Orig)); New.setLinkage(GlobalValue::ExternalLinkage); New.setVisibility(GlobalValue::HiddenVisibility); } + assert(!Renamer.needsRenaming(New) && "Invalid global name."); }; auto ExtractFunctions = [&](Function &New, const Function &Orig, ValueToValueMapTy &VMap) { - assert(Orig.hasName() && "Extracted functions must have names."); if (KVPair.second.count(&Orig)) copyFunctionBody(New, Orig, VMap); if (New.hasLocalLinkage()) { + if (Renamer.needsRenaming(New)) + New.setName(Renamer.getRename(Orig)); New.setLinkage(GlobalValue::ExternalLinkage); New.setVisibility(GlobalValue::HiddenVisibility); } + assert(!Renamer.needsRenaming(New) && "Invalid function name."); }; CloneSubModule(*KVPair.first, M, ExtractGlobalVars, ExtractFunctions, diff --git a/test/ExecutionEngine/OrcLazy/anonymous_globals.ll b/test/ExecutionEngine/OrcLazy/anonymous_globals.ll new file mode 100644 index 00000000000..c4c09a0d5a2 --- /dev/null +++ b/test/ExecutionEngine/OrcLazy/anonymous_globals.ll @@ -0,0 +1,18 @@ +; RUN: lli -jit-kind=orc-lazy %s + +define private void @0() { +entry: + ret void +} + +define private void @"\01L_foo"() { +entry: + ret void +} + +define i32 @main(i32 %argc, i8** nocapture readnone %argv) { +entry: + call void @0() + tail call void @"\01L_foo"() + ret i32 0 +}