[Orc] Refactor JITCompileCallbackManagerBase and CompileOnDemandLayer to support

target-independent callback management.

This is a prerequisite for adding orc-based lazy-jitting to lli.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233166 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Lang Hames
2015-03-25 02:45:50 +00:00
parent 2186876e87
commit 339fa95661
4 changed files with 60 additions and 61 deletions

View File

@ -142,9 +142,8 @@ public:
typedef std::function<uint64_t(const std::string &)> LookupFtor; typedef std::function<uint64_t(const std::string &)> LookupFtor;
/// @brief Construct a compile-on-demand layer instance. /// @brief Construct a compile-on-demand layer instance.
CompileOnDemandLayer(BaseLayerT &BaseLayer, LLVMContext &Context) CompileOnDemandLayer(BaseLayerT &BaseLayer, CompileCallbackMgrT &CallbackMgr)
: BaseLayer(BaseLayer), : BaseLayer(BaseLayer), CompileCallbackMgr(CallbackMgr) {}
CompileCallbackMgr(BaseLayer, Context, 0, 64) {}
/// @brief Add a module to the compile-on-demand layer. /// @brief Add a module to the compile-on-demand layer.
template <typename ModuleSetT> template <typename ModuleSetT>
@ -294,7 +293,7 @@ private:
M.getDataLayout()); M.getDataLayout());
auto &CCInfo = KVPair.second; auto &CCInfo = KVPair.second;
CCInfo.setUpdateAction( CCInfo.setUpdateAction(
CompileCallbackMgr.getLocalFPUpdater(StubsH, AddrName)); getLocalFPUpdater(BaseLayer, StubsH, AddrName));
} }
} }
@ -345,7 +344,7 @@ private:
} }
BaseLayerT &BaseLayer; BaseLayerT &BaseLayer;
CompileCallbackMgrT CompileCallbackMgr; CompileCallbackMgrT &CompileCallbackMgr;
ModuleSetInfoListT ModuleSetInfos; ModuleSetInfoListT ModuleSetInfos;
}; };

View File

