<div dir="ltr"><div dir="ltr"><div>Hi Hans,</div><div><br></div><div>I've re-applied this in r343122 with a fix to disable the offending test case when -DLLVM_ENABLE_THREADS=OFF.</div><div><br></div><div>Cheers,</div><div>Lang.</div></div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Sep 26, 2018 at 7:19 AM Lang Hames <<a href="mailto:lhames@gmail.com">lhames@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hi Hans,<div><br></div><div>Thanks. I will try building with LLVM_ENABLE_THREADS=Off and see if I can reproduce.</div><div><br></div><div>Cheers,</div><div>Lang.</div></div><br><div class="gmail_quote"><div dir="ltr">On Wed, Sep 26, 2018 at 5:17 AM Hans Wennborg <<a href="mailto:hans@chromium.org" target="_blank">hans@chromium.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The test hits an assert in builds configured with LLVM_ENABLE_THREADS=OFF<br>
<br>
I've reverted in r343099, hopefully untangling this successfully from<br>
the changes that came after.<br>
<br>
This is the test output:<br>
<br>
FAIL: LLVM :: ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll<br>
(30708 of 43135)<br>
******************** TEST 'LLVM ::<br>
ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll' FAILED<br>
********************<br>
Script:<br>
--<br>
: 'RUN: at line 1';<br>
/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm-build/Release+Asserts/bin/lli<br>
-jit-kind=orc-lazy -compile-threads=2 -thread-entry hello<br>
/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll<br>
| /b/swarming/w/ir/kitchen-workdir/src/third_party/llvm-build/Release+Asserts/bin/FileCheck<br>
/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll<br>
--<br>
Exit Code: 2<br>
Command Output (stderr):<br>
--<br>
Warning: request a ThreadPool with 2 threads, but LLVM_ENABLE_THREADS<br>
has been turned off<br>
lli: /b/swarming/w/ir/kitchen-workdir/src/third_party/llvm/lib/ExecutionEngine/Orc/Core.cpp:1748:<br>
Expected<llvm::JITEvaluatedSymbol> llvm::orc::lookup(const<br>
llvm::orc::JITDylibList &, llvm::orc::SymbolStringPtr): Assertion<br>
`ResultMap->size() == 1 && "Unexpected number of results"' failed.<br>
Stack dump:<br>
0. Program arguments:<br>
/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm-build/Release+Asserts/bin/lli<br>
-jit-kind=orc-lazy -compile-threads=2 -thread-entry hello<br>
/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll<br>
#0 0x0000000000edb744 PrintStackTraceSignalHandler(void*)<br>
(/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm-build/Release+Asserts/bin/lli+0xedb744)<br>
#1 0x0000000000ed960e llvm::sys::RunSignalHandlers()<br>
(/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm-build/Release+Asserts/bin/lli+0xed960e)<br>
#2 0x0000000000edb902 SignalHandler(int)<br>
(/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm-build/Release+Asserts/bin/lli+0xedb902)<br>
#3 0x00007f52f1bea330 __restore_rt<br>
(/lib/x86_64-linux-gnu/libpthread.so.0+0x10330)<br>
#4 0x00007f52f0a02c37 gsignal<br>
/build/eglibc-ripdx6/eglibc-2.19/signal/../nptl/sysdeps/unix/sysv/linux/raise.c:56:0<br>
#5 0x00007f52f0a06028 abort /build/eglibc-ripdx6/eglibc-2.19/stdlib/abort.c:91:0<br>
#6 0x00007f52f09fbbf6 __assert_fail_base<br>
/build/eglibc-ripdx6/eglibc-2.19/assert/assert.c:92:0<br>
#7 0x00007f52f09fbca2 (/lib/x86_64-linux-gnu/libc.so.6+0x2fca2)<br>
#8 0x0000000000baf6ce<br>
llvm::orc::lookup(std::vector<llvm::orc::JITDylib*,<br>
std::allocator<llvm::orc::JITDylib*> > const&,<br>
llvm::orc::SymbolStringPtr)<br>
(/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm-build/Release+Asserts/bin/lli+0xbaf6ce)<br>
#9 0x0000000000bcb38f<br>
llvm::orc::LLJIT::lookupLinkerMangled(llvm::orc::JITDylib&,<br>
llvm::StringRef)<br>
(/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm-build/Release+Asserts/bin/lli+0xbcb38f)<br>
#10 0x00000000005d8863 runOrcLazyJIT(char const*)<br>
(/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm-build/Release+Asserts/bin/lli+0x5d8863)<br>
#11 0x00000000005d41f4 main<br>
(/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm-build/Release+Asserts/bin/lli+0x5d41f4)<br>
#12 0x00007f52f09edf45 __libc_start_main<br>
/build/eglibc-ripdx6/eglibc-2.19/csu/libc-start.c:321:0<br>
#13 0x00000000005d2466 _start<br>
(/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm-build/Release+Asserts/bin/lli+0x5d2466)<br>
FileCheck error: '-' is empty.<br>
FileCheck command line:<br>
/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm-build/Release+Asserts/bin/FileCheck<br>
/b/swarming/w/ir/kitchen-workdir/src/third_party/llvm/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll<br>
--<br>
********************<br>
<br>
On Wed, Sep 26, 2018 at 4:39 AM, Lang Hames via llvm-commits<br>
<<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> wrote:<br>
> Author: lhames<br>
> Date: Tue Sep 25 19:39:42 2018<br>
> New Revision: 343058<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=343058&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=343058&view=rev</a><br>
> Log:<br>
> [ORC] Add support for multithreaded compiles to LLJIT and LLLazyJIT.<br>
><br>
> LLJIT and LLLazyJIT can now be constructed with an optional NumCompileThreads<br>
> arguments. If this is non-zero then a thread-pool will be created with the<br>
> given number of threads, and compile tasks will be dispatched to the thread<br>
> pool.<br>
><br>
> To enable testing of this feature, two new flags are added to lli:<br>
><br>
> (1) -compile-threads=N (N = 0 by default) controls the number of compile threads<br>
> to use.<br>
><br>
> (2) -thread-entry can be used to execute code on additional threads. For each<br>
> -thread-entry argument supplied (multiple are allowed) a new thread will be<br>
> created and the given symbol called. These additional thread entry points are<br>
> called after static constructors are run, but before main.<br>
><br>
> Added:<br>
>     llvm/trunk/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll<br>
> Modified:<br>
>     llvm/trunk/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h<br>
>     llvm/trunk/include/llvm/ExecutionEngine/Orc/LLJIT.h<br>
>     llvm/trunk/lib/ExecutionEngine/Orc/LLJIT.cpp<br>
>     llvm/trunk/tools/lli/lli.cpp<br>
><br>
> Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h?rev=343058&r1=343057&r2=343058&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h?rev=343058&r1=343057&r2=343058&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h (original)<br>
> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/ExecutionUtils.h Tue Sep 25 19:39:42 2018<br>
> @@ -67,6 +67,9 @@ public:<br>
>    SubtargetFeatures &getFeatures() { return Features; }<br>
>    TargetOptions &getOptions() { return Options; }<br>
><br>
> +  Triple& getTargetTriple() { return TT; }<br>
> +  const Triple& getTargetTriple() const { return TT; }<br>
> +<br>
>  private:<br>
>    Triple TT;<br>
>    std::string Arch;<br>
><br>
> Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/LLJIT.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/LLJIT.h?rev=343058&r1=343057&r2=343058&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/LLJIT.h?rev=343058&r1=343057&r2=343058&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/ExecutionEngine/Orc/LLJIT.h (original)<br>
> +++ llvm/trunk/include/llvm/ExecutionEngine/Orc/LLJIT.h Tue Sep 25 19:39:42 2018<br>
> @@ -22,7 +22,7 @@<br>
>  #include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"<br>
>  #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"<br>
>  #include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"<br>
> -#include "llvm/Target/TargetMachine.h"<br>
> +#include "llvm/Support/ThreadPool.h"<br>
><br>
>  namespace llvm {<br>
>  namespace orc {<br>
> @@ -30,11 +30,19 @@ namespace orc {<br>
>  /// A pre-fabricated ORC JIT stack that can serve as an alternative to MCJIT.<br>
>  class LLJIT {<br>
>  public:<br>
> +<br>
> +  /// Destruct this instance. If a multi-threaded instance, waits for all<br>
> +  /// compile threads to complete.<br>
> +  ~LLJIT();<br>
> +<br>
>    /// Create an LLJIT instance.<br>
> +  /// If NumCompileThreads is not equal to zero, creates a multi-threaded<br>
> +  /// LLJIT with the given number of compile threads.<br>
>    static Expected<std::unique_ptr<LLJIT>><br>
> -  Create(std::unique_ptr<TargetMachine> TM, DataLayout DL);<br>
> +  Create(JITTargetMachineBuilder JTMB, DataLayout DL,<br>
> +         unsigned NumCompileThreads = 0);<br>
><br>
> -  /// Returns a reference to the ExecutionSession for this JIT instance.<br>
> +  /// Returns the ExecutionSession for this instance.<br>
>    ExecutionSession &getExecutionSession() { return *ES; }<br>
><br>
>    /// Returns a reference to the JITDylib representing the JIT'd main program.<br>
> @@ -91,9 +99,15 @@ public:<br>
>    RTDyldObjectLinkingLayer2 &getObjLinkingLayer() { return ObjLinkingLayer; }<br>
><br>
>  protected:<br>
> +<br>
> +  /// Create an LLJIT instance with a single compile thread.<br>
>    LLJIT(std::unique_ptr<ExecutionSession> ES, std::unique_ptr<TargetMachine> TM,<br>
>          DataLayout DL);<br>
><br>
> +  /// Create an LLJIT instance with multiple compile threads.<br>
> +  LLJIT(std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,<br>
> +        DataLayout DL, unsigned NumCompileThreads);<br>
> +<br>
>    std::unique_ptr<RuntimeDyld::MemoryManager> getMemoryManager(VModuleKey K);<br>
><br>
>    std::string mangle(StringRef UnmangledName);<br>
> @@ -105,8 +119,8 @@ protected:<br>
>    std::unique_ptr<ExecutionSession> ES;<br>
>    JITDylib &Main;<br>
><br>
> -  std::unique_ptr<TargetMachine> TM;<br>
>    DataLayout DL;<br>
> +  std::unique_ptr<ThreadPool> CompileThreads;<br>
><br>
>    RTDyldObjectLinkingLayer2 ObjLinkingLayer;<br>
>    IRCompileLayer2 CompileLayer;<br>
> @@ -118,9 +132,13 @@ protected:<br>
>  /// compilation of LLVM IR.<br>
>  class LLLazyJIT : public LLJIT {<br>
>  public:<br>
> +<br>
>    /// Create an LLLazyJIT instance.<br>
> +  /// If NumCompileThreads is not equal to zero, creates a multi-threaded<br>
> +  /// LLLazyJIT with the given number of compile threads.<br>
>    static Expected<std::unique_ptr<LLLazyJIT>><br>
> -  Create(std::unique_ptr<TargetMachine> TM, DataLayout DL);<br>
> +  Create(JITTargetMachineBuilder JTMB, DataLayout DL,<br>
> +         unsigned NumCompileThreads = 0);<br>
><br>
>    /// Set an IR transform (e.g. pass manager pipeline) to run on each function<br>
>    /// when it is compiled.<br>
> @@ -137,11 +155,20 @@ public:<br>
>    }<br>
><br>
>  private:<br>
> +<br>
> +  // Create a single-threaded LLLazyJIT instance.<br>
>    LLLazyJIT(std::unique_ptr<ExecutionSession> ES,<br>
>              std::unique_ptr<TargetMachine> TM, DataLayout DL,<br>
>              std::unique_ptr<JITCompileCallbackManager> CCMgr,<br>
>              std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);<br>
><br>
> +  // Create a multi-threaded LLLazyJIT instance.<br>
> +  LLLazyJIT(std::unique_ptr<ExecutionSession> ES,<br>
> +            JITTargetMachineBuilder JTMB, DataLayout DL,<br>
> +            unsigned NumCompileThreads,<br>
> +            std::unique_ptr<JITCompileCallbackManager> CCMgr,<br>
> +            std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder);<br>
> +<br>
>    std::unique_ptr<JITCompileCallbackManager> CCMgr;<br>
>    std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder;<br>
><br>
><br>
> Modified: llvm/trunk/lib/ExecutionEngine/Orc/LLJIT.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/LLJIT.cpp?rev=343058&r1=343057&r2=343058&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/LLJIT.cpp?rev=343058&r1=343057&r2=343058&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/ExecutionEngine/Orc/LLJIT.cpp (original)<br>
> +++ llvm/trunk/lib/ExecutionEngine/Orc/LLJIT.cpp Tue Sep 25 19:39:42 2018<br>
> @@ -12,13 +12,45 @@<br>
>  #include "llvm/ExecutionEngine/SectionMemoryManager.h"<br>
>  #include "llvm/IR/Mangler.h"<br>
><br>
> +namespace {<br>
> +<br>
> +  // A SimpleCompiler that owns its TargetMachine.<br>
> +  class TMOwningSimpleCompiler : public llvm::orc::SimpleCompiler {<br>
> +  public:<br>
> +    TMOwningSimpleCompiler(std::unique_ptr<llvm::TargetMachine> TM)<br>
> +      : llvm::orc::SimpleCompiler(*TM), TM(std::move(TM)) {}<br>
> +  private:<br>
> +    // FIXME: shared because std::functions (and thus<br>
> +    // IRCompileLayer2::CompileFunction) are not moveable.<br>
> +    std::shared_ptr<llvm::TargetMachine> TM;<br>
> +  };<br>
> +<br>
> +} // end anonymous namespace<br>
> +<br>
>  namespace llvm {<br>
>  namespace orc {<br>
><br>
> +LLJIT::~LLJIT() {<br>
> +  if (CompileThreads)<br>
> +    CompileThreads->wait();<br>
> +}<br>
> +<br>
>  Expected<std::unique_ptr<LLJIT>><br>
> -LLJIT::Create(std::unique_ptr<TargetMachine> TM, DataLayout DL) {<br>
> +LLJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,<br>
> +              unsigned NumCompileThreads) {<br>
> +<br>
> +  if (NumCompileThreads == 0) {<br>
> +    // If NumCompileThreads == 0 then create a single-threaded LLJIT instance.<br>
> +    auto TM = JTMB.createTargetMachine();<br>
> +    if (!TM)<br>
> +      return TM.takeError();<br>
> +    return std::unique_ptr<LLJIT>(new LLJIT(llvm::make_unique<ExecutionSession>(),<br>
> +                                            std::move(*TM), std::move(DL)));<br>
> +  }<br>
> +<br>
>    return std::unique_ptr<LLJIT>(new LLJIT(llvm::make_unique<ExecutionSession>(),<br>
> -                                          std::move(TM), std::move(DL)));<br>
> +                                          std::move(JTMB), std::move(DL),<br>
> +                                          NumCompileThreads));<br>
>  }<br>
><br>
>  Error LLJIT::defineAbsolute(StringRef Name, JITEvaluatedSymbol Sym) {<br>
> @@ -52,12 +84,35 @@ Expected<JITEvaluatedSymbol> LLJIT::look<br>
>  LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,<br>
>               std::unique_ptr<TargetMachine> TM, DataLayout DL)<br>
>      : ES(std::move(ES)), Main(this->ES->createJITDylib("main")),<br>
> -      TM(std::move(TM)), DL(std::move(DL)),<br>
> +      DL(std::move(DL)),<br>
>        ObjLinkingLayer(*this->ES,<br>
>                        [this](VModuleKey K) { return getMemoryManager(K); }),<br>
> -      CompileLayer(*this->ES, ObjLinkingLayer, SimpleCompiler(*this->TM)),<br>
> +      CompileLayer(*this->ES, ObjLinkingLayer, TMOwningSimpleCompiler(std::move(TM))),<br>
>        CtorRunner(Main), DtorRunner(Main) {}<br>
><br>
> +LLJIT::LLJIT(std::unique_ptr<ExecutionSession> ES,<br>
> +             JITTargetMachineBuilder JTMB, DataLayout DL,<br>
> +             unsigned NumCompileThreads)<br>
> +    : ES(std::move(ES)), Main(this->ES->createJITDylib("main")),<br>
> +      DL(std::move(DL)),<br>
> +      ObjLinkingLayer(*this->ES,<br>
> +                      [this](VModuleKey K) { return getMemoryManager(K); }),<br>
> +      CompileLayer(*this->ES, ObjLinkingLayer, MultiThreadedSimpleCompiler(std::move(JTMB))),<br>
> +      CtorRunner(Main), DtorRunner(Main) {<br>
> +  assert(NumCompileThreads != 0 &&<br>
> +         "Multithreaded LLJIT instance can not be created with 0 threads");<br>
> +<br>
> +  CompileThreads = llvm::make_unique<ThreadPool>(NumCompileThreads);<br>
> +  this->ES->setDispatchMaterialization([this](JITDylib &JD, std::unique_ptr<MaterializationUnit> MU) {<br>
> +      // FIXME: Switch to move capture once we have c++14.<br>
> +      auto SharedMU = std::shared_ptr<MaterializationUnit>(std::move(MU));<br>
> +      auto Work = [SharedMU, &JD]() {<br>
> +        SharedMU->doMaterialize(JD);<br>
> +      };<br>
> +      CompileThreads->async(std::move(Work));<br>
> +    });<br>
> +}<br>
> +<br>
>  std::unique_ptr<RuntimeDyld::MemoryManager><br>
>  LLJIT::getMemoryManager(VModuleKey K) {<br>
>    return llvm::make_unique<SectionMemoryManager>();<br>
> @@ -90,10 +145,11 @@ void LLJIT::recordCtorDtors(Module &M) {<br>
>  }<br>
><br>
>  Expected<std::unique_ptr<LLLazyJIT>><br>
> -LLLazyJIT::Create(std::unique_ptr<TargetMachine> TM, DataLayout DL) {<br>
> +  LLLazyJIT::Create(JITTargetMachineBuilder JTMB, DataLayout DL,<br>
> +                    unsigned NumCompileThreads) {<br>
>    auto ES = llvm::make_unique<ExecutionSession>();<br>
><br>
> -  const Triple &TT = TM->getTargetTriple();<br>
> +  const Triple &TT = JTMB.getTargetTriple();<br>
><br>
>    auto CCMgr = createLocalCompileCallbackManager(TT, *ES, 0);<br>
>    if (!CCMgr)<br>
> @@ -107,9 +163,18 @@ LLLazyJIT::Create(std::unique_ptr<Target<br>
>          std::string("No indirect stubs manager builder for ") + TT.str(),<br>
>          inconvertibleErrorCode());<br>
><br>
> -  return std::unique_ptr<LLLazyJIT>(<br>
> -      new LLLazyJIT(std::move(ES), std::move(TM), std::move(DL),<br>
> +  if (NumCompileThreads == 0) {<br>
> +    auto TM = JTMB.createTargetMachine();<br>
> +    if (!TM)<br>
> +      return TM.takeError();<br>
> +    return std::unique_ptr<LLLazyJIT>(<br>
> +      new LLLazyJIT(std::move(ES), std::move(*TM), std::move(DL),<br>
>                      std::move(CCMgr), std::move(ISMBuilder)));<br>
> +  }<br>
> +<br>
> +  return std::unique_ptr<LLLazyJIT>(<br>
> +      new LLLazyJIT(std::move(ES), std::move(JTMB), std::move(DL),<br>
> +                    NumCompileThreads, std::move(CCMgr), std::move(ISMBuilder)));<br>
>  }<br>
><br>
>  Error LLLazyJIT::addLazyIRModule(JITDylib &JD, ThreadSafeModule TSM) {<br>
> @@ -134,6 +199,15 @@ LLLazyJIT::LLLazyJIT(<br>
>        CCMgr(std::move(CCMgr)), TransformLayer(*this->ES, CompileLayer),<br>
>        CODLayer(*this->ES, TransformLayer, *this->CCMgr, std::move(ISMBuilder)) {<br>
>  }<br>
> +<br>
> +LLLazyJIT::LLLazyJIT(<br>
> +    std::unique_ptr<ExecutionSession> ES, JITTargetMachineBuilder JTMB,<br>
> +    DataLayout DL, unsigned NumCompileThreads, std::unique_ptr<JITCompileCallbackManager> CCMgr,<br>
> +    std::function<std::unique_ptr<IndirectStubsManager>()> ISMBuilder)<br>
> +    : LLJIT(std::move(ES), std::move(JTMB), std::move(DL), NumCompileThreads),<br>
> +      CCMgr(std::move(CCMgr)), TransformLayer(*this->ES, CompileLayer),<br>
> +      CODLayer(*this->ES, TransformLayer, *this->CCMgr, std::move(ISMBuilder)) {<br>
> +}<br>
><br>
>  } // End namespace orc.<br>
>  } // End namespace llvm.<br>
><br>
> Added: llvm/trunk/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll?rev=343058&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll?rev=343058&view=auto</a><br>
> ==============================================================================<br>
> --- llvm/trunk/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll (added)<br>
> +++ llvm/trunk/test/ExecutionEngine/OrcLazy/multiple-compile-threads-basic.ll Tue Sep 25 19:39:42 2018<br>
> @@ -0,0 +1,18 @@<br>
> +; RUN: lli -jit-kind=orc-lazy -compile-threads=5 -thread-entry hello %s | FileCheck %s<br>
> +;<br>
> +; CHECK: Hello<br>
> +<br>
> +@.str = private unnamed_addr constant [7 x i8] c"Hello\0A\00", align 1<br>
> +<br>
> +define void @hello() {<br>
> +entry:<br>
> +  %call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str, i32 0, i32 0))<br>
> +  ret void<br>
> +}<br>
> +<br>
> +declare i32 @printf(i8*, ...)<br>
> +<br>
> +define i32 @main(i32 %argc, i8** %argv) {<br>
> +entry:<br>
> +  ret i32 0<br>
> +}<br>
><br>
> Modified: llvm/trunk/tools/lli/lli.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=343058&r1=343057&r2=343058&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=343058&r1=343057&r2=343058&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/tools/lli/lli.cpp (original)<br>
> +++ llvm/trunk/tools/lli/lli.cpp Tue Sep 25 19:39:42 2018<br>
> @@ -97,6 +97,17 @@ namespace {<br>
>                                             "orc-lazy",<br>
>                                             "Orc-based lazy JIT.")));<br>
><br>
> +  cl::opt<unsigned><br>
> +  LazyJITCompileThreads("compile-threads",<br>
> +                        cl::desc("Choose the number of compile threads "<br>
> +                                 "(jit-kind=orc-lazy only)"),<br>
> +                        cl::init(0));<br>
> +<br>
> +  cl::list<std::string><br>
> +  ThreadEntryPoints("thread-entry",<br>
> +                    cl::desc("calls the given entry-point on a new thread "<br>
> +                             "(jit-kind=orc-lazy only)"));<br>
> +<br>
>    // The MCJIT supports building for a target address space separate from<br>
>    // the JIT compilation process. Use a forked process and a copying<br>
>    // memory manager with IPC to execute using this functionality.<br>
> @@ -363,6 +374,19 @@ int main(int argc, char **argv, char * c<br>
><br>
>    if (UseJITKind == JITKind::OrcLazy)<br>
>      return runOrcLazyJIT(argv[0]);<br>
> +  else {<br>
> +    // Make sure nobody used an orc-lazy specific option accidentally.<br>
> +<br>
> +    if (LazyJITCompileThreads != 0) {<br>
> +      errs() << "-compile-threads requires -jit-kind=orc-lazy\n";<br>
> +      exit(1);<br>
> +    }<br>
> +<br>
> +    if (!ThreadEntryPoints.empty()) {<br>
> +      errs() << "-thread-entry requires -jit-kind=orc-lazy\n";<br>
> +      exit(1);<br>
> +    }<br>
> +  }<br>
><br>
>    LLVMContext Context;<br>
><br>
> @@ -745,11 +769,11 @@ int runOrcLazyJIT(const char *ProgName)<br>
>      reportError(Err, ProgName);<br>
><br>
>    const auto &TT = MainModule.getModule()->getTargetTriple();<br>
> -  orc::JITTargetMachineBuilder TMD =<br>
> +  orc::JITTargetMachineBuilder JTMB =<br>
>        TT.empty() ? ExitOnErr(orc::JITTargetMachineBuilder::detectHost())<br>
>                   : orc::JITTargetMachineBuilder(Triple(TT));<br>
><br>
> -  TMD.setArch(MArch)<br>
> +  JTMB.setArch(MArch)<br>
>        .setCPU(getCPUStr())<br>
>        .addFeatures(getFeatureList())<br>
>        .setRelocationModel(RelocModel.getNumOccurrences()<br>
> @@ -758,9 +782,13 @@ int runOrcLazyJIT(const char *ProgName)<br>
>        .setCodeModel(CMModel.getNumOccurrences()<br>
>                          ? Optional<CodeModel::Model>(CMModel)<br>
>                          : None);<br>
> -  auto TM = ExitOnErr(TMD.createTargetMachine());<br>
> -  auto DL = TM->createDataLayout();<br>
> -  auto J = ExitOnErr(orc::LLLazyJIT::Create(std::move(TM), DL));<br>
> +  DataLayout DL("");<br>
> +  {<br>
> +    // Create a throwaway TargetMachine to get the data layout.<br>
> +    auto TM = ExitOnErr(JTMB.createTargetMachine());<br>
> +    DL = TM->createDataLayout();<br>
> +  }<br>
> +  auto J = ExitOnErr(orc::LLLazyJIT::Create(std::move(JTMB), DL, LazyJITCompileThreads));<br>
><br>
>    auto Dump = createDebugDumper();<br>
><br>
> @@ -807,6 +835,16 @@ int runOrcLazyJIT(const char *ProgName)<br>
>    // Run any static constructors.<br>
>    ExitOnErr(J->runConstructors());<br>
><br>
> +  // Run any -thread-entry points.<br>
> +  std::vector<std::thread> AltEntryThreads;<br>
> +  for (auto &ThreadEntryPoint : ThreadEntryPoints) {<br>
> +    auto EntryPointSym = ExitOnErr(J->lookup(ThreadEntryPoint));<br>
> +    typedef void (*EntryPointPtr)();<br>
> +    auto EntryPoint =<br>
> +      reinterpret_cast<EntryPointPtr>(static_cast<uintptr_t>(EntryPointSym.getAddress()));<br>
> +    AltEntryThreads.push_back(std::thread([EntryPoint]() { EntryPoint(); }));<br>
> +  }<br>
> +<br>
>    // Run main.<br>
>    auto MainSym = ExitOnErr(J->lookup("main"));<br>
>    typedef int (*MainFnPtr)(int, const char *[]);<br>
> @@ -817,8 +855,12 @@ int runOrcLazyJIT(const char *ProgName)<br>
>        reinterpret_cast<MainFnPtr>(static_cast<uintptr_t>(MainSym.getAddress()));<br>
>    auto Result = Main(ArgV.size(), (const char **)ArgV.data());<br>
><br>
> -  ExitOnErr(J->runDestructors());<br>
> +  // Wait for -entry-point threads.<br>
> +  for (auto &AltEntryThread : AltEntryThreads)<br>
> +    AltEntryThread.join();<br>
><br>
> +  // Run destructors.<br>
> +  ExitOnErr(J->runDestructors());<br>
>    CXXRuntimeOverrides.runDestructors();<br>
><br>
>    return Result;<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>
</blockquote></div>