[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;
/// @brief Construct a compile-on-demand layer instance.
CompileOnDemandLayer(BaseLayerT &BaseLayer, LLVMContext &Context)
: BaseLayer(BaseLayer),
CompileCallbackMgr(BaseLayer, Context, 0, 64) {}
CompileOnDemandLayer(BaseLayerT &BaseLayer, CompileCallbackMgrT &CallbackMgr)
: BaseLayer(BaseLayer), CompileCallbackMgr(CallbackMgr) {}
/// @brief Add a module to the compile-on-demand layer.
template <typename ModuleSetT>
@ -294,7 +293,7 @@ private:
M.getDataLayout());
auto &CCInfo = KVPair.second;
CCInfo.setUpdateAction(
CompileCallbackMgr.getLocalFPUpdater(StubsH, AddrName));
getLocalFPUpdater(BaseLayer, StubsH, AddrName));
}
}
@ -345,7 +344,7 @@ private:
}
BaseLayerT &BaseLayer;
CompileCallbackMgrT CompileCallbackMgr;
CompileCallbackMgrT &CompileCallbackMgr;
ModuleSetInfoListT ModuleSetInfos;
};

View File

@ -26,10 +26,34 @@ namespace orc {
/// @brief Base class for JITLayer independent aspects of
/// JITCompileCallbackManager.
template <typename TargetT>
class JITCompileCallbackManagerBase {
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.
/// @param ErrorHandlerAddress The address of an error handler in the target
/// process to be used if a compile callback fails.
@ -41,6 +65,8 @@ public:
: ErrorHandlerAddress(ErrorHandlerAddress),
NumTrampolinesPerBlock(NumTrampolinesPerBlock) {}
virtual ~JITCompileCallbackManagerBase() {}
/// @brief Execute the callback for the given trampoline id. Called by the JIT
/// to compile functions on demand.
TargetAddress executeCompileCallback(TargetAddress TrampolineID) {
@ -67,14 +93,14 @@ public:
return ErrorHandlerAddress;
}
/// @brief Get/create a compile callback with the given signature.
virtual CompileCallbackInfo getCompileCallback(FunctionType &FT) = 0;
protected:
typedef std::function<TargetAddress()> CompileFtorT;
typedef std::function<void(TargetAddress)> UpdateFtorT;
struct CallbackHandler {
CompileFtorT Compile;
UpdateFtorT Update;
CompileFtor Compile;
UpdateFtor Update;
};
TargetAddress ErrorHandlerAddress;
@ -87,15 +113,9 @@ protected:
/// @brief Manage compile callbacks.
template <typename JITLayerT, typename TargetT>
class JITCompileCallbackManager :
public JITCompileCallbackManagerBase<TargetT> {
class JITCompileCallbackManager : public JITCompileCallbackManagerBase {
public:
typedef typename JITCompileCallbackManagerBase<TargetT>::CompileFtorT
CompileFtorT;
typedef typename JITCompileCallbackManagerBase<TargetT>::UpdateFtorT
UpdateFtorT;
/// @brief Construct a JITCompileCallbackManager.
/// @param JIT JIT layer to emit callback trampolines, etc. into.
/// @param Context LLVMContext to use for trampoline & resolve block modules.
@ -108,36 +128,14 @@ public:
JITCompileCallbackManager(JITLayerT &JIT, LLVMContext &Context,
TargetAddress ErrorHandlerAddress,
unsigned NumTrampolinesPerBlock)
: JITCompileCallbackManagerBase<TargetT>(ErrorHandlerAddress,
NumTrampolinesPerBlock),
: JITCompileCallbackManagerBase(ErrorHandlerAddress,
NumTrampolinesPerBlock),
JIT(JIT) {
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.
CompileCallbackInfo getCompileCallback(FunctionType &FT) {
CompileCallbackInfo getCompileCallback(FunctionType &FT) final {
TargetAddress TrampolineAddr = getAvailableTrampolineAddr(FT.getContext());
auto &CallbackHandler =
this->ActiveTrampolines[TrampolineAddr];
@ -151,19 +149,6 @@ public:
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:
std::vector<std::unique_ptr<Module>>
@ -216,6 +201,22 @@ private:
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,
Constant *Initializer);

View File

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