@ -26,10 +26,34 @@ namespace orc {
/// @brief Base class for JITLayer independent aspects of /// @brief Base class for JITLayer independent aspects of
/// JITCompileCallbackManager. /// JITCompileCallbackManager.
template <typename TargetT>
class JITCompileCallbackManagerBase { class JITCompileCallbackManagerBase {
public: public:
typedef std::function<TargetAddress()> CompileFtor;
typedef std::function<void(TargetAddress)> UpdateFtor;
/// @brief Handle to a newly created compile callback. Can be used to get an
/// IR constant representing the address of the trampoline, and to set
/// the compile and update actions for the callback.
class CompileCallbackInfo {
public:
CompileCallbackInfo(Constant *Addr, CompileFtor &Compile,
UpdateFtor &Update)
: Addr(Addr), Compile(Compile), Update(Update) {}
Constant* getAddress() const { return Addr; }
void setCompileAction(CompileFtor Compile) {
this->Compile = std::move(Compile);
}
void setUpdateAction(UpdateFtor Update) {
this->Update = std::move(Update);
}
private:
Constant *Addr;
CompileFtor &Compile;
UpdateFtor &Update;
};
/// @brief Construct a JITCompileCallbackManagerBase. /// @brief Construct a JITCompileCallbackManagerBase.
/// @param ErrorHandlerAddress The address of an error handler in the target /// @param ErrorHandlerAddress The address of an error handler in the target
/// process to be used if a compile callback fails. /// process to be used if a compile callback fails.
@ -41,6 +65,8 @@ public:
: ErrorHandlerAddress(ErrorHandlerAddress), : ErrorHandlerAddress(ErrorHandlerAddress),
NumTrampolinesPerBlock(NumTrampolinesPerBlock) {} NumTrampolinesPerBlock(NumTrampolinesPerBlock) {}
virtual ~JITCompileCallbackManagerBase() {}
/// @brief Execute the callback for the given trampoline id. Called by the JIT /// @brief Execute the callback for the given trampoline id. Called by the JIT
/// to compile functions on demand. /// to compile functions on demand.
TargetAddress executeCompileCallback(TargetAddress TrampolineID) { TargetAddress executeCompileCallback(TargetAddress TrampolineID) {
@ -67,14 +93,14 @@ public:
return ErrorHandlerAddress; return ErrorHandlerAddress;
} }
/// @brief Get/create a compile callback with the given signature.
virtual CompileCallbackInfo getCompileCallback(FunctionType &FT) = 0;
protected: protected:
typedef std::function<TargetAddress()> CompileFtorT;
typedef std::function<void(TargetAddress)> UpdateFtorT;
struct CallbackHandler { struct CallbackHandler {
CompileFtorT Compile; CompileFtor Compile;
UpdateFtorT Update; UpdateFtor Update;
}; };
TargetAddress ErrorHandlerAddress; TargetAddress ErrorHandlerAddress;
@ -87,15 +113,9 @@ protected:
/// @brief Manage compile callbacks. /// @brief Manage compile callbacks.
template <typename JITLayerT, typename TargetT> template <typename JITLayerT, typename TargetT>
class JITCompileCallbackManager : class JITCompileCallbackManager : public JITCompileCallbackManagerBase {
public JITCompileCallbackManagerBase<TargetT> {
public: public:
typedef typename JITCompileCallbackManagerBase<TargetT>::CompileFtorT
CompileFtorT;
typedef typename JITCompileCallbackManagerBase<TargetT>::UpdateFtorT
UpdateFtorT;
/// @brief Construct a JITCompileCallbackManager. /// @brief Construct a JITCompileCallbackManager.
/// @param JIT JIT layer to emit callback trampolines, etc. into. /// @param JIT JIT layer to emit callback trampolines, etc. into.
/// @param Context LLVMContext to use for trampoline & resolve block modules. /// @param Context LLVMContext to use for trampoline & resolve block modules.
@ -108,36 +128,14 @@ public:
JITCompileCallbackManager(JITLayerT &JIT, LLVMContext &Context, JITCompileCallbackManager(JITLayerT &JIT, LLVMContext &Context,
TargetAddress ErrorHandlerAddress, TargetAddress ErrorHandlerAddress,
unsigned NumTrampolinesPerBlock) unsigned NumTrampolinesPerBlock)
: JITCompileCallbackManagerBase<TargetT>(ErrorHandlerAddress, : JITCompileCallbackManagerBase(ErrorHandlerAddress,
NumTrampolinesPerBlock), NumTrampolinesPerBlock),
JIT(JIT) { JIT(JIT) {
emitResolverBlock(Context); emitResolverBlock(Context);
} }
/// @brief Handle to a newly created compile callback. Can be used to get an
/// IR constant representing the address of the trampoline, and to set
/// the compile and update actions for the callback.
class CompileCallbackInfo {
public:
CompileCallbackInfo(Constant *Addr, CompileFtorT &Compile,
UpdateFtorT &Update)
: Addr(Addr), Compile(Compile), Update(Update) {}
Constant* getAddress() const { return Addr; }
void setCompileAction(CompileFtorT Compile) {
this->Compile = std::move(Compile);
}
void setUpdateAction(UpdateFtorT Update) {
this->Update = std::move(Update);
}
private:
Constant *Addr;
CompileFtorT &Compile;
UpdateFtorT &Update;
};
/// @brief Get/create a compile callback with the given signature. /// @brief Get/create a compile callback with the given signature.
CompileCallbackInfo getCompileCallback(FunctionType &FT) { CompileCallbackInfo getCompileCallback(FunctionType &FT) final {
TargetAddress TrampolineAddr = getAvailableTrampolineAddr(FT.getContext()); TargetAddress TrampolineAddr = getAvailableTrampolineAddr(FT.getContext());
auto &CallbackHandler = auto &CallbackHandler =
this->ActiveTrampolines[TrampolineAddr]; this->ActiveTrampolines[TrampolineAddr];
@ -151,19 +149,6 @@ public:
CallbackHandler.Update); CallbackHandler.Update);
} }
/// @brief Get a functor for updating the value of a named function pointer.
UpdateFtorT getLocalFPUpdater(typename JITLayerT::ModuleSetHandleT H,
std::string Name) {
// FIXME: Move-capture Name once we can use C++14.
return [=](TargetAddress Addr) {
auto FPSym = JIT.findSymbolIn(H, Name, true);
assert(FPSym && "Cannot find function pointer to update.");
void *FPAddr = reinterpret_cast<void*>(
static_cast<uintptr_t>(FPSym.getAddress()));
memcpy(FPAddr, &Addr, sizeof(uintptr_t));
};
}
private: private:
std::vector<std::unique_ptr<Module>> std::vector<std::unique_ptr<Module>>
@ -216,6 +201,22 @@ private:
TargetAddress ResolverBlockAddr; TargetAddress ResolverBlockAddr;
}; };
/// @brief Get an update functor for updating the value of a named function
/// pointer.
template <typename JITLayerT>
JITCompileCallbackManagerBase::UpdateFtor
getLocalFPUpdater(JITLayerT &JIT, typename JITLayerT::ModuleSetHandleT H,
std::string Name) {
// FIXME: Move-capture Name once we can use C++14.
return [=,&JIT](TargetAddress Addr) {
auto FPSym = JIT.findSymbolIn(H, Name, true);
assert(FPSym && "Cannot find function pointer to update.");
void *FPAddr = reinterpret_cast<void*>(
static_cast<uintptr_t>(FPSym.getAddress()));
memcpy(FPAddr, &Addr, sizeof(uintptr_t));
};
}
GlobalVariable* createImplPointer(Function &F, const Twine &Name, GlobalVariable* createImplPointer(Function &F, const Twine &Name,
Constant *Initializer); Constant *Initializer);

View File

@ -25,9 +25,8 @@ public:
/// @brief Insert module-level inline callback asm into module M for the /// @brief Insert module-level inline callback asm into module M for the
/// symbols managed by JITResolveCallbackHandler J. /// symbols managed by JITResolveCallbackHandler J.
static void insertResolverBlock( static void insertResolverBlock(Module &M,
Module &M, JITCompileCallbackManagerBase &JCBM);
JITCompileCallbackManagerBase<OrcX86_64> &JCBM);
/// @brief Get a label name from the given index. /// @brief Get a label name from the given index.
typedef std::function<std::string(unsigned)> LabelNameFtor; typedef std::function<std::string(unsigned)> LabelNameFtor;

View File

@ -39,7 +39,7 @@ template <typename OStream> void restoreX86Regs(OStream &OS) {
} }
template <typename TargetT> template <typename TargetT>
uint64_t executeCompileCallback(JITCompileCallbackManagerBase<TargetT> *JCBM, uint64_t executeCompileCallback(JITCompileCallbackManagerBase *JCBM,
TargetAddress CallbackID) { TargetAddress CallbackID) {
return JCBM->executeCompileCallback(CallbackID); return JCBM->executeCompileCallback(CallbackID);
} }
@ -52,7 +52,7 @@ namespace orc {
const char* OrcX86_64::ResolverBlockName = "orc_resolver_block"; const char* OrcX86_64::ResolverBlockName = "orc_resolver_block";
void OrcX86_64::insertResolverBlock( void OrcX86_64::insertResolverBlock(
Module &M, JITCompileCallbackManagerBase<OrcX86_64> &JCBM) { Module &M, JITCompileCallbackManagerBase &JCBM) {
const unsigned X86_64_TrampolineLength = 6; const unsigned X86_64_TrampolineLength = 6;
auto CallbackPtr = executeCompileCallback<OrcX86_64>; auto CallbackPtr = executeCompileCallback<OrcX86_64>;
uint64_t CallbackAddr = uint64_t CallbackAddr =