Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit df3ef60

Browse files
committed
[Orc] Expose the compile callback API through the C bindings.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@251683 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent e05ab11 commit df3ef60

File tree

5 files changed

+153
-35
lines changed

5 files changed

+153
-35
lines changed

include/llvm-c/OrcBindings.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ typedef uint32_t LLVMOrcModuleHandle;
3535
typedef uint64_t LLVMOrcTargetAddress;
3636
typedef uint64_t (*LLVMOrcSymbolResolverFn)(const char *Name,
3737
void *LookupCtx);
38+
typedef uint64_t (*LLVMOrcLazyCompileCallbackFn)(LLVMOrcJITStackRef JITStack,
39+
void *CallbackCtx);
3840

3941
/**
4042
* Create an ORC JIT stack.
@@ -61,6 +63,28 @@ void LLVMOrcGetMangledSymbol(LLVMOrcJITStackRef JITStack, char **MangledSymbol,
6163

6264
void LLVMOrcDisposeMangledSymbol(char *MangledSymbol);
6365

66+
/**
67+
* Create a lazy compile callback.
68+
*/
69+
LLVMOrcTargetAddress
70+
LLVMOrcCreateLazyCompileCallback(LLVMOrcJITStackRef JITStack,
71+
LLVMOrcLazyCompileCallbackFn Callback,
72+
void *CallbackCtx);
73+
74+
/**
75+
* Create a named indirect call stub.
76+
*/
77+
void LLVMOrcCreateIndirectStub(LLVMOrcJITStackRef JITStack,
78+
const char *StubName,
79+
LLVMOrcTargetAddress InitAddr);
80+
81+
/**
82+
* Set the pointer for the given indirect stub.
83+
*/
84+
void LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack,
85+
const char *StubName,
86+
LLVMOrcTargetAddress NewAddr);
87+
6488
/**
6589
* Add module to be eagerly compiled.
6690
*/

lib/ExecutionEngine/Orc/OrcCBindings.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212

1313
using namespace llvm;
1414

