18
18
#include " clang/Sema/Sema.h"
19
19
20
20
#include " llvm/ExecutionEngine/Orc/LLJIT.h"
21
+ #include " llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
21
22
#include " llvm/Support/Error.h"
22
23
#include " llvm/Support/TargetSelect.h"
24
+ #include " llvm/Support/Threading.h"
23
25
#include " llvm/Testing/Support/Error.h"
24
26
25
27
#include " gmock/gmock.h"
@@ -51,9 +53,27 @@ class TestCreateResetExecutor : public Interpreter {
51
53
llvm::Error &Err)
52
54
: Interpreter(std::move(CI), Err) {}
53
55
54
- llvm::Error testCreateExecutor () { return Interpreter::CreateExecutor (); }
56
+ llvm::Error testCreateJITBuilderError () {
57
+ JB = nullptr ;
58
+ return Interpreter::CreateExecutor ();
59
+ }
60
+
61
+ llvm::Error testCreateExecutor () {
62
+ JB = std::make_unique<llvm::orc::LLJITBuilder>();
63
+ return Interpreter::CreateExecutor ();
64
+ }
55
65
56
66
void resetExecutor () { Interpreter::ResetExecutor (); }
67
+
68
+ private:
69
+ llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
70
+ CreateJITBuilder (CompilerInstance &CI) override {
71
+ if (JB)
72
+ return std::move (JB);
73
+ return llvm::make_error<llvm::StringError>(" TestError" , std::error_code ());
74
+ }
75
+
76
+ std::unique_ptr<llvm::orc::LLJITBuilder> JB;
57
77
};
58
78
59
79
#ifdef _AIX
@@ -69,6 +89,8 @@ TEST(InterpreterExtensionsTest, ExecutorCreateReset) {
69
89
llvm::Error ErrOut = llvm::Error::success ();
70
90
TestCreateResetExecutor Interp (cantFail (CB.CreateCpp ()), ErrOut);
71
91
cantFail (std::move (ErrOut));
92
+ EXPECT_THAT_ERROR (Interp.testCreateJITBuilderError (),
93
+ llvm::FailedWithMessage (" TestError" ));
72
94
cantFail (Interp.testCreateExecutor ());
73
95
Interp.resetExecutor ();
74
96
cantFail (Interp.testCreateExecutor ());
@@ -126,4 +148,97 @@ TEST(InterpreterExtensionsTest, FindRuntimeInterface) {
126
148
EXPECT_EQ (1U , Interp.RuntimeIBPtr ->TransformerQueries );
127
149
}
128
150
151
+ class CustomJBInterpreter : public Interpreter {
152
+ using CustomJITBuilderCreatorFunction =
153
+ std::function<llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>()>;
154
+ CustomJITBuilderCreatorFunction JBCreator = nullptr ;
155
+
156
+ public:
157
+ CustomJBInterpreter (std::unique_ptr<CompilerInstance> CI, llvm::Error &ErrOut)
158
+ : Interpreter(std::move(CI), ErrOut) {}
159
+
160
+ ~CustomJBInterpreter () override {
161
+ // Skip cleanUp() because it would trigger LLJIT default dtors
162
+ Interpreter::ResetExecutor ();
163
+ }
164
+
165
+ void setCustomJITBuilderCreator (CustomJITBuilderCreatorFunction Fn) {
166
+ JBCreator = std::move (Fn);
167
+ }
168
+
169
+ llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
170
+ CreateJITBuilder (CompilerInstance &CI) override {
171
+ if (JBCreator)
172
+ return JBCreator ();
173
+ return Interpreter::CreateJITBuilder (CI);
174
+ }
175
+
176
+ llvm::Error CreateExecutor () { return Interpreter::CreateExecutor (); }
177
+ };
178
+
179
+ static void initArmTarget () {
180
+ static llvm::once_flag F;
181
+ llvm::call_once (F, [] {
182
+ LLVMInitializeARMTarget ();
183
+ LLVMInitializeARMTargetInfo ();
184
+ LLVMInitializeARMTargetMC ();
185
+ LLVMInitializeARMAsmPrinter ();
186
+ });
187
+ }
188
+
189
+ llvm::llvm_shutdown_obj Shutdown;
190
+
191
+ TEST (InterpreterExtensionsTest, DefaultCrossJIT) {
192
+ IncrementalCompilerBuilder CB;
193
+ CB.SetTargetTriple (" armv6-none-eabi" );
194
+ auto CI = cantFail (CB.CreateCpp ());
195
+ llvm::Error ErrOut = llvm::Error::success ();
196
+ CustomJBInterpreter Interp (std::move (CI), ErrOut);
197
+ cantFail (std::move (ErrOut));
198
+
199
+ initArmTarget ();
200
+ cantFail (Interp.CreateExecutor ());
201
+ }
202
+
203
+ TEST (InterpreterExtensionsTest, CustomCrossJIT) {
204
+ std::string TargetTriple = " armv6-none-eabi" ;
205
+
206
+ IncrementalCompilerBuilder CB;
207
+ CB.SetTargetTriple (TargetTriple);
208
+ auto CI = cantFail (CB.CreateCpp ());
209
+ llvm::Error ErrOut = llvm::Error::success ();
210
+ CustomJBInterpreter Interp (std::move (CI), ErrOut);
211
+ cantFail (std::move (ErrOut));
212
+
213
+ using namespace llvm ::orc;
214
+ LLJIT *JIT = nullptr ;
215
+ std::vector<std::unique_ptr<llvm::MemoryBuffer>> Objs;
216
+ Interp.setCustomJITBuilderCreator ([&]() {
217
+ initArmTarget ();
218
+ auto JTMB = JITTargetMachineBuilder (llvm::Triple (TargetTriple));
219
+ JTMB.setCPU (" cortex-m0plus" );
220
+ auto JB = std::make_unique<LLJITBuilder>();
221
+ JB->setJITTargetMachineBuilder (JTMB);
222
+ JB->setPlatformSetUp (setUpInactivePlatform);
223
+ JB->setNotifyCreatedCallback ([&](LLJIT &J) {
224
+ ObjectLayer &ObjLayer = J.getObjLinkingLayer ();
225
+ auto *JITLinkObjLayer = llvm::dyn_cast<ObjectLinkingLayer>(&ObjLayer);
226
+ JITLinkObjLayer->setReturnObjectBuffer (
227
+ [&Objs](std::unique_ptr<llvm::MemoryBuffer> MB) {
228
+ Objs.push_back (std::move (MB));
229
+ });
230
+ JIT = &J;
231
+ return llvm::Error::success ();
232
+ });
233
+ return JB;
234
+ });
235
+
236
+ EXPECT_EQ (0U , Objs.size ());
237
+ cantFail (Interp.CreateExecutor ());
238
+ cantFail (Interp.ParseAndExecute (" int a = 1;" ));
239
+ ExecutorAddr Addr = cantFail (JIT->lookup (" a" ));
240
+ EXPECT_NE (0U , Addr.getValue ());
241
+ EXPECT_EQ (1U , Objs.size ());
242
+ }
243
+
129
244
} // end anonymous namespace
0 commit comments