mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 18:54:02 +01:00
[Orc] Expose the compile callback API through the C bindings.
llvm-svn: 251683
This commit is contained in:
parent
4059955e80
commit
d06d3863b2
@ -35,6 +35,8 @@ typedef uint32_t LLVMOrcModuleHandle;
|
||||
typedef uint64_t LLVMOrcTargetAddress;
|
||||
typedef uint64_t (*LLVMOrcSymbolResolverFn)(const char *Name,
|
||||
void *LookupCtx);
|
||||
typedef uint64_t (*LLVMOrcLazyCompileCallbackFn)(LLVMOrcJITStackRef JITStack,
|
||||
void *CallbackCtx);
|
||||
|
||||
/**
|
||||
* Create an ORC JIT stack.
|
||||
@ -61,6 +63,28 @@ void LLVMOrcGetMangledSymbol(LLVMOrcJITStackRef JITStack, char **MangledSymbol,
|
||||
|
||||
void LLVMOrcDisposeMangledSymbol(char *MangledSymbol);
|
||||
|
||||
/**
|
||||
* Create a lazy compile callback.
|
||||
*/
|
||||
LLVMOrcTargetAddress
|
||||
LLVMOrcCreateLazyCompileCallback(LLVMOrcJITStackRef JITStack,
|
||||
LLVMOrcLazyCompileCallbackFn Callback,
|
||||
void *CallbackCtx);
|
||||
|
||||
/**
|
||||
* Create a named indirect call stub.
|
||||
*/
|
||||
void LLVMOrcCreateIndirectStub(LLVMOrcJITStackRef JITStack,
|
||||
const char *StubName,
|
||||
LLVMOrcTargetAddress InitAddr);
|
||||
|
||||
/**
|
||||
* Set the pointer for the given indirect stub.
|
||||
*/
|
||||
void LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack,
|
||||
const char *StubName,
|
||||
LLVMOrcTargetAddress NewAddr);
|
||||
|
||||
/**
|
||||
* Add module to be eagerly compiled.
|
||||
*/
|
||||
|
@ -12,9 +12,6 @@
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
|
||||
|
||||
LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM,
|
||||
LLVMContextRef Context) {
|
||||
TargetMachine *TM2(unwrap(TM));
|
||||
@ -45,6 +42,28 @@ void LLVMOrcDisposeMangledSymbol(char *MangledName) {
|
||||
delete[] MangledName;
|
||||
}
|
||||
|
||||
LLVMOrcTargetAddress
|
||||
LLVMOrcCreateLazyCompileCallback(LLVMOrcJITStackRef JITStack,
|
||||
LLVMOrcLazyCompileCallbackFn Callback,
|
||||
void *CallbackCtx) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
return J.createLazyCompileCallback(Callback, CallbackCtx);
|
||||
}
|
||||
|
||||
void LLVMOrcCreateIndirectStub(LLVMOrcJITStackRef JITStack,
|
||||
const char *StubName,
|
||||
LLVMOrcTargetAddress InitAddr) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
J.createIndirectStub(StubName, InitAddr);
|
||||
}
|
||||
|
||||
void LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack,
|
||||
const char *StubName,
|
||||
LLVMOrcTargetAddress NewAddr) {
|
||||
OrcCBindingsStack &J = *unwrap(JITStack);
|
||||
J.setIndirectStubPointer(StubName, NewAddr);
|
||||
}
|
||||
|
||||
LLVMOrcModuleHandle
|
||||
LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
|
||||
LLVMOrcSymbolResolverFn SymbolResolver,
|
||||
|
@ -17,17 +17,18 @@
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm-c/OrcBindings.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class OrcCBindingsStack;
|
||||
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
|
||||
|
||||
class OrcCBindingsStack {
|
||||
private:
|
||||
|
||||
public:
|
||||
|
||||
typedef orc::TargetAddress (*CExternalSymbolResolverFn)(const char *Name,
|
||||
void *Ctx);
|
||||
|
||||
typedef orc::JITCompileCallbackManagerBase CompileCallbackMgr;
|
||||
typedef orc::ObjectLinkingLayer<> ObjLayerT;
|
||||
typedef orc::IRCompileLayer<ObjLayerT> CompileLayerT;
|
||||
@ -91,13 +92,14 @@ public:
|
||||
OrcCBindingsStack(TargetMachine &TM, LLVMContext &Context,
|
||||
CallbackManagerBuilder &BuildCallbackMgr,
|
||||
IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
|
||||
: DL(TM.createDataLayout()),
|
||||
: Context(Context), DL(TM.createDataLayout()),
|
||||
ObjectLayer(),
|
||||
CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)),
|
||||
CCMgr(BuildCallbackMgr(CompileLayer, CCMgrMemMgr, Context)),
|
||||
CODLayer(CompileLayer,
|
||||
[](Function &F) { std::set<Function*> S; S.insert(&F); return S; },
|
||||
*CCMgr, std::move(IndirectStubsMgrBuilder), false),
|
||||
IndirectStubsMgr(IndirectStubsMgrBuilder()),
|
||||
CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {}
|
||||
|
||||
~OrcCBindingsStack() {
|
||||
@ -122,8 +124,27 @@ public:
|
||||
return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
|
||||
}
|
||||
|
||||
orc::TargetAddress
|
||||
createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback,
|
||||
void *CallbackCtx) {
|
||||
auto CCInfo = CCMgr->getCompileCallback(Context);
|
||||
CCInfo.setCompileAction(
|
||||
[=]() -> orc::TargetAddress {
|
||||
return Callback(wrap(this), CallbackCtx);
|
||||
});
|
||||
return CCInfo.getAddress();
|
||||
}
|
||||
|
||||
void createIndirectStub(StringRef StubName, orc::TargetAddress Addr) {
|
||||
IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported);
|
||||
}
|
||||
|
||||
void setIndirectStubPointer(StringRef Name, orc::TargetAddress Addr) {
|
||||
IndirectStubsMgr->updatePointer(Name, Addr);
|
||||
}
|
||||
|
||||
std::shared_ptr<RuntimeDyld::SymbolResolver>
|
||||
createResolver(CExternalSymbolResolverFn ExternalResolver,
|
||||
createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
auto Resolver = orc::createLambdaResolver(
|
||||
[this, ExternalResolver, ExternalResolverCtx](const std::string &Name) {
|
||||
@ -157,7 +178,7 @@ public:
|
||||
ModuleHandleT addIRModule(LayerT &Layer,
|
||||
Module *M,
|
||||
std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
|
||||
CExternalSymbolResolverFn ExternalResolver,
|
||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
|
||||
// Attach a data-layout if one isn't already present.
|
||||
@ -194,7 +215,7 @@ public:
|
||||
}
|
||||
|
||||
ModuleHandleT addIRModuleEager(Module* M,
|
||||
CExternalSymbolResolverFn ExternalResolver,
|
||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
return addIRModule(CompileLayer, std::move(M),
|
||||
llvm::make_unique<SectionMemoryManager>(),
|
||||
@ -202,7 +223,7 @@ public:
|
||||
}
|
||||
|
||||
ModuleHandleT addIRModuleLazy(Module* M,
|
||||
CExternalSymbolResolverFn ExternalResolver,
|
||||
LLVMOrcSymbolResolverFn ExternalResolver,
|
||||
void *ExternalResolverCtx) {
|
||||
return addIRModule(CODLayer, std::move(M), nullptr,
|
||||
std::move(ExternalResolver), ExternalResolverCtx);
|
||||
@ -215,6 +236,8 @@ public:
|
||||
}
|
||||
|
||||
orc::JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
|
||||
if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
|
||||
return Sym;
|
||||
return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
|
||||
}
|
||||
|
||||
@ -241,6 +264,7 @@ private:
|
||||
return NewHandle;
|
||||
}
|
||||
|
||||
LLVMContext &Context;
|
||||
DataLayout DL;
|
||||
SectionMemoryManager CCMgrMemMgr;
|
||||
|
||||
@ -249,6 +273,8 @@ private:
|
||||
std::unique_ptr<CompileCallbackMgr> CCMgr;
|
||||
CODLayerT CODLayer;
|
||||
|
||||
std::unique_ptr<orc::IndirectStubsManagerBase> IndirectStubsMgr;
|
||||
|
||||
std::vector<std::unique_ptr<GenericHandle>> GenericHandles;
|
||||
std::vector<unsigned> FreeHandleIndexes;
|
||||
|
||||
|
@ -51,21 +51,41 @@ protected:
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct CompileContext {
|
||||
CompileContext() : Compiled(false) { }
|
||||
|
||||
OrcCAPIExecutionTest* APIExecTest;
|
||||
std::unique_ptr<Module> M;
|
||||
LLVMOrcModuleHandle H;
|
||||
bool Compiled;
|
||||
};
|
||||
|
||||
static LLVMOrcTargetAddress myCompileCallback(LLVMOrcJITStackRef JITStack,
|
||||
void *Ctx) {
|
||||
CompileContext *CCtx = static_cast<CompileContext*>(Ctx);
|
||||
auto *ET = CCtx->APIExecTest;
|
||||
CCtx->M = ET->createTestModule(ET->TM->getTargetTriple());
|
||||
CCtx->H = LLVMOrcAddEagerlyCompiledIR(JITStack, wrap(CCtx->M.get()),
|
||||
myResolver, 0);
|
||||
CCtx->Compiled = true;
|
||||
LLVMOrcTargetAddress MainAddr = LLVMOrcGetSymbolAddress(JITStack, "main");
|
||||
LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr);
|
||||
return MainAddr;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
char *OrcCAPIExecutionTest::testFuncName = 0;
|
||||
|
||||
TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
|
||||
auto TM = getHostTargetMachineIfSupported();
|
||||
|
||||
if (!TM)
|
||||
return;
|
||||
|
||||
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
|
||||
|
||||
LLVMOrcJITStackRef JIT =
|
||||
LLVMOrcCreateInstance(wrap(TM.get()), LLVMGetGlobalContext());
|
||||
|
||||
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
|
||||
|
||||
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
|
||||
|
||||
LLVMOrcModuleHandle H =
|
||||
@ -82,17 +102,16 @@ TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
|
||||
}
|
||||
|
||||
TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
|
||||
auto TM = getHostTargetMachineIfSupported();
|
||||
|
||||
if (!TM)
|
||||
return;
|
||||
|
||||
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
|
||||
|
||||
LLVMOrcJITStackRef JIT =
|
||||
LLVMOrcCreateInstance(wrap(TM.get()), LLVMGetGlobalContext());
|
||||
|
||||
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
|
||||
|
||||
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
|
||||
|
||||
LLVMOrcModuleHandle H =
|
||||
LLVMOrcAddLazilyCompiledIR(JIT, wrap(M.get()), myResolver, 0);
|
||||
MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
|
||||
@ -106,4 +125,37 @@ TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
|
||||
LLVMOrcDisposeInstance(JIT);
|
||||
}
|
||||
|
||||
TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
|
||||
if (!TM)
|
||||
return;
|
||||
|
||||
LLVMOrcJITStackRef JIT =
|
||||
LLVMOrcCreateInstance(wrap(TM.get()), LLVMGetGlobalContext());
|
||||
|
||||
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
|
||||
|
||||
CompileContext C;
|
||||
C.APIExecTest = this;
|
||||
LLVMOrcCreateIndirectStub(JIT, "foo",
|
||||
LLVMOrcCreateLazyCompileCallback(JIT,
|
||||
myCompileCallback,
|
||||
&C));
|
||||
MainFnTy FooFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "foo");
|
||||
int Result = FooFn();
|
||||
EXPECT_TRUE(C.Compiled)
|
||||
<< "Function wasn't lazily compiled";
|
||||
EXPECT_EQ(Result, 42)
|
||||
<< "Direct-callback JIT'd code did not return expected result";
|
||||
|
||||
C.Compiled = false;
|
||||
FooFn();
|
||||
EXPECT_FALSE(C.Compiled)
|
||||
<< "Direct-callback JIT'd code was JIT'd twice";
|
||||
|
||||
LLVMOrcRemoveModule(JIT, C.H);
|
||||
|
||||
LLVMOrcDisposeMangledSymbol(testFuncName);
|
||||
LLVMOrcDisposeInstance(JIT);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -38,23 +38,20 @@ public:
|
||||
InitializeNativeTargetAsmPrinter();
|
||||
NativeTargetInitialized = true;
|
||||
}
|
||||
|
||||
// Try to select a TargetMachine for the host.
|
||||
TM.reset(EngineBuilder().selectTarget());
|
||||
|
||||
if (TM) {
|
||||
// If we found a TargetMachine, check that it's one that Orc supports.
|
||||
const Triple& TT = TM->getTargetTriple();
|
||||
if (TT.getArch() != Triple::x86_64 || !TT.isOSDarwin())
|
||||
TM = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
// Get a target machine for the host if it supports JIT execution.
|
||||
std::unique_ptr<TargetMachine> getHostTargetMachineIfSupported() {
|
||||
std::unique_ptr<TargetMachine> TM(EngineBuilder().selectTarget());
|
||||
|
||||
if (!TM)
|
||||
return nullptr;
|
||||
|
||||
const Triple& TT = TM->getTargetTriple();
|
||||
|
||||
if (TT.getArch() != Triple::x86_64 || !TT.isOSDarwin())
|
||||
return nullptr;
|
||||
|
||||
return TM;
|
||||
}
|
||||
|
||||
protected:
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
private:
|
||||
static bool NativeTargetInitialized;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user