Hans Wennborg | 083ca9b | 2015-10-06 23:24:35 +0000 | [diff] [blame] | 1 | //===- MCJITTestBase.h - Common base class for MCJIT Unit tests -*- C++ -*-===// |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 2 | // |
| 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 Kramer | a7c40ef | 2014-08-13 16:26:38 +0000 | [diff] [blame] | 16 | #ifndef LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTBASE_H |
| 17 | #define LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTBASE_H |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 18 | |
Chandler Carruth | 8a8cd2b | 2014-01-07 11:48:04 +0000 | [diff] [blame] | 19 | #include "MCJITTestAPICommon.h" |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 20 | #include "llvm/Config/config.h" |
| 21 | #include "llvm/ExecutionEngine/ExecutionEngine.h" |
Andrew Kaylor | ab5ba51 | 2012-11-27 19:42:02 +0000 | [diff] [blame] | 22 | #include "llvm/ExecutionEngine/SectionMemoryManager.h" |
Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 23 | #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 Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 28 | #include "llvm/Support/CodeGen.h" |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 29 | |
| 30 | namespace llvm { |
| 31 | |
Daniel Malea | 4146b04 | 2013-06-28 20:37:20 +0000 | [diff] [blame] | 32 | /// Helper class that can build very simple Modules |
| 33 | class TrivialModuleBuilder { |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 34 | protected: |
Daniel Malea | 4146b04 | 2013-06-28 20:37:20 +0000 | [diff] [blame] | 35 | LLVMContext Context; |
| 36 | IRBuilder<> Builder; |
| 37 | std::string BuilderTriple; |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 38 | |
Daniel Malea | 4146b04 | 2013-06-28 20:37:20 +0000 | [diff] [blame] | 39 | TrivialModuleBuilder(const std::string &Triple) |
| 40 | : Builder(Context), BuilderTriple(Triple) {} |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 41 | |
Daniel Malea | 4146b04 | 2013-06-28 20:37:20 +0000 | [diff] [blame] | 42 | Module *createEmptyModule(StringRef Name = StringRef()) { |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 43 | Module * M = new Module(Name, Context); |
Daniel Malea | 4146b04 | 2013-06-28 20:37:20 +0000 | [diff] [blame] | 44 | M->setTargetTriple(Triple::normalize(BuilderTriple)); |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 45 | 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 | |
Duncan P. N. Exon Smith | c8925b1 | 2015-10-20 18:30:20 +0000 | [diff] [blame] | 72 | for (Argument &A : Result->args()) |
| 73 | CallArgs.push_back(&A); |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 74 | |
| 75 | Value *ReturnCode = Builder.CreateCall(Callee, CallArgs); |
| 76 | Builder.CreateRet(ReturnCode); |
| 77 | return Result; |
| 78 | } |
| 79 | |
| 80 | // Inserts a function named 'main' that returns a uint32_t: |
| 81 | // int32_t main() { return X; } |
| 82 | // where X is given by returnCode |
| 83 | Function *insertMainFunction(Module *M, uint32_t returnCode) { |
| 84 | Function *Result = startFunction<int32_t(void)>(M, "main"); |
| 85 | |
| 86 | Value *ReturnVal = ConstantInt::get(Context, APInt(32, returnCode)); |
| 87 | endFunctionWithRet(Result, ReturnVal); |
| 88 | |
| 89 | return Result; |
| 90 | } |
| 91 | |
| 92 | // Inserts a function |
| 93 | // int32_t add(int32_t a, int32_t b) { return a + b; } |
| 94 | // in the current module and returns a pointer to it. |
| 95 | Function *insertAddFunction(Module *M, StringRef Name = "add") { |
| 96 | Function *Result = startFunction<int32_t(int32_t, int32_t)>(M, Name); |
| 97 | |
| 98 | Function::arg_iterator args = Result->arg_begin(); |
Duncan P. N. Exon Smith | c8925b1 | 2015-10-20 18:30:20 +0000 | [diff] [blame] | 99 | Value *Arg1 = &*args; |
| 100 | Value *Arg2 = &*++args; |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 101 | Value *AddResult = Builder.CreateAdd(Arg1, Arg2); |
| 102 | |
| 103 | endFunctionWithRet(Result, AddResult); |
| 104 | |
| 105 | return Result; |
| 106 | } |
| 107 | |
Lang Hames | efe7e22 | 2014-10-22 23:18:42 +0000 | [diff] [blame] | 108 | // Inserts a declaration to a function defined elsewhere |
| 109 | template <typename FuncType> |
| 110 | Function *insertExternalReferenceToFunction(Module *M, StringRef Name) { |
| 111 | Function *Result = Function::Create( |
| 112 | TypeBuilder<FuncType, false>::get(Context), |
| 113 | GlobalValue::ExternalLinkage, Name, M); |
| 114 | return Result; |
| 115 | } |
| 116 | |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 117 | // Inserts an declaration to a function defined elsewhere |
| 118 | Function *insertExternalReferenceToFunction(Module *M, StringRef Name, |
| 119 | FunctionType *FuncTy) { |
| 120 | Function *Result = Function::Create(FuncTy, |
| 121 | GlobalValue::ExternalLinkage, |
| 122 | Name, M); |
| 123 | return Result; |
| 124 | } |
| 125 | |
| 126 | // Inserts an declaration to a function defined elsewhere |
| 127 | Function *insertExternalReferenceToFunction(Module *M, Function *Func) { |
| 128 | Function *Result = Function::Create(Func->getFunctionType(), |
Andrew Kaylor | 6bbb2c9 | 2013-10-01 01:48:36 +0000 | [diff] [blame] | 129 | GlobalValue::ExternalLinkage, |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 130 | Func->getName(), M); |
| 131 | return Result; |
| 132 | } |
| 133 | |
| 134 | // Inserts a global variable of type int32 |
Andrew Kaylor | 6bbb2c9 | 2013-10-01 01:48:36 +0000 | [diff] [blame] | 135 | // FIXME: make this a template function to support any type |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 136 | GlobalVariable *insertGlobalInt32(Module *M, |
| 137 | StringRef name, |
| 138 | int32_t InitialValue) { |
| 139 | Type *GlobalTy = TypeBuilder<types::i<32>, true>::get(Context); |
| 140 | Constant *IV = ConstantInt::get(Context, APInt(32, InitialValue)); |
| 141 | GlobalVariable *Global = new GlobalVariable(*M, |
| 142 | GlobalTy, |
| 143 | false, |
| 144 | GlobalValue::ExternalLinkage, |
| 145 | IV, |
| 146 | name); |
| 147 | return Global; |
| 148 | } |
Andrew Kaylor | 6bbb2c9 | 2013-10-01 01:48:36 +0000 | [diff] [blame] | 149 | |
| 150 | // Inserts a function |
| 151 | // int32_t recursive_add(int32_t num) { |
| 152 | // if (num == 0) { |
| 153 | // return num; |
| 154 | // } else { |
| 155 | // int32_t recursive_param = num - 1; |
| 156 | // return num + Helper(recursive_param); |
| 157 | // } |
| 158 | // } |
| 159 | // NOTE: if Helper is left as the default parameter, Helper == recursive_add. |
| 160 | Function *insertAccumulateFunction(Module *M, |
Hans Wennborg | 083ca9b | 2015-10-06 23:24:35 +0000 | [diff] [blame] | 161 | Function *Helper = nullptr, |
| 162 | StringRef Name = "accumulate") { |
Andrew Kaylor | 6bbb2c9 | 2013-10-01 01:48:36 +0000 | [diff] [blame] | 163 | Function *Result = startFunction<int32_t(int32_t)>(M, Name); |
Hans Wennborg | 083ca9b | 2015-10-06 23:24:35 +0000 | [diff] [blame] | 164 | if (!Helper) |
Andrew Kaylor | 6bbb2c9 | 2013-10-01 01:48:36 +0000 | [diff] [blame] | 165 | Helper = Result; |
| 166 | |
| 167 | BasicBlock *BaseCase = BasicBlock::Create(Context, "", Result); |
| 168 | BasicBlock *RecursiveCase = BasicBlock::Create(Context, "", Result); |
| 169 | |
| 170 | // if (num == 0) |
Duncan P. N. Exon Smith | c8925b1 | 2015-10-20 18:30:20 +0000 | [diff] [blame] | 171 | Value *Param = &*Result->arg_begin(); |
Andrew Kaylor | 6bbb2c9 | 2013-10-01 01:48:36 +0000 | [diff] [blame] | 172 | Value *Zero = ConstantInt::get(Context, APInt(32, 0)); |
| 173 | Builder.CreateCondBr(Builder.CreateICmpEQ(Param, Zero), |
| 174 | BaseCase, RecursiveCase); |
| 175 | |
| 176 | // return num; |
| 177 | Builder.SetInsertPoint(BaseCase); |
| 178 | Builder.CreateRet(Param); |
| 179 | |
| 180 | // int32_t recursive_param = num - 1; |
| 181 | // return Helper(recursive_param); |
| 182 | Builder.SetInsertPoint(RecursiveCase); |
| 183 | Value *One = ConstantInt::get(Context, APInt(32, 1)); |
| 184 | Value *RecursiveParam = Builder.CreateSub(Param, One); |
| 185 | Value *RecursiveReturn = Builder.CreateCall(Helper, RecursiveParam); |
| 186 | Value *Accumulator = Builder.CreateAdd(Param, RecursiveReturn); |
| 187 | Builder.CreateRet(Accumulator); |
| 188 | |
| 189 | return Result; |
| 190 | } |
| 191 | |
| 192 | // Populates Modules A and B: |
| 193 | // Module A { Extern FB1, Function FA which calls FB1 }, |
| 194 | // Module B { Extern FA, Function FB1, Function FB2 which calls FA }, |
Ahmed Charles | 56440fd | 2014-03-06 05:51:42 +0000 | [diff] [blame] | 195 | void createCrossModuleRecursiveCase(std::unique_ptr<Module> &A, Function *&FA, |
| 196 | std::unique_ptr<Module> &B, |
| 197 | Function *&FB1, Function *&FB2) { |
Andrew Kaylor | 6bbb2c9 | 2013-10-01 01:48:36 +0000 | [diff] [blame] | 198 | // Define FB1 in B. |
| 199 | B.reset(createEmptyModule("B")); |
Hans Wennborg | 083ca9b | 2015-10-06 23:24:35 +0000 | [diff] [blame] | 200 | FB1 = insertAccumulateFunction(B.get(), nullptr, "FB1"); |
Andrew Kaylor | 6bbb2c9 | 2013-10-01 01:48:36 +0000 | [diff] [blame] | 201 | |
| 202 | // Declare FB1 in A (as an external). |
| 203 | A.reset(createEmptyModule("A")); |
| 204 | Function *FB1Extern = insertExternalReferenceToFunction(A.get(), FB1); |
| 205 | |
| 206 | // Define FA in A (with a call to FB1). |
| 207 | FA = insertAccumulateFunction(A.get(), FB1Extern, "FA"); |
| 208 | |
| 209 | // Declare FA in B (as an external) |
| 210 | Function *FAExtern = insertExternalReferenceToFunction(B.get(), FA); |
| 211 | |
| 212 | // Define FB2 in B (with a call to FA) |
| 213 | FB2 = insertAccumulateFunction(B.get(), FAExtern, "FB2"); |
| 214 | } |
| 215 | |
| 216 | // Module A { Function FA }, |
| 217 | // Module B { Extern FA, Function FB which calls FA }, |
| 218 | // Module C { Extern FB, Function FC which calls FB }, |
Ahmed Charles | 56440fd | 2014-03-06 05:51:42 +0000 | [diff] [blame] | 219 | void |
| 220 | createThreeModuleChainedCallsCase(std::unique_ptr<Module> &A, Function *&FA, |
| 221 | std::unique_ptr<Module> &B, Function *&FB, |
| 222 | std::unique_ptr<Module> &C, Function *&FC) { |
Andrew Kaylor | 6bbb2c9 | 2013-10-01 01:48:36 +0000 | [diff] [blame] | 223 | A.reset(createEmptyModule("A")); |
| 224 | FA = insertAddFunction(A.get()); |
| 225 | |
| 226 | B.reset(createEmptyModule("B")); |
| 227 | Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA); |
| 228 | FB = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(B.get(), FAExtern_in_B); |
| 229 | |
| 230 | C.reset(createEmptyModule("C")); |
| 231 | Function *FBExtern_in_C = insertExternalReferenceToFunction(C.get(), FB); |
| 232 | FC = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(C.get(), FBExtern_in_C); |
| 233 | } |
| 234 | |
Andrew Kaylor | 6bbb2c9 | 2013-10-01 01:48:36 +0000 | [diff] [blame] | 235 | // Module A { Function FA }, |
| 236 | // Populates Modules A and B: |
| 237 | // Module B { Function FB } |
Ahmed Charles | 56440fd | 2014-03-06 05:51:42 +0000 | [diff] [blame] | 238 | void createTwoModuleCase(std::unique_ptr<Module> &A, Function *&FA, |
| 239 | std::unique_ptr<Module> &B, Function *&FB) { |
Andrew Kaylor | 6bbb2c9 | 2013-10-01 01:48:36 +0000 | [diff] [blame] | 240 | A.reset(createEmptyModule("A")); |
| 241 | FA = insertAddFunction(A.get()); |
| 242 | |
| 243 | B.reset(createEmptyModule("B")); |
| 244 | FB = insertAddFunction(B.get()); |
| 245 | } |
| 246 | |
| 247 | // Module A { Function FA }, |
| 248 | // Module B { Extern FA, Function FB which calls FA } |
Ahmed Charles | 56440fd | 2014-03-06 05:51:42 +0000 | [diff] [blame] | 249 | void createTwoModuleExternCase(std::unique_ptr<Module> &A, Function *&FA, |
| 250 | std::unique_ptr<Module> &B, Function *&FB) { |
Andrew Kaylor | 6bbb2c9 | 2013-10-01 01:48:36 +0000 | [diff] [blame] | 251 | A.reset(createEmptyModule("A")); |
| 252 | FA = insertAddFunction(A.get()); |
| 253 | |
| 254 | B.reset(createEmptyModule("B")); |
| 255 | Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA); |
| 256 | FB = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(B.get(), |
| 257 | FAExtern_in_B); |
| 258 | } |
| 259 | |
| 260 | // Module A { Function FA }, |
| 261 | // Module B { Extern FA, Function FB which calls FA }, |
| 262 | // Module C { Extern FB, Function FC which calls FA }, |
Ahmed Charles | 56440fd | 2014-03-06 05:51:42 +0000 | [diff] [blame] | 263 | void createThreeModuleCase(std::unique_ptr<Module> &A, Function *&FA, |
| 264 | std::unique_ptr<Module> &B, Function *&FB, |
| 265 | std::unique_ptr<Module> &C, Function *&FC) { |
Andrew Kaylor | 6bbb2c9 | 2013-10-01 01:48:36 +0000 | [diff] [blame] | 266 | A.reset(createEmptyModule("A")); |
| 267 | FA = insertAddFunction(A.get()); |
| 268 | |
| 269 | B.reset(createEmptyModule("B")); |
| 270 | Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA); |
| 271 | FB = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(B.get(), FAExtern_in_B); |
| 272 | |
| 273 | C.reset(createEmptyModule("C")); |
| 274 | Function *FAExtern_in_C = insertExternalReferenceToFunction(C.get(), FA); |
| 275 | FC = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(C.get(), FAExtern_in_C); |
| 276 | } |
Daniel Malea | 4146b04 | 2013-06-28 20:37:20 +0000 | [diff] [blame] | 277 | }; |
| 278 | |
| 279 | class MCJITTestBase : public MCJITTestAPICommon, public TrivialModuleBuilder { |
| 280 | protected: |
Andrew Kaylor | 6bbb2c9 | 2013-10-01 01:48:36 +0000 | [diff] [blame] | 281 | |
Daniel Malea | 4146b04 | 2013-06-28 20:37:20 +0000 | [diff] [blame] | 282 | MCJITTestBase() |
| 283 | : TrivialModuleBuilder(HostTriple) |
| 284 | , OptLevel(CodeGenOpt::None) |
Daniel Malea | 4146b04 | 2013-06-28 20:37:20 +0000 | [diff] [blame] | 285 | , CodeModel(CodeModel::Default) |
| 286 | , MArch("") |
| 287 | , MM(new SectionMemoryManager) |
| 288 | { |
| 289 | // The architectures below are known to be compatible with MCJIT as they |
| 290 | // are copied from test/ExecutionEngine/MCJIT/lit.local.cfg and should be |
| 291 | // kept in sync. |
| 292 | SupportedArchs.push_back(Triple::aarch64); |
| 293 | SupportedArchs.push_back(Triple::arm); |
Akira Hatanaka | 2e23624 | 2013-07-24 01:58:40 +0000 | [diff] [blame] | 294 | SupportedArchs.push_back(Triple::mips); |
| 295 | SupportedArchs.push_back(Triple::mipsel); |
Petar Jovanovic | 9720283 | 2015-05-28 13:48:41 +0000 | [diff] [blame] | 296 | SupportedArchs.push_back(Triple::mips64); |
| 297 | SupportedArchs.push_back(Triple::mips64el); |
Daniel Malea | 4146b04 | 2013-06-28 20:37:20 +0000 | [diff] [blame] | 298 | SupportedArchs.push_back(Triple::x86); |
| 299 | SupportedArchs.push_back(Triple::x86_64); |
| 300 | |
| 301 | // Some architectures have sub-architectures in which tests will fail, like |
| 302 | // ARM. These two vectors will define if they do have sub-archs (to avoid |
| 303 | // extra work for those who don't), and if so, if they are listed to work |
| 304 | HasSubArchs.push_back(Triple::arm); |
| 305 | SupportedSubArchs.push_back("armv6"); |
| 306 | SupportedSubArchs.push_back("armv7"); |
| 307 | |
Saleem Abdulrasool | d3bafe3 | 2014-03-31 23:42:23 +0000 | [diff] [blame] | 308 | UnsupportedEnvironments.push_back(Triple::Cygnus); |
Daniel Malea | 4146b04 | 2013-06-28 20:37:20 +0000 | [diff] [blame] | 309 | } |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 310 | |
Rafael Espindola | 2a8a279 | 2014-08-19 04:04:25 +0000 | [diff] [blame] | 311 | void createJIT(std::unique_ptr<Module> M) { |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 312 | |
| 313 | // Due to the EngineBuilder constructor, it is required to have a Module |
| 314 | // in order to construct an ExecutionEngine (i.e. MCJIT) |
| 315 | assert(M != 0 && "a non-null Module must be provided to create MCJIT"); |
| 316 | |
Rafael Espindola | 2a8a279 | 2014-08-19 04:04:25 +0000 | [diff] [blame] | 317 | EngineBuilder EB(std::move(M)); |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 318 | std::string Error; |
| 319 | TheJIT.reset(EB.setEngineKind(EngineKind::JIT) |
Lang Hames | 4a5697e | 2014-12-03 00:51:19 +0000 | [diff] [blame] | 320 | .setMCJITMemoryManager(std::move(MM)) |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 321 | .setErrorStr(&Error) |
| 322 | .setOptLevel(CodeGenOpt::None) |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 323 | .setCodeModel(CodeModel::JITDefault) |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 324 | .setMArch(MArch) |
| 325 | .setMCPU(sys::getHostCPUName()) |
| 326 | //.setMAttrs(MAttrs) |
| 327 | .create()); |
| 328 | // At this point, we cannot modify the module any more. |
| 329 | assert(TheJIT.get() != NULL && "error creating MCJIT with EngineBuilder"); |
| 330 | } |
| 331 | |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 332 | CodeGenOpt::Level OptLevel; |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 333 | CodeModel::Model CodeModel; |
| 334 | StringRef MArch; |
| 335 | SmallVector<std::string, 1> MAttrs; |
Ahmed Charles | 56440fd | 2014-03-06 05:51:42 +0000 | [diff] [blame] | 336 | std::unique_ptr<ExecutionEngine> TheJIT; |
Lang Hames | 4a5697e | 2014-12-03 00:51:19 +0000 | [diff] [blame] | 337 | std::unique_ptr<RTDyldMemoryManager> MM; |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 338 | |
Ahmed Charles | 56440fd | 2014-03-06 05:51:42 +0000 | [diff] [blame] | 339 | std::unique_ptr<Module> M; |
Andrew Kaylor | 5e7d792 | 2012-10-04 20:29:44 +0000 | [diff] [blame] | 340 | }; |
| 341 | |
| 342 | } // namespace llvm |
| 343 | |
Hans Wennborg | 083ca9b | 2015-10-06 23:24:35 +0000 | [diff] [blame] | 344 | #endif // LLVM_UNITTESTS_EXECUTIONENGINE_MCJIT_MCJITTESTBASE_H |