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"
26
28
#include " gtest/gtest.h"
29
+
27
30
#include < system_error>
28
31
32
+ #if defined(_AIX)
33
+ #define CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
34
+ #endif
35
+
29
36
using namespace clang ;
30
37
namespace {
31
38
@@ -41,6 +48,10 @@ struct LLVMInitRAII {
41
48
LLVMInitRAII () {
42
49
llvm::InitializeNativeTarget ();
43
50
llvm::InitializeNativeTargetAsmPrinter ();
51
+ LLVMInitializeARMTarget ();
52
+ LLVMInitializeARMTargetInfo ();
53
+ LLVMInitializeARMTargetMC ();
54
+ LLVMInitializeARMAsmPrinter ();
44
55
}
45
56
~LLVMInitRAII () { llvm::llvm_shutdown (); }
46
57
} LLVMInit;
@@ -51,12 +62,30 @@ class TestCreateResetExecutor : public Interpreter {
51
62
llvm::Error &Err)
52
63
: Interpreter(std::move(CI), Err) {}
53
64
54
- llvm::Error testCreateExecutor () { return Interpreter::CreateExecutor (); }
65
+ llvm::Error testCreateJITBuilderError () {
66
+ JB = nullptr ;
67
+ return Interpreter::CreateExecutor ();
68
+ }
69
+
70
+ llvm::Error testCreateExecutor () {
71
+ JB = std::make_unique<llvm::orc::LLJITBuilder>();
72
+ return Interpreter::CreateExecutor ();
73
+ }
55
74
56
75
void resetExecutor () { Interpreter::ResetExecutor (); }
76
+
77
+ private:
78
+ llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
79
+ CreateJITBuilder (CompilerInstance &CI) override {
80
+ if (JB)
81
+ return std::move (JB);
82
+ return llvm::make_error<llvm::StringError>(" TestError" , std::error_code ());
83
+ }
84
+
85
+ std::unique_ptr<llvm::orc::LLJITBuilder> JB;
57
86
};
58
87
59
- #ifdef _AIX
88
+ #ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
60
89
TEST (InterpreterExtensionsTest, DISABLED_ExecutorCreateReset) {
61
90
#else
62
91
TEST (InterpreterExtensionsTest, ExecutorCreateReset) {
@@ -69,6 +98,8 @@ TEST(InterpreterExtensionsTest, ExecutorCreateReset) {
69
98
llvm::Error ErrOut = llvm::Error::success ();
70
99
TestCreateResetExecutor Interp (cantFail (CB.CreateCpp ()), ErrOut);
71
100
cantFail (std::move (ErrOut));
101
+ EXPECT_THAT_ERROR (Interp.testCreateJITBuilderError (),
102
+ llvm::FailedWithMessage (" TestError" ));
72
103
cantFail (Interp.testCreateExecutor ());
73
104
Interp.resetExecutor ();
74
105
cantFail (Interp.testCreateExecutor ());
@@ -126,4 +157,90 @@ TEST(InterpreterExtensionsTest, FindRuntimeInterface) {
126
157
EXPECT_EQ (1U , Interp.RuntimeIBPtr ->TransformerQueries );
127
158
}
128
159
160
+ class CustomJBInterpreter : public Interpreter {
161
+ using CustomJITBuilderCreatorFunction =
162
+ std::function<llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>()>;
163
+ CustomJITBuilderCreatorFunction JBCreator = nullptr ;
164
+
165
+ public:
166
+ CustomJBInterpreter (std::unique_ptr<CompilerInstance> CI, llvm::Error &ErrOut)
167
+ : Interpreter(std::move(CI), ErrOut) {}
168
+
169
+ ~CustomJBInterpreter () override {
170
+ // Skip cleanUp() because it would trigger LLJIT default dtors
171
+ Interpreter::ResetExecutor ();
172
+ }
173
+
174
+ void setCustomJITBuilderCreator (CustomJITBuilderCreatorFunction Fn) {
175
+ JBCreator = std::move (Fn);
176
+ }
177
+
178
+ llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
179
+ CreateJITBuilder (CompilerInstance &CI) override {
180
+ if (JBCreator)
181
+ return JBCreator ();
182
+ return Interpreter::CreateJITBuilder (CI);
183
+ }
184
+
185
+ llvm::Error CreateExecutor () { return Interpreter::CreateExecutor (); }
186
+ };
187
+
188
+ #ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
189
+ TEST (InterpreterExtensionsTest, DISABLED_DefaultCrossJIT) {
190
+ #else
191
+ TEST (InterpreterExtensionsTest, DefaultCrossJIT) {
192
+ #endif
193
+ IncrementalCompilerBuilder CB;
194
+ CB.SetTargetTriple (" armv6-none-eabi" );
195
+ auto CI = cantFail (CB.CreateCpp ());
196
+ llvm::Error ErrOut = llvm::Error::success ();
197
+ CustomJBInterpreter Interp (std::move (CI), ErrOut);
198
+ cantFail (std::move (ErrOut));
199
+ cantFail (Interp.CreateExecutor ());
200
+ }
201
+
202
+ #ifdef CLANG_INTERPRETER_PLATFORM_CANNOT_CREATE_LLJIT
203
+ TEST (InterpreterExtensionsTest, DISABLED_CustomCrossJIT) {
204
+ #else
205
+ TEST (InterpreterExtensionsTest, CustomCrossJIT) {
206
+ #endif
207
+ std::string TargetTriple = " armv6-none-eabi" ;
208
+
209
+ IncrementalCompilerBuilder CB;
210
+ CB.SetTargetTriple (TargetTriple);
211
+ auto CI = cantFail (CB.CreateCpp ());
212
+ llvm::Error ErrOut = llvm::Error::success ();
213
+ CustomJBInterpreter Interp (std::move (CI), ErrOut);
214
+ cantFail (std::move (ErrOut));
215
+
216
+ using namespace llvm ::orc;
217
+ LLJIT *JIT = nullptr ;
218
+ std::vector<std::unique_ptr<llvm::MemoryBuffer>> Objs;
219
+ Interp.setCustomJITBuilderCreator ([&]() {
220
+ auto JTMB = JITTargetMachineBuilder (llvm::Triple (TargetTriple));
221
+ JTMB.setCPU (" cortex-m0plus" );
222
+ auto JB = std::make_unique<LLJITBuilder>();
223
+ JB->setJITTargetMachineBuilder (JTMB);
224
+ JB->setPlatformSetUp (setUpInactivePlatform);
225
+ JB->setNotifyCreatedCallback ([&](LLJIT &J) {
226
+ ObjectLayer &ObjLayer = J.getObjLinkingLayer ();
227
+ auto *JITLinkObjLayer = llvm::dyn_cast<ObjectLinkingLayer>(&ObjLayer);
228
+ JITLinkObjLayer->setReturnObjectBuffer (
229
+ [&Objs](std::unique_ptr<llvm::MemoryBuffer> MB) {
230
+ Objs.push_back (std::move (MB));
231
+ });
232
+ JIT = &J;
233
+ return llvm::Error::success ();
234
+ });
235
+ return JB;
236
+ });
237
+
238
+ EXPECT_EQ (0U , Objs.size ());
239
+ cantFail (Interp.CreateExecutor ());
240
+ cantFail (Interp.ParseAndExecute (" int a = 1;" ));
241
+ ExecutorAddr Addr = cantFail (JIT->lookup (" a" ));
242
+ EXPECT_NE (0U , Addr.getValue ());
243
+ EXPECT_EQ (1U , Objs.size ());
244
+ }
245
+
129
246
} // end anonymous namespace
0 commit comments