<div dir="ltr">Haven't done a comprehensive review, but was just looking at the XFAILs and it seems some comments are now out of date<br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jan 11, 2016 at 8:35 AM, Lang Hames via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: lhames<br>
Date: Mon Jan 11 10:35:55 2016<br>
New Revision: 257343<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=257343&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=257343&view=rev</a><br>
Log:<br>
[LLI] Replace the LLI remote-JIT support with the new ORC remote-JIT components.<br>
<br>
The new ORC remote-JITing support provides a superset of the old code's<br>
functionality, so we can replace the old stuff. As a bonus, a couple of<br>
previously XFAILed tests have started passing.<br>
<br>
<br>
Added:<br>
    llvm/trunk/tools/lli/RemoteJITUtils.h<br>
Removed:<br>
    llvm/trunk/tools/lli/RPCChannel.h<br>
    llvm/trunk/tools/lli/RemoteMemoryManager.cpp<br>
    llvm/trunk/tools/lli/RemoteMemoryManager.h<br>
    llvm/trunk/tools/lli/RemoteTarget.cpp<br>
    llvm/trunk/tools/lli/RemoteTarget.h<br>
    llvm/trunk/tools/lli/RemoteTargetExternal.cpp<br>
    llvm/trunk/tools/lli/RemoteTargetExternal.h<br>
    llvm/trunk/tools/lli/RemoteTargetMessage.h<br>
    llvm/trunk/tools/lli/Unix/<br>
    llvm/trunk/tools/lli/Windows/<br>
Modified:<br>
    llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h<br>
    llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h<br>
    llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll<br>
    llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll<br>
    llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll<br>
    llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/stubs-remote.ll<br>
    llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-sm-pic.ll<br>
    llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll<br>
    llvm/trunk/tools/lli/CMakeLists.txt<br>
    llvm/trunk/tools/lli/ChildTarget/CMakeLists.txt<br>
    llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp<br>
    llvm/trunk/tools/lli/lli.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h?rev=257343&r1=257342&r2=257343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h?rev=257343&r1=257342&r2=257343&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h (original)<br>
+++ llvm/trunk/include/llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h Mon Jan 11 10:35:55 2016<br>
@@ -25,14 +25,58 @@<br>
 namespace llvm {<br>
 namespace orc {<br>
<br>
+/// Generic ORC Architecture support.<br>
+///<br>
+/// This class can be substituted as the target architecure support class for<br>
+/// ORC templates that require one (e.g. IndirectStubsManagers). It does not<br>
+/// support lazy JITing however, and any attempt to use that functionality<br>
+/// will result in execution of an llvm_unreachable.<br>
+class OrcGenericArchitecture {<br>
+public:<br>
+  static const unsigned PointerSize = sizeof(uintptr_t);<br>
+  static const unsigned TrampolineSize = 1;<br>
+  static const unsigned ResolverCodeSize = 1;<br>
+<br>
+  typedef TargetAddress (*JITReentryFn)(void *CallbackMgr, void *TrampolineId);<br>
+<br>
+  static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,<br>
+                                void *CallbackMgr) {<br>
+    llvm_unreachable("writeResolverCode is not supported by the generic host "<br>
+                     "support class");<br>
+  }<br>
+<br>
+  static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,<br>
+                               unsigned NumTrampolines) {<br>
+    llvm_unreachable("writeTrampolines is not supported by the generic host "<br>
+                     "support class");<br>
+  }<br>
+<br>
+  class IndirectStubsInfo {<br>
+  public:<br>
+    const static unsigned StubSize = 1;<br>
+    unsigned getNumStubs() const { llvm_unreachable("Not supported"); }<br>
+    void *getStub(unsigned Idx) const { llvm_unreachable("Not supported"); }<br>
+    void **getPtr(unsigned Idx) const { llvm_unreachable("Not supported"); }<br>
+  };<br>
+<br>
+  static std::error_code emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,<br>
+                                                unsigned MinStubs,<br>
+                                                void *InitialPtrVal) {<br>
+    llvm_unreachable("emitIndirectStubsBlock is not supported by the generic "<br>
+                     "host support class");<br>
+  }<br>
+};<br>
+<br>
+/// @brief X86_64 support.<br>
+///<br>
+/// X86_64 supports lazy JITing.<br>
 class OrcX86_64 {<br>
 public:<br>
   static const unsigned PointerSize = 8;<br>
   static const unsigned TrampolineSize = 8;<br>
   static const unsigned ResolverCodeSize = 0x78;<br>
<br>
-  typedef TargetAddress (*JITReentryFn)(void *CallbackMgr,<br>
-                                        void *TrampolineId);<br>
+  typedef TargetAddress (*JITReentryFn)(void *CallbackMgr, void *TrampolineId);<br>
<br>
   /// @brief Write the resolver code into the given memory. The user is be<br>
   ///        responsible for allocating the memory and setting permissions.<br>
@@ -49,6 +93,7 @@ public:<br>
   ///        makeIndirectStubsBlock function.<br>
   class IndirectStubsInfo {<br>
     friend class OrcX86_64;<br>
+<br>
   public:<br>
     const static unsigned StubSize = 8;<br>
<br>
@@ -57,7 +102,7 @@ public:<br>
         : NumStubs(Other.NumStubs), StubsMem(std::move(Other.StubsMem)) {<br>
       Other.NumStubs = 0;<br>
     }<br>
-    IndirectStubsInfo& operator=(IndirectStubsInfo &&Other) {<br>
+    IndirectStubsInfo &operator=(IndirectStubsInfo &&Other) {<br>
       NumStubs = Other.NumStubs;<br>
       Other.NumStubs = 0;<br>
       StubsMem = std::move(Other.StubsMem);<br>
@@ -69,17 +114,18 @@ public:<br>
<br>
     /// @brief Get a pointer to the stub at the given index, which must be in<br>
     ///        the range 0 .. getNumStubs() - 1.<br>
-    void* getStub(unsigned Idx) const {<br>
-      return static_cast<uint64_t*>(StubsMem.base()) + Idx;<br>
+    void *getStub(unsigned Idx) const {<br>
+      return static_cast<uint64_t *>(StubsMem.base()) + Idx;<br>
     }<br>
<br>
     /// @brief Get a pointer to the implementation-pointer at the given index,<br>
     ///        which must be in the range 0 .. getNumStubs() - 1.<br>
-    void** getPtr(unsigned Idx) const {<br>
+    void **getPtr(unsigned Idx) const {<br>
       char *PtrsBase =<br>
-        static_cast<char*>(StubsMem.base()) + NumStubs * StubSize;<br>
-      return reinterpret_cast<void**>(PtrsBase) + Idx;<br>
+          static_cast<char *>(StubsMem.base()) + NumStubs * StubSize;<br>
+      return reinterpret_cast<void **>(PtrsBase) + Idx;<br>
     }<br>
+<br>
   private:<br>
     unsigned NumStubs;<br>
     sys::OwningMemoryBlock StubsMem;<br>
<br>
Modified: llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h?rev=257343&r1=257342&r2=257343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h?rev=257343&r1=257342&r2=257343&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h (original)<br>
+++ llvm/trunk/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h Mon Jan 11 10:35:55 2016<br>
@@ -77,6 +77,11 @@ class OrcMCJITReplacement : public Execu<br>
       return ClientMM->deregisterEHFrames(Addr, LoadAddr, Size);<br>
     }<br>
<br>
+    void notifyObjectLoaded(RuntimeDyld &RTDyld,<br>
+                            const object::ObjectFile &O) override {<br>
+      return ClientMM->notifyObjectLoaded(RTDyld, O);<br>
+    }<br>
+<br>
     void notifyObjectLoaded(ExecutionEngine *EE,<br>
                             const object::ObjectFile &O) override {<br>
       return ClientMM->notifyObjectLoaded(EE, O);<br>
<br>
Modified: llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll?rev=257343&r1=257342&r2=257343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll?rev=257343&r1=257342&r2=257343&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll (original)<br>
+++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll Mon Jan 11 10:35:55 2016<br>
@@ -1,5 +1,4 @@<br>
 ; RUN: %lli -remote-mcjit -disable-lazy-compilation=false -mcjit-remote-process=lli-child-target%exeext %s<br>
-; XFAIL: *<br>
 ; This test should fail until remote symbol resolution is supported.<br></blockquote><div><br></div><div>Here ^</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
 define i32 @main() nounwind {<br>
<br>
Modified: llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll?rev=257343&r1=257342&r2=257343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll?rev=257343&r1=257342&r2=257343&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll (original)<br>
+++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-sm-pic.ll Mon Jan 11 10:35:55 2016<br>
@@ -1,4 +1,5 @@<br>
-; RUN: %lli -remote-mcjit -relocation-model=pic -code-model=small %s > /dev/null<br>
+; RUN: %lli -remote-mcjit -mcjit-remote-process=lli-child-target%exeext \<br>
+; RUN:   -relocation-model=pic -code-model=small %s > /dev/null<br>
 ; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386<br>
<br>
 @count = global i32 1, align 4<br>
<br>
Modified: llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll?rev=257343&r1=257342&r2=257343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll?rev=257343&r1=257342&r2=257343&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll (original)<br>
+++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-sm-pic.ll Mon Jan 11 10:35:55 2016<br>
@@ -1,4 +1,5 @@<br>
-; RUN: %lli -remote-mcjit -O0 -relocation-model=pic -code-model=small %s<br>
+; RUN: %lli -remote-mcjit -mcjit-remote-process=lli-child-target%exeext \<br>
+; RUN:   -O0 -relocation-model=pic -code-model=small %s<br>
 ; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386<br>
<br>
 @.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1<br>
<br>
Modified: llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/stubs-remote.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/stubs-remote.ll?rev=257343&r1=257342&r2=257343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/stubs-remote.ll?rev=257343&r1=257342&r2=257343&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/stubs-remote.ll (original)<br>
+++ llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/stubs-remote.ll Mon Jan 11 10:35:55 2016<br>
@@ -1,5 +1,4 @@<br>
 ; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -disable-lazy-compilation=false -mcjit-remote-process=lli-child-target%exeext %s<br>
-; XFAIL: *<br>
 ; This test should fail until remote symbol resolution is supported.<br></blockquote><div><br>And here ^<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
 define i32 @main() nounwind {<br>
<br>
Modified: llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-sm-pic.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-sm-pic.ll?rev=257343&r1=257342&r2=257343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-sm-pic.ll?rev=257343&r1=257342&r2=257343&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-sm-pic.ll (original)<br>
+++ llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/test-global-init-nonzero-sm-pic.ll Mon Jan 11 10:35:55 2016<br>
@@ -1,4 +1,5 @@<br>
-; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -relocation-model=pic -code-model=small %s > /dev/null<br>
+; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext \<br>
+; RUN:   -relocation-model=pic -code-model=small %s > /dev/null<br>
 ; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386<br>
<br>
 @count = global i32 1, align 4<br>
<br>
Modified: llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll?rev=257343&r1=257342&r2=257343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll?rev=257343&r1=257342&r2=257343&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll (original)<br>
+++ llvm/trunk/test/ExecutionEngine/OrcMCJIT/remote/test-ptr-reloc-sm-pic.ll Mon Jan 11 10:35:55 2016<br>
@@ -1,4 +1,5 @@<br>
-; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -O0 -relocation-model=pic -code-model=small %s<br>
+; RUN: %lli -jit-kind=orc-mcjit -remote-mcjit -mcjit-remote-process=lli-child-target%exeext \<br>
+; RUN:   -O0 -relocation-model=pic -code-model=small %s<br>
 ; XFAIL: mips-, mipsel-, aarch64, arm, i686, i386<br>
<br>
 @.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1<br>
<br>
Modified: llvm/trunk/tools/lli/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/CMakeLists.txt?rev=257343&r1=257342&r2=257343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/CMakeLists.txt?rev=257343&r1=257342&r2=257343&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/CMakeLists.txt (original)<br>
+++ llvm/trunk/tools/lli/CMakeLists.txt Mon Jan 11 10:35:55 2016<br>
@@ -38,8 +38,5 @@ endif( LLVM_USE_INTEL_JITEVENTS )<br>
 add_llvm_tool(lli<br>
   lli.cpp<br>
   OrcLazyJIT.cpp<br>
-  RemoteMemoryManager.cpp<br>
-  RemoteTarget.cpp<br>
-  RemoteTargetExternal.cpp<br>
   )<br>
 export_executable_symbols(lli)<br>
<br>
Modified: llvm/trunk/tools/lli/ChildTarget/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/ChildTarget/CMakeLists.txt?rev=257343&r1=257342&r2=257343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/ChildTarget/CMakeLists.txt?rev=257343&r1=257342&r2=257343&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/ChildTarget/CMakeLists.txt (original)<br>
+++ llvm/trunk/tools/lli/ChildTarget/CMakeLists.txt Mon Jan 11 10:35:55 2016<br>
@@ -1,8 +1,10 @@<br>
-set(LLVM_LINK_COMPONENTS support)<br>
+set(LLVM_LINK_COMPONENTS<br>
+  OrcJIT<br>
+  Support<br>
+  )<br>
<br>
 add_llvm_executable(lli-child-target<br>
   ChildTarget.cpp<br>
-  ../RemoteTarget.cpp<br>
 )<br>
<br>
 set_target_properties(lli-child-target PROPERTIES FOLDER "Misc")<br>
<br>
Modified: llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp?rev=257343&r1=257342&r2=257343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp?rev=257343&r1=257342&r2=257343&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp (original)<br>
+++ llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp Mon Jan 11 10:35:55 2016<br>
@@ -1,244 +1,69 @@<br>
-#include "llvm/Config/config.h"<br>
-#include "../RPCChannel.h"<br>
-#include "../RemoteTarget.h"<br>
-#include "../RemoteTargetMessage.h"<br>
-#include "llvm/Support/Memory.h"<br>
-#include <assert.h><br>
-#include <map><br>
-#include <stdint.h><br>
-#include <string><br>
-#include <vector><br>
+#include "llvm/ExecutionEngine/Orc/OrcArchitectureSupport.h"<br>
+#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetServer.h"<br>
+#include "llvm/Support/Debug.h"<br>
+#include "llvm/Support/DynamicLibrary.h"<br>
+#include "llvm/Support/Process.h"<br>
+#include <sstream><br>
<br>
-using namespace llvm;<br>
-<br>
-class LLIChildTarget {<br>
-public:<br>
-  void initialize();<br>
-  LLIMessageType waitForIncomingMessage();<br>
-  void handleMessage(LLIMessageType messageType);<br>
-  RemoteTarget *RT;<br>
-  RPCChannel RPC;<br>
-<br>
-private:<br>
-  // Incoming message handlers<br>
-  void handleAllocateSpace();<br>
-  void handleLoadSection(bool IsCode);<br>
-  void handleExecute();<br>
-<br>
-  // Outgoing message handlers<br>
-  void sendChildActive();<br>
-  void sendAllocationResult(uint64_t Addr);<br>
-  void sendLoadStatus(uint32_t Status);<br>
-  void sendExecutionComplete(int Result);<br>
-<br>
-  // OS-specific functions<br>
-  void initializeConnection();<br>
-  int WriteBytes(const void *Data, size_t Size) {<br>
-    return RPC.WriteBytes(Data, Size) ? Size : -1;<br>
-  }<br>
-  int ReadBytes(void *Data, size_t Size) {<br>
-    return RPC.ReadBytes(Data, Size) ? Size : -1;<br>
-  }<br>
+#include "../RemoteJITUtils.h"<br>
<br>
-  // Communication handles (OS-specific)<br>
-  void *ConnectionData;<br>
-};<br>
-<br>
-int main() {<br>
-  LLIChildTarget  ThisChild;<br>
-  ThisChild.RT = new RemoteTarget();<br>
-  ThisChild.initialize();<br>
-  LLIMessageType MsgType;<br>
-  do {<br>
-    MsgType = ThisChild.waitForIncomingMessage();<br>
-    ThisChild.handleMessage(MsgType);<br>
-  } while (MsgType != LLI_Terminate &&<br>
-           MsgType != LLI_Error);<br>
-  delete ThisChild.RT;<br>
-  return 0;<br>
-}<br>
+using namespace llvm;<br>
+using namespace llvm::orc;<br>
+using namespace llvm::sys;<br>
<br>
-// Public methods<br>
-void LLIChildTarget::initialize() {<br>
-  RPC.createClient();<br>
-  sendChildActive();<br>
-}<br>
+#ifdef __x86_64__<br>
+typedef OrcX86_64 HostOrcArch;<br>
+#else<br>
+typedef OrcGenericArchitecture HostOrcArch;<br>
+#endif<br>
<br>
-LLIMessageType LLIChildTarget::waitForIncomingMessage() {<br>
-  int32_t MsgType = -1;<br>
-  if (ReadBytes(&MsgType, 4) > 0)<br>
-    return (LLIMessageType)MsgType;<br>
-  return LLI_Error;<br>
-}<br>
+int main(int argc, char *argv[]) {<br>
<br>
-void LLIChildTarget::handleMessage(LLIMessageType messageType) {<br>
-  switch (messageType) {<br>
-    case LLI_AllocateSpace:<br>
-      handleAllocateSpace();<br>
-      break;<br>
-    case LLI_LoadCodeSection:<br>
-      handleLoadSection(true);<br>
-      break;<br>
-    case LLI_LoadDataSection:<br>
-      handleLoadSection(false);<br>
-      break;<br>
-    case LLI_Execute:<br>
-      handleExecute();<br>
-      break;<br>
-    case LLI_Terminate:<br>
-      RT->stop();<br>
-      break;<br>
-    default:<br>
-      // FIXME: Handle error!<br>
-      break;<br>
+  if (argc != 3) {<br>
+    errs() << "Usage: " << argv[0] << " <input fd> <output fd>\n";<br>
+    return 1;<br>
   }<br>
-}<br>
-<br>
-// Incoming message handlers<br>
-void LLIChildTarget::handleAllocateSpace() {<br>
-  // Read and verify the message data size.<br>
-  uint32_t DataSize = 0;<br>
-  int rc = ReadBytes(&DataSize, 4);<br>
-  (void)rc;<br>
-  assert(rc == 4);<br>
-  assert(DataSize == 8);<br>
-<br>
-  // Read the message arguments.<br>
-  uint32_t Alignment = 0;<br>
-  uint32_t AllocSize = 0;<br>
-  rc = ReadBytes(&Alignment, 4);<br>
-  assert(rc == 4);<br>
-  rc = ReadBytes(&AllocSize, 4);<br>
-  assert(rc == 4);<br>
-<br>
-  // Allocate the memory.<br>
-  uint64_t Addr;<br>
-  RT->allocateSpace(AllocSize, Alignment, Addr);<br>
-<br>
-  // Send AllocationResult message.<br>
-  sendAllocationResult(Addr);<br>
-}<br>
-<br>
-void LLIChildTarget::handleLoadSection(bool IsCode) {<br>
-  // Read the message data size.<br>
-  uint32_t DataSize = 0;<br>
-  int rc = ReadBytes(&DataSize, 4);<br>
-  (void)rc;<br>
-  assert(rc == 4);<br>
-<br>
-  // Read the target load address.<br>
-  uint64_t Addr = 0;<br>
-  rc = ReadBytes(&Addr, 8);<br>
-  assert(rc == 8);<br>
-  size_t BufferSize = DataSize - 8;<br>
-<br>
-  if (!RT->isAllocatedMemory(Addr, BufferSize))<br>
-    return sendLoadStatus(LLI_Status_NotAllocated);<br>
-<br>
-  // Read section data into previously allocated buffer<br>
-  rc = ReadBytes((void*)Addr, BufferSize);<br>
-  if (rc != (int)(BufferSize))<br>
-    return sendLoadStatus(LLI_Status_IncompleteMsg);<br>
-<br>
-  // If IsCode, mark memory executable<br>
-  if (IsCode)<br>
-    sys::Memory::InvalidateInstructionCache((void *)Addr, BufferSize);<br>
<br>
-  // Send MarkLoadComplete message.<br>
-  sendLoadStatus(LLI_Status_Success);<br>
-}<br>
-<br>
-void LLIChildTarget::handleExecute() {<br>
-  // Read the message data size.<br>
-  uint32_t DataSize = 0;<br>
-  int rc = ReadBytes(&DataSize, 4);<br>
-  (void)rc;<br>
-  assert(rc == 4);<br>
-  assert(DataSize == 8);<br>
-<br>
-  // Read the target address.<br>
-  uint64_t Addr = 0;<br>
-  rc = ReadBytes(&Addr, 8);<br>
-  assert(rc == 8);<br>
-<br>
-  // Call function<br>
-  int32_t Result = -1;<br>
-  RT->executeCode(Addr, Result);<br>
-<br>
-  // Send ExecutionResult message.<br>
-  sendExecutionComplete(Result);<br>
-}<br>
+  int InFD;<br>
+  int OutFD;<br>
+  {<br>
+    std::istringstream InFDStream(argv[1]), OutFDStream(argv[2]);<br>
+    InFDStream >> InFD;<br>
+    OutFDStream >> OutFD;<br>
+  }<br>
<br>
-// Outgoing message handlers<br>
-void LLIChildTarget::sendChildActive() {<br>
-  // Write the message type.<br>
-  uint32_t MsgType = (uint32_t)LLI_ChildActive;<br>
-  int rc = WriteBytes(&MsgType, 4);<br>
-  (void)rc;<br>
-  assert(rc == 4);<br>
-<br>
-  // Write the data size.<br>
-  uint32_t DataSize = 0;<br>
-  rc = WriteBytes(&DataSize, 4);<br>
-  assert(rc == 4);<br>
-}<br>
+  if (sys::DynamicLibrary::LoadLibraryPermanently(nullptr)) {<br>
+    errs() << "Error loading program symbols.\n";<br>
+    return 1;<br>
+  }<br>
<br>
-void LLIChildTarget::sendAllocationResult(uint64_t Addr) {<br>
-  // Write the message type.<br>
-  uint32_t MsgType = (uint32_t)LLI_AllocationResult;<br>
-  int rc = WriteBytes(&MsgType, 4);<br>
-  (void)rc;<br>
-  assert(rc == 4);<br>
-<br>
-  // Write the data size.<br>
-  uint32_t DataSize = 8;<br>
-  rc = WriteBytes(&DataSize, 4);<br>
-  assert(rc == 4);<br>
-<br>
-  // Write the allocated address.<br>
-  rc = WriteBytes(&Addr, 8);<br>
-  assert(rc == 8);<br>
-}<br>
+  auto SymbolLookup = [](const std::string &Name) {<br>
+    return RTDyldMemoryManager::getSymbolAddressInProcess(Name);<br>
+  };<br>
+<br>
+  FDRPCChannel Channel(InFD, OutFD);<br>
+  typedef remote::OrcRemoteTargetServer<FDRPCChannel, HostOrcArch> JITServer;<br>
+  JITServer Server(Channel, SymbolLookup);<br>
+<br>
+  while (1) {<br>
+    JITServer::JITProcId Id = JITServer::InvalidId;<br>
+    if (auto EC = Server.getNextProcId(Id)) {<br>
+      errs() << "Error: " << EC.message() << "\n";<br>
+      return 1;<br>
+    }<br>
+    switch (Id) {<br>
+    case JITServer::TerminateSessionId:<br>
+      return 0;<br>
+    default:<br>
+      if (auto EC = Server.handleKnownProcedure(Id)) {<br>
+        errs() << "Error: " << EC.message() << "\n";<br>
+        return 1;<br>
+      }<br>
+    }<br>
+  }<br>
<br>
-void LLIChildTarget::sendLoadStatus(uint32_t Status) {<br>
-  // Write the message type.<br>
-  uint32_t MsgType = (uint32_t)LLI_LoadResult;<br>
-  int rc = WriteBytes(&MsgType, 4);<br>
-  (void)rc;<br>
-  assert(rc == 4);<br>
-<br>
-  // Write the data size.<br>
-  uint32_t DataSize = 4;<br>
-  rc = WriteBytes(&DataSize, 4);<br>
-  assert(rc == 4);<br>
-<br>
-  // Write the result.<br>
-  rc = WriteBytes(&Status, 4);<br>
-  assert(rc == 4);<br>
-}<br>
+  close(InFD);<br>
+  close(OutFD);<br>
<br>
-void LLIChildTarget::sendExecutionComplete(int Result) {<br>
-  // Write the message type.<br>
-  uint32_t MsgType = (uint32_t)LLI_ExecutionResult;<br>
-  int rc = WriteBytes(&MsgType, 4);<br>
-  (void)rc;<br>
-  assert(rc == 4);<br>
-<br>
-<br>
-  // Write the data size.<br>
-  uint32_t DataSize = 4;<br>
-  rc = WriteBytes(&DataSize, 4);<br>
-  assert(rc == 4);<br>
-<br>
-  // Write the result.<br>
-  rc = WriteBytes(&Result, 4);<br>
-  assert(rc == 4);<br>
+  return 0;<br>
 }<br>
-<br>
-#ifdef LLVM_ON_UNIX<br>
-#include "../Unix/RPCChannel.inc"<br>
-#endif<br>
-<br>
-#ifdef LLVM_ON_WIN32<br>
-#include "../Windows/RPCChannel.inc"<br>
-#endif<br>
<br>
Removed: llvm/trunk/tools/lli/RPCChannel.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RPCChannel.h?rev=257342&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RPCChannel.h?rev=257342&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/RPCChannel.h (original)<br>
+++ llvm/trunk/tools/lli/RPCChannel.h (removed)<br>
@@ -1,49 +0,0 @@<br>
-//===---------- RPCChannel.h - LLVM out-of-process JIT execution ----------===//<br>
-//<br>
-//                     The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-//<br>
-// Definition of the RemoteTargetExternal class which executes JITed code in a<br>
-// separate process from where it was built.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#ifndef LLVM_TOOLS_LLI_RPCCHANNEL_H<br>
-#define LLVM_TOOLS_LLI_RPCCHANNEL_H<br>
-<br>
-#include <stdlib.h><br>
-#include <string><br>
-<br>
-namespace llvm {<br>
-<br>
-class RPCChannel {<br>
-public:<br>
-  std::string ChildName;<br>
-<br>
-  RPCChannel() {}<br>
-  ~RPCChannel();<br>
-<br>
-  /// Start the remote process.<br>
-  ///<br>
-  /// @returns True on success. On failure, ErrorMsg is updated with<br>
-  ///          descriptive text of the encountered error.<br>
-  bool createServer();<br>
-<br>
-  bool createClient();<br>
-<br>
-  // This will get filled in as a point to an OS-specific structure.<br>
-  void *ConnectionData;<br>
-<br>
-  bool WriteBytes(const void *Data, size_t Size);<br>
-  bool ReadBytes(void *Data, size_t Size);<br>
-<br>
-  void Wait();<br>
-};<br>
-<br>
-} // end namespace llvm<br>
-<br>
-#endif<br>
<br>
Added: llvm/trunk/tools/lli/RemoteJITUtils.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteJITUtils.h?rev=257343&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteJITUtils.h?rev=257343&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/RemoteJITUtils.h (added)<br>
+++ llvm/trunk/tools/lli/RemoteJITUtils.h Mon Jan 11 10:35:55 2016<br>
@@ -0,0 +1,131 @@<br>
+//===-- RemoteJITUtils.h - Utilities for remote-JITing with LLI -*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// Utilities for remote-JITing with LLI.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_TOOLS_LLI_REMOTEJITUTILS_H<br>
+#define LLVM_TOOLS_LLI_REMOTEJITUTILS_H<br>
+<br>
+#include "llvm/ExecutionEngine/Orc/RPCChannel.h"<br>
+#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"<br>
+<br>
+#if !defined(_MSC_VER) && !defined(__MINGW32__)<br>
+#include <unistd.h><br>
+#else<br>
+#include <io.h><br>
+#endif<br>
+<br>
+/// RPC channel that reads from and writes from file descriptors.<br>
+class FDRPCChannel : public llvm::orc::remote::RPCChannel {<br>
+public:<br>
+  FDRPCChannel(int InFD, int OutFD) : InFD(InFD), OutFD(OutFD) {}<br>
+<br>
+  std::error_code readBytes(char *Dst, unsigned Size) override {<br>
+    assert(Dst && "Attempt to read into null.");<br>
+    ssize_t ReadResult = ::read(InFD, Dst, Size);<br>
+    if (ReadResult != Size)<br>
+      return std::error_code(errno, std::generic_category());<br>
+    return std::error_code();<br>
+  }<br>
+<br>
+  std::error_code appendBytes(const char *Src, unsigned Size) override {<br>
+    assert(Src && "Attempt to append from null.");<br>
+    ssize_t WriteResult = ::write(OutFD, Src, Size);<br>
+    if (WriteResult != Size)<br>
+      std::error_code(errno, std::generic_category());<br>
+    return std::error_code();<br>
+  }<br>
+<br>
+  std::error_code send() override { return std::error_code(); }<br>
+<br>
+private:<br>
+  int InFD, OutFD;<br>
+};<br>
+<br>
+// launch the remote process (see lli.cpp) and return a channel to it.<br>
+std::unique_ptr<FDRPCChannel> launchRemote();<br>
+<br>
+namespace llvm {<br>
+<br>
+// ForwardingMM - Adapter to connect MCJIT to Orc's Remote memory manager.<br>
+class ForwardingMemoryManager : public llvm::RTDyldMemoryManager {<br>
+public:<br>
+  void setMemMgr(std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr) {<br>
+    this->MemMgr = std::move(MemMgr);<br>
+  }<br>
+<br>
+  void setResolver(std::unique_ptr<RuntimeDyld::SymbolResolver> Resolver) {<br>
+    this->Resolver = std::move(Resolver);<br>
+  }<br>
+<br>
+  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,<br>
+                               unsigned SectionID,<br>
+                               StringRef SectionName) override {<br>
+    return MemMgr->allocateCodeSection(Size, Alignment, SectionID, SectionName);<br>
+  }<br>
+<br>
+  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,<br>
+                               unsigned SectionID, StringRef SectionName,<br>
+                               bool IsReadOnly) override {<br>
+    return MemMgr->allocateDataSection(Size, Alignment, SectionID, SectionName,<br>
+                                       IsReadOnly);<br>
+  }<br>
+<br>
+  void reserveAllocationSpace(uintptr_t CodeSize, uint32_t CodeAlign,<br>
+                              uintptr_t RODataSize, uint32_t RODataAlign,<br>
+                              uintptr_t RWDataSize,<br>
+                              uint32_t RWDataAlign) override {<br>
+    MemMgr->reserveAllocationSpace(CodeSize, CodeAlign, RODataSize, RODataAlign,<br>
+                                   RWDataSize, RWDataAlign);<br>
+  }<br>
+<br>
+  bool needsToReserveAllocationSpace() override {<br>
+    return MemMgr->needsToReserveAllocationSpace();<br>
+  }<br>
+<br>
+  void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,<br>
+                        size_t Size) override {<br>
+    MemMgr->registerEHFrames(Addr, LoadAddr, Size);<br>
+  }<br>
+<br>
+  void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,<br>
+                          size_t Size) override {<br>
+    MemMgr->deregisterEHFrames(Addr, LoadAddr, Size);<br>
+  }<br>
+<br>
+  bool finalizeMemory(std::string *ErrMsg = nullptr) override {<br>
+    return MemMgr->finalizeMemory(ErrMsg);<br>
+  }<br>
+<br>
+  void notifyObjectLoaded(RuntimeDyld &RTDyld,<br>
+                          const object::ObjectFile &Obj) override {<br>
+    MemMgr->notifyObjectLoaded(RTDyld, Obj);<br>
+  }<br>
+<br>
+  // Don't hide the sibling notifyObjectLoaded from RTDyldMemoryManager.<br>
+  using RTDyldMemoryManager::notifyObjectLoaded;<br>
+<br>
+  RuntimeDyld::SymbolInfo findSymbol(const std::string &Name) override {<br>
+    return Resolver->findSymbol(Name);<br>
+  }<br>
+<br>
+  RuntimeDyld::SymbolInfo<br>
+  findSymbolInLogicalDylib(const std::string &Name) override {<br>
+    return Resolver->findSymbolInLogicalDylib(Name);<br>
+  }<br>
+<br>
+private:<br>
+  std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr;<br>
+  std::unique_ptr<RuntimeDyld::SymbolResolver> Resolver;<br>
+};<br>
+}<br>
+<br>
+#endif<br>
<br>
Removed: llvm/trunk/tools/lli/RemoteMemoryManager.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteMemoryManager.cpp?rev=257342&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteMemoryManager.cpp?rev=257342&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/RemoteMemoryManager.cpp (original)<br>
+++ llvm/trunk/tools/lli/RemoteMemoryManager.cpp (removed)<br>
@@ -1,174 +0,0 @@<br>
-//===---- RemoteMemoryManager.cpp - Recording memory manager --------------===//<br>
-//<br>
-//                     The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-//<br>
-// This memory manager allocates local storage and keeps a record of each<br>
-// allocation. Iterators are provided for all data and code allocations.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#include "RemoteMemoryManager.h"<br>
-#include "llvm/ExecutionEngine/ExecutionEngine.h"<br>
-#include "llvm/Support/Debug.h"<br>
-#include "llvm/Support/Format.h"<br>
-#include "llvm/Support/raw_ostream.h"<br>
-<br>
-using namespace llvm;<br>
-<br>
-#define DEBUG_TYPE "lli"<br>
-<br>
-RemoteMemoryManager::~RemoteMemoryManager() {<br>
-  for (SmallVector<Allocation, 2>::iterator<br>
-         I = AllocatedSections.begin(), E = AllocatedSections.end();<br>
-       I != E; ++I)<br>
-    sys::Memory::releaseMappedMemory(I->MB);<br>
-}<br>
-<br>
-uint8_t *RemoteMemoryManager::<br>
-allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,<br>
-                    StringRef SectionName) {<br>
-  // The recording memory manager is just a local copy of the remote target.<br>
-  // The alignment requirement is just stored here for later use. Regular<br>
-  // heap storage is sufficient here, but we're using mapped memory to work<br>
-  // around a bug in MCJIT.<br>
-  sys::MemoryBlock Block = allocateSection(Size);<br>
-  // AllocatedSections will own this memory.<br>
-  AllocatedSections.push_back( Allocation(Block, Alignment, true) );<br>
-  // UnmappedSections has the same information but does not own the memory.<br>
-  UnmappedSections.push_back( Allocation(Block, Alignment, true) );<br>
-  return (uint8_t*)Block.base();<br>
-}<br>
-<br>
-uint8_t *RemoteMemoryManager::<br>
-allocateDataSection(uintptr_t Size, unsigned Alignment,<br>
-                    unsigned SectionID, StringRef SectionName,<br>
-                    bool IsReadOnly) {<br>
-  // The recording memory manager is just a local copy of the remote target.<br>
-  // The alignment requirement is just stored here for later use. Regular<br>
-  // heap storage is sufficient here, but we're using mapped memory to work<br>
-  // around a bug in MCJIT.<br>
-  sys::MemoryBlock Block = allocateSection(Size);<br>
-  // AllocatedSections will own this memory.<br>
-  AllocatedSections.push_back( Allocation(Block, Alignment, false) );<br>
-  // UnmappedSections has the same information but does not own the memory.<br>
-  UnmappedSections.push_back( Allocation(Block, Alignment, false) );<br>
-  return (uint8_t*)Block.base();<br>
-}<br>
-<br>
-sys::MemoryBlock RemoteMemoryManager::allocateSection(uintptr_t Size) {<br>
-  std::error_code ec;<br>
-  sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(Size,<br>
-                                                          &Near,<br>
-                                                          sys::Memory::MF_READ |<br>
-                                                          sys::Memory::MF_WRITE,<br>
-                                                          ec);<br>
-  assert(!ec && MB.base());<br>
-<br>
-  // FIXME: This is part of a work around to keep sections near one another<br>
-  // when MCJIT performs relocations after code emission but before<br>
-  // the generated code is moved to the remote target.<br>
-  // Save this address as the basis for our next request<br>
-  Near = MB;<br>
-  return MB;<br>
-}<br>
-<br>
-void RemoteMemoryManager::notifyObjectLoaded(ExecutionEngine *EE,<br>
-                                             const object::ObjectFile &Obj) {<br>
-  // The client should have called setRemoteTarget() before triggering any<br>
-  // code generation.<br>
-  assert(Target);<br>
-  if (!Target)<br>
-    return;<br>
-<br>
-  // FIXME: Make this function thread safe.<br>
-<br>
-  // Lay out our sections in order, with all the code sections first, then<br>
-  // all the data sections.<br>
-  uint64_t CurOffset = 0;<br>
-  unsigned MaxAlign = Target->getPageAlignment();<br>
-  SmallVector<std::pair<Allocation, uint64_t>, 16> Offsets;<br>
-  unsigned NumSections = UnmappedSections.size();<br>
-  // We're going to go through the list twice to separate code and data, but<br>
-  // it's a very small list, so that's OK.<br>
-  for (size_t i = 0, e = NumSections; i != e; ++i) {<br>
-    Allocation &Section = UnmappedSections[i];<br>
-    if (Section.IsCode) {<br>
-      unsigned Size = Section.MB.size();<br>
-      unsigned Align = Section.Alignment;<br>
-      DEBUG(dbgs() << "code region: size " << Size<br>
-                  << ", alignment " << Align << "\n");<br>
-      // Align the current offset up to whatever is needed for the next<br>
-      // section.<br>
-      CurOffset = (CurOffset + Align - 1) / Align * Align;<br>
-      // Save off the address of the new section and allocate its space.<br>
-      Offsets.push_back(std::pair<Allocation,uint64_t>(Section, CurOffset));<br>
-      CurOffset += Size;<br>
-    }<br>
-  }<br>
-  // Adjust to keep code and data aligned on separate pages.<br>
-  CurOffset = (CurOffset + MaxAlign - 1) / MaxAlign * MaxAlign;<br>
-  for (size_t i = 0, e = NumSections; i != e; ++i) {<br>
-    Allocation &Section = UnmappedSections[i];<br>
-    if (!Section.IsCode) {<br>
-      unsigned Size = Section.MB.size();<br>
-      unsigned Align = Section.Alignment;<br>
-      DEBUG(dbgs() << "data region: size " << Size<br>
-                  << ", alignment " << Align << "\n");<br>
-      // Align the current offset up to whatever is needed for the next<br>
-      // section.<br>
-      CurOffset = (CurOffset + Align - 1) / Align * Align;<br>
-      // Save off the address of the new section and allocate its space.<br>
-      Offsets.push_back(std::pair<Allocation,uint64_t>(Section, CurOffset));<br>
-      CurOffset += Size;<br>
-    }<br>
-  }<br>
-<br>
-  // Allocate space in the remote target.<br>
-  uint64_t RemoteAddr;<br>
-  if (!Target->allocateSpace(CurOffset, MaxAlign, RemoteAddr))<br>
-    report_fatal_error(Target->getErrorMsg());<br>
-<br>
-  // Map the section addresses so relocations will get updated in the local<br>
-  // copies of the sections.<br>
-  for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {<br>
-    uint64_t Addr = RemoteAddr + Offsets[i].second;<br>
-    EE->mapSectionAddress(const_cast<void*>(Offsets[i].first.MB.base()), Addr);<br>
-<br>
-    DEBUG(dbgs() << "  Mapping local: " << Offsets[i].first.MB.base()<br>
-                 << " to remote: 0x" << format("%llx", Addr) << "\n");<br>
-<br>
-    MappedSections[Addr] = Offsets[i].first;<br>
-  }<br>
-<br>
-  UnmappedSections.clear();<br>
-}<br>
-<br>
-bool RemoteMemoryManager::finalizeMemory(std::string *ErrMsg) {<br>
-  // FIXME: Make this function thread safe.<br>
-  for (DenseMap<uint64_t, Allocation>::iterator<br>
-         I = MappedSections.begin(), E = MappedSections.end();<br>
-       I != E; ++I) {<br>
-    uint64_t RemoteAddr = I->first;<br>
-    const Allocation &Section = I->second;<br>
-    if (Section.IsCode) {<br>
-      if (!Target->loadCode(RemoteAddr, Section.MB.base(), Section.MB.size()))<br>
-        report_fatal_error(Target->getErrorMsg());<br>
-      DEBUG(dbgs() << "  loading code: " << Section.MB.base()<br>
-            << " to remote: 0x" << format("%llx", RemoteAddr) << "\n");<br>
-    } else {<br>
-      if (!Target->loadData(RemoteAddr, Section.MB.base(), Section.MB.size()))<br>
-        report_fatal_error(Target->getErrorMsg());<br>
-      DEBUG(dbgs() << "  loading data: " << Section.MB.base()<br>
-            << " to remote: 0x" << format("%llx", RemoteAddr) << "\n");<br>
-    }<br>
-  }<br>
-<br>
-  MappedSections.clear();<br>
-<br>
-  return false;<br>
-}<br>
<br>
Removed: llvm/trunk/tools/lli/RemoteMemoryManager.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteMemoryManager.h?rev=257342&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteMemoryManager.h?rev=257342&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/RemoteMemoryManager.h (original)<br>
+++ llvm/trunk/tools/lli/RemoteMemoryManager.h (removed)<br>
@@ -1,101 +0,0 @@<br>
-//===- RemoteMemoryManager.h - LLI MCJIT recording memory manager ------===//<br>
-//<br>
-//                     The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-//<br>
-// This memory manager allocates local storage and keeps a record of each<br>
-// allocation. Iterators are provided for all data and code allocations.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#ifndef LLVM_TOOLS_LLI_REMOTEMEMORYMANAGER_H<br>
-#define LLVM_TOOLS_LLI_REMOTEMEMORYMANAGER_H<br>
-<br>
-#include "RemoteTarget.h"<br>
-#include "llvm/ADT/DenseMap.h"<br>
-#include "llvm/ADT/SmallVector.h"<br>
-#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"<br>
-#include "llvm/Support/ErrorHandling.h"<br>
-#include "llvm/Support/Memory.h"<br>
-#include <utility><br>
-<br>
-namespace llvm {<br>
-<br>
-class RemoteMemoryManager : public RTDyldMemoryManager {<br>
-public:<br>
-  // Notice that this structure takes ownership of the memory allocated.<br>
-  struct Allocation {<br>
-    Allocation() {}<br>
-    Allocation(sys::MemoryBlock mb, unsigned a, bool code)<br>
-      : MB(mb), Alignment(a), IsCode(code) {}<br>
-<br>
-    sys::MemoryBlock  MB;<br>
-    unsigned          Alignment;<br>
-    bool              IsCode;<br>
-  };<br>
-<br>
-private:<br>
-  // This vector contains Allocation objects for all sections which we have<br>
-  // allocated.  This vector effectively owns the memory associated with the<br>
-  // allocations.<br>
-  SmallVector<Allocation, 2>  AllocatedSections;<br>
-<br>
-  // This vector contains pointers to Allocation objects for any sections we<br>
-  // have allocated locally but have not yet remapped for the remote target.<br>
-  // When we receive notification of a completed module load, we will map<br>
-  // these sections into the remote target.<br>
-  SmallVector<Allocation, 2>  UnmappedSections;<br>
-<br>
-  // This map tracks the sections we have remapped for the remote target<br>
-  // but have not yet copied to the target.<br>
-  DenseMap<uint64_t, Allocation>  MappedSections;<br>
-<br>
-  // FIXME: This is part of a work around to keep sections near one another<br>
-  // when MCJIT performs relocations after code emission but before<br>
-  // the generated code is moved to the remote target.<br>
-  sys::MemoryBlock Near;<br>
-  sys::MemoryBlock allocateSection(uintptr_t Size);<br>
-<br>
-  RemoteTarget *Target;<br>
-<br>
-public:<br>
-  RemoteMemoryManager() : Target(nullptr) {}<br>
-  ~RemoteMemoryManager() override;<br>
-<br>
-  uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,<br>
-                               unsigned SectionID,<br>
-                               StringRef SectionName) override;<br>
-<br>
-  uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,<br>
-                               unsigned SectionID, StringRef SectionName,<br>
-                               bool IsReadOnly) override;<br>
-<br>
-  // For now, remote symbol resolution is not support in lli.  The MCJIT<br>
-  // interface does support this, but clients must provide their own<br>
-  // mechanism for finding remote symbol addresses.  MCJIT will resolve<br>
-  // symbols from Modules it contains.<br>
-  uint64_t getSymbolAddress(const std::string &Name) override { return 0; }<br>
-<br>
-  void notifyObjectLoaded(ExecutionEngine *EE,<br>
-                          const object::ObjectFile &Obj) override;<br>
-<br>
-  bool finalizeMemory(std::string *ErrMsg) override;<br>
-<br>
-  // For now, remote EH frame registration isn't supported.  Remote symbol<br>
-  // resolution is a prerequisite to supporting remote EH frame registration.<br>
-  void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr,<br>
-                        size_t Size) override {}<br>
-  void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr,<br>
-                          size_t Size) override {}<br>
-<br>
-  // This is a non-interface function used by lli<br>
-  void setRemoteTarget(RemoteTarget *T) { Target = T; }<br>
-};<br>
-<br>
-} // end namespace llvm<br>
-<br>
-#endif<br>
<br>
Removed: llvm/trunk/tools/lli/RemoteTarget.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTarget.cpp?rev=257342&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTarget.cpp?rev=257342&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/RemoteTarget.cpp (original)<br>
+++ llvm/trunk/tools/lli/RemoteTarget.cpp (removed)<br>
@@ -1,71 +0,0 @@<br>
-//===- RemoteTarget.cpp - LLVM Remote process JIT execution -----*- C++ -*-===//<br>
-//<br>
-//                     The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-//<br>
-// Implementation of the RemoteTarget class which executes JITed code in a<br>
-// separate address range from where it was built.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#include "RemoteTarget.h"<br>
-#include "llvm/ADT/StringRef.h"<br>
-#include "llvm/Support/DataTypes.h"<br>
-#include "llvm/Support/Memory.h"<br>
-#include <stdlib.h><br>
-#include <string><br>
-<br>
-using namespace llvm;<br>
-<br>
-////////////////////////////////////////////////////////////////////////////////<br>
-// Simulated remote execution<br>
-//<br>
-// This implementation will simply move generated code and data to a new memory<br>
-// location in the current executable and let it run from there.<br>
-////////////////////////////////////////////////////////////////////////////////<br>
-<br>
-bool RemoteTarget::allocateSpace(size_t Size, unsigned Alignment,<br>
-                                 uint64_t &Address) {<br>
-  sys::MemoryBlock *Prev = Allocations.size() ? &Allocations.back() : nullptr;<br>
-  sys::MemoryBlock Mem = sys::Memory::AllocateRWX(Size, Prev, &ErrorMsg);<br>
-  if (Mem.base() == nullptr)<br>
-    return false;<br>
-  if ((uintptr_t)Mem.base() % Alignment) {<br>
-    ErrorMsg = "unable to allocate sufficiently aligned memory";<br>
-    return false;<br>
-  }<br>
-  Address = reinterpret_cast<uint64_t>(Mem.base());<br>
-  Allocations.push_back(Mem);<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTarget::loadData(uint64_t Address, const void *Data, size_t Size) {<br>
-  memcpy ((void*)Address, Data, Size);<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTarget::loadCode(uint64_t Address, const void *Data, size_t Size) {<br>
-  memcpy ((void*)Address, Data, Size);<br>
-  sys::MemoryBlock Mem((void*)Address, Size);<br>
-  sys::Memory::setExecutable(Mem, &ErrorMsg);<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTarget::executeCode(uint64_t Address, int &RetVal) {<br>
-  int (*fn)() = (int(*)())Address;<br>
-  RetVal = fn();<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTarget::create() {<br>
-  return true;<br>
-}<br>
-<br>
-void RemoteTarget::stop() {<br>
-  for (unsigned i = 0, e = Allocations.size(); i != e; ++i)<br>
-    sys::Memory::ReleaseRWX(Allocations[i]);<br>
-}<br>
<br>
Removed: llvm/trunk/tools/lli/RemoteTarget.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTarget.h?rev=257342&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTarget.h?rev=257342&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/RemoteTarget.h (original)<br>
+++ llvm/trunk/tools/lli/RemoteTarget.h (removed)<br>
@@ -1,122 +0,0 @@<br>
-//===- RemoteTarget.h - LLVM Remote process JIT execution ----------------===//<br>
-//<br>
-//                     The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-//<br>
-// Definition of the RemoteTarget class which executes JITed code in a<br>
-// separate address range from where it was built.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#ifndef LLVM_TOOLS_LLI_REMOTETARGET_H<br>
-#define LLVM_TOOLS_LLI_REMOTETARGET_H<br>
-<br>
-#include "llvm/ADT/SmallVector.h"<br>
-#include "llvm/ADT/StringRef.h"<br>
-#include "llvm/Support/DataTypes.h"<br>
-#include "llvm/Support/Memory.h"<br>
-#include <stdlib.h><br>
-#include <string><br>
-<br>
-namespace llvm {<br>
-<br>
-class RemoteTarget {<br>
-  bool IsRunning;<br>
-<br>
-  typedef SmallVector<sys::MemoryBlock, 16> AllocMapType;<br>
-  AllocMapType Allocations;<br>
-<br>
-protected:<br>
-  std::string ErrorMsg;<br>
-<br>
-public:<br>
-  StringRef getErrorMsg() const { return ErrorMsg; }<br>
-<br>
-  /// Allocate space in the remote target address space.<br>
-  ///<br>
-  /// @param      Size      Amount of space, in bytes, to allocate.<br>
-  /// @param      Alignment Required minimum alignment for allocated space.<br>
-  /// @param[out] Address   Remote address of the allocated memory.<br>
-  ///<br>
-  /// @returns True on success. On failure, ErrorMsg is updated with<br>
-  ///          descriptive text of the encountered error.<br>
-  virtual bool allocateSpace(size_t Size,<br>
-                             unsigned Alignment,<br>
-                             uint64_t &Address);<br>
-<br>
-  bool isAllocatedMemory(uint64_t Address, uint32_t Size) {<br>
-    uint64_t AddressEnd = Address + Size;<br>
-    for (AllocMapType::const_iterator I = Allocations.begin(),<br>
-                                      E = Allocations.end();<br>
-         I != E; ++I) {<br>
-      if (Address >= (uint64_t)I->base() &&<br>
-          AddressEnd <= (uint64_t)I->base() + I->size())<br>
-        return true;<br>
-    }<br>
-    return false;<br>
-  }<br>
-<br>
-  /// Load data into the target address space.<br>
-  ///<br>
-  /// @param      Address   Destination address in the target process.<br>
-  /// @param      Data      Source address in the host process.<br>
-  /// @param      Size      Number of bytes to copy.<br>
-  ///<br>
-  /// @returns True on success. On failure, ErrorMsg is updated with<br>
-  ///          descriptive text of the encountered error.<br>
-  virtual bool loadData(uint64_t Address,<br>
-                        const void *Data,<br>
-                        size_t Size);<br>
-<br>
-  /// Load code into the target address space and prepare it for execution.<br>
-  ///<br>
-  /// @param      Address   Destination address in the target process.<br>
-  /// @param      Data      Source address in the host process.<br>
-  /// @param      Size      Number of bytes to copy.<br>
-  ///<br>
-  /// @returns True on success. On failure, ErrorMsg is updated with<br>
-  ///          descriptive text of the encountered error.<br>
-  virtual bool loadCode(uint64_t Address,<br>
-                        const void *Data,<br>
-                        size_t Size);<br>
-<br>
-  /// Execute code in the target process. The called function is required<br>
-  /// to be of signature int "(*)(void)".<br>
-  ///<br>
-  /// @param      Address   Address of the loaded function in the target<br>
-  ///                       process.<br>
-  /// @param[out] RetVal    The integer return value of the called function.<br>
-  ///<br>
-  /// @returns True on success. On failure, ErrorMsg is updated with<br>
-  ///          descriptive text of the encountered error.<br>
-  virtual bool executeCode(uint64_t Address,<br>
-                           int &RetVal);<br>
-<br>
-  /// Minimum alignment for memory permissions. Used to separate code and<br>
-  /// data regions to make sure data doesn't get marked as code or vice<br>
-  /// versa.<br>
-  ///<br>
-  /// @returns Page alignment return value. Default of 4k.<br>
-  virtual unsigned getPageAlignment() { return 4096; }<br>
-<br>
-  /// Start the remote process.<br>
-  virtual bool create();<br>
-<br>
-  /// Terminate the remote process.<br>
-  virtual void stop();<br>
-<br>
-  RemoteTarget() : IsRunning(false), ErrorMsg("") {}<br>
-  virtual ~RemoteTarget() { if (IsRunning) stop(); }<br>
-private:<br>
-  // Main processing function for the remote target process. Command messages<br>
-  // are received on file descriptor CmdFD and responses come back on OutFD.<br>
-  static void doRemoteTargeting(int CmdFD, int OutFD);<br>
-};<br>
-<br>
-} // end namespace llvm<br>
-<br>
-#endif<br>
<br>
Removed: llvm/trunk/tools/lli/RemoteTargetExternal.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTargetExternal.cpp?rev=257342&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTargetExternal.cpp?rev=257342&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/RemoteTargetExternal.cpp (original)<br>
+++ llvm/trunk/tools/lli/RemoteTargetExternal.cpp (removed)<br>
@@ -1,327 +0,0 @@<br>
-//===---- RemoteTargetExternal.cpp - LLVM out-of-process JIT execution ----===//<br>
-//<br>
-//                     The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-//<br>
-// Implementation of the RemoteTargetExternal class which executes JITed code<br>
-// in a separate process from where it was built.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#include "llvm/Config/config.h"<br>
-#include "RemoteTarget.h"<br>
-#include "RemoteTargetExternal.h"<br>
-#include "llvm/ADT/StringRef.h"<br>
-#include "llvm/Support/DataTypes.h"<br>
-#include "llvm/Support/Debug.h"<br>
-#include "llvm/Support/Format.h"<br>
-#include "llvm/Support/Memory.h"<br>
-#include "llvm/Support/Program.h"<br>
-#include "llvm/Support/raw_ostream.h"<br>
-#include <string><br>
-<br>
-using namespace llvm;<br>
-<br>
-#define DEBUG_TYPE "lli"<br>
-<br>
-bool RemoteTargetExternal::allocateSpace(size_t Size, unsigned Alignment,<br>
-                                 uint64_t &Address) {<br>
-  DEBUG(dbgs() << "Message [allocate space] size: " << Size <<<br>
-                  ", align: " << Alignment << "\n");<br>
-  if (!SendAllocateSpace(Alignment, Size)) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::allocateSpace)";<br>
-    return false;<br>
-  }<br>
-  if (!Receive(LLI_AllocationResult, Address)) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::allocateSpace)";<br>
-    return false;<br>
-  }<br>
-  if (Address == 0) {<br>
-    ErrorMsg += "failed allocation, (RemoteTargetExternal::allocateSpace)";<br>
-    return false;<br>
-  }<br>
-  DEBUG(dbgs() << "Message [allocate space] addr: 0x" <<<br>
-                  format("%llx", Address) << "\n");<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTargetExternal::loadData(uint64_t Address, const void *Data, size_t Size) {<br>
-  DEBUG(dbgs() << "Message [load data] addr: 0x" << format("%llx", Address) <<<br>
-                  ", size: " << Size << "\n");<br>
-  if (!SendLoadSection(Address, Data, (uint32_t)Size, false)) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::loadData)";<br>
-    return false;<br>
-  }<br>
-  int Status = LLI_Status_Success;<br>
-  if (!Receive(LLI_LoadResult, Status)) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::loadData)";<br>
-    return false;<br>
-  }<br>
-  if (Status == LLI_Status_IncompleteMsg) {<br>
-    ErrorMsg += "incomplete load data, (RemoteTargetExternal::loadData)";<br>
-    return false;<br>
-  }<br>
-  if (Status == LLI_Status_NotAllocated) {<br>
-    ErrorMsg += "data memory not allocated, (RemoteTargetExternal::loadData)";<br>
-    return false;<br>
-  }<br>
-  DEBUG(dbgs() << "Message [load data] complete\n");<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTargetExternal::loadCode(uint64_t Address, const void *Data, size_t Size) {<br>
-  DEBUG(dbgs() << "Message [load code] addr: 0x" << format("%llx", Address) <<<br>
-                  ", size: " << Size << "\n");<br>
-  if (!SendLoadSection(Address, Data, (uint32_t)Size, true)) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::loadCode)";<br>
-    return false;<br>
-  }<br>
-  int Status = LLI_Status_Success;<br>
-  if (!Receive(LLI_LoadResult, Status)) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::loadCode)";<br>
-    return false;<br>
-  }<br>
-  if (Status == LLI_Status_IncompleteMsg) {<br>
-    ErrorMsg += "incomplete load data, (RemoteTargetExternal::loadData)";<br>
-    return false;<br>
-  }<br>
-  if (Status == LLI_Status_NotAllocated) {<br>
-    ErrorMsg += "data memory not allocated, (RemoteTargetExternal::loadData)";<br>
-    return false;<br>
-  }<br>
-  DEBUG(dbgs() << "Message [load code] complete\n");<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTargetExternal::executeCode(uint64_t Address, int32_t &RetVal) {<br>
-  DEBUG(dbgs() << "Message [exectue code] addr: " << Address << "\n");<br>
-  if (!SendExecute(Address)) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::executeCode)";<br>
-    return false;<br>
-  }<br>
-  if (!Receive(LLI_ExecutionResult, RetVal)) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::executeCode)";<br>
-    return false;<br>
-  }<br>
-  DEBUG(dbgs() << "Message [exectue code] return: " << RetVal << "\n");<br>
-  return true;<br>
-}<br>
-<br>
-void RemoteTargetExternal::stop() {<br>
-  SendTerminate();<br>
-  RPC.Wait();<br>
-}<br>
-<br>
-bool RemoteTargetExternal::SendAllocateSpace(uint32_t Alignment, uint32_t Size) {<br>
-  if (!SendHeader(LLI_AllocateSpace)) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::SendAllocateSpace)";<br>
-    return false;<br>
-  }<br>
-<br>
-  AppendWrite((const void *)&Alignment, 4);<br>
-  AppendWrite((const void *)&Size, 4);<br>
-<br>
-  if (!SendPayload()) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::SendAllocateSpace)";<br>
-    return false;<br>
-  }<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTargetExternal::SendLoadSection(uint64_t Addr,<br>
-                                       const void *Data,<br>
-                                       uint32_t Size,<br>
-                                       bool IsCode) {<br>
-  LLIMessageType MsgType = IsCode ? LLI_LoadCodeSection : LLI_LoadDataSection;<br>
-  if (!SendHeader(MsgType)) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::SendLoadSection)";<br>
-    return false;<br>
-  }<br>
-<br>
-  AppendWrite((const void *)&Addr, 8);<br>
-  AppendWrite(Data, Size);<br>
-<br>
-  if (!SendPayload()) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::SendLoadSection)";<br>
-    return false;<br>
-  }<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTargetExternal::SendExecute(uint64_t Addr) {<br>
-  if (!SendHeader(LLI_Execute)) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::SendExecute)";<br>
-    return false;<br>
-  }<br>
-<br>
-  AppendWrite((const void *)&Addr, 8);<br>
-<br>
-  if (!SendPayload()) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::SendExecute)";<br>
-    return false;<br>
-  }<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTargetExternal::SendTerminate() {<br>
-  return SendHeader(LLI_Terminate);<br>
-  // No data or data size is sent with Terminate<br>
-}<br>
-<br>
-bool RemoteTargetExternal::Receive(LLIMessageType Msg) {<br>
-  if (!ReceiveHeader(Msg))<br>
-    return false;<br>
-  int Unused;<br>
-  AppendRead(&Unused, 0);<br>
-  if (!ReceivePayload())<br>
-    return false;<br>
-  ReceiveData.clear();<br>
-  Sizes.clear();<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTargetExternal::Receive(LLIMessageType Msg, int32_t &Data) {<br>
-  if (!ReceiveHeader(Msg))<br>
-    return false;<br>
-  AppendRead(&Data, 4);<br>
-  if (!ReceivePayload())<br>
-    return false;<br>
-  ReceiveData.clear();<br>
-  Sizes.clear();<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTargetExternal::Receive(LLIMessageType Msg, uint64_t &Data) {<br>
-  if (!ReceiveHeader(Msg))<br>
-    return false;<br>
-  AppendRead(&Data, 8);<br>
-  if (!ReceivePayload())<br>
-    return false;<br>
-  ReceiveData.clear();<br>
-  Sizes.clear();<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTargetExternal::ReceiveHeader(LLIMessageType ExpectedMsgType) {<br>
-  assert(ReceiveData.empty() && Sizes.empty() &&<br>
-         "Payload vector not empty to receive header");<br>
-<br>
-  // Message header, with type to follow<br>
-  uint32_t MsgType;<br>
-  if (!ReadBytes(&MsgType, 4)) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::ReceiveHeader)";<br>
-    return false;<br>
-  }<br>
-  if (MsgType != (uint32_t)ExpectedMsgType) {<br>
-    ErrorMsg = "received unexpected message type";<br>
-    ErrorMsg += ". Expecting: ";<br>
-    ErrorMsg += ExpectedMsgType;<br>
-    ErrorMsg += ", Got: ";<br>
-    ErrorMsg += MsgType;<br>
-    return false;<br>
-  }<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTargetExternal::ReceivePayload() {<br>
-  assert(!ReceiveData.empty() &&<br>
-         "Payload vector empty to receive");<br>
-  assert(ReceiveData.size() == Sizes.size() &&<br>
-         "Unexpected mismatch between data and size");<br>
-<br>
-  uint32_t TotalSize = 0;<br>
-  for (int I=0, E=Sizes.size(); I < E; I++)<br>
-    TotalSize += Sizes[I];<br>
-<br>
-  // Payload size header<br>
-  uint32_t DataSize;<br>
-  if (!ReadBytes(&DataSize, 4)) {<br>
-    ErrorMsg += ", invalid data size";<br>
-    return false;<br>
-  }<br>
-  if (DataSize != TotalSize) {<br>
-    ErrorMsg = "unexpected data size";<br>
-    ErrorMsg += ". Expecting: ";<br>
-    ErrorMsg += TotalSize;<br>
-    ErrorMsg += ", Got: ";<br>
-    ErrorMsg += DataSize;<br>
-    return false;<br>
-  }<br>
-  if (DataSize == 0)<br>
-    return true;<br>
-<br>
-  // Payload itself<br>
-  for (int I=0, E=Sizes.size(); I < E; I++) {<br>
-    if (!ReadBytes(ReceiveData[I], Sizes[I])) {<br>
-      ErrorMsg = "unexpected data while reading message";<br>
-      return false;<br>
-    }<br>
-  }<br>
-<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTargetExternal::SendHeader(LLIMessageType MsgType) {<br>
-  assert(SendData.empty() && Sizes.empty() &&<br>
-         "Payload vector not empty to send header");<br>
-<br>
-  // Message header, with type to follow<br>
-  if (!WriteBytes(&MsgType, 4)) {<br>
-    ErrorMsg += ", (RemoteTargetExternal::SendHeader)";<br>
-    return false;<br>
-  }<br>
-  return true;<br>
-}<br>
-<br>
-bool RemoteTargetExternal::SendPayload() {<br>
-  assert(!SendData.empty() && !Sizes.empty() &&<br>
-         "Payload vector empty to send");<br>
-  assert(SendData.size() == Sizes.size() &&<br>
-         "Unexpected mismatch between data and size");<br>
-<br>
-  uint32_t TotalSize = 0;<br>
-  for (int I=0, E=Sizes.size(); I < E; I++)<br>
-    TotalSize += Sizes[I];<br>
-<br>
-  // Payload size header<br>
-  if (!WriteBytes(&TotalSize, 4)) {<br>
-    ErrorMsg += ", invalid data size";<br>
-    return false;<br>
-  }<br>
-  if (TotalSize == 0)<br>
-    return true;<br>
-<br>
-  // Payload itself<br>
-  for (int I=0, E=Sizes.size(); I < E; I++) {<br>
-    if (!WriteBytes(SendData[I], Sizes[I])) {<br>
-      ErrorMsg = "unexpected data while writing message";<br>
-      return false;<br>
-    }<br>
-  }<br>
-<br>
-  SendData.clear();<br>
-  Sizes.clear();<br>
-  return true;<br>
-}<br>
-<br>
-void RemoteTargetExternal::AppendWrite(const void *Data, uint32_t Size) {<br>
-  SendData.push_back(Data);<br>
-  Sizes.push_back(Size);<br>
-}<br>
-<br>
-void RemoteTargetExternal::AppendRead(void *Data, uint32_t Size) {<br>
-  ReceiveData.push_back(Data);<br>
-  Sizes.push_back(Size);<br>
-}<br>
-<br>
-#ifdef LLVM_ON_UNIX<br>
-#include "Unix/RPCChannel.inc"<br>
-#endif<br>
-<br>
-#ifdef LLVM_ON_WIN32<br>
-#include "Windows/RPCChannel.inc"<br>
-#endif<br>
<br>
Removed: llvm/trunk/tools/lli/RemoteTargetExternal.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTargetExternal.h?rev=257342&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTargetExternal.h?rev=257342&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/RemoteTargetExternal.h (original)<br>
+++ llvm/trunk/tools/lli/RemoteTargetExternal.h (removed)<br>
@@ -1,143 +0,0 @@<br>
-//===----- RemoteTargetExternal.h - LLVM out-of-process JIT execution -----===//<br>
-//<br>
-//                     The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-//<br>
-// Definition of the RemoteTargetExternal class which executes JITed code in a<br>
-// separate process from where it was built.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#ifndef LLVM_TOOLS_LLI_REMOTETARGETEXTERNAL_H<br>
-#define LLVM_TOOLS_LLI_REMOTETARGETEXTERNAL_H<br>
-<br>
-#include "RPCChannel.h"<br>
-#include "RemoteTarget.h"<br>
-#include "RemoteTargetMessage.h"<br>
-#include "llvm/ADT/SmallVector.h"<br>
-#include "llvm/ADT/StringRef.h"<br>
-#include "llvm/Config/config.h"<br>
-#include "llvm/Support/DataTypes.h"<br>
-#include "llvm/Support/Memory.h"<br>
-#include <stdlib.h><br>
-#include <string><br>
-<br>
-namespace llvm {<br>
-<br>
-class RemoteTargetExternal : public RemoteTarget {<br>
-  RPCChannel RPC;<br>
-<br>
-  bool WriteBytes(const void *Data, size_t Size) {<br>
-    return RPC.WriteBytes(Data, Size);<br>
-  }<br>
-<br>
-  bool ReadBytes(void *Data, size_t Size) { return RPC.ReadBytes(Data, Size); }<br>
-<br>
-public:<br>
-  /// Allocate space in the remote target address space.<br>
-  ///<br>
-  /// @param      Size      Amount of space, in bytes, to allocate.<br>
-  /// @param      Alignment Required minimum alignment for allocated space.<br>
-  /// @param[out] Address   Remote address of the allocated memory.<br>
-  ///<br>
-  /// @returns True on success. On failure, ErrorMsg is updated with<br>
-  ///          descriptive text of the encountered error.<br>
-  bool allocateSpace(size_t Size, unsigned Alignment,<br>
-                     uint64_t &Address) override;<br>
-<br>
-  /// Load data into the target address space.<br>
-  ///<br>
-  /// @param      Address   Destination address in the target process.<br>
-  /// @param      Data      Source address in the host process.<br>
-  /// @param      Size      Number of bytes to copy.<br>
-  ///<br>
-  /// @returns True on success. On failure, ErrorMsg is updated with<br>
-  ///          descriptive text of the encountered error.<br>
-  bool loadData(uint64_t Address, const void *Data, size_t Size) override;<br>
-<br>
-  /// Load code into the target address space and prepare it for execution.<br>
-  ///<br>
-  /// @param      Address   Destination address in the target process.<br>
-  /// @param      Data      Source address in the host process.<br>
-  /// @param      Size      Number of bytes to copy.<br>
-  ///<br>
-  /// @returns True on success. On failure, ErrorMsg is updated with<br>
-  ///          descriptive text of the encountered error.<br>
-  bool loadCode(uint64_t Address, const void *Data, size_t Size) override;<br>
-<br>
-  /// Execute code in the target process. The called function is required<br>
-  /// to be of signature int "(*)(void)".<br>
-  ///<br>
-  /// @param      Address   Address of the loaded function in the target<br>
-  ///                       process.<br>
-  /// @param[out] RetVal    The integer return value of the called function.<br>
-  ///<br>
-  /// @returns True on success. On failure, ErrorMsg is updated with<br>
-  ///          descriptive text of the encountered error.<br>
-  bool executeCode(uint64_t Address, int &RetVal) override;<br>
-<br>
-  /// Minimum alignment for memory permissions. Used to separate code and<br>
-  /// data regions to make sure data doesn't get marked as code or vice<br>
-  /// versa.<br>
-  ///<br>
-  /// @returns Page alignment return value. Default of 4k.<br>
-  unsigned getPageAlignment() override { return 4096; }<br>
-<br>
-  bool create() override {<br>
-    RPC.ChildName = ChildName;<br>
-    if (!RPC.createServer())<br>
-      return true;<br>
-<br>
-    // We must get Ack from the client (blocking read)<br>
-    if (!Receive(LLI_ChildActive)) {<br>
-      ErrorMsg += ", (RPCChannel::create) - Stopping process!";<br>
-      stop();<br>
-      return false;<br>
-    }<br>
-<br>
-    return true;<br>
-  }<br>
-<br>
-  /// Terminate the remote process.<br>
-  void stop() override;<br>
-<br>
-  RemoteTargetExternal(std::string &Name) : RemoteTarget(), ChildName(Name) {}<br>
-  ~RemoteTargetExternal() override {}<br>
-<br>
-private:<br>
-  std::string ChildName;<br>
-<br>
-  bool SendAllocateSpace(uint32_t Alignment, uint32_t Size);<br>
-  bool SendLoadSection(uint64_t Addr,<br>
-                       const void *Data,<br>
-                       uint32_t Size,<br>
-                       bool IsCode);<br>
-  bool SendExecute(uint64_t Addr);<br>
-  bool SendTerminate();<br>
-<br>
-  // High-level wrappers for receiving data<br>
-  bool Receive(LLIMessageType Msg);<br>
-  bool Receive(LLIMessageType Msg, int32_t &Data);<br>
-  bool Receive(LLIMessageType Msg, uint64_t &Data);<br>
-<br>
-  // Lower level target-independent read/write to deal with errors<br>
-  bool ReceiveHeader(LLIMessageType Msg);<br>
-  bool ReceivePayload();<br>
-  bool SendHeader(LLIMessageType Msg);<br>
-  bool SendPayload();<br>
-<br>
-  // Functions to append/retrieve data from the payload<br>
-  SmallVector<const void *, 2> SendData;<br>
-  SmallVector<void *, 1> ReceiveData; // Future proof<br>
-  SmallVector<int, 2> Sizes;<br>
-  void AppendWrite(const void *Data, uint32_t Size);<br>
-  void AppendRead(void *Data, uint32_t Size);<br>
-};<br>
-<br>
-} // end namespace llvm<br>
-<br>
-#endif<br>
<br>
Removed: llvm/trunk/tools/lli/RemoteTargetMessage.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTargetMessage.h?rev=257342&view=auto" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTargetMessage.h?rev=257342&view=auto</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/RemoteTargetMessage.h (original)<br>
+++ llvm/trunk/tools/lli/RemoteTargetMessage.h (removed)<br>
@@ -1,85 +0,0 @@<br>
-//===---- RemoteTargetMessage.h - LLI out-of-process message protocol -----===//<br>
-//<br>
-//                     The LLVM Compiler Infrastructure<br>
-//<br>
-// This file is distributed under the University of Illinois Open Source<br>
-// License. See LICENSE.TXT for details.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-//<br>
-// Definition of the LLIMessageType enum which is used for communication with a<br>
-// child process for remote execution.<br>
-//<br>
-//===----------------------------------------------------------------------===//<br>
-<br>
-#ifndef LLVM_TOOLS_LLI_REMOTETARGETMESSAGE_H<br>
-#define LLVM_TOOLS_LLI_REMOTETARGETMESSAGE_H<br>
-<br>
-namespace llvm {<br>
-<br>
-// LLI messages from parent-to-child or vice versa follow an exceedingly simple<br>
-// protocol where the first four bytes represent the message type, the next<br>
-// four bytes represent the size of data for the command and following bytes<br>
-// represent the actual data.<br>
-//<br>
-// The protocol is not intended to be robust, secure or fault-tolerant.  It is<br>
-// only here for testing purposes and is therefore intended to be the simplest<br>
-// implementation that will work.  It is assumed that the parent and child<br>
-// share characteristics like endianness.<br>
-//<br>
-// Quick description of the protocol:<br>
-//<br>
-// { Header + Payload Size + Payload }<br>
-//<br>
-// The protocol message consist of a header, the payload size (which can be<br>
-// zero), and the payload itself. The payload can contain any number of items,<br>
-// and the size has to be the sum of them all. Each end is responsible for<br>
-// reading/writing the correct number of items with the correct sizes.<br>
-//<br>
-// The current four known exchanges are:<br>
-//<br>
-//  * Allocate Space:<br>
-//   Parent: { LLI_AllocateSpace, 8, Alignment, Size }<br>
-//    Child: { LLI_AllocationResult, 8, Address }<br>
-//<br>
-//  * Load Data:<br>
-//   Parent: { LLI_LoadDataSection, 8+Size, Address, Data }<br>
-//    Child: { LLI_LoadComplete, 4, StatusCode }<br>
-//<br>
-//  * Load Code:<br>
-//   Parent: { LLI_LoadCodeSection, 8+Size, Address, Code }<br>
-//    Child: { LLI_LoadComplete, 4, StatusCode }<br>
-//<br>
-//  * Execute Code:<br>
-//   Parent: { LLI_Execute, 8, Address }<br>
-//    Child: { LLI_ExecutionResult, 4, Result }<br>
-//<br>
-// It is the responsibility of either side to check for correct headers,<br>
-// sizes and payloads, since any inconsistency would misalign the pipe, and<br>
-// result in data corruption.<br>
-<br>
-enum LLIMessageType {<br>
-  LLI_Error = -1,<br>
-  LLI_ChildActive = 0,        // Data = not used<br>
-  LLI_AllocateSpace,          // Data = struct { uint32_t Align, uint_32t Size }<br>
-  LLI_AllocationResult,       // Data = uint64_t Address (child memory space)<br>
-<br>
-  LLI_LoadCodeSection,        // Data = uint64_t Address, void * SectionData<br>
-  LLI_LoadDataSection,        // Data = uint64_t Address, void * SectionData<br>
-  LLI_LoadResult,             // Data = uint32_t LLIMessageStatus<br>
-<br>
-  LLI_Execute,                // Data = uint64_t Address<br>
-  LLI_ExecutionResult,        // Data = uint32_t Result<br>
-<br>
-  LLI_Terminate               // Data = not used<br>
-};<br>
-<br>
-enum LLIMessageStatus {<br>
-  LLI_Status_Success = 0,     // Operation succeeded<br>
-  LLI_Status_NotAllocated,    // Address+Size not allocated in child space<br>
-  LLI_Status_IncompleteMsg    // Size received doesn't match request<br>
-};<br>
-<br>
-} // end namespace llvm<br>
-<br>
-#endif<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=257343&r1=257342&r2=257343&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=257343&r1=257342&r2=257343&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/tools/lli/lli.cpp (original)<br>
+++ llvm/trunk/tools/lli/lli.cpp Mon Jan 11 10:35:55 2016<br>
@@ -13,11 +13,9 @@<br>
 //<br>
 //===----------------------------------------------------------------------===//<br>
<br>
-#include "llvm/IR/LLVMContext.h"<br>
 #include "OrcLazyJIT.h"<br>
-#include "RemoteMemoryManager.h"<br>
-#include "RemoteTarget.h"<br>
-#include "RemoteTargetExternal.h"<br>
+#include "RemoteJITUtils.h"<br>
+#include "llvm/IR/LLVMContext.h"<br>
 #include "llvm/ADT/Triple.h"<br>
 #include "llvm/Bitcode/ReaderWriter.h"<br>
 #include "llvm/CodeGen/LinkAllCodegenComponents.h"<br>
@@ -28,6 +26,7 @@<br>
 #include "llvm/ExecutionEngine/ObjectCache.h"<br>
 #include "llvm/ExecutionEngine/OrcMCJITReplacement.h"<br>
 #include "llvm/ExecutionEngine/SectionMemoryManager.h"<br>
+#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"<br>
 #include "llvm/IR/IRBuilder.h"<br>
 #include "llvm/IR/Module.h"<br>
 #include "llvm/IR/Type.h"<br>
@@ -449,7 +448,7 @@ int main(int argc, char **argv, char * c<br>
   RTDyldMemoryManager *RTDyldMM = nullptr;<br>
   if (!ForceInterpreter) {<br>
     if (RemoteMCJIT)<br>
-      RTDyldMM = new RemoteMemoryManager();<br>
+      RTDyldMM = new ForwardingMemoryManager();<br>
     else<br>
       RTDyldMM = new SectionMemoryManager();<br>
<br>
@@ -582,6 +581,27 @@ int main(int argc, char **argv, char * c<br>
<br>
   int Result;<br>
<br>
+  // Sanity check use of remote-jit: LLI currently only supports use of the<br>
+  // remote JIT on Unix platforms.<br>
+  // FIXME: Remove this pointless fallback mode which causes tests to "pass"<br>
+  // on platforms where they should XFAIL.<br>
+  if (RemoteMCJIT) {<br>
+#ifndef LLVM_ON_UNIX<br>
+    errs() << "Warning: host does not support external remote targets.\n"<br>
+           << "  Defaulting to local execution execution\n";<br></blockquote><div><br></div><div>Duplicate "execution" here ^ ?</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    RemoteMCJIT = false;<br>
+#else<br>
+    if (ChildExecPath.empty()) {<br>
+      errs() << "-remote-mcjit requires -mcjit-remote-process.\n";<br>
+      exit(1);<br>
+    } else if (!sys::fs::can_execute(ChildExecPath)) {<br>
+      errs() << "Unable to find usable child executable: '" << ChildExecPath<br>
+             << "'\n";<br>
+      return -1;<br>
+    }<br>
+#endif<br>
+  }<br>
+<br>
   if (!RemoteMCJIT) {<br>
     // If the program doesn't explicitly call exit, we will need the Exit<br>
     // function later on to make an explicit call, so get the function now.<br>
@@ -629,66 +649,123 @@ int main(int argc, char **argv, char * c<br>
     // Remote target MCJIT doesn't (yet) support static constructors. No reason<br>
     // it couldn't. This is a limitation of the LLI implemantation, not the<br>
     // MCJIT itself. FIXME.<br>
-    //<br>
-    RemoteMemoryManager *MM = static_cast<RemoteMemoryManager*>(RTDyldMM);<br>
-    // Everything is prepared now, so lay out our program for the target<br>
-    // address space, assign the section addresses to resolve any relocations,<br>
-    // and send it to the target.<br>
<br>
-    std::unique_ptr<RemoteTarget> Target;<br>
-    if (!ChildExecPath.empty()) { // Remote execution on a child process<br>
-#ifndef LLVM_ON_UNIX<br>
-      // FIXME: Remove this pointless fallback mode which causes tests to "pass"<br>
-      // on platforms where they should XFAIL.<br>
-      errs() << "Warning: host does not support external remote targets.\n"<br>
-             << "  Defaulting to simulated remote execution\n";<br>
-      Target.reset(new RemoteTarget);<br>
-#else<br>
-      if (!sys::fs::can_execute(ChildExecPath)) {<br>
-        errs() << "Unable to find usable child executable: '" << ChildExecPath<br>
-               << "'\n";<br>
-        return -1;<br>
-      }<br>
-      Target.reset(new RemoteTargetExternal(ChildExecPath));<br>
-#endif<br>
-    } else {<br>
-      // No child process name provided, use simulated remote execution.<br>
-      Target.reset(new RemoteTarget);<br>
+    // Lanch the remote process and get a channel to it.<br>
+    std::unique_ptr<FDRPCChannel> C = launchRemote();<br>
+    if (!C) {<br>
+      errs() << "Failed to launch remote JIT.\n";<br>
+      exit(1);<br>
+    }<br>
+<br>
+    // Create a remote target client running over the channel.<br>
+    typedef orc::remote::OrcRemoteTargetClient<orc::remote::RPCChannel> MyRemote;<br>
+    ErrorOr<MyRemote> R = MyRemote::Create(*C);<br>
+    if (!R) {<br>
+      errs() << "Could not create remote: " << R.getError().message() << "\n";<br>
+      exit(1);<br>
+    }<br>
+<br>
+    // Create a remote memory manager.<br>
+    std::unique_ptr<MyRemote::RCMemoryManager> RemoteMM;<br>
+    if (auto EC = R->createRemoteMemoryManager(RemoteMM)) {<br>
+      errs() << "Could not create remote memory manager: " << EC.message() << "\n";<br>
+      exit(1);<br>
     }<br>
<br>
-    // Give the memory manager a pointer to our remote target interface object.<br>
-    MM->setRemoteTarget(Target.get());<br>
+    // Forward MCJIT's memory manager calls to the remote memory manager.<br>
+    static_cast<ForwardingMemoryManager*>(RTDyldMM)->setMemMgr(<br>
+      std::move(RemoteMM));<br>
+<br>
+    // Forward MCJIT's symbol resolution calls to the remote.<br>
+    static_cast<ForwardingMemoryManager*>(RTDyldMM)->setResolver(<br>
+      orc::createLambdaResolver(<br>
+        [&](const std::string &Name) {<br>
+          orc::TargetAddress Addr = 0;<br>
+          if (auto EC = R->getSymbolAddress(Addr, Name)) {<br>
+            errs() << "Failure during symbol lookup: " << EC.message() << "\n";<br>
+            exit(1);<br>
+          }<br>
+          return RuntimeDyld::SymbolInfo(Addr, JITSymbolFlags::Exported);<br>
+        },<br>
+        [](const std::string &Name) { return nullptr; }<br>
+      ));<br>
<br>
-    // Create the remote target.<br>
-    if (!Target->create()) {<br>
-      errs() << "ERROR: " << Target->getErrorMsg() << "\n";<br>
-      return EXIT_FAILURE;<br>
-    }<br>
-<br>
-    // Since we're executing in a (at least simulated) remote address space,<br>
-    // we can't use the ExecutionEngine::runFunctionAsMain(). We have to<br>
-    // grab the function address directly here and tell the remote target<br>
-    // to execute the function.<br>
-    //<br>
-    // Our memory manager will map generated code into the remote address<br>
-    // space as it is loaded and copy the bits over during the finalizeMemory<br>
-    // operation.<br>
-    //<br>
+    // Grab the target address of the JIT'd main function on the remote and call<br>
+    // it.<br>
     // FIXME: argv and envp handling.<br>
-    uint64_t Entry = EE->getFunctionAddress(EntryFn->getName().str());<br>
-<br>
+    orc::TargetAddress Entry = EE->getFunctionAddress(EntryFn->getName().str());<br>
+    EE->finalizeObject();<br>
     DEBUG(dbgs() << "Executing '" << EntryFn->getName() << "' at 0x"<br>
                  << format("%llx", Entry) << "\n");<br>
-<br>
-    if (!Target->executeCode(Entry, Result))<br>
-      errs() << "ERROR: " << Target->getErrorMsg() << "\n";<br>
+    if (auto EC = R->callIntVoid(Result, Entry))<br>
+      errs() << "ERROR: " << EC.message() << "\n";<br>
<br>
     // Like static constructors, the remote target MCJIT support doesn't handle<br>
     // this yet. It could. FIXME.<br>
<br>
-    // Stop the remote target<br>
-    Target->stop();<br>
+    // Delete the EE - we need to tear it down *before* we terminate the session<br>
+    // with the remote, otherwise it'll crash when it tries to release resources<br>
+    // on a remote that has already been disconnected.<br>
+    delete EE;<br>
+    EE = nullptr;<br>
+<br>
+    // Signal the remote target that we're done JITing.<br>
+    R->terminateSession();<br>
   }<br>
<br>
   return Result;<br>
 }<br>
+<br>
+std::unique_ptr<FDRPCChannel> launchRemote() {<br>
+#ifndef LLVM_ON_UNIX<br>
+  llvm_unreachable("launchRemote not supported on non-Unix platforms");<br>
+#else<br>
+  int PipeFD[2][2];<br>
+  pid_t ChildPID;<br>
+<br>
+  // Create two pipes.<br>
+  if (pipe(PipeFD[0]) != 0 || pipe(PipeFD[1]) != 0)<br>
+    perror("Error creating pipe: ");<br>
+<br>
+  ChildPID = fork();<br>
+<br>
+  if (ChildPID == 0) {<br>
+    // In the child...<br>
+<br>
+    // Close the parent ends of the pipes<br>
+    close(PipeFD[0][1]);<br>
+    close(PipeFD[1][0]);<br>
+<br>
+<br>
+    // Execute the child process.<br>
+    std::unique_ptr<char[]> ChildPath, ChildIn, ChildOut;<br>
+    {<br>
+      ChildPath.reset(new char[ChildExecPath.size() + 1]);<br>
+      std::copy(ChildExecPath.begin(), ChildExecPath.end(), &ChildPath[0]);<br>
+      ChildPath[ChildExecPath.size()] = '\0';<br>
+      std::string ChildInStr = std::to_string(PipeFD[0][0]);<br>
+      ChildIn.reset(new char[ChildInStr.size() + 1]);<br>
+      std::copy(ChildInStr.begin(), ChildInStr.end(), &ChildIn[0]);<br>
+      ChildIn[ChildInStr.size()] = '\0';<br>
+      std::string ChildOutStr = std::to_string(PipeFD[1][1]);<br>
+      ChildOut.reset(new char[ChildOutStr.size() + 1]);<br>
+      std::copy(ChildOutStr.begin(), ChildOutStr.end(), &ChildOut[0]);<br>
+      ChildOut[ChildOutStr.size()] = '\0';<br>
+    }<br>
+<br>
+    char * const args[] = { &ChildPath[0], &ChildIn[0], &ChildOut[0], nullptr };<br>
+    int rc = execv(ChildExecPath.c_str(), args);<br>
+    if (rc != 0)<br>
+      perror("Error executing child process: ");<br>
+    llvm_unreachable("Error executing child process");<br>
+  }<br>
+  // else we're the parent...<br>
+<br>
+  // Close the child ends of the pipes<br>
+  close(PipeFD[0][0]);<br>
+  close(PipeFD[1][1]);<br>
+<br>
+  // Return an RPC channel connected to our end of the pipes.<br>
+  return llvm::make_unique<FDRPCChannel>(PipeFD[1][0], PipeFD[0][1]);<br>
+#endif<br>
+}<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org">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><br></div></div>