12d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor//===- MCJITTestBase.h - Common base class for MCJIT Unit tests ----------===// 22d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 32d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// The LLVM Compiler Infrastructure 42d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 52d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// This file is distributed under the University of Illinois Open Source 62d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// License. See LICENSE.TXT for details. 72d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 82d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor//===----------------------------------------------------------------------===// 92d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 102d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// This class implements common functionality required by the MCJIT unit tests, 112d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// as well as logic to skip tests on unsupported architectures and operating 122d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// systems. 132d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor// 142d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor//===----------------------------------------------------------------------===// 152d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 162d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 172d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor#ifndef MCJIT_TEST_BASE_H 182d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor#define MCJIT_TEST_BASE_H 192d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 2036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MCJITTestAPICommon.h" 212d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor#include "llvm/Config/config.h" 222d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor#include "llvm/ExecutionEngine/ExecutionEngine.h" 23927ba6a0b36b8219955a657545fcb1c863734993Andrew Kaylor#include "llvm/ExecutionEngine/SectionMemoryManager.h" 240b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Function.h" 250b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/IRBuilder.h" 260b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h" 270b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/Module.h" 280b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/TypeBuilder.h" 292d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor#include "llvm/Support/CodeGen.h" 302d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 312d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylornamespace llvm { 322d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 335fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea/// Helper class that can build very simple Modules 345fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Maleaclass TrivialModuleBuilder { 352d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylorprotected: 365fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea LLVMContext Context; 375fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea IRBuilder<> Builder; 385fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea std::string BuilderTriple; 392d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 405fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea TrivialModuleBuilder(const std::string &Triple) 415fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea : Builder(Context), BuilderTriple(Triple) {} 422d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 435fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea Module *createEmptyModule(StringRef Name = StringRef()) { 442d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Module * M = new Module(Name, Context); 455fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea M->setTargetTriple(Triple::normalize(BuilderTriple)); 462d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor return M; 472d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor } 482d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 492d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor template<typename FuncType> 502d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Function *startFunction(Module *M, StringRef Name) { 512d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Function *Result = Function::Create( 522d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor TypeBuilder<FuncType, false>::get(Context), 532d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor GlobalValue::ExternalLinkage, Name, M); 542d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 552d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor BasicBlock *BB = BasicBlock::Create(Context, Name, Result); 562d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Builder.SetInsertPoint(BB); 572d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 582d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor return Result; 592d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor } 602d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 612d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor void endFunctionWithRet(Function *Func, Value *RetValue) { 622d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Builder.CreateRet(RetValue); 632d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor } 642d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 652d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // Inserts a simple function that invokes Callee and takes the same arguments: 662d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // int Caller(...) { return Callee(...); } 672d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor template<typename Signature> 682d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Function *insertSimpleCallFunction(Module *M, Function *Callee) { 692d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Function *Result = startFunction<Signature>(M, "caller"); 702d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 712d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor SmallVector<Value*, 1> CallArgs; 722d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 732d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Function::arg_iterator arg_iter = Result->arg_begin(); 742d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor for(;arg_iter != Result->arg_end(); ++arg_iter) 752d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor CallArgs.push_back(arg_iter); 762d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 772d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Value *ReturnCode = Builder.CreateCall(Callee, CallArgs); 782d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Builder.CreateRet(ReturnCode); 792d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor return Result; 802d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor } 812d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 822d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // Inserts a function named 'main' that returns a uint32_t: 832d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // int32_t main() { return X; } 842d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // where X is given by returnCode 852d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Function *insertMainFunction(Module *M, uint32_t returnCode) { 862d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Function *Result = startFunction<int32_t(void)>(M, "main"); 872d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 882d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Value *ReturnVal = ConstantInt::get(Context, APInt(32, returnCode)); 892d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor endFunctionWithRet(Result, ReturnVal); 902d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 912d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor return Result; 922d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor } 932d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 942d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // Inserts a function 952d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // int32_t add(int32_t a, int32_t b) { return a + b; } 962d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // in the current module and returns a pointer to it. 972d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Function *insertAddFunction(Module *M, StringRef Name = "add") { 982d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Function *Result = startFunction<int32_t(int32_t, int32_t)>(M, Name); 992d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 1002d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Function::arg_iterator args = Result->arg_begin(); 1012d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Value *Arg1 = args; 1022d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Value *Arg2 = ++args; 1032d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Value *AddResult = Builder.CreateAdd(Arg1, Arg2); 1042d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 1052d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor endFunctionWithRet(Result, AddResult); 1062d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 1072d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor return Result; 1082d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor } 1092d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 1102d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // Inserts an declaration to a function defined elsewhere 1112d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Function *insertExternalReferenceToFunction(Module *M, StringRef Name, 1122d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor FunctionType *FuncTy) { 1132d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Function *Result = Function::Create(FuncTy, 1142d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor GlobalValue::ExternalLinkage, 1152d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Name, M); 1162d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor return Result; 1172d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor } 1182d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 1192d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // Inserts an declaration to a function defined elsewhere 1202d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Function *insertExternalReferenceToFunction(Module *M, Function *Func) { 1212d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Function *Result = Function::Create(Func->getFunctionType(), 12270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor GlobalValue::ExternalLinkage, 1232d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Func->getName(), M); 1242d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor return Result; 1252d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor } 1262d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 1272d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // Inserts a global variable of type int32 12870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // FIXME: make this a template function to support any type 1292d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor GlobalVariable *insertGlobalInt32(Module *M, 1302d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor StringRef name, 1312d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor int32_t InitialValue) { 1322d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Type *GlobalTy = TypeBuilder<types::i<32>, true>::get(Context); 1332d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Constant *IV = ConstantInt::get(Context, APInt(32, InitialValue)); 1342d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor GlobalVariable *Global = new GlobalVariable(*M, 1352d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor GlobalTy, 1362d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor false, 1372d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor GlobalValue::ExternalLinkage, 1382d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor IV, 1392d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor name); 1402d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor return Global; 1412d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor } 14270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 14370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Inserts a function 14470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // int32_t recursive_add(int32_t num) { 14570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // if (num == 0) { 14670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // return num; 14770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // } else { 14870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // int32_t recursive_param = num - 1; 14970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // return num + Helper(recursive_param); 15070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // } 15170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // } 15270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // NOTE: if Helper is left as the default parameter, Helper == recursive_add. 15370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *insertAccumulateFunction(Module *M, 15470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *Helper = 0, 15570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor StringRef Name = "accumulate") { 15670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *Result = startFunction<int32_t(int32_t)>(M, Name); 15770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor if (Helper == 0) 15870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Helper = Result; 15970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 16070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor BasicBlock *BaseCase = BasicBlock::Create(Context, "", Result); 16170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor BasicBlock *RecursiveCase = BasicBlock::Create(Context, "", Result); 16270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 16370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // if (num == 0) 16470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Value *Param = Result->arg_begin(); 16570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Value *Zero = ConstantInt::get(Context, APInt(32, 0)); 16670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Builder.CreateCondBr(Builder.CreateICmpEQ(Param, Zero), 16770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor BaseCase, RecursiveCase); 16870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 16970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // return num; 17070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Builder.SetInsertPoint(BaseCase); 17170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Builder.CreateRet(Param); 17270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 17370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // int32_t recursive_param = num - 1; 17470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // return Helper(recursive_param); 17570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Builder.SetInsertPoint(RecursiveCase); 17670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Value *One = ConstantInt::get(Context, APInt(32, 1)); 17770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Value *RecursiveParam = Builder.CreateSub(Param, One); 17870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Value *RecursiveReturn = Builder.CreateCall(Helper, RecursiveParam); 17970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Value *Accumulator = Builder.CreateAdd(Param, RecursiveReturn); 18070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Builder.CreateRet(Accumulator); 18170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 18270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor return Result; 18370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor } 18470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 18570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Populates Modules A and B: 18670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Module A { Extern FB1, Function FA which calls FB1 }, 18770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Module B { Extern FA, Function FB1, Function FB2 which calls FA }, 18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void createCrossModuleRecursiveCase(std::unique_ptr<Module> &A, Function *&FA, 18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> &B, 19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Function *&FB1, Function *&FB2) { 19170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Define FB1 in B. 19270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor B.reset(createEmptyModule("B")); 19370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FB1 = insertAccumulateFunction(B.get(), 0, "FB1"); 19470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 19570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Declare FB1 in A (as an external). 19670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor A.reset(createEmptyModule("A")); 19770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FB1Extern = insertExternalReferenceToFunction(A.get(), FB1); 19870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 19970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Define FA in A (with a call to FB1). 20070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FA = insertAccumulateFunction(A.get(), FB1Extern, "FA"); 20170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 20270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Declare FA in B (as an external) 20370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FAExtern = insertExternalReferenceToFunction(B.get(), FA); 20470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 20570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Define FB2 in B (with a call to FA) 20670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FB2 = insertAccumulateFunction(B.get(), FAExtern, "FB2"); 20770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor } 20870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 20970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Module A { Function FA }, 21070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Module B { Extern FA, Function FB which calls FA }, 21170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Module C { Extern FB, Function FC which calls FB }, 21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void 21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createThreeModuleChainedCallsCase(std::unique_ptr<Module> &A, Function *&FA, 21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> &B, Function *&FB, 21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> &C, Function *&FC) { 21670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor A.reset(createEmptyModule("A")); 21770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FA = insertAddFunction(A.get()); 21870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 21970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor B.reset(createEmptyModule("B")); 22070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA); 22170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FB = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(B.get(), FAExtern_in_B); 22270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 22370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor C.reset(createEmptyModule("C")); 22470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FBExtern_in_C = insertExternalReferenceToFunction(C.get(), FB); 22570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FC = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(C.get(), FBExtern_in_C); 22670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor } 22770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 22870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 22970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Module A { Function FA }, 23070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Populates Modules A and B: 23170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Module B { Function FB } 23236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void createTwoModuleCase(std::unique_ptr<Module> &A, Function *&FA, 23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> &B, Function *&FB) { 23470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor A.reset(createEmptyModule("A")); 23570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FA = insertAddFunction(A.get()); 23670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 23770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor B.reset(createEmptyModule("B")); 23870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FB = insertAddFunction(B.get()); 23970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor } 24070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 24170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Module A { Function FA }, 24270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Module B { Extern FA, Function FB which calls FA } 24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void createTwoModuleExternCase(std::unique_ptr<Module> &A, Function *&FA, 24436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> &B, Function *&FB) { 24570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor A.reset(createEmptyModule("A")); 24670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FA = insertAddFunction(A.get()); 24770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 24870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor B.reset(createEmptyModule("B")); 24970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA); 25070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FB = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(B.get(), 25170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FAExtern_in_B); 25270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor } 25370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 25470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Module A { Function FA }, 25570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Module B { Extern FA, Function FB which calls FA }, 25670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor // Module C { Extern FB, Function FC which calls FA }, 25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void createThreeModuleCase(std::unique_ptr<Module> &A, Function *&FA, 25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> &B, Function *&FB, 25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> &C, Function *&FC) { 26070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor A.reset(createEmptyModule("A")); 26170c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FA = insertAddFunction(A.get()); 26270c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 26370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor B.reset(createEmptyModule("B")); 26470c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FAExtern_in_B = insertExternalReferenceToFunction(B.get(), FA); 26570c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FB = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(B.get(), FAExtern_in_B); 26670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 26770c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor C.reset(createEmptyModule("C")); 26870c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor Function *FAExtern_in_C = insertExternalReferenceToFunction(C.get(), FA); 26970c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor FC = insertSimpleCallFunction<int32_t(int32_t, int32_t)>(C.get(), FAExtern_in_C); 27070c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor } 2715fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea}; 2725fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea 27370c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 2745fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Maleaclass MCJITTestBase : public MCJITTestAPICommon, public TrivialModuleBuilder { 2755fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Maleaprotected: 27670c1ea493e6156eccde5270c139ef423b19ab580Andrew Kaylor 2775fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea MCJITTestBase() 2785fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea : TrivialModuleBuilder(HostTriple) 2795fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea , OptLevel(CodeGenOpt::None) 2805fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea , RelocModel(Reloc::Default) 2815fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea , CodeModel(CodeModel::Default) 2825fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea , MArch("") 2835fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea , MM(new SectionMemoryManager) 2845fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea { 2855fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea // The architectures below are known to be compatible with MCJIT as they 2865fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea // are copied from test/ExecutionEngine/MCJIT/lit.local.cfg and should be 2875fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea // kept in sync. 2885fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea SupportedArchs.push_back(Triple::aarch64); 2895fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea SupportedArchs.push_back(Triple::arm); 2903af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka SupportedArchs.push_back(Triple::mips); 2913af1c9d3343357849f19f7467f9c16220ad37ca4Akira Hatanaka SupportedArchs.push_back(Triple::mipsel); 2925fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea SupportedArchs.push_back(Triple::x86); 2935fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea SupportedArchs.push_back(Triple::x86_64); 2945fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea 2955fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea // Some architectures have sub-architectures in which tests will fail, like 2965fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea // ARM. These two vectors will define if they do have sub-archs (to avoid 2975fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea // extra work for those who don't), and if so, if they are listed to work 2985fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea HasSubArchs.push_back(Triple::arm); 2995fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea SupportedSubArchs.push_back("armv6"); 3005fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea SupportedSubArchs.push_back("armv7"); 3015fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea 3025fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea // The operating systems below are known to be incompatible with MCJIT as 3035fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea // they are copied from the test/ExecutionEngine/MCJIT/lit.local.cfg and 3045fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea // should be kept in sync. 3055fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea UnsupportedOSs.push_back(Triple::Cygwin); 3065fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea UnsupportedOSs.push_back(Triple::Darwin); 30736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines UnsupportedEnvironments.push_back(Triple::Cygnus); 3095fa8186b8dcc0be77f4ab64b1ef46ad919315b54Daniel Malea } 3102d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 3112d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor void createJIT(Module *M) { 3122d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 3132d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // Due to the EngineBuilder constructor, it is required to have a Module 3142d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // in order to construct an ExecutionEngine (i.e. MCJIT) 3152d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor assert(M != 0 && "a non-null Module must be provided to create MCJIT"); 3162d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 3172d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor EngineBuilder EB(M); 3182d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor std::string Error; 3192d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor TheJIT.reset(EB.setEngineKind(EngineKind::JIT) 3202d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor .setUseMCJIT(true) /* can this be folded into the EngineKind enum? */ 32113a3cf192887233fb9452ec5b7f841e4652c33c7Filip Pizlo .setMCJITMemoryManager(MM) 3222d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor .setErrorStr(&Error) 3232d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor .setOptLevel(CodeGenOpt::None) 3242d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor .setAllocateGVsWithCode(false) /*does this do anything?*/ 3252d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor .setCodeModel(CodeModel::JITDefault) 3262d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor .setRelocationModel(Reloc::Default) 3272d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor .setMArch(MArch) 3282d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor .setMCPU(sys::getHostCPUName()) 3292d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor //.setMAttrs(MAttrs) 3302d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor .create()); 3312d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor // At this point, we cannot modify the module any more. 3322d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor assert(TheJIT.get() != NULL && "error creating MCJIT with EngineBuilder"); 3332d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor } 3342d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 3352d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor CodeGenOpt::Level OptLevel; 3362d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor Reloc::Model RelocModel; 3372d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor CodeModel::Model CodeModel; 3382d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor StringRef MArch; 3392d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor SmallVector<std::string, 1> MAttrs; 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<ExecutionEngine> TheJIT; 34113a3cf192887233fb9452ec5b7f841e4652c33c7Filip Pizlo RTDyldMemoryManager *MM; 3422d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 34336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<Module> M; 3442d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor}; 3452d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 3462d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor} // namespace llvm 3472d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor 3482d6d585c85ce8c56461f17b7b49fff24eed7b8fbAndrew Kaylor#endif // MCJIT_TEST_H 349