2016-05-07 05:36:38 +02:00
|
|
|
//===-------------- OrcABISupport.h - ABI support code ---------*- C++ -*-===//
|
[Orc] New JIT APIs.
This patch adds a new set of JIT APIs to LLVM. The aim of these new APIs is to
cleanly support a wider range of JIT use cases in LLVM, and encourage the
development and contribution of re-usable infrastructure for LLVM JIT use-cases.
These APIs are intended to live alongside the MCJIT APIs, and should not affect
existing clients.
Included in this patch:
1) New headers in include/llvm/ExecutionEngine/Orc that provide a set of
components for building JIT infrastructure.
Implementation code for these headers lives in lib/ExecutionEngine/Orc.
2) A prototype re-implementation of MCJIT (OrcMCJITReplacement) built out of the
new components.
3) Minor changes to RTDyldMemoryManager needed to support the new components.
These changes should not impact existing clients.
4) A new flag for lli, -use-orcmcjit, which will cause lli to use the
OrcMCJITReplacement class as its underlying execution engine, rather than
MCJIT itself.
Tests to follow shortly.
Special thanks to Michael Ilseman, Pete Cooper, David Blaikie, Eric Christopher,
Justin Bogner, and Jim Grosbach for extensive feedback and discussion.
llvm-svn: 226940
2015-01-23 22:25:00 +01:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//
|
2016-05-07 05:36:38 +02:00
|
|
|
// ABI specific code for Orc, e.g. callback assembly.
|
[Orc] New JIT APIs.
This patch adds a new set of JIT APIs to LLVM. The aim of these new APIs is to
cleanly support a wider range of JIT use cases in LLVM, and encourage the
development and contribution of re-usable infrastructure for LLVM JIT use-cases.
These APIs are intended to live alongside the MCJIT APIs, and should not affect
existing clients.
Included in this patch:
1) New headers in include/llvm/ExecutionEngine/Orc that provide a set of
components for building JIT infrastructure.
Implementation code for these headers lives in lib/ExecutionEngine/Orc.
2) A prototype re-implementation of MCJIT (OrcMCJITReplacement) built out of the
new components.
3) Minor changes to RTDyldMemoryManager needed to support the new components.
These changes should not impact existing clients.
4) A new flag for lli, -use-orcmcjit, which will cause lli to use the
OrcMCJITReplacement class as its underlying execution engine, rather than
MCJIT itself.
Tests to follow shortly.
Special thanks to Michael Ilseman, Pete Cooper, David Blaikie, Eric Christopher,
Justin Bogner, and Jim Grosbach for extensive feedback and discussion.
llvm-svn: 226940
2015-01-23 22:25:00 +01:00
|
|
|
//
|
2016-05-07 05:36:38 +02:00
|
|
|
// ABI classes should be part of the JIT *target* process, not the host
|
2015-10-19 19:43:51 +02:00
|
|
|
// process (except where you're doing hosted JITing and the two are one and the
|
|
|
|
// same).
|
|
|
|
//
|
[Orc] New JIT APIs.
This patch adds a new set of JIT APIs to LLVM. The aim of these new APIs is to
cleanly support a wider range of JIT use cases in LLVM, and encourage the
development and contribution of re-usable infrastructure for LLVM JIT use-cases.
These APIs are intended to live alongside the MCJIT APIs, and should not affect
existing clients.
Included in this patch:
1) New headers in include/llvm/ExecutionEngine/Orc that provide a set of
components for building JIT infrastructure.
Implementation code for these headers lives in lib/ExecutionEngine/Orc.
2) A prototype re-implementation of MCJIT (OrcMCJITReplacement) built out of the
new components.
3) Minor changes to RTDyldMemoryManager needed to support the new components.
These changes should not impact existing clients.
4) A new flag for lli, -use-orcmcjit, which will cause lli to use the
OrcMCJITReplacement class as its underlying execution engine, rather than
MCJIT itself.
Tests to follow shortly.
Special thanks to Michael Ilseman, Pete Cooper, David Blaikie, Eric Christopher,
Justin Bogner, and Jim Grosbach for extensive feedback and discussion.
llvm-svn: 226940
2015-01-23 22:25:00 +01:00
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2016-05-07 05:36:38 +02:00
|
|
|
#ifndef LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H
|
|
|
|
#define LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H
|
[Orc] New JIT APIs.
This patch adds a new set of JIT APIs to LLVM. The aim of these new APIs is to
cleanly support a wider range of JIT use cases in LLVM, and encourage the
development and contribution of re-usable infrastructure for LLVM JIT use-cases.
These APIs are intended to live alongside the MCJIT APIs, and should not affect
existing clients.
Included in this patch:
1) New headers in include/llvm/ExecutionEngine/Orc that provide a set of
components for building JIT infrastructure.
Implementation code for these headers lives in lib/ExecutionEngine/Orc.
2) A prototype re-implementation of MCJIT (OrcMCJITReplacement) built out of the
new components.
3) Minor changes to RTDyldMemoryManager needed to support the new components.
These changes should not impact existing clients.
4) A new flag for lli, -use-orcmcjit, which will cause lli to use the
OrcMCJITReplacement class as its underlying execution engine, rather than
MCJIT itself.
Tests to follow shortly.
Special thanks to Michael Ilseman, Pete Cooper, David Blaikie, Eric Christopher,
Justin Bogner, and Jim Grosbach for extensive feedback and discussion.
llvm-svn: 226940
2015-01-23 22:25:00 +01:00
|
|
|
|
|
|
|
#include "IndirectionUtils.h"
|
2015-10-19 19:43:51 +02:00
|
|
|
#include "llvm/Support/Memory.h"
|
2016-01-11 03:41:17 +01:00
|
|
|
#include "llvm/Support/Process.h"
|
[Orc] New JIT APIs.
This patch adds a new set of JIT APIs to LLVM. The aim of these new APIs is to
cleanly support a wider range of JIT use cases in LLVM, and encourage the
development and contribution of re-usable infrastructure for LLVM JIT use-cases.
These APIs are intended to live alongside the MCJIT APIs, and should not affect
existing clients.
Included in this patch:
1) New headers in include/llvm/ExecutionEngine/Orc that provide a set of
components for building JIT infrastructure.
Implementation code for these headers lives in lib/ExecutionEngine/Orc.
2) A prototype re-implementation of MCJIT (OrcMCJITReplacement) built out of the
new components.
3) Minor changes to RTDyldMemoryManager needed to support the new components.
These changes should not impact existing clients.
4) A new flag for lli, -use-orcmcjit, which will cause lli to use the
OrcMCJITReplacement class as its underlying execution engine, rather than
MCJIT itself.
Tests to follow shortly.
Special thanks to Michael Ilseman, Pete Cooper, David Blaikie, Eric Christopher,
Justin Bogner, and Jim Grosbach for extensive feedback and discussion.
llvm-svn: 226940
2015-01-23 22:25:00 +01:00
|
|
|
|
|
|
|
namespace llvm {
|
2015-02-21 21:44:36 +01:00
|
|
|
namespace orc {
|
[Orc] New JIT APIs.
This patch adds a new set of JIT APIs to LLVM. The aim of these new APIs is to
cleanly support a wider range of JIT use cases in LLVM, and encourage the
development and contribution of re-usable infrastructure for LLVM JIT use-cases.
These APIs are intended to live alongside the MCJIT APIs, and should not affect
existing clients.
Included in this patch:
1) New headers in include/llvm/ExecutionEngine/Orc that provide a set of
components for building JIT infrastructure.
Implementation code for these headers lives in lib/ExecutionEngine/Orc.
2) A prototype re-implementation of MCJIT (OrcMCJITReplacement) built out of the
new components.
3) Minor changes to RTDyldMemoryManager needed to support the new components.
These changes should not impact existing clients.
4) A new flag for lli, -use-orcmcjit, which will cause lli to use the
OrcMCJITReplacement class as its underlying execution engine, rather than
MCJIT itself.
Tests to follow shortly.
Special thanks to Michael Ilseman, Pete Cooper, David Blaikie, Eric Christopher,
Justin Bogner, and Jim Grosbach for extensive feedback and discussion.
llvm-svn: 226940
2015-01-23 22:25:00 +01:00
|
|
|
|
2016-05-07 05:36:38 +02:00
|
|
|
/// Generic ORC ABI support.
|
2016-01-11 17:35:55 +01:00
|
|
|
///
|
|
|
|
/// This class can be substituted as the target architecure support class for
|
|
|
|
/// ORC templates that require one (e.g. IndirectStubsManagers). It does not
|
|
|
|
/// support lazy JITing however, and any attempt to use that functionality
|
|
|
|
/// will result in execution of an llvm_unreachable.
|
2016-05-07 05:36:38 +02:00
|
|
|
class OrcGenericABI {
|
2016-01-11 17:35:55 +01:00
|
|
|
public:
|
|
|
|
static const unsigned PointerSize = sizeof(uintptr_t);
|
|
|
|
static const unsigned TrampolineSize = 1;
|
|
|
|
static const unsigned ResolverCodeSize = 1;
|
|
|
|
|
2016-08-01 22:49:11 +02:00
|
|
|
typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr,
|
|
|
|
void *TrampolineId);
|
2016-01-11 17:35:55 +01:00
|
|
|
|
|
|
|
static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
|
|
|
|
void *CallbackMgr) {
|
|
|
|
llvm_unreachable("writeResolverCode is not supported by the generic host "
|
|
|
|
"support class");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
|
|
|
|
unsigned NumTrampolines) {
|
|
|
|
llvm_unreachable("writeTrampolines is not supported by the generic host "
|
|
|
|
"support class");
|
|
|
|
}
|
|
|
|
|
|
|
|
class IndirectStubsInfo {
|
|
|
|
public:
|
|
|
|
const static unsigned StubSize = 1;
|
|
|
|
unsigned getNumStubs() const { llvm_unreachable("Not supported"); }
|
|
|
|
void *getStub(unsigned Idx) const { llvm_unreachable("Not supported"); }
|
|
|
|
void **getPtr(unsigned Idx) const { llvm_unreachable("Not supported"); }
|
|
|
|
};
|
|
|
|
|
2016-04-25 21:56:45 +02:00
|
|
|
static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
|
|
|
|
unsigned MinStubs, void *InitialPtrVal) {
|
2016-01-11 17:35:55 +01:00
|
|
|
llvm_unreachable("emitIndirectStubsBlock is not supported by the generic "
|
|
|
|
"host support class");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-02-02 20:31:15 +01:00
|
|
|
/// @brief Provide information about stub blocks generated by the
|
|
|
|
/// makeIndirectStubsBlock function.
|
2016-04-25 21:56:45 +02:00
|
|
|
template <unsigned StubSizeVal> class GenericIndirectStubsInfo {
|
2016-02-02 20:31:15 +01:00
|
|
|
public:
|
|
|
|
const static unsigned StubSize = StubSizeVal;
|
|
|
|
|
|
|
|
GenericIndirectStubsInfo() : NumStubs(0) {}
|
|
|
|
GenericIndirectStubsInfo(unsigned NumStubs, sys::OwningMemoryBlock StubsMem)
|
|
|
|
: NumStubs(NumStubs), StubsMem(std::move(StubsMem)) {}
|
|
|
|
GenericIndirectStubsInfo(GenericIndirectStubsInfo &&Other)
|
|
|
|
: NumStubs(Other.NumStubs), StubsMem(std::move(Other.StubsMem)) {
|
|
|
|
Other.NumStubs = 0;
|
|
|
|
}
|
|
|
|
GenericIndirectStubsInfo &operator=(GenericIndirectStubsInfo &&Other) {
|
|
|
|
NumStubs = Other.NumStubs;
|
|
|
|
Other.NumStubs = 0;
|
|
|
|
StubsMem = std::move(Other.StubsMem);
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// @brief Number of stubs in this block.
|
|
|
|
unsigned getNumStubs() const { return NumStubs; }
|
|
|
|
|
|
|
|
/// @brief Get a pointer to the stub at the given index, which must be in
|
|
|
|
/// the range 0 .. getNumStubs() - 1.
|
|
|
|
void *getStub(unsigned Idx) const {
|
2016-02-02 22:38:30 +01:00
|
|
|
return static_cast<char *>(StubsMem.base()) + Idx * StubSize;
|
2016-02-02 20:31:15 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/// @brief Get a pointer to the implementation-pointer at the given index,
|
|
|
|
/// which must be in the range 0 .. getNumStubs() - 1.
|
|
|
|
void **getPtr(unsigned Idx) const {
|
2016-04-25 21:56:45 +02:00
|
|
|
char *PtrsBase = static_cast<char *>(StubsMem.base()) + NumStubs * StubSize;
|
2016-02-02 20:31:15 +01:00
|
|
|
return reinterpret_cast<void **>(PtrsBase) + Idx;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
unsigned NumStubs;
|
|
|
|
sys::OwningMemoryBlock StubsMem;
|
|
|
|
};
|
|
|
|
|
2016-04-29 23:32:00 +02:00
|
|
|
class OrcAArch64 {
|
|
|
|
public:
|
|
|
|
static const unsigned PointerSize = 8;
|
|
|
|
static const unsigned TrampolineSize = 12;
|
2016-05-01 02:14:45 +02:00
|
|
|
static const unsigned ResolverCodeSize = 0x120;
|
2016-04-29 23:32:00 +02:00
|
|
|
|
|
|
|
typedef GenericIndirectStubsInfo<8> IndirectStubsInfo;
|
|
|
|
|
2016-08-01 22:49:11 +02:00
|
|
|
typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr,
|
|
|
|
void *TrampolineId);
|
2016-04-29 23:32:00 +02:00
|
|
|
|
|
|
|
/// @brief Write the resolver code into the given memory. The user is be
|
|
|
|
/// responsible for allocating the memory and setting permissions.
|
|
|
|
static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
|
|
|
|
void *CallbackMgr);
|
|
|
|
|
|
|
|
/// @brief Write the requsted number of trampolines into the given memory,
|
|
|
|
/// which must be big enough to hold 1 pointer, plus NumTrampolines
|
|
|
|
/// trampolines.
|
|
|
|
static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
|
|
|
|
unsigned NumTrampolines);
|
|
|
|
|
|
|
|
/// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
|
|
|
|
/// the nearest page size.
|
|
|
|
///
|
|
|
|
/// E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k
|
|
|
|
/// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
|
|
|
|
/// will return a block of 1024 (2-pages worth).
|
|
|
|
static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
|
|
|
|
unsigned MinStubs, void *InitialPtrVal);
|
|
|
|
};
|
|
|
|
|
2016-05-07 05:36:38 +02:00
|
|
|
/// @brief X86_64 code that's common to all ABIs.
|
2016-01-11 17:35:55 +01:00
|
|
|
///
|
|
|
|
/// X86_64 supports lazy JITing.
|
2016-05-07 05:36:38 +02:00
|
|
|
class OrcX86_64_Base {
|
2015-02-17 02:18:38 +01:00
|
|
|
public:
|
2015-11-03 17:40:37 +01:00
|
|
|
static const unsigned PointerSize = 8;
|
|
|
|
static const unsigned TrampolineSize = 8;
|
|
|
|
|
2016-02-02 20:31:15 +01:00
|
|
|
typedef GenericIndirectStubsInfo<8> IndirectStubsInfo;
|
|
|
|
|
2015-11-03 17:40:37 +01:00
|
|
|
/// @brief Write the requsted number of trampolines into the given memory,
|
|
|
|
/// which must be big enough to hold 1 pointer, plus NumTrampolines
|
|
|
|
/// trampolines.
|
|
|
|
static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
|
2015-12-14 08:58:25 +01:00
|
|
|
unsigned NumTrampolines);
|
2015-02-17 02:18:38 +01:00
|
|
|
|
2015-10-19 19:43:51 +02:00
|
|
|
/// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
|
|
|
|
/// the nearest page size.
|
|
|
|
///
|
|
|
|
/// E.g. Asking for 4 stubs on x86-64, where stubs are 8-bytes, with 4k
|
|
|
|
/// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
|
|
|
|
/// will return a block of 1024 (2-pages worth).
|
2016-04-25 21:56:45 +02:00
|
|
|
static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
|
|
|
|
unsigned MinStubs, void *InitialPtrVal);
|
2015-02-17 02:18:38 +01:00
|
|
|
};
|
|
|
|
|
2016-05-07 05:36:38 +02:00
|
|
|
/// @brief X86_64 support for SysV ABI (Linux, MacOSX).
|
|
|
|
///
|
|
|
|
/// X86_64_SysV supports lazy JITing.
|
|
|
|
class OrcX86_64_SysV : public OrcX86_64_Base {
|
|
|
|
public:
|
|
|
|
static const unsigned ResolverCodeSize = 0x6C;
|
2016-08-01 22:49:11 +02:00
|
|
|
typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr,
|
|
|
|
void *TrampolineId);
|
2016-05-07 05:36:38 +02:00
|
|
|
|
|
|
|
/// @brief Write the resolver code into the given memory. The user is be
|
|
|
|
/// responsible for allocating the memory and setting permissions.
|
|
|
|
static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
|
|
|
|
void *CallbackMgr);
|
|
|
|
};
|
|
|
|
|
|
|
|
/// @brief X86_64 support for Win32.
|
|
|
|
///
|
|
|
|
/// X86_64_Win32 supports lazy JITing.
|
|
|
|
class OrcX86_64_Win32 : public OrcX86_64_Base {
|
|
|
|
public:
|
|
|
|
static const unsigned ResolverCodeSize = 0x74;
|
2016-08-01 22:49:11 +02:00
|
|
|
typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr,
|
|
|
|
void *TrampolineId);
|
2016-05-07 05:36:38 +02:00
|
|
|
|
|
|
|
/// @brief Write the resolver code into the given memory. The user is be
|
|
|
|
/// responsible for allocating the memory and setting permissions.
|
|
|
|
static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
|
|
|
|
void *CallbackMgr);
|
|
|
|
};
|
|
|
|
|
2016-02-10 02:02:33 +01:00
|
|
|
/// @brief I386 support.
|
|
|
|
///
|
|
|
|
/// I386 supports lazy JITing.
|
|
|
|
class OrcI386 {
|
|
|
|
public:
|
|
|
|
static const unsigned PointerSize = 4;
|
|
|
|
static const unsigned TrampolineSize = 8;
|
2016-02-21 23:50:26 +01:00
|
|
|
static const unsigned ResolverCodeSize = 0x4a;
|
2016-02-10 02:02:33 +01:00
|
|
|
|
|
|
|
typedef GenericIndirectStubsInfo<8> IndirectStubsInfo;
|
|
|
|
|
2016-08-01 22:49:11 +02:00
|
|
|
typedef JITTargetAddress (*JITReentryFn)(void *CallbackMgr,
|
|
|
|
void *TrampolineId);
|
2016-02-10 02:02:33 +01:00
|
|
|
|
|
|
|
/// @brief Write the resolver code into the given memory. The user is be
|
|
|
|
/// responsible for allocating the memory and setting permissions.
|
|
|
|
static void writeResolverCode(uint8_t *ResolveMem, JITReentryFn Reentry,
|
|
|
|
void *CallbackMgr);
|
|
|
|
|
|
|
|
/// @brief Write the requsted number of trampolines into the given memory,
|
|
|
|
/// which must be big enough to hold 1 pointer, plus NumTrampolines
|
|
|
|
/// trampolines.
|
|
|
|
static void writeTrampolines(uint8_t *TrampolineMem, void *ResolverAddr,
|
|
|
|
unsigned NumTrampolines);
|
|
|
|
|
|
|
|
/// @brief Emit at least MinStubs worth of indirect call stubs, rounded out to
|
|
|
|
/// the nearest page size.
|
|
|
|
///
|
|
|
|
/// E.g. Asking for 4 stubs on i386, where stubs are 8-bytes, with 4k
|
|
|
|
/// pages will return a block of 512 stubs (4096 / 8 = 512). Asking for 513
|
|
|
|
/// will return a block of 1024 (2-pages worth).
|
2016-04-25 21:56:45 +02:00
|
|
|
static Error emitIndirectStubsBlock(IndirectStubsInfo &StubsInfo,
|
|
|
|
unsigned MinStubs, void *InitialPtrVal);
|
2016-02-10 02:02:33 +01:00
|
|
|
};
|
|
|
|
|
2015-02-21 21:44:36 +01:00
|
|
|
} // End namespace orc.
|
|
|
|
} // End namespace llvm.
|
[Orc] New JIT APIs.
This patch adds a new set of JIT APIs to LLVM. The aim of these new APIs is to
cleanly support a wider range of JIT use cases in LLVM, and encourage the
development and contribution of re-usable infrastructure for LLVM JIT use-cases.
These APIs are intended to live alongside the MCJIT APIs, and should not affect
existing clients.
Included in this patch:
1) New headers in include/llvm/ExecutionEngine/Orc that provide a set of
components for building JIT infrastructure.
Implementation code for these headers lives in lib/ExecutionEngine/Orc.
2) A prototype re-implementation of MCJIT (OrcMCJITReplacement) built out of the
new components.
3) Minor changes to RTDyldMemoryManager needed to support the new components.
These changes should not impact existing clients.
4) A new flag for lli, -use-orcmcjit, which will cause lli to use the
OrcMCJITReplacement class as its underlying execution engine, rather than
MCJIT itself.
Tests to follow shortly.
Special thanks to Michael Ilseman, Pete Cooper, David Blaikie, Eric Christopher,
Justin Bogner, and Jim Grosbach for extensive feedback and discussion.
llvm-svn: 226940
2015-01-23 22:25:00 +01:00
|
|
|
|
2016-05-07 05:36:38 +02:00
|
|
|
#endif // LLVM_EXECUTIONENGINE_ORC_ORCABISUPPORT_H
|