17
17
#include " clang/Sema/Lookup.h"
18
18
#include " clang/Sema/Sema.h"
19
19
20
+ #include " llvm/ExecutionEngine/Orc/LLJIT.h"
21
+ #include " llvm/ExecutionEngine/Orc/Shared/ExecutorAddress.h"
20
22
#include " llvm/Support/Error.h"
23
+ #include " llvm/Support/TargetSelect.h"
24
+ #include " llvm/Support/Threading.h"
21
25
#include " llvm/Testing/Support/Error.h"
22
26
23
27
#include " gmock/gmock.h"
@@ -33,16 +37,36 @@ class TestCreateResetExecutor : public Interpreter {
33
37
llvm::Error &Err)
34
38
: Interpreter(std::move(CI), Err) {}
35
39
36
- llvm::Error testCreateExecutor () { return Interpreter::CreateExecutor (); }
40
+ llvm::Error testCreateJITBuilderError () {
41
+ JB = nullptr ;
42
+ return Interpreter::CreateExecutor ();
43
+ }
44
+
45
+ llvm::Error testCreateExecutor () {
46
+ JB = std::make_unique<llvm::orc::LLJITBuilder>();
47
+ return Interpreter::CreateExecutor ();
48
+ }
37
49
38
50
void resetExecutor () { Interpreter::ResetExecutor (); }
51
+
52
+ private:
53
+ llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
54
+ CreateJITBuilder (CompilerInstance &CI) override {
55
+ if (JB)
56
+ return std::move (JB);
57
+ return llvm::make_error<llvm::StringError>(" TestError" , std::error_code ());
58
+ }
59
+
60
+ std::unique_ptr<llvm::orc::LLJITBuilder> JB;
39
61
};
40
62
41
63
TEST (InterpreterExtensionsTest, ExecutorCreateReset) {
42
64
clang::IncrementalCompilerBuilder CB;
43
65
llvm::Error ErrOut = llvm::Error::success ();
44
66
TestCreateResetExecutor Interp (cantFail (CB.CreateCpp ()), ErrOut);
45
67
cantFail (std::move (ErrOut));
68
+ EXPECT_THAT_ERROR (Interp.testCreateJITBuilderError (),
69
+ llvm::FailedWithMessage (" TestError" ));
46
70
cantFail (Interp.testCreateExecutor ());
47
71
Interp.resetExecutor ();
48
72
cantFail (Interp.testCreateExecutor ());
@@ -100,4 +124,97 @@ TEST(InterpreterExtensionsTest, FindRuntimeInterface) {
100
124
EXPECT_EQ (1U , Interp.RuntimeIBPtr ->TransformerQueries );
101
125
}
102
126
127
+ class CustomJBInterpreter : public Interpreter {
128
+ using CustomJITBuilderCreatorFunction =
129
+ std::function<llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>()>;
130
+ CustomJITBuilderCreatorFunction JBCreator = nullptr ;
131
+
132
+ public:
133
+ CustomJBInterpreter (std::unique_ptr<CompilerInstance> CI, llvm::Error &ErrOut)
134
+ : Interpreter(std::move(CI), ErrOut) {}
135
+
136
+ ~CustomJBInterpreter () override {
137
+ // Skip cleanUp() because it would trigger LLJIT default dtors
138
+ Interpreter::ResetExecutor ();
139
+ }
140
+
141
+ void setCustomJITBuilderCreator (CustomJITBuilderCreatorFunction Fn) {
142
+ JBCreator = std::move (Fn);
143
+ }
144
+
145
+ llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
146
+ CreateJITBuilder (CompilerInstance &CI) override {
147
+ if (JBCreator)
148
+ return JBCreator ();
149
+ return Interpreter::CreateJITBuilder (CI);
150
+ }
151
+
152
+ llvm::Error CreateExecutor () { return Interpreter::CreateExecutor (); }
153
+ };
154
+
155
+ static void initArmTarget () {
156
+ static llvm::once_flag F;
157
+ llvm::call_once (F, [] {
158
+ LLVMInitializeARMTarget ();
159
+ LLVMInitializeARMTargetInfo ();
160
+ LLVMInitializeARMTargetMC ();
161
+ LLVMInitializeARMAsmPrinter ();
162
+ });
163
+ }
164
+
165
+ llvm::llvm_shutdown_obj Shutdown;
166
+
167
+ TEST (InterpreterExtensionsTest, DefaultCrossJIT) {
168
+ IncrementalCompilerBuilder CB;
169
+ CB.SetTargetTriple (" armv6-none-eabi" );
170
+ auto CI = cantFail (CB.CreateCpp ());
171
+ llvm::Error ErrOut = llvm::Error::success ();
172
+ CustomJBInterpreter Interp (std::move (CI), ErrOut);
173
+ cantFail (std::move (ErrOut));
174
+
175
+ initArmTarget ();
176
+ cantFail (Interp.CreateExecutor ());
177
+ }
178
+
179
+ TEST (InterpreterExtensionsTest, CustomCrossJIT) {
180
+ std::string TargetTriple = " armv6-none-eabi" ;
181
+
182
+ IncrementalCompilerBuilder CB;
183
+ CB.SetTargetTriple (TargetTriple);
184
+ auto CI = cantFail (CB.CreateCpp ());
185
+ llvm::Error ErrOut = llvm::Error::success ();
186
+ CustomJBInterpreter Interp (std::move (CI), ErrOut);
187
+ cantFail (std::move (ErrOut));
188
+
189
+ using namespace llvm ::orc;
190
+ LLJIT *JIT = nullptr ;
191
+ std::vector<std::unique_ptr<llvm::MemoryBuffer>> Objs;
192
+ Interp.setCustomJITBuilderCreator ([&]() {
193
+ initArmTarget ();
194
+ auto JTMB = JITTargetMachineBuilder (llvm::Triple (TargetTriple));
195
+ JTMB.setCPU (" cortex-m0plus" );
196
+ auto JB = std::make_unique<LLJITBuilder>();
197
+ JB->setJITTargetMachineBuilder (JTMB);
198
+ JB->setPlatformSetUp (setUpInactivePlatform);
199
+ JB->setNotifyCreatedCallback ([&](LLJIT &J) {
200
+ ObjectLayer &ObjLayer = J.getObjLinkingLayer ();
201
+ auto *JITLinkObjLayer = llvm::dyn_cast<ObjectLinkingLayer>(&ObjLayer);
202
+ JITLinkObjLayer->setReturnObjectBuffer (
203
+ [&Objs](std::unique_ptr<llvm::MemoryBuffer> MB) {
204
+ Objs.push_back (std::move (MB));
205
+ });
206
+ JIT = &J;
207
+ return llvm::Error::success ();
208
+ });
209
+ return JB;
210
+ });
211
+
212
+ EXPECT_EQ (0U , Objs.size ());
213
+ cantFail (Interp.CreateExecutor ());
214
+ cantFail (Interp.ParseAndExecute (" int a = 1;" ));
215
+ ExecutorAddr Addr = cantFail (JIT->lookup (" a" ));
216
+ EXPECT_NE (0U , Addr.getValue ());
217
+ EXPECT_EQ (1U , Objs.size ());
218
+ }
219
+
103
220
} // end anonymous namespace
0 commit comments