forked from OSchip/llvm-project
[ORC] Hook up the LLVMOrcAddObjectFile function in the Orc C Bindings.
This can be used to add a relocatable object to the JIT session. llvm-svn: 313474
This commit is contained in:
parent
4b93d23abb
commit
ec30063ff3
|
@ -30,7 +30,6 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct LLVMOpaqueSharedModule *LLVMSharedModuleRef;
|
typedef struct LLVMOpaqueSharedModule *LLVMSharedModuleRef;
|
||||||
typedef struct LLVMOpaqueSharedObjectBuffer *LLVMSharedObjectBufferRef;
|
|
||||||
typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef;
|
typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef;
|
||||||
typedef uint32_t LLVMOrcModuleHandle;
|
typedef uint32_t LLVMOrcModuleHandle;
|
||||||
typedef uint64_t LLVMOrcTargetAddress;
|
typedef uint64_t LLVMOrcTargetAddress;
|
||||||
|
@ -67,18 +66,6 @@ LLVMSharedModuleRef LLVMOrcMakeSharedModule(LLVMModuleRef Mod);
|
||||||
|
|
||||||
void LLVMOrcDisposeSharedModuleRef(LLVMSharedModuleRef SharedMod);
|
void LLVMOrcDisposeSharedModuleRef(LLVMSharedModuleRef SharedMod);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an LLVMSharedObjectBufferRef from an LLVMMemoryBufferRef.
|
|
||||||
*/
|
|
||||||
LLVMSharedObjectBufferRef
|
|
||||||
LLVMOrcMakeSharedObjectBuffer(LLVMMemoryBufferRef ObjBuffer);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispose of a shared object buffer.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
LLVMOrcDisposeSharedObjectBufferRef(LLVMSharedObjectBufferRef SharedObjBuffer);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an ORC JIT stack.
|
* Create an ORC JIT stack.
|
||||||
*
|
*
|
||||||
|
@ -155,10 +142,15 @@ LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an object file.
|
* Add an object file.
|
||||||
|
*
|
||||||
|
* This method takes ownership of the given memory buffer and attempts to add
|
||||||
|
* it to the JIT as an object file.
|
||||||
|
* Clients should *not* dispose of the 'Obj' argument: the JIT will manage it
|
||||||
|
* from this call onwards.
|
||||||
*/
|
*/
|
||||||
LLVMOrcErrorCode LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
|
LLVMOrcErrorCode LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
|
||||||
LLVMOrcModuleHandle *RetHandle,
|
LLVMOrcModuleHandle *RetHandle,
|
||||||
LLVMSharedObjectBufferRef Obj,
|
LLVMMemoryBufferRef Obj,
|
||||||
LLVMOrcSymbolResolverFn SymbolResolver,
|
LLVMOrcSymbolResolverFn SymbolResolver,
|
||||||
void *SymbolResolverCtx);
|
void *SymbolResolverCtx);
|
||||||
|
|
||||||
|
|
|
@ -20,16 +20,6 @@ void LLVMOrcDisposeSharedModuleRef(LLVMSharedModuleRef SharedMod) {
|
||||||
delete unwrap(SharedMod);
|
delete unwrap(SharedMod);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMSharedObjectBufferRef
|
|
||||||
LLVMOrcMakeSharedObjectBuffer(LLVMMemoryBufferRef ObjBuffer) {
|
|
||||||
return wrap(new std::shared_ptr<MemoryBuffer>(unwrap(ObjBuffer)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
LLVMOrcDisposeSharedObjectBufferRef(LLVMSharedObjectBufferRef SharedObjBuffer) {
|
|
||||||
delete unwrap(SharedObjBuffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM) {
|
LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM) {
|
||||||
TargetMachine *TM2(unwrap(TM));
|
TargetMachine *TM2(unwrap(TM));
|
||||||
|
|
||||||
|
@ -105,6 +95,18 @@ LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack,
|
||||||
return J.addIRModuleLazy(*RetHandle, *M, SymbolResolver, SymbolResolverCtx);
|
return J.addIRModuleLazy(*RetHandle, *M, SymbolResolver, SymbolResolverCtx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LLVMOrcErrorCode
|
||||||
|
LLVMOrcAddObjectFile(LLVMOrcJITStackRef JITStack,
|
||||||
|
LLVMOrcModuleHandle *RetHandle,
|
||||||
|
LLVMMemoryBufferRef Obj,
|
||||||
|
LLVMOrcSymbolResolverFn SymbolResolver,
|
||||||
|
void *SymbolResolverCtx) {
|
||||||
|
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||||
|
std::unique_ptr<MemoryBuffer> O(unwrap(Obj));
|
||||||
|
return J.addObject(*RetHandle, std::move(O), SymbolResolver,
|
||||||
|
SymbolResolverCtx);
|
||||||
|
}
|
||||||
|
|
||||||
LLVMOrcErrorCode LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack,
|
LLVMOrcErrorCode LLVMOrcRemoveModule(LLVMOrcJITStackRef JITStack,
|
||||||
LLVMOrcModuleHandle H) {
|
LLVMOrcModuleHandle H) {
|
||||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||||
|
|
|
@ -44,26 +44,12 @@ class OrcCBindingsStack;
|
||||||
|
|
||||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr<Module>,
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr<Module>,
|
||||||
LLVMSharedModuleRef)
|
LLVMSharedModuleRef)
|
||||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr<MemoryBuffer>,
|
|
||||||
LLVMSharedObjectBufferRef)
|
|
||||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
|
||||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
|
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
|
||||||
|
|
||||||
class OrcCBindingsStack {
|
namespace detail {
|
||||||
public:
|
|
||||||
|
|
||||||
using CompileCallbackMgr = orc::JITCompileCallbackManager;
|
|
||||||
using ObjLayerT = orc::RTDyldObjectLinkingLayer;
|
|
||||||
using CompileLayerT = orc::IRCompileLayer<ObjLayerT, orc::SimpleCompiler>;
|
|
||||||
using CODLayerT =
|
|
||||||
orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>;
|
|
||||||
|
|
||||||
using CallbackManagerBuilder =
|
|
||||||
std::function<std::unique_ptr<CompileCallbackMgr>()>;
|
|
||||||
|
|
||||||
using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT;
|
|
||||||
|
|
||||||
private:
|
|
||||||
class GenericHandle {
|
class GenericHandle {
|
||||||
public:
|
public:
|
||||||
virtual ~GenericHandle() = default;
|
virtual ~GenericHandle() = default;
|
||||||
|
@ -90,13 +76,56 @@ private:
|
||||||
typename LayerT::ModuleHandleT Handle;
|
typename LayerT::ModuleHandleT Handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename LayerT>
|
template <>
|
||||||
|
class GenericHandleImpl<orc::RTDyldObjectLinkingLayer>
|
||||||
|
: public GenericHandle {
|
||||||
|
private:
|
||||||
|
using LayerT = orc::RTDyldObjectLinkingLayer;
|
||||||
|
public:
|
||||||
|
|
||||||
|
GenericHandleImpl(LayerT &Layer, typename LayerT::ObjHandleT Handle)
|
||||||
|
: Layer(Layer), Handle(std::move(Handle)) {}
|
||||||
|
|
||||||
|
JITSymbol findSymbolIn(const std::string &Name,
|
||||||
|
bool ExportedSymbolsOnly) override {
|
||||||
|
return Layer.findSymbolIn(Handle, Name, ExportedSymbolsOnly);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error removeModule() override { return Layer.removeObject(Handle); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
LayerT &Layer;
|
||||||
|
typename LayerT::ObjHandleT Handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename LayerT, typename HandleT>
|
||||||
std::unique_ptr<GenericHandleImpl<LayerT>>
|
std::unique_ptr<GenericHandleImpl<LayerT>>
|
||||||
createGenericHandle(LayerT &Layer, typename LayerT::ModuleHandleT Handle) {
|
createGenericHandle(LayerT &Layer, HandleT Handle) {
|
||||||
return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer,
|
return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer,
|
||||||
std::move(Handle));
|
std::move(Handle));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // end namespace detail
|
||||||
|
|
||||||
|
class OrcCBindingsStack {
|
||||||
|
public:
|
||||||
|
|
||||||
|
using CompileCallbackMgr = orc::JITCompileCallbackManager;
|
||||||
|
using ObjLayerT = orc::RTDyldObjectLinkingLayer;
|
||||||
|
using CompileLayerT = orc::IRCompileLayer<ObjLayerT, orc::SimpleCompiler>;
|
||||||
|
using CODLayerT =
|
||||||
|
orc::CompileOnDemandLayer<CompileLayerT, CompileCallbackMgr>;
|
||||||
|
|
||||||
|
using CallbackManagerBuilder =
|
||||||
|
std::function<std::unique_ptr<CompileCallbackMgr>()>;
|
||||||
|
|
||||||
|
using IndirectStubsManagerBuilder = CODLayerT::IndirectStubsManagerBuilderT;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
using OwningObject = object::OwningBinary<object::ObjectFile>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using ModuleHandleT = unsigned;
|
using ModuleHandleT = unsigned;
|
||||||
|
|
||||||
|
@ -266,6 +295,33 @@ public:
|
||||||
return LLVMOrcErrSuccess;
|
return LLVMOrcErrSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LLVMOrcErrorCode addObject(ModuleHandleT &RetHandle,
|
||||||
|
std::unique_ptr<MemoryBuffer> ObjBuffer,
|
||||||
|
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||||
|
void *ExternalResolverCtx) {
|
||||||
|
if (auto ObjOrErr =
|
||||||
|
object::ObjectFile::createObjectFile(ObjBuffer->getMemBufferRef())) {
|
||||||
|
auto &Obj = *ObjOrErr;
|
||||||
|
auto OwningObj =
|
||||||
|
std::make_shared<OwningObject>(std::move(Obj), std::move(ObjBuffer));
|
||||||
|
|
||||||
|
// Create the resolver.
|
||||||
|
auto Resolver = createResolver(ExternalResolver, ExternalResolverCtx);
|
||||||
|
|
||||||
|
ModuleHandleT H;
|
||||||
|
if (auto HOrErr = ObjectLayer.addObject(std::move(OwningObj),
|
||||||
|
std::move(Resolver)))
|
||||||
|
H = createHandle(ObjectLayer, *HOrErr);
|
||||||
|
else
|
||||||
|
return mapError(HOrErr.takeError());
|
||||||
|
|
||||||
|
RetHandle = H;
|
||||||
|
|
||||||
|
return LLVMOrcErrSuccess;
|
||||||
|
} else
|
||||||
|
return mapError(ObjOrErr.takeError());
|
||||||
|
}
|
||||||
|
|
||||||
JITSymbol findSymbol(const std::string &Name,
|
JITSymbol findSymbol(const std::string &Name,
|
||||||
bool ExportedSymbolsOnly) {
|
bool ExportedSymbolsOnly) {
|
||||||
if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
|
if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
|
||||||
|
@ -301,17 +357,19 @@ public:
|
||||||
const std::string &getErrorMessage() const { return ErrMsg; }
|
const std::string &getErrorMessage() const { return ErrMsg; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename LayerT>
|
template <typename LayerT, typename HandleT>
|
||||||
unsigned createHandle(LayerT &Layer, typename LayerT::ModuleHandleT Handle) {
|
unsigned createHandle(LayerT &Layer, HandleT Handle) {
|
||||||
unsigned NewHandle;
|
unsigned NewHandle;
|
||||||
if (!FreeHandleIndexes.empty()) {
|
if (!FreeHandleIndexes.empty()) {
|
||||||
NewHandle = FreeHandleIndexes.back();
|
NewHandle = FreeHandleIndexes.back();
|
||||||
FreeHandleIndexes.pop_back();
|
FreeHandleIndexes.pop_back();
|
||||||
GenericHandles[NewHandle] = createGenericHandle(Layer, std::move(Handle));
|
GenericHandles[NewHandle] =
|
||||||
|
detail::createGenericHandle(Layer, std::move(Handle));
|
||||||
return NewHandle;
|
return NewHandle;
|
||||||
} else {
|
} else {
|
||||||
NewHandle = GenericHandles.size();
|
NewHandle = GenericHandles.size();
|
||||||
GenericHandles.push_back(createGenericHandle(Layer, std::move(Handle)));
|
GenericHandles.push_back(
|
||||||
|
detail::createGenericHandle(Layer, std::move(Handle)));
|
||||||
}
|
}
|
||||||
return NewHandle;
|
return NewHandle;
|
||||||
}
|
}
|
||||||
|
@ -338,7 +396,7 @@ private:
|
||||||
CompileLayerT CompileLayer;
|
CompileLayerT CompileLayer;
|
||||||
CODLayerT CODLayer;
|
CODLayerT CODLayer;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<GenericHandle>> GenericHandles;
|
std::vector<std::unique_ptr<detail::GenericHandle>> GenericHandles;
|
||||||
std::vector<unsigned> FreeHandleIndexes;
|
std::vector<unsigned> FreeHandleIndexes;
|
||||||
|
|
||||||
orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
|
orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#include "OrcTestCommon.h"
|
#include "OrcTestCommon.h"
|
||||||
|
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||||
#include "llvm-c/Core.h"
|
#include "llvm-c/Core.h"
|
||||||
#include "llvm-c/OrcBindings.h"
|
#include "llvm-c/OrcBindings.h"
|
||||||
#include "llvm-c/Target.h"
|
#include "llvm-c/Target.h"
|
||||||
|
@ -37,6 +38,15 @@ protected:
|
||||||
return MB.takeModule();
|
return MB.takeModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<object::OwningBinary<object::ObjectFile>>
|
||||||
|
createTestObject() {
|
||||||
|
orc::SimpleCompiler IRCompiler(*TM);
|
||||||
|
auto M = createTestModule(TM->getTargetTriple());
|
||||||
|
M->setDataLayout(TM->createDataLayout());
|
||||||
|
return std::make_shared<object::OwningBinary<object::ObjectFile>>(
|
||||||
|
IRCompiler(*M));
|
||||||
|
}
|
||||||
|
|
||||||
typedef int (*MainFnTy)();
|
typedef int (*MainFnTy)();
|
||||||
|
|
||||||
static int myTestFuncImpl() {
|
static int myTestFuncImpl() {
|
||||||
|
@ -134,6 +144,36 @@ TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
|
||||||
LLVMOrcDisposeInstance(JIT);
|
LLVMOrcDisposeInstance(JIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(OrcCAPIExecutionTest, TestAddObjectFile) {
|
||||||
|
if (!TM)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::unique_ptr<MemoryBuffer> ObjBuffer;
|
||||||
|
{
|
||||||
|
auto OwningObj = createTestObject();
|
||||||
|
auto ObjAndBuffer = OwningObj->takeBinary();
|
||||||
|
ObjBuffer = std::move(ObjAndBuffer.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
LLVMOrcJITStackRef JIT =
|
||||||
|
LLVMOrcCreateInstance(wrap(TM.get()));
|
||||||
|
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
|
||||||
|
|
||||||
|
LLVMOrcModuleHandle H;
|
||||||
|
LLVMOrcAddObjectFile(JIT, &H, wrap(ObjBuffer.release()), myResolver, nullptr);
|
||||||
|
LLVMOrcTargetAddress MainAddr;
|
||||||
|
LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
|
||||||
|
MainFnTy MainFn = (MainFnTy)MainAddr;
|
||||||
|
int Result = MainFn();
|
||||||
|
EXPECT_EQ(Result, 42)
|
||||||
|
<< "Lazily JIT'd code did not return expected result";
|
||||||
|
|
||||||
|
LLVMOrcRemoveModule(JIT, H);
|
||||||
|
|
||||||
|
LLVMOrcDisposeMangledSymbol(testFuncName);
|
||||||
|
LLVMOrcDisposeInstance(JIT);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
|
TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
|
||||||
if (!TM)
|
if (!TM)
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue