blob: d2e62d2cea274ac3345bdc19b2ee66affba0cb8f [file] [log] [blame]
Hans Wennborg083ca9b2015-10-06 23:24:35 +00001//===- MCJITTestBase.h - Common base class for MCJIT Unit tests -*- C++ -*-===//
Andrew Kaylor5e7d7922012-10-04 20:29:44 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This class implements common functionality required by the MCJIT unit tests,
11// as well as logic to skip tests on unsupported architectures and operating
12// systems.
13//
14//===----------------------------------------------------------------------===//
15
Benjamin Kramera7c40ef2014-08-13 16:26:38 +000016#ifndef LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTBASE_H
17#define LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTBASE_H
Andrew Kaylor5e7d7922012-10-04 20:29:44 +000018
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000019#include "MCJITTestAPICommon.h"
Andrew Kaylor5e7d7922012-10-04 20:29:44 +000020#include "llvm/Config/config.h"
21#include "llvm/ExecutionEngine/ExecutionEngine.h"
Andrew Kaylorab5ba512012-11-27 19:42:02 +000022#include "llvm/ExecutionEngine/SectionMemoryManager.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000023#include "llvm/IR/Function.h"
24#include "llvm/IR/IRBuilder.h"
25#include "llvm/IR/LLVMContext.h"
26#include "llvm/IR/Module.h"
27#include "llvm/IR/TypeBuilder.h"
Andrew Kaylor5e7d7922012-10-04 20:29:44 +000028#include "llvm/Support/CodeGen.h"
Andrew Kaylor5e7d7922012-10-04 20:29:44 +000029
30namespace llvm {
31
Daniel Malea4146b042013-06-28 20:37:20 +000032/// Helper class that can build very simple Modules
33class TrivialModuleBuilder {
Andrew Kaylor5e7d7922012-10-04 20:29:44 +000034protected:
Daniel Malea4146b042013-06-28 20:37:20 +000035 LLVMContext Context;
36 IRBuilder<> Builder;
37 std::string BuilderTriple;
Andrew Kaylor5e7d7922012-10-04 20:29:44 +000038
Daniel Malea4146b042013-06-28 20:37:20 +000039 TrivialModuleBuilder(const std::string &Triple)
40 : Builder(Context), BuilderTriple(Triple) {}
Andrew Kaylor5e7d7922012-10-04 20:29:44 +000041
Daniel Malea4146b042013-06-28 20:37:20 +000042 Module *createEmptyModule(StringRef Name = StringRef()) {
Andrew Kaylor5e7d7922012-10-04 20:29:44 +000043 Module * M = new Module(Name, Context);
Daniel Malea4146b042013-06-28 20:37:20 +000044 M->setTargetTriple(Triple::normalize(BuilderTriple));
Andrew Kaylor5e7d7922012-10-04 20:29:44 +000045 return M;
46 }
47
48 template<typename FuncType>
49 Function *startFunction(Module *M, StringRef Name) {
50 Function *Result = Function::Create(
51 TypeBuilder<FuncType, false>::get(Context),
52 GlobalValue::ExternalLinkage, Name, M);
53
54 BasicBlock *BB = BasicBlock::Create(Context, Name, Result);
55 Builder.SetInsertPoint(BB);
56
57 return Result;
58 }
59
60 void endFunctionWithRet(Function *Func, Value *RetValue) {
61 Builder.CreateRet(RetValue);
62 }
63
64 // Inserts a simple function that invokes Callee and takes the same arguments:
65 // int Caller(...) { return Callee(...); }
66 template<typename Signature>
67 Function *insertSimpleCallFunction(Module *M, Function *Callee) {
68 Function *Result = startFunction<Signature>(M, "caller");
69
70 SmallVector<Value*, 1> CallArgs;
71
72 Function::arg_iterator arg_iter = Result->arg_begin();
73 for(;arg_iter != Result->arg_end(); ++arg_iter)
74 CallArgs.push_back(arg_iter);
75
76 Value *ReturnCode = Builder.CreateCall(Callee, CallArgs);
77 Builder.CreateRet(ReturnCode);
78 return Result;
79 }
80
81 // Inserts a function named 'main' that returns a uint32_t:
82 // int32_t main() { return X; }
83 // where X is given by returnCode
84 Function *insertMainFunction(Module *M, uint32_t returnCode) {
85 Function *Result = startFunction<int32_t(void)>(M, "main");
86
87 Value *ReturnVal = ConstantInt::get(Context, APInt(32, returnCode));
88 endFunctionWithRet(Result, ReturnVal);
89
90 return Result;
91 }
92
93 // Inserts a function
94 // int32_t add(int32_t a, int32_t b) { return a + b; }
95 // in the current module and returns a pointer to it.
96 Function *insertAddFunction(Module *M, StringRef Name = "add") {
97 Function *Result = startFunction<int32_t(int32_t, int32_t)>(M, Name);
98
99 Function::arg_iterator args = Result->arg_begin();
100 Value *Arg1 = args;
101 Value *Arg2 = ++args;
102 Value *AddResult = Builder.CreateAdd(Arg1, Arg2);
103
104 endFunctionWithRet(Result, AddResult);
105
106 return Result;
107 }
108
Lang Hamesefe7e222014-10-22 23:18:42 +0000109 // Inserts a declaration to a function defined elsewhere
110 template <typename FuncType>
111 Function *insertExternalReferenceToFunction(Module *M, StringRef Name) {
112 Function *Result = Function::Create(
113 TypeBuilder<FuncType, false>::get(Context),
114 GlobalValue::ExternalLinkage, Name, M);
115 return Result;
116 }
117
Andrew Kaylor5e7d7922012-10-04 20:29:44 +0000118 // Inserts an declaration to a function defined elsewhere
119 Function *insertExternalReferenceToFunction(Module *M, StringRef Name,
120 FunctionType *FuncTy) {
121 Function *Result = Function::Create(FuncTy,
122 GlobalValue::ExternalLinkage,
123 Name, M);
124 return Result;
125 }
126
127 // Inserts an declaration to a function defined elsewhere
128 Function *insertExternalReferenceToFunction(Module *M, Function *Func) {
129 Function *Result = Function::Create(Func->getFunctionType(),
Andrew Kaylor6bbb2c92013-10-01 01:48:36 +0000130 GlobalValue::ExternalLinkage,
Andrew Kaylor5e7d7922012-10-04 20:29:44 +0000131 Func->getName(), M);
132 return Result;
133 }
134
135 // Inserts a global variable of type int32
Andrew Kaylor6bbb2c92013-10-01 01:48:36 +0000136 // FIXME: make this a template function to support any type
Andrew Kaylor5e7d7922012-10-04 20:29:44 +0000137 GlobalVariable *insertGlobalInt32(Module *M,
138 StringRef name,
139 int32_t InitialValue) {
140 Type *GlobalTy = TypeBuilder<types::i<32>, true>::get(Context);
141 Constant *IV = ConstantInt::get(Context, APInt(32, InitialValue));
142 GlobalVariable *Global = new GlobalVariable(*M,
143 GlobalTy,
144 false,
145 GlobalValue::ExternalLinkage,
146 IV,
147 name);
148 return Global;
149 }
Andrew Kaylor6bbb2c92013-10-01 01:48:36 +0000150
151 // Inserts a function
152 // int32_t recursive_add(int32_t num) {
153 // if (num == 0) {
154 // return num;
155 // } else {
156 // int32_t recursive_param = num - 1;
157 // return num + Helper(recursive_param);
158 // }
159 // }
160 // NOTE: if Helper is left as the default parameter, Helper == recursive_add.
161 Function *insertAccumulateFunction(Module *M,
Hans Wennborg083ca9b2015-10-06 23:24:35 +0000162 Function *Helper = nullptr,
163 StringRef Name = "accumulate") {
Andrew Kaylor6bbb2c92013-10-01 01:48:36 +0000164 Function *Result = startFunction<int32_t(int32_t)>(M, Name);
Hans Wennborg083ca9b2015-10-06 23:24:35 +0000165 if (!Helper)
Andrew Kaylor6bbb2c92013-10-01 01:48:36 +0000166 Helper = Result;
167
168 BasicBlock *BaseCase = BasicBlock::Create(Context, "", Result);
169 BasicBlock *RecursiveCase = BasicBlock::Create(Context, "", Result);
170
171 // if (num == 0)
172 Value *Param = Result->arg_begin();
173 Value *Zero = ConstantInt::get(Context, APInt(32, 0));
174 Builder.CreateCondBr(Builder.CreateICmpEQ(Param, Zero),
175 BaseCase, RecursiveCase);
176
177 // return num;
178 Builder.SetInsertPoint(BaseCase);
179 Builder.CreateRet(Param);
180
181 // int32_t recursive_param = num - 1;
182 // return Helper(recursive_param);
183 Builder.SetInsertPoint(RecursiveCase);
184 Value *One = ConstantInt::get(Context, APInt(32, 1));
185 Value *RecursiveParam = Builder.CreateSub(Param, One);
186 Value *RecursiveReturn = Builder.CreateCall(Helper, RecursiveParam);
187 Value *Accumulator = Builder.CreateAdd(Param, RecursiveReturn);
188 Builder.CreateRet(Accumulator);
189
190 return Result;
191 }
192
193 // Populates Modules A and B:
194 // Module A { Extern FB1, Function FA which calls FB1 },
195 // Module B { Extern FA, Function FB1, Function FB2 which calls FA },
Ahmed Charles56440fd2014-03-06 05:51:42 +0000196 void createCrossModuleRecursiveCase(std::unique_ptr<Module> &A, Function *&FA,
197 std::unique_ptr<Module> &B,
198 Function *&FB1, Function *&FB2) {
Andrew Kaylor6bbb2c92013-10-01 01:48:36 +0000199 // Define FB1 in B.
200 B.reset(createEmptyModule("B"));
Hans Wennborg083ca9b2015-10-06 23:24:35 +0000201 FB1 = insertAccumulateFunction(B.get(), nullptr, "FB1");
Andrew Kaylor6bbb2c92013-10-01 01:48:36 +0000202
203 // Declare FB1 in A (as an external).
204 A.reset(createEmptyModule("A"));
205 Function *FB1Extern = insertExternalReferenceToFunction(A.get(), FB1);
206
207 // Define FA in A (with a call to FB1).
208 FA = insertAccumulateFunction(A.get(), FB1Extern, "FA");
209
210 // Declare FA in B (as an external)
211 Function *FAExtern = insertExternalReferenceToFunction(B.get(), FA);
212
213 // Define FB2 in B (with a call to FA)
214 FB2 = insertAccumulateFunction(B.get(), FAExtern, "FB2");
215 }
216
217 // Module A { Function FA },
218 // Module B { Extern FA, Function FB which calls FA },
219 // Module C { Extern FB, Function FC which calls FB },
Ahmed Charles56440fd2014-03-06 05:51:42 +0000220 void
221 createThreeModuleChainedCallsCase(std::unique_ptr<Module> &A, Function *&FA,
222 std::unique_ptr<Module> &B, Function *&FB,
223 std::unique_ptr<Module> &C, Function *&FC) {
Andrew Kaylor6bbb2c92013-10-01 01:48:36 +0000224 A.reset(createEmptyModule("A"));
225 FA = insertAddFunction(A.get());
226
227 B.reset(createEmptyModule("B"));
228 Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA);
229 FB = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(B.get(), FAExtern_in_B);
230
231 C.reset(createEmptyModule("C"));
232 Function *FBExtern_in_C = insertExternalReferenceToFunction(C.get(), FB);
233 FC = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(C.get(), FBExtern_in_C);
234 }
235
Andrew Kaylor6bbb2c92013-10-01 01:48:36 +0000236 // Module A { Function FA },
237 // Populates Modules A and B:
238 // Module B { Function FB }
Ahmed Charles56440fd2014-03-06 05:51:42 +0000239 void createTwoModuleCase(std::unique_ptr<Module> &A, Function *&FA,
240 std::unique_ptr<Module> &B, Function *&FB) {
Andrew Kaylor6bbb2c92013-10-01 01:48:36 +0000241 A.reset(createEmptyModule("A"));
242 FA = insertAddFunction(A.get());
243
244 B.reset(createEmptyModule("B"));
245 FB = insertAddFunction(B.get());
246 }
247
248 // Module A { Function FA },
249 // Module B { Extern FA, Function FB which calls FA }
Ahmed Charles56440fd2014-03-06 05:51:42 +0000250 void createTwoModuleExternCase(std::unique_ptr<Module> &A, Function *&FA,
251 std::unique_ptr<Module> &B, Function *&FB) {
Andrew Kaylor6bbb2c92013-10-01 01:48:36 +0000252 A.reset(createEmptyModule("A"));
253 FA = insertAddFunction(A.get());
254
255 B.reset(createEmptyModule("B"));
256 Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA);
257 FB = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(B.get(),
258 FAExtern_in_B);
259 }
260
261 // Module A { Function FA },
262 // Module B { Extern FA, Function FB which calls FA },
263 // Module C { Extern FB, Function FC which calls FA },
Ahmed Charles56440fd2014-03-06 05:51:42 +0000264 void createThreeModuleCase(std::unique_ptr<Module> &A, Function *&FA,
265 std::unique_ptr<Module> &B, Function *&FB,
266 std::unique_ptr<Module> &C, Function *&FC) {
Andrew Kaylor6bbb2c92013-10-01 01:48:36 +0000267 A.reset(createEmptyModule("A"));
268 FA = insertAddFunction(A.get());
269
270 B.reset(createEmptyModule("B"));
271 Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA);
272 FB = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(B.get(), FAExtern_in_B);
273
274 C.reset(createEmptyModule("C"));
275 Function *FAExtern_in_C = insertExternalReferenceToFunction(C.get(), FA);
276 FC = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(C.get(), FAExtern_in_C);
277 }
Daniel Malea4146b042013-06-28 20:37:20 +0000278};
279
280class MCJITTestBase : public MCJITTestAPICommon, public TrivialModuleBuilder {
281protected:
Andrew Kaylor6bbb2c92013-10-01 01:48:36 +0000282
Daniel Malea4146b042013-06-28 20:37:20 +0000283 MCJITTestBase()
284 : TrivialModuleBuilder(HostTriple)
285 , OptLevel(CodeGenOpt::None)
286 , RelocModel(Reloc::Default)
287 , CodeModel(CodeModel::Default)
288 , MArch("")
289 , MM(new SectionMemoryManager)
290 {
291 // The architectures below are known to be compatible with MCJIT as they
292 // are copied from test/ExecutionEngine/MCJIT/lit.local.cfg and should be
293 // kept in sync.
294 SupportedArchs.push_back(Triple::aarch64);
295 SupportedArchs.push_back(Triple::arm);
Akira Hatanaka2e236242013-07-24 01:58:40 +0000296 SupportedArchs.push_back(Triple::mips);
297 SupportedArchs.push_back(Triple::mipsel);
Petar Jovanovic97202832015-05-28 13:48:41 +0000298 SupportedArchs.push_back(Triple::mips64);
299 SupportedArchs.push_back(Triple::mips64el);
Daniel Malea4146b042013-06-28 20:37:20 +0000300 SupportedArchs.push_back(Triple::x86);
301 SupportedArchs.push_back(Triple::x86_64);
302
303 // Some architectures have sub-architectures in which tests will fail, like
304 // ARM. These two vectors will define if they do have sub-archs (to avoid
305 // extra work for those who don't), and if so, if they are listed to work
306 HasSubArchs.push_back(Triple::arm);
307 SupportedSubArchs.push_back("armv6");
308 SupportedSubArchs.push_back("armv7");
309
Saleem Abdulrasoold3bafe32014-03-31 23:42:23 +0000310 UnsupportedEnvironments.push_back(Triple::Cygnus);
Daniel Malea4146b042013-06-28 20:37:20 +0000311 }
Andrew Kaylor5e7d7922012-10-04 20:29:44 +0000312
Rafael Espindola2a8a2792014-08-19 04:04:25 +0000313 void createJIT(std::unique_ptr<Module> M) {
Andrew Kaylor5e7d7922012-10-04 20:29:44 +0000314
315 // Due to the EngineBuilder constructor, it is required to have a Module
316 // in order to construct an ExecutionEngine (i.e. MCJIT)
317 assert(M != 0 && "a non-null Module must be provided to create MCJIT");
318
Rafael Espindola2a8a2792014-08-19 04:04:25 +0000319 EngineBuilder EB(std::move(M));
Andrew Kaylor5e7d7922012-10-04 20:29:44 +0000320 std::string Error;
321 TheJIT.reset(EB.setEngineKind(EngineKind::JIT)
Lang Hames4a5697e2014-12-03 00:51:19 +0000322 .setMCJITMemoryManager(std::move(MM))
Andrew Kaylor5e7d7922012-10-04 20:29:44 +0000323 .setErrorStr(&Error)
324 .setOptLevel(CodeGenOpt::None)
Andrew Kaylor5e7d7922012-10-04 20:29:44 +0000325 .setCodeModel(CodeModel::JITDefault)
326 .setRelocationModel(Reloc::Default)
327 .setMArch(MArch)
328 .setMCPU(sys::getHostCPUName())
329 //.setMAttrs(MAttrs)
330 .create());
331 // At this point, we cannot modify the module any more.
332 assert(TheJIT.get() != NULL && "error creating MCJIT with EngineBuilder");
333 }
334
Andrew Kaylor5e7d7922012-10-04 20:29:44 +0000335 CodeGenOpt::Level OptLevel;
336 Reloc::Model RelocModel;
337 CodeModel::Model CodeModel;
338 StringRef MArch;
339 SmallVector<std::string, 1> MAttrs;
Ahmed Charles56440fd2014-03-06 05:51:42 +0000340 std::unique_ptr<ExecutionEngine> TheJIT;
Lang Hames4a5697e2014-12-03 00:51:19 +0000341 std::unique_ptr<RTDyldMemoryManager> MM;
Andrew Kaylor5e7d7922012-10-04 20:29:44 +0000342
Ahmed Charles56440fd2014-03-06 05:51:42 +0000343 std::unique_ptr<Module> M;
Andrew Kaylor5e7d7922012-10-04 20:29:44 +0000344};
345
346} // namespace llvm
347
Hans Wennborg083ca9b2015-10-06 23:24:35 +0000348#endif // LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTBASE_H