[llvm] r336385 - [ORC] In CompileOnDemandLayer2, clone modules on to different contexts by
Lang Hames via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 5 19:02:08 PDT 2018
Looks like Heejin Ahn fixed this in r336389. Thanks Heejin!
-- Lang.
On Thu, Jul 5, 2018 at 6:57 PM Lang Hames <lhames at gmail.com> wrote:
> It did. Sorry! Looking in to it now. I think it's just missing a
> dependency.
>
> -- Lang.
>
> On Thu, Jul 5, 2018 at 2:07 PM Sean Fertile <sfertile at ca.ibm.com> wrote:
>
>> Hi Lang,
>>
>> I think this commit broke
>> http://lab.llvm.org:8011/builders/clang-ppc64le-linux-multistage
>>
>> Thanks
>> Sean
>>
>>
>>
>> ----- Original message -----
>> From: Lang Hames via llvm-commits <llvm-commits at lists.llvm.org>
>> Sent by: "llvm-commits" <llvm-commits-bounces at lists.llvm.org>
>> To: llvm-commits at lists.llvm.org
>> Cc:
>> Subject: [llvm] r336385 - [ORC] In CompileOnDemandLayer2, clone modules
>> on to different contexts by
>> Date: Thu, Jul 5, 2018 3:06 PM
>>
>> Author: lhames
>> Date: Thu Jul 5 12:01:27 2018
>> New Revision: 336385
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=336385&view=rev
>> Log:
>> [ORC] In CompileOnDemandLayer2, clone modules on to different contexts by
>> writing them to a buffer and re-loading them.
>>
>> Also introduces a multithreaded variant of SimpleCompiler
>> (MultiThreadedSimpleCompiler) for compiling IR concurrently on multiple
>> threads.
>>
>> These changes are required to JIT IR on multiple threads correctly.
>>
>> No test case yet. I will be looking at how to modify LLI / LLJIT to test
>> multithreaded JIT support soon.
>>
>> Modified:
>> llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
>> llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileUtils.h
>> llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
>>
>> Modified:
>> llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h?rev=336385&r1=336384&r2=336385&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
>> (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h
>> Thu Jul 5 12:01:27 2018
>> @@ -93,15 +93,8 @@ private:
>> using StubManagersMap =
>> std::map<const VSO *, std::unique_ptr<IndirectStubsManager>>;
>>
>> - using SymbolNameToDefinitionMap =
>> - IRMaterializationUnit::SymbolNameToDefinitionMap;
>> -
>> IndirectStubsManager &getStubsManager(const VSO &V);
>>
>> - std::unique_ptr<Module>
>> - extractFunctions(Module &M, const SymbolNameSet &SymbolNames,
>> - const SymbolNameToDefinitionMap &SymbolToDefiniton);
>> -
>> void emitExtractedFunctionsModule(MaterializationResponsibility R,
>> std::unique_ptr<Module> M,
>> std::shared_ptr<SymbolResolver>
>> Resolver);
>>
>> Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileUtils.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileUtils.h?rev=336385&r1=336384&r2=336385&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileUtils.h (original)
>> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/CompileUtils.h Thu Jul 5
>> 12:01:27 2018
>> @@ -16,6 +16,7 @@
>>
>> #include "llvm/ADT/SmallVector.h"
>> #include "llvm/ExecutionEngine/ObjectCache.h"
>> +#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
>> #include "llvm/IR/LegacyPassManager.h"
>> #include "llvm/Object/Binary.h"
>> #include "llvm/Object/ObjectFile.h"
>> @@ -35,24 +36,10 @@ class Module;
>>
>> namespace orc {
>>
>> -/// Simple compile functor: Takes a single IR module and returns an
>> -/// ObjectFile.
>> +/// Simple compile functor: Takes a single IR module and returns an
>> ObjectFile.
>> +/// This compiler supports a single compilation thread and LLVMContext
>> only.
>> +/// For multithreaded compilation, use MultiThreadedSimpleCompiler below.
>> class SimpleCompiler {
>> -private:
>> - class SmallVectorMemoryBuffer : public MemoryBuffer {
>> - public:
>> - SmallVectorMemoryBuffer(SmallVector<char, 0> Buffer)
>> - : Buffer(std::move(Buffer)) {
>> - init(this->Buffer.data(), this->Buffer.data() +
>> this->Buffer.size(),
>> - false);
>> - }
>> -
>> - BufferKind getBufferKind() const override { return
>> MemoryBuffer_Malloc; }
>> -
>> - private:
>> - SmallVector<char, 0> Buffer;
>> - };
>> -
>> public:
>> using CompileResult = std::unique_ptr<MemoryBuffer>;
>>
>> @@ -114,6 +101,29 @@ private:
>> ObjectCache *ObjCache = nullptr;
>> };
>>
>> +/// A thread-safe version of SimpleCompiler.
>> +///
>> +/// This class creates a new TargetMachine and SimpleCompiler instance
>> for each
>> +/// compile.
>> +class MultiThreadedSimpleCompiler {
>> +public:
>> + MultiThreadedSimpleCompiler(JITTargetMachineBuilder JTMB,
>> + ObjectCache *ObjCache = nullptr)
>> + : JTMB(std::move(JTMB)), ObjCache(ObjCache) {}
>> +
>> + void setObjectCache(ObjectCache *ObjCache) { this->ObjCache =
>> ObjCache; }
>> +
>> + std::unique_ptr<MemoryBuffer> operator()(Module &M) {
>> + auto TM = cantFail(JTMB.createTargetMachine());
>> + SimpleCompiler C(*TM, ObjCache);
>> + return C(M);
>> + }
>> +
>> +private:
>> + JITTargetMachineBuilder JTMB;
>> + ObjectCache *ObjCache = nullptr;
>> +};
>> +
>> } // end namespace orc
>>
>> } // end namespace llvm
>>
>> Modified: llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp?rev=336385&r1=336384&r2=336385&view=diff
>>
>> ==============================================================================
>> --- llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp (original)
>> +++ llvm/trunk/lib/ExecutionEngine/Orc/CompileOnDemandLayer.cpp Thu Jul
>> 5 12:01:27 2018
>> @@ -8,9 +8,12 @@
>>
>> //===----------------------------------------------------------------------===//
>>
>> #include "llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h"
>> +#include "llvm/Bitcode/BitcodeReader.h"
>> +#include "llvm/Bitcode/BitcodeWriter.h"
>> #include "llvm/IR/Mangler.h"
>> #include "llvm/IR/Module.h"
>> #include "llvm/Support/raw_ostream.h"
>> +#include "llvm/Transforms/Utils/Cloning.h"
>>
>> using namespace llvm;
>> using namespace llvm::orc;
>> @@ -68,36 +71,58 @@ static void extractAliases(Materializati
>> R.delegate(symbolAliases(std::move(Aliases)));
>> }
>>
>> -static std::unique_ptr<Module> extractGlobals(Module &M) {
>> - // FIXME: Add alias support.
>> +static std::unique_ptr<Module>
>> +extractAndClone(Module &M, LLVMContext &NewContext, StringRef Suffix,
>> + function_ref<bool(const GlobalValue *)>
>> ShouldCloneDefinition) {
>> + SmallVector<char, 1> ClonedModuleBuffer;
>>
>> - auto GlobalsModule = llvm::make_unique<Module>(
>> - (M.getName() + ".globals").str(), M.getContext());
>> - GlobalsModule->setDataLayout(M.getDataLayout());
>> -
>> - ValueToValueMapTy VMap;
>> -
>> - for (auto &GV : M.globals())
>> - if (!GV.isDeclaration() && !VMap.count(&GV))
>> - cloneGlobalVariableDecl(*GlobalsModule, GV, &VMap);
>> -
>> - // Clone the module flags.
>> - cloneModuleFlagsMetadata(*GlobalsModule, M, VMap);
>> -
>> - auto Materializer = createLambdaValueMaterializer([&](Value *V) ->
>> Value * {
>> - if (auto *F = dyn_cast<Function>(V))
>> - return cloneFunctionDecl(*GlobalsModule, *F);
>> - return nullptr;
>> - });
>> + {
>> + std::set<GlobalValue *> ClonedDefsInSrc;
>> + ValueToValueMapTy VMap;
>> + auto Tmp = CloneModule(M, VMap, [&](const GlobalValue *GV) {
>> + if (ShouldCloneDefinition(GV)) {
>> + ClonedDefsInSrc.insert(const_cast<GlobalValue *>(GV));
>> + return true;
>> + }
>> + return false;
>> + });
>> +
>> + for (auto *GV : ClonedDefsInSrc) {
>> + // Delete the definition and bump the linkage in the source module.
>> + if (isa<Function>(GV)) {
>> + auto &F = *cast<Function>(GV);
>> + F.deleteBody();
>> + F.setPersonalityFn(nullptr);
>> + } else if (isa<GlobalVariable>(GV)) {
>> + cast<GlobalVariable>(GV)->setInitializer(nullptr);
>> + } else
>> + llvm_unreachable("Unsupported global type");
>> +
>> + GV->setLinkage(GlobalValue::ExternalLinkage);
>> + }
>> +
>> + BitcodeWriter BCWriter(ClonedModuleBuffer);
>>
>> - // Move the global variable initializers.
>> - for (auto &GV : M.globals()) {
>> - if (!GV.isDeclaration())
>> - moveGlobalVariableInitializer(GV, VMap, &Materializer);
>> - GV.setInitializer(nullptr);
>> + BCWriter.writeModule(*Tmp);
>> + BCWriter.writeSymtab();
>> + BCWriter.writeStrtab();
>> }
>>
>> - return GlobalsModule;
>> + MemoryBufferRef ClonedModuleBufferRef(
>> + StringRef(ClonedModuleBuffer.data(), ClonedModuleBuffer.size()),
>> + "cloned module buffer");
>> +
>> + auto ClonedModule =
>> + cantFail(parseBitcodeFile(ClonedModuleBufferRef, NewContext));
>> + ClonedModule->setModuleIdentifier((M.getName() + Suffix).str());
>> + return ClonedModule;
>> +}
>> +
>> +static std::unique_ptr<Module> extractGlobals(Module &M,
>> + LLVMContext &NewContext) {
>> + return extractAndClone(M, NewContext, ".globals", [](const GlobalValue
>> *GV) {
>> + return isa<GlobalVariable>(GV);
>> + });
>> }
>>
>> namespace llvm {
>> @@ -132,12 +157,29 @@ private:
>> // original function definitions in the target VSO. All other
>> // symbols should be looked up in the backing resolver.
>>
>> - // Find the functions that have been requested.
>> auto RequestedSymbols = R.getRequestedSymbols();
>>
>> - // Extract them into a new module.
>> - auto ExtractedFunctionsModule =
>> - Parent.extractFunctions(*M, RequestedSymbols,
>> SymbolToDefinition);
>> + // Extract the requested functions into a new module.
>> + std::unique_ptr<Module> ExtractedFunctionsModule;
>> + if (!RequestedSymbols.empty()) {
>> + std::string Suffix;
>> + std::set<const GlobalValue *> FunctionsToClone;
>> + for (auto &Name : RequestedSymbols) {
>> + auto I = SymbolToDefinition.find(Name);
>> + assert(I != SymbolToDefinition.end() && I->second != nullptr &&
>> + "Should have a non-null definition");
>> + FunctionsToClone.insert(I->second);
>> + Suffix += ".";
>> + Suffix += *Name;
>> + }
>> +
>> + std::lock_guard<std::mutex> Lock(SourceModuleMutex);
>> + ExtractedFunctionsModule =
>> + extractAndClone(*M, Parent.GetAvailableContext(), Suffix,
>> + [&](const GlobalValue *GV) -> bool {
>> + return FunctionsToClone.count(GV);
>> + });
>> + }
>>
>> // Build a new ExtractingIRMaterializationUnit to delegate the
>> unrequested
>> // symbols to.
>> @@ -162,8 +204,9 @@ private:
>> std::move(DelegatedSymbolToDefinition), Parent,
>> BackingResolver));
>> }
>>
>> - Parent.emitExtractedFunctionsModule(
>> - std::move(R), std::move(ExtractedFunctionsModule),
>> BackingResolver);
>> + if (ExtractedFunctionsModule)
>> + Parent.emitExtractedFunctionsModule(
>> + std::move(R), std::move(ExtractedFunctionsModule),
>> BackingResolver);
>> }
>>
>> void discard(const VSO &V, SymbolStringPtr Name) override {
>> @@ -173,6 +216,7 @@ private:
>> "ExtractingIRMaterializationUnit");
>> }
>>
>> + mutable std::mutex SourceModuleMutex;
>> CompileOnDemandLayer2 &Parent;
>> std::shared_ptr<SymbolResolver> BackingResolver;
>> };
>> @@ -207,7 +251,7 @@ void CompileOnDemandLayer2::emit(Materia
>>
>> extractAliases(R, *M, Mangle);
>>
>> - auto GlobalsModule = extractGlobals(*M);
>> + auto GlobalsModule = extractGlobals(*M, GetAvailableContext());
>>
>> // Delete the bodies of any available externally functions, rename the
>> // rest, and build the compile callbacks.
>> @@ -221,6 +265,7 @@ void CompileOnDemandLayer2::emit(Materia
>>
>> if (F.hasAvailableExternallyLinkage()) {
>> F.deleteBody();
>> + F.setPersonalityFn(nullptr);
>> continue;
>> }
>>
>> @@ -229,7 +274,10 @@ void CompileOnDemandLayer2::emit(Materia
>> F.setName(F.getName() + "$body");
>> auto StubDecl = cloneFunctionDecl(*M, F);
>> StubDecl->setName(StubUnmangledName);
>> + StubDecl->setPersonalityFn(nullptr);
>> + StubDecl->setLinkage(GlobalValue::ExternalLinkage);
>> F.replaceAllUsesWith(StubDecl);
>> +
>> auto StubName = Mangle(StubUnmangledName);
>> auto BodyName = Mangle(F.getName());
>> if (auto CallbackAddr = CCMgr.getCompileCallback(
>> @@ -302,52 +350,6 @@ IndirectStubsManager &CompileOnDemandLay
>> return *I->second;
>> }
>>
>> -std::unique_ptr<Module> CompileOnDemandLayer2::extractFunctions(
>> - Module &M, const SymbolNameSet &SymbolNames,
>> - const SymbolNameToDefinitionMap &SymbolToDefinition) {
>> - assert(!SymbolNames.empty() && "Can not extract an empty function
>> set");
>> -
>> - std::string ExtractedModName;
>> - {
>> - raw_string_ostream ExtractedModNameStream(ExtractedModName);
>> - ExtractedModNameStream << M.getName();
>> - for (auto &Name : SymbolNames)
>> - ExtractedModNameStream << "." << *Name;
>> - }
>> -
>> - auto ExtractedFunctionsModule =
>> - llvm::make_unique<Module>(ExtractedModName, GetAvailableContext());
>> - ExtractedFunctionsModule->setDataLayout(M.getDataLayout());
>> -
>> - ValueToValueMapTy VMap;
>> -
>> - auto Materializer = createLambdaValueMaterializer([&](Value *V) ->
>> Value * {
>> - GlobalValue *NewGV = nullptr;
>> - if (auto *F = dyn_cast<Function>(V))
>> - NewGV = cloneFunctionDecl(*ExtractedFunctionsModule, *F);
>> - else if (auto *GV = dyn_cast<GlobalVariable>(V))
>> - NewGV = cloneGlobalVariableDecl(*ExtractedFunctionsModule, *GV);
>> -
>> - if (NewGV)
>> - NewGV->setLinkage(GlobalValue::ExternalLinkage);
>> - return NewGV;
>> - });
>> -
>> - std::vector<std::pair<Function *, Function *>> OrigToNew;
>> - for (auto &FunctionName : SymbolNames) {
>> - assert(SymbolToDefinition.count(FunctionName) &&
>> - "No definition for symbol");
>> - auto *OrigF =
>> cast<Function>(SymbolToDefinition.find(FunctionName)->second);
>> - auto *NewF = cloneFunctionDecl(*ExtractedFunctionsModule, *OrigF,
>> &VMap);
>> - OrigToNew.push_back(std::make_pair(OrigF, NewF));
>> - }
>> -
>> - for (auto &KV : OrigToNew)
>> - moveFunctionBody(*KV.first, VMap, &Materializer, KV.second);
>> -
>> - return ExtractedFunctionsModule;
>> -}
>> -
>> void CompileOnDemandLayer2::emitExtractedFunctionsModule(
>> MaterializationResponsibility R, std::unique_ptr<Module> M,
>> std::shared_ptr<SymbolResolver> Resolver) {
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at lists.llvm.org
>> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>
>>
>>
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180705/4d28d17f/attachment.html>
More information about the llvm-commits
mailing list