[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 18:57:10 PDT 2018
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/fcabb4ff/attachment.html>
More information about the llvm-commits
mailing list