13
13
#include " gtest/gtest.h"
14
14
15
15
#include " llvm/ADT/Triple.h"
16
+ #include " llvm/ExecutionEngine/Orc/CompileUtils.h"
17
+ #include " llvm/IR/LLVMContext.h"
18
+ #include " llvm/IR/Module.h"
19
+ #include " llvm/IRReader/IRReader.h"
20
+ #include " llvm/Support/Error.h"
21
+ #include " llvm/Support/SourceMgr.h"
16
22
#include < string>
17
23
18
24
using namespace llvm ;
25
+ using namespace llvm ::orc;
26
+
27
+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS (ThreadSafeModule, LLVMOrcThreadSafeModuleRef)
19
28
20
29
// OrcCAPITestBase contains several helper methods and pointers for unit tests
21
30
// written for the LLVM-C API. It provides the following helpers:
@@ -109,6 +118,7 @@ class OrcCAPITestBase : public testing::Test {
109
118
}
110
119
111
120
static void materializationUnitFn () {}
121
+
112
122
// Stub definition generator, where all Names are materialized from the
113
123
// materializationUnitFn() test function and defined into the JIT Dylib
114
124
static LLVMErrorRef
@@ -132,29 +142,47 @@ class OrcCAPITestBase : public testing::Test {
132
142
}
133
143
return LLVMErrorSuccess;
134
144
}
135
- // create a test LLVM IR module containing a function named "sum" which has
136
- // returns the sum of its two parameters
137
- static LLVMOrcThreadSafeModuleRef createTestModule () {
138
- LLVMOrcThreadSafeContextRef TSC = LLVMOrcCreateNewThreadSafeContext ();
139
- LLVMContextRef Ctx = LLVMOrcThreadSafeContextGetContext (TSC);
140
- LLVMModuleRef Mod = LLVMModuleCreateWithNameInContext (" test" , Ctx);
145
+
146
+ static Error createSMDiagnosticError (llvm::SMDiagnostic &Diag) {
147
+ std::string Msg;
141
148
{
142
- LLVMTypeRef Int32Ty = LLVMInt32TypeInContext (Ctx);
143
- LLVMTypeRef ParamTys[] = {Int32Ty, Int32Ty};
144
- LLVMTypeRef TestFnTy = LLVMFunctionType (Int32Ty, ParamTys, 2 , 0 );
145
- LLVMValueRef TestFn = LLVMAddFunction (Mod, " sum" , TestFnTy);
146
- LLVMBuilderRef IRBuilder = LLVMCreateBuilderInContext (Ctx);
147
- LLVMBasicBlockRef EntryBB = LLVMAppendBasicBlock (TestFn, " entry" );
148
- LLVMPositionBuilderAtEnd (IRBuilder, EntryBB);
149
- LLVMValueRef Arg1 = LLVMGetParam (TestFn, 0 );
150
- LLVMValueRef Arg2 = LLVMGetParam (TestFn, 1 );
151
- LLVMValueRef Sum = LLVMBuildAdd (IRBuilder, Arg1, Arg2, " " );
152
- LLVMBuildRet (IRBuilder, Sum);
153
- LLVMDisposeBuilder (IRBuilder);
149
+ raw_string_ostream OS (Msg);
150
+ Diag.print (" " , OS);
154
151
}
155
- LLVMOrcThreadSafeModuleRef TSM = LLVMOrcCreateNewThreadSafeModule (Mod, TSC);
156
- LLVMOrcDisposeThreadSafeContext (TSC);
157
- return TSM;
152
+ return make_error<StringError>(std::move (Msg), inconvertibleErrorCode ());
153
+ }
154
+
155
+ // Create an LLVM IR module from the given StringRef.
156
+ static Expected<std::unique_ptr<Module>>
157
+ parseTestModule (LLVMContext &Ctx, StringRef Source, StringRef Name) {
158
+ assert (TargetSupported &&
159
+ " Attempted to create module for unsupported target" );
160
+ SMDiagnostic Err;
161
+ if (auto M = parseIR (MemoryBufferRef (Source, Name), Err, Ctx))
162
+ return std::move (M);
163
+ return createSMDiagnosticError (Err);
164
+ }
165
+
166
+ // returns the sum of its two parameters
167
+ static LLVMOrcThreadSafeModuleRef createTestModule (StringRef Source,
168
+ StringRef Name) {
169
+ auto Ctx = std::make_unique<LLVMContext>();
170
+ auto M = cantFail (parseTestModule (*Ctx, Source, Name));
171
+ return wrap (new ThreadSafeModule (std::move (M), std::move (Ctx)));
172
+ }
173
+
174
+ static LLVMMemoryBufferRef createTestObject (StringRef Source,
175
+ StringRef Name) {
176
+ auto Ctx = std::make_unique<LLVMContext>();
177
+ auto M = cantFail (parseTestModule (*Ctx, Source, Name));
178
+
179
+ auto JTMB = cantFail (JITTargetMachineBuilder::detectHost ());
180
+ M->setDataLayout (cantFail (JTMB.getDefaultDataLayoutForTarget ()));
181
+ auto TM = cantFail (JTMB.createTargetMachine ());
182
+
183
+ SimpleCompiler SC (*TM);
184
+ auto ObjBuffer = cantFail (SC (*M));
185
+ return wrap (ObjBuffer.release ());
158
186
}
159
187
160
188
static std::string TargetTriple;
@@ -164,6 +192,19 @@ class OrcCAPITestBase : public testing::Test {
164
192
std::string OrcCAPITestBase::TargetTriple;
165
193
bool OrcCAPITestBase::TargetSupported = false ;
166
194
195
+ namespace {
196
+
197
+ constexpr StringRef SumExample =
198
+ R"(
199
+ define i32 @sum(i32 %x, i32 %y) {
200
+ entry:
201
+ %r = add nsw i32 %x, %y
202
+ ret i32 %r
203
+ }
204
+ )" ;
205
+
206
+ } // end anonymous namespace.
207
+
167
208
// Consumes the given error ref and returns the string error message.
168
209
static std::string toString (LLVMErrorRef E) {
169
210
char *ErrMsg = LLVMGetErrorMessage (E);
@@ -261,7 +302,7 @@ TEST_F(OrcCAPITestBase, ResourceTrackerDefinitionLifetime) {
261
302
// removed.
262
303
LLVMOrcResourceTrackerRef RT =
263
304
LLVMOrcJITDylibCreateResourceTracker (MainDylib);
264
- LLVMOrcThreadSafeModuleRef TSM = createTestModule ();
305
+ LLVMOrcThreadSafeModuleRef TSM = createTestModule (SumExample, " sum.ll " );
265
306
if (LLVMErrorRef E = LLVMOrcLLJITAddLLVMIRModuleWithRT (Jit, RT, TSM))
266
307
FAIL () << " Failed to add LLVM IR module to LLJIT (triple = " << TargetTriple
267
308
<< " ): " << toString (E);
@@ -290,7 +331,7 @@ TEST_F(OrcCAPITestBase, ResourceTrackerTransfer) {
290
331
LLVMOrcJITDylibGetDefaultResourceTracker (MainDylib);
291
332
LLVMOrcResourceTrackerRef RT2 =
292
333
LLVMOrcJITDylibCreateResourceTracker (MainDylib);
293
- LLVMOrcThreadSafeModuleRef TSM = createTestModule ();
334
+ LLVMOrcThreadSafeModuleRef TSM = createTestModule (SumExample, " sum.ll " );
294
335
if (LLVMErrorRef E = LLVMOrcLLJITAddLLVMIRModuleWithRT (Jit, DefaultRT, TSM))
295
336
FAIL () << " Failed to add LLVM IR module to LLJIT (triple = " << TargetTriple
296
337
<< " ): " << toString (E);
@@ -304,6 +345,27 @@ TEST_F(OrcCAPITestBase, ResourceTrackerTransfer) {
304
345
LLVMOrcReleaseResourceTracker (RT2);
305
346
}
306
347
348
+ TEST_F (OrcCAPITestBase, AddObjectBuffer) {
349
+ if (!Jit) {
350
+ // TODO: Use GTEST_SKIP() when GTest is updated to version 1.10.0
351
+ return ;
352
+ }
353
+
354
+ LLVMOrcObjectLayerRef ObjLinkingLayer = LLVMOrcLLJITGetObjLinkingLayer (Jit);
355
+ LLVMMemoryBufferRef ObjBuffer = createTestObject (SumExample, " sum.ll" );
356
+
357
+ if (LLVMErrorRef E = LLVMOrcObjectLayerAddObjectFile (ObjLinkingLayer,
358
+ MainDylib, ObjBuffer))
359
+ FAIL () << " Failed to add object file to ObjLinkingLayer (triple = "
360
+ << TargetTriple << " ): " << toString (E);
361
+
362
+ LLVMOrcJITTargetAddress SumAddr;
363
+ if (LLVMErrorRef E = LLVMOrcLLJITLookup (Jit, &SumAddr, " sum" ))
364
+ FAIL () << " Symbol \" sum\" was not added into JIT (triple = " << TargetTriple
365
+ << " ): " << toString (E);
366
+ ASSERT_TRUE (!!SumAddr);
367
+ }
368
+
307
369
TEST_F (OrcCAPITestBase, ExecutionTest) {
308
370
if (!Jit) {
309
371
// TODO: Use GTEST_SKIP() when GTest is updated to version 1.10.0
@@ -314,7 +376,7 @@ TEST_F(OrcCAPITestBase, ExecutionTest) {
314
376
315
377
// This test performs OrcJIT compilation of a simple sum module
316
378
LLVMInitializeNativeAsmPrinter ();
317
- LLVMOrcThreadSafeModuleRef TSM = createTestModule ();
379
+ LLVMOrcThreadSafeModuleRef TSM = createTestModule (SumExample, " sum.ll " );
318
380
if (LLVMErrorRef E = LLVMOrcLLJITAddLLVMIRModule (Jit, MainDylib, TSM))
319
381
FAIL () << " Failed to add LLVM IR module to LLJIT (triple = " << TargetTriple
320
382
<< " )" << toString (E);
0 commit comments