1313#include " gtest/gtest.h"
1414
1515#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"
1622#include < string>
1723
1824using namespace llvm ;
25+ using namespace llvm ::orc;
26+
27+ DEFINE_SIMPLE_CONVERSION_FUNCTIONS (ThreadSafeModule, LLVMOrcThreadSafeModuleRef)
1928
2029// OrcCAPITestBase contains several helper methods and pointers for unit tests
2130// written for the LLVM-C API. It provides the following helpers:
@@ -109,6 +118,7 @@ class OrcCAPITestBase : public testing::Test {
109118 }
110119
111120 static void materializationUnitFn () {}
121+
112122 // Stub definition generator, where all Names are materialized from the
113123 // materializationUnitFn() test function and defined into the JIT Dylib
114124 static LLVMErrorRef
@@ -132,29 +142,47 @@ class OrcCAPITestBase : public testing::Test {
132142 }
133143 return LLVMErrorSuccess;
134144 }
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;
141148 {
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);
154151 }
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 ());
158186 }
159187
160188 static std::string TargetTriple;
@@ -164,6 +192,19 @@ class OrcCAPITestBase : public testing::Test {
164192std::string OrcCAPITestBase::TargetTriple;
165193bool OrcCAPITestBase::TargetSupported = false ;
166194
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+
167208// Consumes the given error ref and returns the string error message.
168209static std::string toString (LLVMErrorRef E) {
169210 char *ErrMsg = LLVMGetErrorMessage (E);
@@ -261,7 +302,7 @@ TEST_F(OrcCAPITestBase, ResourceTrackerDefinitionLifetime) {
261302 // removed.
262303 LLVMOrcResourceTrackerRef RT =
263304 LLVMOrcJITDylibCreateResourceTracker (MainDylib);
264- LLVMOrcThreadSafeModuleRef TSM = createTestModule ();
305+ LLVMOrcThreadSafeModuleRef TSM = createTestModule (SumExample, " sum.ll " );
265306 if (LLVMErrorRef E = LLVMOrcLLJITAddLLVMIRModuleWithRT (Jit, RT, TSM))
266307 FAIL () << " Failed to add LLVM IR module to LLJIT (triple = " << TargetTriple
267308 << " ): " << toString (E);
@@ -290,7 +331,7 @@ TEST_F(OrcCAPITestBase, ResourceTrackerTransfer) {
290331 LLVMOrcJITDylibGetDefaultResourceTracker (MainDylib);
291332 LLVMOrcResourceTrackerRef RT2 =
292333 LLVMOrcJITDylibCreateResourceTracker (MainDylib);
293- LLVMOrcThreadSafeModuleRef TSM = createTestModule ();
334+ LLVMOrcThreadSafeModuleRef TSM = createTestModule (SumExample, " sum.ll " );
294335 if (LLVMErrorRef E = LLVMOrcLLJITAddLLVMIRModuleWithRT (Jit, DefaultRT, TSM))
295336 FAIL () << " Failed to add LLVM IR module to LLJIT (triple = " << TargetTriple
296337 << " ): " << toString (E);
@@ -304,6 +345,27 @@ TEST_F(OrcCAPITestBase, ResourceTrackerTransfer) {
304345 LLVMOrcReleaseResourceTracker (RT2);
305346}
306347
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+
307369TEST_F (OrcCAPITestBase, ExecutionTest) {
308370 if (!Jit) {
309371 // TODO: Use GTEST_SKIP() when GTest is updated to version 1.10.0
@@ -314,7 +376,7 @@ TEST_F(OrcCAPITestBase, ExecutionTest) {
314376
315377 // This test performs OrcJIT compilation of a simple sum module
316378 LLVMInitializeNativeAsmPrinter ();
317- LLVMOrcThreadSafeModuleRef TSM = createTestModule ();
379+ LLVMOrcThreadSafeModuleRef TSM = createTestModule (SumExample, " sum.ll " );
318380 if (LLVMErrorRef E = LLVMOrcLLJITAddLLVMIRModule (Jit, MainDylib, TSM))
319381 FAIL () << " Failed to add LLVM IR module to LLJIT (triple = " << TargetTriple
320382 << " )" << toString (E);
0 commit comments