[llvm] r336385 - [ORC] In CompileOnDemandLayer2, clone modules on to different contexts by
Heejin Ahn via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 5 19:13:03 PDT 2018
No problem!
On Thu, Jul 5, 2018 at 7:02 PM Lang Hames <lhames at gmail.com> wrote:
> 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/6ef4c1cd/attachment-0001.html>
More information about the llvm-commits
mailing list