[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