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