[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:
Lang Hames 2017-09-17 03:25:03 +00:00
parent 4b93d23abb
commit ec30063ff3
4 changed files with 138 additions and 46 deletions

View File

@ -30,7 +30,6 @@ extern "C" {
#endif
typedef struct LLVMOpaqueSharedModule *LLVMSharedModuleRef;
typedef struct LLVMOpaqueSharedObjectBuffer *LLVMSharedObjectBufferRef;
typedef struct LLVMOrcOpaqueJITStack *LLVMOrcJITStackRef;
typedef uint32_t LLVMOrcModuleHandle;
typedef uint64_t LLVMOrcTargetAddress;
@ -67,18 +66,6 @@ LLVMSharedModuleRef LLVMOrcMakeSharedModule(LLVMModuleRef Mod);
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.
*
@ -155,10 +142,15 @@ LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack,
/**
* 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,
LLVMOrcModuleHandle *RetHandle,
LLVMSharedObjectBufferRef Obj,
LLVMMemoryBufferRef Obj,
LLVMOrcSymbolResolverFn SymbolResolver,
void *SymbolResolverCtx);

View File

@ -20,16 +20,6 @@ void LLVMOrcDisposeSharedModuleRef(LLVMSharedModuleRef 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) {
TargetMachine *TM2(unwrap(TM));
@ -105,6 +95,18 @@ LLVMOrcAddLazilyCompiledIR(LLVMOrcJITStackRef JITStack,
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,
LLVMOrcModuleHandle H) {
OrcCBindingsStack &J = *unwrap(JITStack);

View File

@ -44,26 +44,12 @@ class OrcCBindingsStack;
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr<Module>,
LLVMSharedModuleRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(std::shared_ptr<MemoryBuffer>,
LLVMSharedObjectBufferRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
class OrcCBindingsStack {
public:
namespace detail {
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 {
public:
virtual ~GenericHandle() = default;
@ -90,13 +76,56 @@ private:
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>>
createGenericHandle(LayerT &Layer, typename LayerT::ModuleHandleT Handle) {
createGenericHandle(LayerT &Layer, HandleT Handle) {
return llvm::make_unique<GenericHandleImpl<LayerT>>(Layer,
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:
using ModuleHandleT = unsigned;
@ -266,6 +295,33 @@ public:
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,
bool ExportedSymbolsOnly) {
if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
@ -301,17 +357,19 @@ public:
const std::string &getErrorMessage() const { return ErrMsg; }
private:
template <typename LayerT>
unsigned createHandle(LayerT &Layer, typename LayerT::ModuleHandleT Handle) {
template <typename LayerT, typename HandleT>
unsigned createHandle(LayerT &Layer, HandleT Handle) {
unsigned NewHandle;
if (!FreeHandleIndexes.empty()) {
NewHandle = FreeHandleIndexes.back();
FreeHandleIndexes.pop_back();
GenericHandles[NewHandle] = createGenericHandle(Layer, std::move(Handle));
GenericHandles[NewHandle] =
detail::createGenericHandle(Layer, std::move(Handle));
return NewHandle;
} else {
NewHandle = GenericHandles.size();
GenericHandles.push_back(createGenericHandle(Layer, std::move(Handle)));
GenericHandles.push_back(
detail::createGenericHandle(Layer, std::move(Handle)));
}
return NewHandle;
}
@ -338,7 +396,7 @@ private:
CompileLayerT CompileLayer;
CODLayerT CODLayer;
std::vector<std::unique_ptr<GenericHandle>> GenericHandles;
std::vector<std::unique_ptr<detail::GenericHandle>> GenericHandles;
std::vector<unsigned> FreeHandleIndexes;
orc::LocalCXXRuntimeOverrides CXXRuntimeOverrides;

View File

@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "OrcTestCommon.h"
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
#include "llvm-c/Core.h"
#include "llvm-c/OrcBindings.h"
#include "llvm-c/Target.h"
@ -37,6 +38,15 @@ protected:
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)();
static int myTestFuncImpl() {
@ -134,6 +144,36 @@ TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
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) {
if (!TM)
return;