[llvm] r191843 - Adding out-of-process execution support to lli.

Richard Smith richard at metafoo.co.uk
Wed Oct 2 14:22:56 PDT 2013


You need some more build system updates here. "ninja check" for a CMake
build does not build lli-child-target, resulting in test failures.


On Wed, Oct 2, 2013 at 10:12 AM, Andrew Kaylor <andrew.kaylor at intel.com>wrote:

> Author: akaylor
> Date: Wed Oct  2 12:12:36 2013
> New Revision: 191843
>
> URL: http://llvm.org/viewvc/llvm-project?rev=191843&view=rev
> Log:
> Adding out-of-process execution support to lli.
>
> At this time only Unix-based systems are supported.  Windows has stubs and
> should re-route to the simulated mode.
>
> Thanks to Sriram Murali for contributions to this patch.
>
>
>
> Added:
>     llvm/trunk/tools/lli/ChildTarget/
>     llvm/trunk/tools/lli/ChildTarget/CMakeLists.txt
>     llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp
>     llvm/trunk/tools/lli/ChildTarget/Makefile
>     llvm/trunk/tools/lli/ChildTarget/Unix/
>     llvm/trunk/tools/lli/ChildTarget/Unix/ChildTarget.inc
>     llvm/trunk/tools/lli/ChildTarget/Windows/
>     llvm/trunk/tools/lli/ChildTarget/Windows/ChildTarget.inc
>     llvm/trunk/tools/lli/RemoteTargetExternal.cpp
>     llvm/trunk/tools/lli/RemoteTargetExternal.h
>     llvm/trunk/tools/lli/RemoteTargetMessage.h
>     llvm/trunk/tools/lli/Unix/
>     llvm/trunk/tools/lli/Unix/RemoteTargetExternal.inc
>     llvm/trunk/tools/lli/Windows/
>     llvm/trunk/tools/lli/Windows/RemoteTargetExternal.inc
> Modified:
>     llvm/trunk/test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll
>     llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll
>
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-common-symbols-remote.ll
>     llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-data-align-remote.ll
>
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll
>
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-remote.ll
>     llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-remote.ll
>     llvm/trunk/tools/lli/CMakeLists.txt
>     llvm/trunk/tools/lli/Makefile
>     llvm/trunk/tools/lli/RemoteTarget.cpp
>     llvm/trunk/tools/lli/RemoteTarget.h
>     llvm/trunk/tools/lli/lli.cpp
>
> Modified: llvm/trunk/test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll?rev=191843&r1=191842&r2=191843&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll
> (original)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/simpletest-remote.ll Wed
> Oct  2 12:12:36 2013
> @@ -1,4 +1,4 @@
> -; RUN: %lli_mcjit -remote-mcjit %s > /dev/null
> +; RUN: %lli_mcjit -remote-mcjit -mcjit-remote-process=lli-child-target %s
> > /dev/null
>  ; XFAIL:  mips
>
>  define i32 @bar() {
>
> Modified: llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll?rev=191843&r1=191842&r2=191843&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll (original)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/stubs-remote.ll Wed Oct
>  2 12:12:36 2013
> @@ -1,4 +1,4 @@
> -; RUN: %lli_mcjit -remote-mcjit -disable-lazy-compilation=false %s
> +; RUN: %lli_mcjit -remote-mcjit -disable-lazy-compilation=false
> -mcjit-remote-process=lli-child-target %s
>  ; XFAIL:  mips
>
>  define i32 @main() nounwind {
>
> Modified:
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-common-symbols-remote.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-common-symbols-remote.ll?rev=191843&r1=191842&r2=191843&view=diff
>
> ==============================================================================
> ---
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-common-symbols-remote.ll
> (original)
> +++
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-common-symbols-remote.ll
> Wed Oct  2 12:12:36 2013
> @@ -1,4 +1,4 @@
> -; RUN: %lli_mcjit -remote-mcjit -O0 -disable-lazy-compilation=false %s
> +; RUN: %lli_mcjit -remote-mcjit -O0 -disable-lazy-compilation=false
> -mcjit-remote-process=lli-child-target %s
>  ; XFAIL: mips
>
>  ; The intention of this test is to verify that symbols mapped to COMMON
> in ELF
>
> Modified:
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-data-align-remote.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-data-align-remote.ll?rev=191843&r1=191842&r2=191843&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-data-align-remote.ll
> (original)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-data-align-remote.ll
> Wed Oct  2 12:12:36 2013
> @@ -1,4 +1,4 @@
> -; RUN:  %lli_mcjit -remote-mcjit -O0 %s
> +; RUN:  %lli_mcjit -remote-mcjit -O0
> -mcjit-remote-process=lli-child-target %s
>  ; XFAIL: mips
>
>  ; Check that a variable is always aligned as specified.
>
> Modified:
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll?rev=191843&r1=191842&r2=191843&view=diff
>
> ==============================================================================
> ---
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll
> (original)
> +++
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-fp-no-external-funcs-remote.ll
> Wed Oct  2 12:12:36 2013
> @@ -1,4 +1,4 @@
> -; RUN: %lli_mcjit -remote-mcjit %s > /dev/null
> +; RUN: %lli_mcjit -remote-mcjit -mcjit-remote-process=lli-child-target %s
> > /dev/null
>  ; XFAIL:  mips
>
>  define double @test(double* %DP, double %Arg) {
>
> Modified:
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-remote.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-remote.ll?rev=191843&r1=191842&r2=191843&view=diff
>
> ==============================================================================
> ---
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-remote.ll
> (original)
> +++
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-global-init-nonzero-remote.ll
> Wed Oct  2 12:12:36 2013
> @@ -1,4 +1,4 @@
> -; RUN: %lli_mcjit -remote-mcjit %s > /dev/null
> +; RUN: %lli_mcjit -remote-mcjit -mcjit-remote-process=lli-child-target %s
> > /dev/null
>  ; XFAIL: mips
>
>  @count = global i32 1, align 4
>
> Modified:
> llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-remote.ll
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-remote.ll?rev=191843&r1=191842&r2=191843&view=diff
>
> ==============================================================================
> --- llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-remote.ll
> (original)
> +++ llvm/trunk/test/ExecutionEngine/MCJIT/remote/test-ptr-reloc-remote.ll
> Wed Oct  2 12:12:36 2013
> @@ -1,4 +1,4 @@
> -; RUN: %lli_mcjit -remote-mcjit -O0 %s
> +; RUN: %lli_mcjit -remote-mcjit -O0
> -mcjit-remote-process=lli-child-target %s
>
>  @.str = private unnamed_addr constant [6 x i8] c"data1\00", align 1
>  @ptr = global i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0),
> align 4
>
> Modified: llvm/trunk/tools/lli/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/CMakeLists.txt?rev=191843&r1=191842&r2=191843&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/lli/CMakeLists.txt (original)
> +++ llvm/trunk/tools/lli/CMakeLists.txt Wed Oct  2 12:12:36 2013
> @@ -1,6 +1,8 @@
>
>  set(LLVM_LINK_COMPONENTS mcjit jit interpreter nativecodegen bitreader
> asmparser irreader selectiondag native instrumentation)
>
> +add_subdirectory(ChildTarget)
> +
>  if( LLVM_USE_OPROFILE )
>    set(LLVM_LINK_COMPONENTS
>      ${LLVM_LINK_COMPONENTS}
> @@ -21,4 +23,5 @@ add_llvm_tool(lli
>    lli.cpp
>    RecordingMemoryManager.cpp
>    RemoteTarget.cpp
> +  RemoteTargetExternal.cpp
>    )
>
> Added: llvm/trunk/tools/lli/ChildTarget/CMakeLists.txt
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/ChildTarget/CMakeLists.txt?rev=191843&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/lli/ChildTarget/CMakeLists.txt (added)
> +++ llvm/trunk/tools/lli/ChildTarget/CMakeLists.txt Wed Oct  2 12:12:36
> 2013
> @@ -0,0 +1,3 @@
> +add_llvm_tool(lli-child-target
> +  ChildTarget.cpp
> +  )
>
> Added: llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp?rev=191843&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp (added)
> +++ llvm/trunk/tools/lli/ChildTarget/ChildTarget.cpp Wed Oct  2 12:12:36
> 2013
> @@ -0,0 +1,241 @@
> +#include "llvm/Config/config.h"
> +
> +#include "../RemoteTargetMessage.h"
> +#include <assert.h>
> +#include <map>
> +#include <stdint.h>
> +#include <string>
> +#include <vector>
> +
> +using namespace llvm;
> +
> +class LLIChildTarget {
> +public:
> +  void initialize();
> +  LLIMessageType waitForIncomingMessage();
> +  void handleMessage(LLIMessageType messageType);
> +
> +private:
> +  // Incoming message handlers
> +  void handleAllocateSpace();
> +  void handleLoadSection(bool IsCode);
> +  void handleExecute();
> +  void handleTerminate();
> +
> +  // Outgoing message handlers
> +  void sendChildActive();
> +  void sendAllocationResult(uint64_t Addr);
> +  void sendLoadComplete();
> +  void sendExecutionComplete(uint64_t Result);
> +
> +  // OS-specific functions
> +  void initializeConnection();
> +  int WriteBytes(const void *Data, size_t Size);
> +  int ReadBytes(void *Data, size_t Size);
> +  uint64_t allocate(uint32_t Alignment, uint32_t Size);
> +  void makeSectionExecutable(uint64_t Addr, uint32_t Size);
> +  void InvalidateInstructionCache(const void *Addr, size_t Len);
> +  void releaseMemory(uint64_t Addr, uint32_t Size);
> +
> +  // Store a map of allocated buffers to sizes.
> +  typedef std::map<uint64_t, uint32_t> AllocMapType;
> +  AllocMapType m_AllocatedBufferMap;
> +
> +  // Communication handles (OS-specific)
> +  void *ConnectionData;
> +};
> +
> +int main() {
> +  LLIChildTarget  ThisChild;
> +  ThisChild.initialize();
> +  LLIMessageType MsgType;
> +  do {
> +    MsgType = ThisChild.waitForIncomingMessage();
> +    ThisChild.handleMessage(MsgType);
> +  } while (MsgType != LLI_Terminate &&
> +           MsgType != LLI_Error);
> +  return 0;
> +}
> +
> +// Public methods
> +void LLIChildTarget::initialize() {
> +  initializeConnection();
> +  sendChildActive();
> +}
> +
> +LLIMessageType LLIChildTarget::waitForIncomingMessage() {
> +  int32_t MsgType = -1;
> +  if (ReadBytes(&MsgType, 4) > 0)
> +    return (LLIMessageType)MsgType;
> +  return LLI_Error;
> +}
> +
> +void LLIChildTarget::handleMessage(LLIMessageType messageType) {
> +  switch (messageType) {
> +    case LLI_AllocateSpace:
> +      handleAllocateSpace();
> +      break;
> +    case LLI_LoadCodeSection:
> +      handleLoadSection(true);
> +      break;
> +    case LLI_LoadDataSection:
> +      handleLoadSection(false);
> +      break;
> +    case LLI_Execute:
> +      handleExecute();
> +      break;
> +    case LLI_Terminate:
> +      handleTerminate();
> +      break;
> +    default:
> +      // FIXME: Handle error!
> +      break;
> +  }
> +}
> +
> +// Incoming message handlers
> +void LLIChildTarget::handleAllocateSpace() {
> +  // Read and verify the message data size.
> +  uint32_t DataSize;
> +  int rc = ReadBytes(&DataSize, 4);
> +  assert(rc == 4);
> +  assert(DataSize == 8);
> +
> +  // Read the message arguments.
> +  uint32_t Alignment;
> +  uint32_t AllocSize;
> +  rc = ReadBytes(&Alignment, 4);
> +  assert(rc == 4);
> +  rc = ReadBytes(&AllocSize, 4);
> +  assert(rc == 4);
> +
> +  // Allocate the memory.
> +  uint64_t Addr = allocate(Alignment, AllocSize);
> +
> +  // Send AllocationResult message.
> +  sendAllocationResult(Addr);
> +}
> +
> +void LLIChildTarget::handleLoadSection(bool IsCode) {
> +  // Read the message data size.
> +  uint32_t DataSize;
> +  int rc = ReadBytes(&DataSize, 4);
> +  assert(rc == 4);
> +
> +  // Read the target load address.
> +  uint64_t Addr;
> +  rc = ReadBytes(&Addr, 8);
> +  assert(rc == 8);
> +
> +  size_t BufferSize = DataSize - 8;
> +
> +  // FIXME: Verify that this is in allocated space
> +
> +  // Read section data into previously allocated buffer
> +  rc = ReadBytes((void*)Addr, DataSize - 8);
> +  assert(rc == (int)(BufferSize));
> +
> +  // If IsCode, mark memory executable
> +  if (IsCode)
> +    makeSectionExecutable(Addr, BufferSize);
> +
> +  // Send MarkLoadComplete message.
> +  sendLoadComplete();
> +}
> +
> +void LLIChildTarget::handleExecute() {
> +  // Read the message data size.
> +  uint32_t DataSize;
> +  int rc = ReadBytes(&DataSize, 4);
> +  assert(rc == 4);
> +  assert(DataSize == 8);
> +
> +  // Read the target address.
> +  uint64_t Addr;
> +  rc = ReadBytes(&Addr, 8);
> +  assert(rc == 8);
> +
> +  // Call function
> +  int Result;
> +  int (*fn)(void) = (int(*)(void))Addr;
> +  Result = fn();
> +
> +  // Send ExecutionResult message.
> +  sendExecutionComplete((int64_t)Result);
> +}
> +
> +void LLIChildTarget::handleTerminate() {
> +  // Release all allocated memory
> +  AllocMapType::iterator Begin = m_AllocatedBufferMap.begin();
> +  AllocMapType::iterator End = m_AllocatedBufferMap.end();
> +  for (AllocMapType::iterator It = Begin; It != End; ++It) {
> +    releaseMemory(It->first, It->second);
> +  }
> +  m_AllocatedBufferMap.clear();
> +}
> +
> +// Outgoing message handlers
> +void LLIChildTarget::sendChildActive() {
> +  // Write the message type.
> +  uint32_t MsgType = (uint32_t)LLI_ChildActive;
> +  int rc = WriteBytes(&MsgType, 4);
> +  assert(rc == 4);
> +
> +  // Write the data size.
> +  uint32_t DataSize = 0;
> +  rc = WriteBytes(&DataSize, 4);
> +  assert(rc == 4);
> +}
> +
> +void LLIChildTarget::sendAllocationResult(uint64_t Addr) {
> +  // Write the message type.
> +  uint32_t MsgType = (uint32_t)LLI_AllocationResult;
> +  int rc = WriteBytes(&MsgType, 4);
> +  assert(rc == 4);
> +
> +  // Write the data size.
> +  uint32_t DataSize = 8;
> +  rc = WriteBytes(&DataSize, 4);
> +  assert(rc == 4);
> +
> +  // Write the allocated address.
> +  rc = WriteBytes(&Addr, 8);
> +  assert(rc == 8);
> +}
> +
> +void LLIChildTarget::sendLoadComplete() {
> +  // Write the message type.
> +  uint32_t MsgType = (uint32_t)LLI_LoadComplete;
> +  int rc = WriteBytes(&MsgType, 4);
> +  assert(rc == 4);
> +
> +  // Write the data size.
> +  uint32_t DataSize = 0;
> +  rc = WriteBytes(&DataSize, 4);
> +  assert(rc == 4);
> +}
> +
> +void LLIChildTarget::sendExecutionComplete(uint64_t Result) {
> +  // Write the message type.
> +  uint32_t MsgType = (uint32_t)LLI_ExecutionResult;
> +  int rc = WriteBytes(&MsgType, 4);
> +  assert(rc == 4);
> +
> +
> +  // Write the data size.
> +  uint32_t DataSize = 8;
> +  rc = WriteBytes(&DataSize, 4);
> +  assert(rc == 4);
> +
> +  // Write the result.
> +  rc = WriteBytes(&Result, 8);
> +  assert(rc == 8);
> +}
> +
> +#ifdef LLVM_ON_UNIX
> +#include "Unix/ChildTarget.inc"
> +#endif
> +
> +#ifdef LLVM_ON_WIN32
> +#include "Windows/ChildTarget.inc"
> +#endif
>
> Added: llvm/trunk/tools/lli/ChildTarget/Makefile
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/ChildTarget/Makefile?rev=191843&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/lli/ChildTarget/Makefile (added)
> +++ llvm/trunk/tools/lli/ChildTarget/Makefile Wed Oct  2 12:12:36 2013
> @@ -0,0 +1,17 @@
> +##===- tools/lli/Makefile ------------------------------*- Makefile
> -*-===##
> +#
> +#                     The LLVM Compiler Infrastructure
> +#
> +# This file is distributed under the University of Illinois Open Source
> +# License. See LICENSE.TXT for details.
> +#
>
> +##===----------------------------------------------------------------------===##
> +
> +LEVEL := ../../..
> +TOOLNAME := lli-child-target
> +
> +include $(LEVEL)/Makefile.config
> +
> +LINK_COMPONENTS :=
> +
> +include $(LLVM_SRC_ROOT)/Makefile.rules
>
> Added: llvm/trunk/tools/lli/ChildTarget/Unix/ChildTarget.inc
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/ChildTarget/Unix/ChildTarget.inc?rev=191843&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/lli/ChildTarget/Unix/ChildTarget.inc (added)
> +++ llvm/trunk/tools/lli/ChildTarget/Unix/ChildTarget.inc Wed Oct  2
> 12:12:36 2013
> @@ -0,0 +1,141 @@
> +//===- ChildTarget.inc - Child process for external JIT execution for
> Unix -==//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// Implementation of the Unix-specific parts of the ChildTarget class
> +// which executes JITed code in a separate process from where it was
> built.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include <unistd.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <sys/mman.h>
> +
> +namespace {
> +
> +struct ConnectionData_t {
> +  int InputPipe;
> +  int OutputPipe;
> +
> +  ConnectionData_t(int in, int out) : InputPipe(in), OutputPipe(out) {}
> +};
> +
> +} // namespace
> +
> +// OS-specific methods
> +void LLIChildTarget::initializeConnection() {
> +  // Store the parent ends of the pipes
> +  ConnectionData = (void*)new ConnectionData_t(STDIN_FILENO,
> STDOUT_FILENO);
> +}
> +
> +int LLIChildTarget::WriteBytes(const void *Data, size_t Size) {
> +  return write(((ConnectionData_t*)ConnectionData)->OutputPipe, Data,
> Size);
> +}
> +
> +int LLIChildTarget::ReadBytes(void *Data, size_t Size) {
> +  return read(((ConnectionData_t*)ConnectionData)->InputPipe, Data, Size);
> +}
> +
> +// The functions below duplicate functionality that is implemented in
> +// Support/Memory.cpp with the goal of avoiding a dependency on any
> +// llvm libraries.
> +
> +uint64_t LLIChildTarget::allocate(uint32_t Alignment, uint32_t Size) {
> +  if (!Alignment)
> +    Alignment = 16;
> +
> +  static const size_t PageSize = getpagesize();
> +  const size_t NumPages = (Size+PageSize-1)/PageSize;
> +  Size = NumPages*PageSize;
> +
> +  int fd = -1;
> +#ifdef NEED_DEV_ZERO_FOR_MMAP
> +  static int zero_fd = open("/dev/zero", O_RDWR);
> +  if (zero_fd == -1)
> +    return 0;
> +  fd = zero_fd;
> +#endif
> +
> +  int MMFlags = MAP_PRIVATE |
> +#ifdef HAVE_MMAP_ANONYMOUS
> +  MAP_ANONYMOUS
> +#else
> +  MAP_ANON
> +#endif
> +  ; // Ends statement above
> +
> +  uint64_t Addr = (uint64_t)::mmap(0, Size, PROT_READ | PROT_WRITE,
> MMFlags, fd, 0);
> +  if (Addr == (uint64_t)MAP_FAILED)
> +    return 0;
> +
> +  // Align the address.
> +  Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
> +
> +  m_AllocatedBufferMap[Addr] = Size;
> +
> +  // Return aligned address
> +  return Addr;
> +}
> +
> +void LLIChildTarget::makeSectionExecutable(uint64_t Addr, uint32_t Size) {
> +  // FIXME: We have to mark the memory as RWX because multiple code
> chunks may
> +  // be on the same page.  The RemoteTarget interface should be changed to
> +  // work around that.
> +  int Result = ::mprotect((void*)Addr, Size, PROT_READ | PROT_WRITE |
> PROT_EXEC);
> +  if (Result != 0)
> +    InvalidateInstructionCache((const void *)Addr, Size);
> +}
> +
> +/// InvalidateInstructionCache - Before the JIT can run a block of code
> +/// that has been emitted it must invalidate the instruction cache on some
> +/// platforms.
> +void LLIChildTarget::InvalidateInstructionCache(const void *Addr,
> +                                        size_t Len) {
> +
> +// icache invalidation for PPC and ARM.
> +#if defined(__APPLE__)
> +
> +#  if (defined(__POWERPC__) || defined (__ppc__) || \
> +     defined(_POWER) || defined(_ARCH_PPC)) || defined(__arm__)
> +  sys_icache_invalidate(const_cast<void *>(Addr), Len);
> +#  endif
> +
> +#else
> +
> +#  if (defined(__POWERPC__) || defined (__ppc__) || \
> +       defined(_POWER) || defined(_ARCH_PPC)) && defined(__GNUC__)
> +  const size_t LineSize = 32;
> +
> +  const intptr_t Mask = ~(LineSize - 1);
> +  const intptr_t StartLine = ((intptr_t) Addr) & Mask;
> +  const intptr_t EndLine = ((intptr_t) Addr + Len + LineSize - 1) & Mask;
> +
> +  for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
> +    asm volatile("dcbf 0, %0" : : "r"(Line));
> +  asm volatile("sync");
> +
> +  for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
> +    asm volatile("icbi 0, %0" : : "r"(Line));
> +  asm volatile("isync");
> +#  elif defined(__arm__) && defined(__GNUC__)
> +  // FIXME: Can we safely always call this for __GNUC__ everywhere?
> +  const char *Start = static_cast<const char *>(Addr);
> +  const char *End = Start + Len;
> +  __clear_cache(const_cast<char *>(Start), const_cast<char *>(End));
> +#  elif defined(__mips__)
> +  const char *Start = static_cast<const char *>(Addr);
> +  cacheflush(const_cast<char *>(Start), Len, BCACHE);
> +#  endif
> +
> +#endif  // end apple
> +}
> +
> +void LLIChildTarget::releaseMemory(uint64_t Addr, uint32_t Size) {
> +  ::munmap((void*)Addr, Size);
> +}
>
> Added: llvm/trunk/tools/lli/ChildTarget/Windows/ChildTarget.inc
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/ChildTarget/Windows/ChildTarget.inc?rev=191843&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/lli/ChildTarget/Windows/ChildTarget.inc (added)
> +++ llvm/trunk/tools/lli/ChildTarget/Windows/ChildTarget.inc Wed Oct  2
> 12:12:36 2013
> @@ -0,0 +1,41 @@
> +//=- ChildTarget.inc - Child process for external JIT execution for
> Windows -=//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// Non-implementation of the Windows-specific parts of the ChildTarget
> class
> +// which executes JITed code in a separate process from where it was
> built.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +// The RemoteTargetExternal implementation should prevent us from ever
> getting
> +// here on Windows, but nothing prevents a user from running this
> directly.
> +void LLIChildTarget::initializeConnection() {
> +  assert(0 && "lli-child-target is not implemented for Windows");
> +}
> +
> +int LLIChildTarget::WriteBytes(const void *Data, size_t Size) {
> +  return 0;
> +}
> +
> +int LLIChildTarget::ReadBytes(void *Data, size_t Size) {
> +  return 0;
> +}
> +
> +uint64_t LLIChildTarget::allocate(uint32_t Alignment, uint32_t Size) {
> +  return 0;
> +}
> +
> +void LLIChildTarget::makeSectionExecutable(uint64_t Addr, uint32_t Size) {
> +}
> +
> +void LLIChildTarget::InvalidateInstructionCache(const void *Addr,
> +                                        size_t Len) {
> +}
> +
> +void LLIChildTarget::releaseMemory(uint64_t Addr, uint32_t Size) {
> +}
>
> Modified: llvm/trunk/tools/lli/Makefile
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/Makefile?rev=191843&r1=191842&r2=191843&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/lli/Makefile (original)
> +++ llvm/trunk/tools/lli/Makefile Wed Oct  2 12:12:36 2013
> @@ -10,6 +10,8 @@
>  LEVEL := ../..
>  TOOLNAME := lli
>
> +PARALLEL_DIRS := ChildTarget
> +
>  include $(LEVEL)/Makefile.config
>
>  LINK_COMPONENTS := mcjit jit instrumentation interpreter nativecodegen
> bitreader asmparser irreader selectiondag native
>
> Modified: llvm/trunk/tools/lli/RemoteTarget.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTarget.cpp?rev=191843&r1=191842&r2=191843&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/lli/RemoteTarget.cpp (original)
> +++ llvm/trunk/tools/lli/RemoteTarget.cpp Wed Oct  2 12:12:36 2013
> @@ -13,13 +13,44 @@
>
>  //===----------------------------------------------------------------------===//
>
>  #include "RemoteTarget.h"
> +#include "RemoteTargetExternal.h"
>  #include "llvm/ADT/StringRef.h"
>  #include "llvm/Support/DataTypes.h"
>  #include "llvm/Support/Memory.h"
>  #include <stdlib.h>
>  #include <string>
> +
>  using namespace llvm;
>
> +// Static methods
> +RemoteTarget *RemoteTarget::createRemoteTarget() {
> +  return new RemoteTarget;
> +}
> +
> +RemoteTarget *RemoteTarget::createExternalRemoteTarget(std::string
> &ChildName) {
> +#ifdef LLVM_ON_UNIX
> +  return new RemoteTargetExternal(ChildName);
> +#else
> +  return 0;
> +#endif
> +}
> +
> +bool RemoteTarget::hostSupportsExternalRemoteTarget() {
> +#ifdef LLVM_ON_UNIX
> +  return true;
> +#else
> +  return false;
> +#endif
> +}
> +
> +
>
> +////////////////////////////////////////////////////////////////////////////////
> +// Simulated remote execution
> +//
> +// This implementation will simply move generated code and data to a new
> memory
> +// location in the current executable and let it run from there.
>
> +////////////////////////////////////////////////////////////////////////////////
> +
>  bool RemoteTarget::allocateSpace(size_t Size, unsigned Alignment,
>                                   uint64_t &Address) {
>    sys::MemoryBlock *Prev = Allocations.size() ? &Allocations.back() :
> NULL;
>
> Modified: llvm/trunk/tools/lli/RemoteTarget.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTarget.h?rev=191843&r1=191842&r2=191843&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/lli/RemoteTarget.h (original)
> +++ llvm/trunk/tools/lli/RemoteTarget.h Wed Oct  2 12:12:36 2013
> @@ -41,7 +41,9 @@ public:
>    ///
>    /// @returns False on success. On failure, ErrorMsg is updated with
>    ///          descriptive text of the encountered error.
> -  bool allocateSpace(size_t Size, unsigned Alignment, uint64_t &Address);
> +  virtual bool allocateSpace(size_t Size,
> +                             unsigned Alignment,
> +                             uint64_t &Address);
>
>    /// Load data into the target address space.
>    ///
> @@ -51,7 +53,9 @@ public:
>    ///
>    /// @returns False on success. On failure, ErrorMsg is updated with
>    ///          descriptive text of the encountered error.
> -  bool loadData(uint64_t Address, const void *Data, size_t Size);
> +  virtual bool loadData(uint64_t Address,
> +                        const void *Data,
> +                        size_t Size);
>
>    /// Load code into the target address space and prepare it for
> execution.
>    ///
> @@ -61,7 +65,9 @@ public:
>    ///
>    /// @returns False on success. On failure, ErrorMsg is updated with
>    ///          descriptive text of the encountered error.
> -  bool loadCode(uint64_t Address, const void *Data, size_t Size);
> +  virtual bool loadCode(uint64_t Address,
> +                        const void *Data,
> +                        size_t Size);
>
>    /// Execute code in the target process. The called function is required
>    /// to be of signature int "(*)(void)".
> @@ -72,24 +78,29 @@ public:
>    ///
>    /// @returns False on success. On failure, ErrorMsg is updated with
>    ///          descriptive text of the encountered error.
> -  bool executeCode(uint64_t Address, int &RetVal);
> +  virtual bool executeCode(uint64_t Address,
> +                           int &RetVal);
>
>    /// Minimum alignment for memory permissions. Used to seperate code and
>    /// data regions to make sure data doesn't get marked as code or vice
>    /// versa.
>    ///
>    /// @returns Page alignment return value. Default of 4k.
> -  unsigned getPageAlignment() { return 4096; }
> +  virtual unsigned getPageAlignment() { return 4096; }
>
>    /// Start the remote process.
> -  void create();
> +  virtual void create();
>
>    /// Terminate the remote process.
> -  void stop();
> +  virtual void stop();
>
>    RemoteTarget() : ErrorMsg(""), IsRunning(false) {}
> -  ~RemoteTarget() { if (IsRunning) stop(); }
> +  virtual ~RemoteTarget() { if (IsRunning) stop(); }
>
> +  // Create an instance of the system-specific remote target class.
> +  static RemoteTarget *createRemoteTarget();
> +  static RemoteTarget *createExternalRemoteTarget(std::string &ChildName);
> +  static bool hostSupportsExternalRemoteTarget();
>  private:
>    // Main processing function for the remote target process. Command
> messages
>    // are received on file descriptor CmdFD and responses come back on
> OutFD.
>
> Added: llvm/trunk/tools/lli/RemoteTargetExternal.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTargetExternal.cpp?rev=191843&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/lli/RemoteTargetExternal.cpp (added)
> +++ llvm/trunk/tools/lli/RemoteTargetExternal.cpp Wed Oct  2 12:12:36 2013
> @@ -0,0 +1,162 @@
> +//===---- RemoteTargetExternal.cpp - LLVM out-of-process JIT execution
> ----===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// Implementation of the RemoteTargetExternal class which executes JITed
> code
> +// in a separate process from where it was built.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include "llvm/Config/config.h"
> +
> +#include "RemoteTarget.h"
> +#include "RemoteTargetExternal.h"
> +
> +#include "llvm/ADT/StringRef.h"
> +#include "llvm/Support/DataTypes.h"
> +#include "llvm/Support/Memory.h"
> +#include "llvm/Support/Program.h"
> +#include "llvm/Support/raw_ostream.h"
> +#include <string>
> +
> +using namespace llvm;
> +
> +bool RemoteTargetExternal::allocateSpace(size_t Size, unsigned Alignment,
> +                                 uint64_t &Address) {
> +  SendAllocateSpace(Alignment, Size);
> +  Receive(LLI_AllocationResult, Address);
> +  return false;
> +}
> +
> +bool RemoteTargetExternal::loadData(uint64_t Address, const void *Data,
> size_t Size) {
> +  SendLoadSection(Address, Data, (uint32_t)Size, false);
> +  Receive(LLI_LoadComplete);
> +  return false;
> +}
> +
> +bool RemoteTargetExternal::loadCode(uint64_t Address, const void *Data,
> size_t Size) {
> +  SendLoadSection(Address, Data, (uint32_t)Size, true);
> +  Receive(LLI_LoadComplete);
> +  return false;
> +}
> +
> +bool RemoteTargetExternal::executeCode(uint64_t Address, int &RetVal) {
> +  SendExecute(Address);
> +
> +  Receive(LLI_ExecutionResult, RetVal);
> +  return false;
> +}
> +
> +void RemoteTargetExternal::stop() {
> +  SendTerminate();
> +  Wait();
> +}
> +
> +void RemoteTargetExternal::SendAllocateSpace(uint32_t Alignment, uint32_t
> Size) {
> +  int rc;
> +  uint32_t MsgType = (uint32_t)LLI_AllocateSpace;
> +  rc = WriteBytes(&MsgType, 4);
> +  assert(rc == 4 && "Error writing message type.");
> +
> +  uint32_t DataSize = 8;
> +  rc = WriteBytes(&DataSize, 4);
> +  assert(rc == 4 && "Error writing data size.");
> +
> +  rc = WriteBytes(&Alignment, 4);
> +  assert(rc == 4 && "Error writing alignment data.");
> +
> +  rc = WriteBytes(&Size, 4);
> +  assert(rc == 4 && "Error writing size data.");
> +}
> +
> +void RemoteTargetExternal::SendLoadSection(uint64_t Addr,
> +                                       const void *Data,
> +                                       uint32_t Size,
> +                                       bool IsCode) {
> +  int rc;
> +  uint32_t MsgType = IsCode ? LLI_LoadCodeSection : LLI_LoadDataSection;
> +  rc = WriteBytes(&MsgType, 4);
> +  assert(rc == 4 && "Error writing message type.");
> +
> +  uint32_t DataSize = Size + 8;
> +  rc = WriteBytes(&DataSize, 4);
> +  assert(rc == 4 && "Error writing data size.");
> +
> +  rc = WriteBytes(&Addr, 8);
> +  assert(rc == 8 && "Error writing data.");
> +
> +  rc = WriteBytes(Data, Size);
> +  assert(rc == (int)Size && "Error writing data.");
> +}
> +
> +void RemoteTargetExternal::SendExecute(uint64_t Addr) {
> +  int rc;
> +  uint32_t MsgType = (uint32_t)LLI_Execute;
> +  rc = WriteBytes(&MsgType, 4);
> +  assert(rc == 4 && "Error writing message type.");
> +
> +  uint32_t DataSize = 8;
> +  rc = WriteBytes(&DataSize, 4);
> +  assert(rc == 4 && "Error writing data size.");
> +
> +  rc = WriteBytes(&Addr, 8);
> +  assert(rc == 8 && "Error writing data.");
> +}
> +
> +void RemoteTargetExternal::SendTerminate() {
> +  int rc;
> +  uint32_t MsgType = (uint32_t)LLI_Terminate;
> +  rc = WriteBytes(&MsgType, 4);
> +  assert(rc == 4 && "Error writing message type.");
> +
> +  // No data or data size is sent with Terminate
> +}
> +
> +
> +void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType) {
> +  int rc;
> +  uint32_t MsgType;
> +  rc = ReadBytes(&MsgType, 4);
> +  assert(rc == 4 && "Error reading message type.");
> +  assert(MsgType == ExpectedMsgType && "Error: received unexpected
> message type.");
> +
> +  uint32_t DataSize;
> +  rc = ReadBytes(&DataSize, 4);
> +  assert(rc == 4 && "Error reading data size.");
> +  assert(DataSize == 0 && "Error: unexpected data size.");
> +}
> +
> +void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType, int
> &Data) {
> +  uint64_t Temp;
> +  Receive(ExpectedMsgType, Temp);
> +  Data = (int)(int64_t)Temp;
> +}
> +
> +void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType,
> uint64_t &Data) {
> +  int rc;
> +  uint32_t MsgType;
> +  rc = ReadBytes(&MsgType, 4);
> +  assert(rc == 4 && "Error reading message type.");
> +  assert(MsgType == ExpectedMsgType && "Error: received unexpected
> message type.");
> +
> +  uint32_t DataSize;
> +  rc = ReadBytes(&DataSize, 4);
> +  assert(rc == 4 && "Error reading data size.");
> +  assert(DataSize == 8 && "Error: unexpected data size.");
> +
> +  rc = ReadBytes(&Data, 8);
> +  assert(DataSize == 8 && "Error: unexpected data.");
> +}
> +
> +#ifdef LLVM_ON_UNIX
> +#include "Unix/RemoteTargetExternal.inc"
> +#endif
> +
> +#ifdef LLVM_ON_WIN32
> +#include "Windows/RemoteTargetExternal.inc"
> +#endif
>
> Added: llvm/trunk/tools/lli/RemoteTargetExternal.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTargetExternal.h?rev=191843&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/lli/RemoteTargetExternal.h (added)
> +++ llvm/trunk/tools/lli/RemoteTargetExternal.h Wed Oct  2 12:12:36 2013
> @@ -0,0 +1,118 @@
> +//===----- RemoteTargetExternal.h - LLVM out-of-process JIT execution
> -----===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// Definition of the RemoteTargetExternal class which executes JITed code
> in a
> +// separate process from where it was built.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLI_REMOTETARGETEXTERNAL_H
> +#define LLI_REMOTETARGETEXTERNAL_H
> +
> +#include "llvm/Config/config.h"
> +
> +#include "llvm/ADT/SmallVector.h"
> +#include "llvm/ADT/StringRef.h"
> +#include "llvm/Support/DataTypes.h"
> +#include "llvm/Support/Memory.h"
> +#include <stdlib.h>
> +#include <string>
> +
> +#include "RemoteTarget.h"
> +#include "RemoteTargetMessage.h"
> +
> +namespace llvm {
> +
> +class RemoteTargetExternal : public RemoteTarget {
> +public:
> +  /// Allocate space in the remote target address space.
> +  ///
> +  /// @param      Size      Amount of space, in bytes, to allocate.
> +  /// @param      Alignment Required minimum alignment for allocated
> space.
> +  /// @param[out] Address   Remote address of the allocated memory.
> +  ///
> +  /// @returns False on success. On failure, ErrorMsg is updated with
> +  ///          descriptive text of the encountered error.
> +  virtual bool allocateSpace(size_t Size,
> +                             unsigned Alignment,
> +                             uint64_t &Address);
> +
> +  /// Load data into the target address space.
> +  ///
> +  /// @param      Address   Destination address in the target process.
> +  /// @param      Data      Source address in the host process.
> +  /// @param      Size      Number of bytes to copy.
> +  ///
> +  /// @returns False on success. On failure, ErrorMsg is updated with
> +  ///          descriptive text of the encountered error.
> +  virtual bool loadData(uint64_t Address, const void *Data, size_t Size);
> +
> +  /// Load code into the target address space and prepare it for
> execution.
> +  ///
> +  /// @param      Address   Destination address in the target process.
> +  /// @param      Data      Source address in the host process.
> +  /// @param      Size      Number of bytes to copy.
> +  ///
> +  /// @returns False on success. On failure, ErrorMsg is updated with
> +  ///          descriptive text of the encountered error.
> +  virtual bool loadCode(uint64_t Address, const void *Data, size_t Size);
> +
> +  /// Execute code in the target process. The called function is required
> +  /// to be of signature int "(*)(void)".
> +  ///
> +  /// @param      Address   Address of the loaded function in the target
> +  ///                       process.
> +  /// @param[out] RetVal    The integer return value of the called
> function.
> +  ///
> +  /// @returns False on success. On failure, ErrorMsg is updated with
> +  ///          descriptive text of the encountered error.
> +  virtual bool executeCode(uint64_t Address, int &RetVal);
> +
> +  /// Minimum alignment for memory permissions. Used to seperate code and
> +  /// data regions to make sure data doesn't get marked as code or vice
> +  /// versa.
> +  ///
> +  /// @returns Page alignment return value. Default of 4k.
> +  virtual unsigned getPageAlignment() { return 4096; }
> +
> +  /// Start the remote process.
> +  virtual void create();
> +
> +  /// Terminate the remote process.
> +  virtual void stop();
> +
> +  RemoteTargetExternal(std::string &Name) : RemoteTarget(),
> ChildName(Name) {}
> +  virtual ~RemoteTargetExternal() {}
> +
> +private:
> +  std::string ChildName;
> +
> +  // This will get filled in as a point to an OS-specific structure.
> +  void *ConnectionData;
> +
> +  void SendAllocateSpace(uint32_t Alignment, uint32_t Size);
> +  void SendLoadSection(uint64_t Addr,
> +                       const void *Data,
> +                       uint32_t Size,
> +                       bool IsCode);
> +  void SendExecute(uint64_t Addr);
> +  void SendTerminate();
> +
> +  void Receive(LLIMessageType Msg);
> +  void Receive(LLIMessageType Msg, int &Data);
> +  void Receive(LLIMessageType Msg, uint64_t &Data);
> +
> +  int WriteBytes(const void *Data, size_t Size);
> +  int ReadBytes(void *Data, size_t Size);
> +  void Wait();
> +};
> +
> +} // end namespace llvm
> +
> +#endif // LLI_REMOTETARGETEXTERNAL_H
>
> Added: llvm/trunk/tools/lli/RemoteTargetMessage.h
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/RemoteTargetMessage.h?rev=191843&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/lli/RemoteTargetMessage.h (added)
> +++ llvm/trunk/tools/lli/RemoteTargetMessage.h Wed Oct  2 12:12:36 2013
> @@ -0,0 +1,45 @@
> +//===---- RemoteTargetMessage.h - LLI out-of-process message protocol
> -----===//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// Definition of the LLIMessageType enum which is used for communication
> with a
> +// child process for remote execution.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#ifndef LLI_REMOTETARGETMESSAGE_H
> +#define LLI_REMOTETARGETMESSAGE_H
> +
> +namespace llvm {
> +
> +// LLI messages from parent-to-child or vice versa follow an exceedingly
> simple
> +// protocol where the first four bytes represent the message type, the
> next
> +// four bytes represent the size of data for the command and following
> bytes
> +// represent the actual data.
> +//
> +// The protocol is not intended to be robust, secure or fault-tolerant.
>  It is
> +// only here for testing purposes and is therefore intended to be the
> simplest
> +// implementation that will work.  It is assumed that the parent and child
> +// share characteristics like endianness.
> +
> +enum LLIMessageType {
> +  LLI_Error = -1,
> +  LLI_ChildActive = 0,        // Data = not used
> +  LLI_AllocateSpace,          // Data = struct { uint_32t Align, uint_32t
> Size }
> +  LLI_AllocationResult,       // Data = uint64_t AllocAddress (in Child
> memory space)
> +  LLI_LoadCodeSection,        // Data = uint32_t Addr, followed by
> section contests
> +  LLI_LoadDataSection,        // Data = uint32_t Addr, followed by
> section contents
> +  LLI_LoadComplete,           // Data = not used
> +  LLI_Execute,                // Data = Address of function to execute
> +  LLI_ExecutionResult,        // Data = uint64_t Result
> +  LLI_Terminate               // Data = not used
> +};
> +
> +} // end namespace llvm
> +
> +#endif
>
> Added: llvm/trunk/tools/lli/Unix/RemoteTargetExternal.inc
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/Unix/RemoteTargetExternal.inc?rev=191843&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/lli/Unix/RemoteTargetExternal.inc (added)
> +++ llvm/trunk/tools/lli/Unix/RemoteTargetExternal.inc Wed Oct  2 12:12:36
> 2013
> @@ -0,0 +1,91 @@
> +//=- RemoteTargetExternal.inc - LLVM out-of-process JIT execution for
> Unix --=//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// Implementation of the Unix-specific parts of the RemoteTargetExternal
> class
> +// which executes JITed code in a separate process from where it was
> built.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +#include <unistd.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <sys/wait.h>
> +
> +namespace {
> +
> +struct ConnectionData_t {
> +  int InputPipe;
> +  int OutputPipe;
> +
> +  ConnectionData_t(int in, int out) : InputPipe(in), OutputPipe(out) {}
> +};
> +
> +} // namespace
> +
> +namespace llvm {
> +
> +void RemoteTargetExternal::create() {
> +  int PipeFD[2][2];
> +  pid_t ChildPID;
> +
> +  pipe(PipeFD[0]);
> +  pipe(PipeFD[1]);
> +
> +  ChildPID = fork();
> +
> +  if (ChildPID == 0) {
> +    // In the child...
> +
> +    // Close the parent ends of the pipes
> +    close(PipeFD[0][1]);
> +    close(PipeFD[1][0]);
> +
> +    // Use our pipes as stdin and stdout
> +    if (PipeFD[0][0] != STDIN_FILENO) {
> +      dup2(PipeFD[0][0], STDIN_FILENO);
> +      close(PipeFD[0][0]);
> +    }
> +    if (PipeFD[1][1] != STDOUT_FILENO) {
> +      dup2(PipeFD[1][1], STDOUT_FILENO);
> +      close(PipeFD[1][1]);
> +    }
> +
> +    // Execute the child process.
> +    char *args[1] = { NULL };
> +    int rc = execv(ChildName.c_str(), args);
> +    if (rc != 0)
> +      perror("Error executing child process: ");
> +  }
> +  else {
> +    // In the parent...
> +
> +    // Close the child ends of the pipes
> +    close(PipeFD[0][0]);
> +    close(PipeFD[1][1]);
> +
> +    // Store the parent ends of the pipes
> +    ConnectionData = (void*)new ConnectionData_t(PipeFD[1][0],
> PipeFD[0][1]);
> +
> +    Receive(LLI_ChildActive);
> +  }
> +}
> +
> +int RemoteTargetExternal::WriteBytes(const void *Data, size_t Size) {
> +  return write(((ConnectionData_t*)ConnectionData)->OutputPipe, Data,
> Size);
> +}
> +
> +int RemoteTargetExternal::ReadBytes(void *Data, size_t Size) {
> +  return read(((ConnectionData_t*)ConnectionData)->InputPipe, Data, Size);
> +}
> +
> +void RemoteTargetExternal::Wait() {
> +  wait(NULL);
> +}
> +
> +} // namespace llvm
> \ No newline at end of file
>
> Added: llvm/trunk/tools/lli/Windows/RemoteTargetExternal.inc
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/Windows/RemoteTargetExternal.inc?rev=191843&view=auto
>
> ==============================================================================
> --- llvm/trunk/tools/lli/Windows/RemoteTargetExternal.inc (added)
> +++ llvm/trunk/tools/lli/Windows/RemoteTargetExternal.inc Wed Oct  2
> 12:12:36 2013
> @@ -0,0 +1,32 @@
> +//= RemoteTargetExternal.inc - LLVM out-of-process JIT execution for
> Windows =//
> +//
> +//                     The LLVM Compiler Infrastructure
> +//
> +// This file is distributed under the University of Illinois Open Source
> +// License. See LICENSE.TXT for details.
> +//
>
> +//===----------------------------------------------------------------------===//
> +//
> +// Definition of the Windows-specific parts of the RemoteTargetExternal
> class
> +// which is meant to execute JITed code in a separate process from where
> it was
> +// built.  To support this functionality on Windows, implement these
> functions.
> +//
>
> +//===----------------------------------------------------------------------===//
> +
> +namespace llvm {
> +
> +void RemoteTargetExternal::create() {
> +}
> +
> +int RemoteTargetExternal::WriteBytes(const void *Data, size_t Size) {
> +  return 0;
> +}
> +
> +int RemoteTargetExternal::ReadBytes(void *Data, size_t Size) {
> +  return 0;
> +}
> +
> +void RemoteTargetExternal::Wait() {
> +}
> +
> +} // namespace llvm
>
> Modified: llvm/trunk/tools/lli/lli.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=191843&r1=191842&r2=191843&view=diff
>
> ==============================================================================
> --- llvm/trunk/tools/lli/lli.cpp (original)
> +++ llvm/trunk/tools/lli/lli.cpp Wed Oct  2 12:12:36 2013
> @@ -41,6 +41,7 @@
>  #include "llvm/Support/PluginLoader.h"
>  #include "llvm/Support/PrettyStackTrace.h"
>  #include "llvm/Support/Process.h"
> +#include "llvm/Support/Program.h"
>  #include "llvm/Support/Signals.h"
>  #include "llvm/Support/SourceMgr.h"
>  #include "llvm/Support/TargetSelect.h"
> @@ -83,6 +84,18 @@ namespace {
>      cl::desc("Execute MCJIT'ed code in a separate process."),
>      cl::init(false));
>
> +  // Manually specify the child process for remote execution. This
> overrides
> +  // the simulated remote execution that allocates address space for child
> +  // execution. The child process resides in the disk and communicates
> with lli
> +  // via stdin/stdout pipes.
> +  cl::opt<std::string>
> +  MCJITRemoteProcess("mcjit-remote-process",
> +            cl::desc("Specify the filename of the process to launch "
> +                     "for remote MCJIT execution.  If none is specified,"
> +                     "\n\tremote execution will be simulated
> in-process."),
> +            cl::value_desc("filename"),
> +            cl::init(""));
> +
>    // Determine optimization level.
>    cl::opt<char>
>    OptLevel("O",
> @@ -481,30 +494,50 @@ int main(int argc, char **argv, char * c
>      // Everything is prepared now, so lay out our program for the target
>      // address space, assign the section addresses to resolve any
> relocations,
>      // and send it to the target.
> -    RemoteTarget Target;
> -    Target.create();
> +
> +    OwningPtr<RemoteTarget> Target;
> +    if (!MCJITRemoteProcess.empty()) { // Remote execution on a child
> process
> +      if (!RemoteTarget::hostSupportsExternalRemoteTarget()) {
> +        errs() << "Warning: host does not support external remote
> targets.\n"
> +               << "  Defaulting to simulated remote execution\n";
> +        Target.reset(RemoteTarget::createRemoteTarget());
> +      } else {
> +        std::string ChildEXE = sys::FindProgramByName(MCJITRemoteProcess);
> +        if (ChildEXE == "") {
> +          errs() << "Unable to find child target: '\''" <<
> MCJITRemoteProcess << "\'\n";
> +          return -1;
> +        }
> +
>  Target.reset(RemoteTarget::createExternalRemoteTarget(MCJITRemoteProcess));
> +      }
> +    } else {
> +      // No child process name provided, use simulated remote execution.
> +      Target.reset(RemoteTarget::createRemoteTarget());
> +    }
> +
> +    // Create the remote target
> +    Target->create();
>
>      // Trigger compilation.
>      EE->generateCodeForModule(Mod);
>
>      // Layout the target memory.
> -    layoutRemoteTargetMemory(&Target, MM);
> +    layoutRemoteTargetMemory(Target.get(), MM);
>
>      // Since we're executing in a (at least simulated) remote address
> space,
>      // we can't use the ExecutionEngine::runFunctionAsMain(). We have to
>      // grab the function address directly here and tell the remote target
>      // to execute the function.
>      // FIXME: argv and envp handling.
> -    uint64_t Entry = (uint64_t)EE->getPointerToFunction(EntryFn);
> +    uint64_t Entry = EE->getFunctionAddress(EntryFn->getName().str());
>
>      DEBUG(dbgs() << "Executing '" << EntryFn->getName() << "' at 0x"
>                   << format("%llx", Entry) << "\n");
>
> -    if (Target.executeCode(Entry, Result))
> -      errs() << "ERROR: " << Target.getErrorMsg() << "\n";
> +    if (Target->executeCode(Entry, Result))
> +      errs() << "ERROR: " << Target->getErrorMsg() << "\n";
>
> -    Target.stop();
> -  } else {
> +    Target->stop();
> +  } else { // !RemoteMCJIT
>      // Trigger compilation separately so code regions that need to be
>      // invalidated will be known.
>      (void)EE->getPointerToFunction(EntryFn);
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131002/300256c3/attachment.html>


More information about the llvm-commits mailing list