[llvm] [cmake] Add possibility to use ChooseMSVCCRT.cmake when include LLVM library
[llvm-core.git] / unittests / ExecutionEngine / Orc / OrcCAPITest.cpp
blob39fdc2e9ce9b6fef1ab69e2bbe5ecd64ced8d0dc
1 //===--------------- OrcCAPITest.cpp - Unit tests Orc C API ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "OrcTestCommon.h"
10 #include "llvm/ExecutionEngine/Orc/CompileUtils.h"
11 #include "llvm-c/Core.h"
12 #include "llvm-c/OrcBindings.h"
13 #include "llvm-c/Target.h"
14 #include "llvm-c/TargetMachine.h"
15 #include "gtest/gtest.h"
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
21 namespace llvm {
23 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
25 class OrcCAPIExecutionTest : public testing::Test, public OrcExecutionTest {
26 protected:
27 std::unique_ptr<Module> createTestModule(const Triple &TT) {
28 ModuleBuilder MB(Context, TT.str(), "");
29 Type *IntTy = Type::getScalarTy<int>(Context);
30 Function *TestFunc =
31 MB.createFunctionDecl(FunctionType::get(IntTy, {}, false), "testFunc");
32 Function *Main = MB.createFunctionDecl(
33 FunctionType::get(
34 IntTy,
35 {IntTy, Type::getInt8PtrTy(Context)->getPointerTo()},
36 false),
37 "main");
39 Main->getBasicBlockList().push_back(BasicBlock::Create(Context));
40 IRBuilder<> B(&Main->back());
41 Value* Result = B.CreateCall(TestFunc);
42 B.CreateRet(Result);
44 return MB.takeModule();
47 std::unique_ptr<MemoryBuffer> createTestObject() {
48 orc::SimpleCompiler IRCompiler(*TM);
49 auto M = createTestModule(TM->getTargetTriple());
50 M->setDataLayout(TM->createDataLayout());
51 return IRCompiler(*M);
54 typedef int (*MainFnTy)();
56 static int myTestFuncImpl() {
57 return 42;
60 static char *testFuncName;
62 static uint64_t myResolver(const char *Name, void *Ctx) {
63 if (!strncmp(Name, testFuncName, 8))
64 return (uint64_t)&myTestFuncImpl;
65 return 0;
68 struct CompileContext {
69 CompileContext() : Compiled(false) { }
71 OrcCAPIExecutionTest* APIExecTest;
72 std::unique_ptr<Module> M;
73 LLVMOrcModuleHandle H;
74 bool Compiled;
77 static LLVMOrcTargetAddress myCompileCallback(LLVMOrcJITStackRef JITStack,
78 void *Ctx) {
79 CompileContext *CCtx = static_cast<CompileContext*>(Ctx);
80 auto *ET = CCtx->APIExecTest;
81 CCtx->M = ET->createTestModule(ET->TM->getTargetTriple());
82 LLVMOrcAddEagerlyCompiledIR(JITStack, &CCtx->H, wrap(CCtx->M.release()),
83 myResolver, nullptr);
84 CCtx->Compiled = true;
85 LLVMOrcTargetAddress MainAddr;
86 LLVMOrcGetSymbolAddress(JITStack, &MainAddr, "main");
87 LLVMOrcSetIndirectStubPointer(JITStack, "foo", MainAddr);
88 return MainAddr;
92 char *OrcCAPIExecutionTest::testFuncName = nullptr;
94 TEST_F(OrcCAPIExecutionTest, TestEagerIRCompilation) {
95 if (!SupportsJIT)
96 return;
98 LLVMOrcJITStackRef JIT =
99 LLVMOrcCreateInstance(wrap(TM.get()));
101 std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
103 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
105 LLVMOrcModuleHandle H;
106 LLVMOrcAddEagerlyCompiledIR(JIT, &H, wrap(M.release()), myResolver, nullptr);
108 // get symbol address searching the entire stack
110 LLVMOrcTargetAddress MainAddr;
111 LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
112 MainFnTy MainFn = (MainFnTy)MainAddr;
113 int Result = MainFn();
114 EXPECT_EQ(Result, 42)
115 << "Eagerly JIT'd code did not return expected result";
118 // and then just searching a single handle
120 LLVMOrcTargetAddress MainAddr;
121 LLVMOrcGetSymbolAddressIn(JIT, &MainAddr, H, "main");
122 MainFnTy MainFn = (MainFnTy)MainAddr;
123 int Result = MainFn();
124 EXPECT_EQ(Result, 42)
125 << "Eagerly JIT'd code did not return expected result";
128 LLVMOrcRemoveModule(JIT, H);
130 LLVMOrcDisposeMangledSymbol(testFuncName);
131 LLVMOrcDisposeInstance(JIT);
134 TEST_F(OrcCAPIExecutionTest, TestLazyIRCompilation) {
135 if (!SupportsIndirection)
136 return;
138 LLVMOrcJITStackRef JIT =
139 LLVMOrcCreateInstance(wrap(TM.get()));
141 std::unique_ptr<Module> M = createTestModule(TM->getTargetTriple());
143 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
145 LLVMOrcModuleHandle H;
146 LLVMOrcAddLazilyCompiledIR(JIT, &H, wrap(M.release()), myResolver, nullptr);
147 LLVMOrcTargetAddress MainAddr;
148 LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
149 MainFnTy MainFn = (MainFnTy)MainAddr;
150 int Result = MainFn();
151 EXPECT_EQ(Result, 42)
152 << "Lazily JIT'd code did not return expected result";
154 LLVMOrcRemoveModule(JIT, H);
156 LLVMOrcDisposeMangledSymbol(testFuncName);
157 LLVMOrcDisposeInstance(JIT);
160 TEST_F(OrcCAPIExecutionTest, TestAddObjectFile) {
161 if (!SupportsJIT)
162 return;
164 auto ObjBuffer = createTestObject();
166 LLVMOrcJITStackRef JIT =
167 LLVMOrcCreateInstance(wrap(TM.get()));
168 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
170 LLVMOrcModuleHandle H;
171 LLVMOrcAddObjectFile(JIT, &H, wrap(ObjBuffer.release()), myResolver, nullptr);
172 LLVMOrcTargetAddress MainAddr;
173 LLVMOrcGetSymbolAddress(JIT, &MainAddr, "main");
174 MainFnTy MainFn = (MainFnTy)MainAddr;
175 int Result = MainFn();
176 EXPECT_EQ(Result, 42)
177 << "Lazily JIT'd code did not return expected result";
179 LLVMOrcRemoveModule(JIT, H);
181 LLVMOrcDisposeMangledSymbol(testFuncName);
182 LLVMOrcDisposeInstance(JIT);
185 TEST_F(OrcCAPIExecutionTest, TestDirectCallbacksAPI) {
186 if (!SupportsIndirection)
187 return;
189 LLVMOrcJITStackRef JIT =
190 LLVMOrcCreateInstance(wrap(TM.get()));
192 LLVMOrcGetMangledSymbol(JIT, &testFuncName, "testFunc");
194 CompileContext C;
195 C.APIExecTest = this;
196 LLVMOrcTargetAddress CCAddr;
197 LLVMOrcCreateLazyCompileCallback(JIT, &CCAddr, myCompileCallback, &C);
198 LLVMOrcCreateIndirectStub(JIT, "foo", CCAddr);
199 LLVMOrcTargetAddress MainAddr;
200 LLVMOrcGetSymbolAddress(JIT, &MainAddr, "foo");
201 MainFnTy FooFn = (MainFnTy)MainAddr;
202 int Result = FooFn();
203 EXPECT_TRUE(C.Compiled)
204 << "Function wasn't lazily compiled";
205 EXPECT_EQ(Result, 42)
206 << "Direct-callback JIT'd code did not return expected result";
208 C.Compiled = false;
209 FooFn();
210 EXPECT_FALSE(C.Compiled)
211 << "Direct-callback JIT'd code was JIT'd twice";
213 LLVMOrcRemoveModule(JIT, C.H);
215 LLVMOrcDisposeMangledSymbol(testFuncName);
216 LLVMOrcDisposeInstance(JIT);
219 } // namespace llvm