15-
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
16-
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
17-
1815
LLVMOrcJITStackRef LLVMOrcCreateInstance(LLVMTargetMachineRef TM,
1916
LLVMContextRef Context) {
2017
TargetMachine *TM2(unwrap(TM));
@@ -45,6 +42,28 @@ void LLVMOrcDisposeMangledSymbol(char *MangledName) {
4542
delete[] MangledName;
4643
}
4744

45+
LLVMOrcTargetAddress
46+
LLVMOrcCreateLazyCompileCallback(LLVMOrcJITStackRef JITStack,
47+
LLVMOrcLazyCompileCallbackFn Callback,
48+
void *CallbackCtx) {
49+
OrcCBindingsStack &J = *unwrap(JITStack);
50+
return J.createLazyCompileCallback(Callback, CallbackCtx);
51+
}
52+
53+
void LLVMOrcCreateIndirectStub(LLVMOrcJITStackRef JITStack,
54+
const char *StubName,
55+
LLVMOrcTargetAddress InitAddr) {
56+
OrcCBindingsStack &J = *unwrap(JITStack);
57+
J.createIndirectStub(StubName, InitAddr);
58+
}
59+
60+
void LLVMOrcSetIndirectStubPointer(LLVMOrcJITStackRef JITStack,
61+
const char *StubName,
62+
LLVMOrcTargetAddress NewAddr) {
63+
OrcCBindingsStack &J = *unwrap(JITStack);
64+
J.setIndirectStubPointer(StubName, NewAddr);
65+
}
66+
4867
LLVMOrcModuleHandle
4968
LLVMOrcAddEagerlyCompiledIR(LLVMOrcJITStackRef JITStack, LLVMModuleRef Mod,
5069
LLVMOrcSymbolResolverFn SymbolResolver,

lib/ExecutionEngine/Orc/OrcCBindingsStack.h

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,17 @@
1717
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
1818
#include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
1919
#include "llvm/IR/LLVMContext.h"
20+
#include "llvm-c/OrcBindings.h"
2021

2122
namespace llvm {
2223

23-
class OrcCBindingsStack {
24-
private:
24+
class OrcCBindingsStack;
2525

26-
public:
26+
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(OrcCBindingsStack, LLVMOrcJITStackRef)
27+
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
2728

28-
typedef orc::TargetAddress (*CExternalSymbolResolverFn)(const char *Name,
29-
void *Ctx);
29+
class OrcCBindingsStack {
30+
public:
3031

3132
typedef orc::JITCompileCallbackManagerBase CompileCallbackMgr;
3233
typedef orc::ObjectLinkingLayer<> ObjLayerT;
@@ -91,13 +92,14 @@ class OrcCBindingsStack {
9192
OrcCBindingsStack(TargetMachine &TM, LLVMContext &Context,
9293
CallbackManagerBuilder &BuildCallbackMgr,
9394
IndirectStubsManagerBuilder IndirectStubsMgrBuilder)
94-
: DL(TM.createDataLayout()),
95+
: Context(Context), DL(TM.createDataLayout()),
9596
ObjectLayer(),
9697
CompileLayer(ObjectLayer, orc::SimpleCompiler(TM)),
9798
CCMgr(BuildCallbackMgr(CompileLayer, CCMgrMemMgr, Context)),
9899
CODLayer(CompileLayer,
99100
[](Function &F) { std::set<Function*> S; S.insert(&F); return S; },
100101
*CCMgr, std::move(IndirectStubsMgrBuilder), false),
102+
IndirectStubsMgr(IndirectStubsMgrBuilder()),
101103
CXXRuntimeOverrides([this](const std::string &S) { return mangle(S); }) {}
102104

103105
~OrcCBindingsStack() {
@@ -122,8 +124,27 @@ class OrcCBindingsStack {
122124
return reinterpret_cast<PtrTy>(static_cast<uintptr_t>(Addr));
123125
}
124126

127+
orc::TargetAddress
128+
createLazyCompileCallback(LLVMOrcLazyCompileCallbackFn Callback,
129+
void *CallbackCtx) {
130+
auto CCInfo = CCMgr->getCompileCallback(Context);
131+
CCInfo.setCompileAction(
132+
[=]() -> orc::TargetAddress {
133+
return Callback(wrap(this), CallbackCtx);
134+
});
135+
return CCInfo.getAddress();
136+
}
137+
138+
void createIndirectStub(StringRef StubName, orc::TargetAddress Addr) {
139+
IndirectStubsMgr->createStub(StubName, Addr, JITSymbolFlags::Exported);
140+
}
141+
142+
void setIndirectStubPointer(StringRef Name, orc::TargetAddress Addr) {
143+
IndirectStubsMgr->updatePointer(Name, Addr);
144+
}
145+
125146
std::shared_ptr<RuntimeDyld::SymbolResolver>
126-
createResolver(CExternalSymbolResolverFn ExternalResolver,
147+
createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
127148
void *ExternalResolverCtx) {
128149
auto Resolver = orc::createLambdaResolver(
129150
[this, ExternalResolver, ExternalResolverCtx](const std::string &Name) {
@@ -157,7 +178,7 @@ class OrcCBindingsStack {
157178
ModuleHandleT addIRModule(LayerT &Layer,
158179
Module *M,
159180
std::unique_ptr<RuntimeDyld::MemoryManager> MemMgr,
160-
CExternalSymbolResolverFn ExternalResolver,
181+
LLVMOrcSymbolResolverFn ExternalResolver,
161182
void *ExternalResolverCtx) {
162183

163184
// Attach a data-layout if one isn't already present.
@@ -194,15 +215,15 @@ class OrcCBindingsStack {
194215
}
195216

196217
ModuleHandleT addIRModuleEager(Module* M,
197-
CExternalSymbolResolverFn ExternalResolver,
218+
LLVMOrcSymbolResolverFn ExternalResolver,
198219
void *ExternalResolverCtx) {
199220
return addIRModule(CompileLayer, std::move(M),
200221
llvm::make_unique<SectionMemoryManager>(),
201222
std::move(ExternalResolver), ExternalResolverCtx);
202223
}
203224

204225
ModuleHandleT addIRModuleLazy(Module* M,
205-
CExternalSymbolResolverFn ExternalResolver,
226+
LLVMOrcSymbolResolverFn ExternalResolver,
206227
void *ExternalResolverCtx) {
207228
return addIRModule(CODLayer, std::move(M), nullptr,
208229
std::move(ExternalResolver), ExternalResolverCtx);
@@ -215,6 +236,8 @@ class OrcCBindingsStack {
215236
}
216237

217238
orc::JITSymbol findSymbol(const std::string &Name, bool ExportedSymbolsOnly) {
239+
if (auto Sym = IndirectStubsMgr->findStub(Name, ExportedSymbolsOnly))
240+
return Sym;
218241
return CODLayer.findSymbol(mangle(Name), ExportedSymbolsOnly);
219242
}
220243

@@ -241,6 +264,7 @@ class OrcCBindingsStack {
241264
return NewHandle;
242265
}
243266

267+
LLVMContext &Context;
244268
DataLayout DL;
245269
SectionMemoryManager CCMgrMemMgr;
246270

@@ -249,6 +273,8 @@ class OrcCBindingsStack {
249273
std::unique_ptr<CompileCallbackMgr> CCMgr;
250274
CODLayerT CODLayer;
251275

276+
std::unique_ptr<orc::IndirectStubsManagerBase> IndirectStubsMgr;
277+
252278
std::vector<std::unique_ptr<GenericHandle>> GenericHandles;
253279
std::vector<unsigned> FreeHandleIndexes;
254280

unittests/ExecutionEngine/Orc/OrcCAPITest.cpp

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,41 @@ class OrcCAPIExecutionTest : public testing::Test, public OrcExecutionTest {
5151
return 0;
5252
}
5353

54+
struct CompileContext {
55+
CompileContext() : Compiled(false) { }
56+
57+
OrcCAPIExecutionTest* APIExecTest;
58+
std::unique_ptr<Module> M;
59+
LLVMOrcModuleHandle H;
60+
bool Compiled;
61+
};
62+
63+
static LLVMOrcTargetAddress myCompileCallback(LLVMOrcJITStackRef JITStack,
64+
void *Ctx) {
65+
CompileContext *CCtx = static_cast<CompileContext*>(Ctx);
66+
auto *ET = CCtx->APIExecTest;
67+
CCtx->M = ET->createTestModule(ET->TM->getTargetTriple());
68+
CCtx->H = LLVMOrcAddEagerlyCompiledIR(JITStack, wrap(CCtx->M.get()),
69+
myResolver, 0);
70+
CCtx->Compiled = true;
71+
LLVMOrcTargetAddress MainAddr = LLVMOrcGetSymbolAddress(JITStack, "main");
72+
LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr);
73+
return MainAddr;
74+
}
75+
5476
};
5577

5678
char *OrcCAPIExecutionTest::testFuncName = 0;
5779

5880
TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
59-
auto TM = getHostTargetMachineIfSupported();
60-
6181
if (!TM)
6282
return;
6383

64-
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
65-
6684
LLVMOrcJITStackRef JIT =
6785
LLVMOrcCreateInstance(wrap(TM.get()), LLVMGetGlobalContext());
6886

87+
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
88+
6989
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
7090

7191
LLVMOrcModuleHandle H =
@@ -82,17 +102,16 @@ TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
82102
}
83103

84104
TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
85-
auto TM = getHostTargetMachineIfSupported();
86-
87105
if (!TM)
88106
return;
89107

90-
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
91-
92108
LLVMOrcJITStackRef JIT =
93109
LLVMOrcCreateInstance(wrap(TM.get()), LLVMGetGlobalContext());
94110

111+
std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
112+
95113
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
114+
96115
LLVMOrcModuleHandle H =
97116
LLVMOrcAddLazilyCompiledIR(JIT, wrap(M.get()), myResolver, 0);
98117
MainFnTy MainFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "main");
@@ -106,4 +125,37 @@ TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
106125
LLVMOrcDisposeInstance(JIT);
107126
}
108127

128+
TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
129+
if (!TM)
130+
return;
131+
132+
LLVMOrcJITStackRef JIT =
133+
LLVMOrcCreateInstance(wrap(TM.get()), LLVMGetGlobalContext());
134+
135+
LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
136+
137+
CompileContext C;
138+
C.APIExecTest = this;
139+
LLVMOrcCreateIndirectStub(JIT, "foo",
140+
LLVMOrcCreateLazyCompileCallback(JIT,
141+
myCompileCallback,
142+
&C));
143+
MainFnTy FooFn = (MainFnTy)LLVMOrcGetSymbolAddress(JIT, "foo");
144+
int Result = FooFn();
145+
EXPECT_TRUE(C.Compiled)
146+
<< "Function wasn't lazily compiled";
147+
EXPECT_EQ(Result, 42)
148+
<< "Direct-callback JIT'd code did not return expected result";
149+
150+
C.Compiled = false;
151+
FooFn();
152+
EXPECT_FALSE(C.Compiled)
153+
<< "Direct-callback JIT'd code was JIT'd twice";
154+
155+
LLVMOrcRemoveModule(JIT, C.H);
156+
157+
LLVMOrcDisposeMangledSymbol(testFuncName);
158+
LLVMOrcDisposeInstance(JIT);
159+
}
160+
109161
}

unittests/ExecutionEngine/Orc/OrcTestCommon.h

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,23 +38,20 @@ class OrcExecutionTest {
3838
InitializeNativeTargetAsmPrinter();
3939
NativeTargetInitialized = true;
4040
}
41-
};
42-
43-
// Get a target machine for the host if it supports JIT execution.
44-
std::unique_ptr<TargetMachine> getHostTargetMachineIfSupported() {
45-
std::unique_ptr<TargetMachine> TM(EngineBuilder().selectTarget());
46-
47-
if (!TM)
48-
return nullptr;
49-
50-
const Triple& TT = TM->getTargetTriple();
5141

52-
if (TT.getArch() != Triple::x86_64 || !TT.isOSDarwin())
53-
return nullptr;
42+
// Try to select a TargetMachine for the host.
43+
TM.reset(EngineBuilder().selectTarget());
5444

55-
return TM;
56-
}
45+
if (TM) {
46+
// If we found a TargetMachine, check that it's one that Orc supports.
47+
const Triple& TT = TM->getTargetTriple();
48+
if (TT.getArch() != Triple::x86_64 || !TT.isOSDarwin())
49+
TM = nullptr;
50+
}
51+
};
5752

53+
protected:
54+
std::unique_ptr<TargetMachine> TM;
5855
private:
5956
static bool NativeTargetInitialized;
6057
};

0 commit comments

Comments
 (0)