1*b987b7ceSReid Spencer //===--- HowToUseJIT.cpp - An example use of the JIT ----------------------===// 2*b987b7ceSReid Spencer // 3*b987b7ceSReid Spencer // The LLVM Compiler Infrastructure 4*b987b7ceSReid Spencer // 5*b987b7ceSReid Spencer // This file was developed by Valery A. Khamenya and is distributed under the 6*b987b7ceSReid Spencer // University of Illinois Open Source License. See LICENSE.TXT for details. 7*b987b7ceSReid Spencer // 8*b987b7ceSReid Spencer //===----------------------------------------------------------------------===// 9*b987b7ceSReid Spencer // 10*b987b7ceSReid Spencer // This small program provides an example of how to quickly build a small 11*b987b7ceSReid Spencer // module with two functions and execute it with the JIT. 12*b987b7ceSReid Spencer // 13*b987b7ceSReid Spencer // Goal: 14*b987b7ceSReid Spencer // The goal of this snippet is to create in the memory 15*b987b7ceSReid Spencer // the LLVM module consisting of two functions as follow: 16*b987b7ceSReid Spencer // 17*b987b7ceSReid Spencer // int add1(int x) { 18*b987b7ceSReid Spencer // return x+1; 19*b987b7ceSReid Spencer // } 20*b987b7ceSReid Spencer // 21*b987b7ceSReid Spencer // int foo() { 22*b987b7ceSReid Spencer // return add1(10); 23*b987b7ceSReid Spencer // } 24*b987b7ceSReid Spencer // 25*b987b7ceSReid Spencer // then compile the module via JIT, then execute the `foo' 26*b987b7ceSReid Spencer // function and return result to a driver, i.e. to a "host program". 27*b987b7ceSReid Spencer // 28*b987b7ceSReid Spencer // Some remarks and questions: 29*b987b7ceSReid Spencer // 30*b987b7ceSReid Spencer // - could we invoke some code using noname functions too? 31*b987b7ceSReid Spencer // e.g. evaluate "foo()+foo()" without fears to introduce 32*b987b7ceSReid Spencer // conflict of temporary function name with some real 33*b987b7ceSReid Spencer // existing function name? 34*b987b7ceSReid Spencer // 35*b987b7ceSReid Spencer //===----------------------------------------------------------------------===// 36*b987b7ceSReid Spencer 37*b987b7ceSReid Spencer #include "llvm/Module.h" 38*b987b7ceSReid Spencer #include "llvm/Constants.h" 39*b987b7ceSReid Spencer #include "llvm/Type.h" 40*b987b7ceSReid Spencer #include "llvm/Instructions.h" 41*b987b7ceSReid Spencer #include "llvm/ModuleProvider.h" 42*b987b7ceSReid Spencer #include "llvm/ExecutionEngine/ExecutionEngine.h" 43*b987b7ceSReid Spencer #include "llvm/ExecutionEngine/GenericValue.h" 44*b987b7ceSReid Spencer #include <iostream> 45*b987b7ceSReid Spencer using namespace llvm; 46*b987b7ceSReid Spencer 47*b987b7ceSReid Spencer int main() { 48*b987b7ceSReid Spencer // Create some module to put our function into it. 49*b987b7ceSReid Spencer Module *M = new Module("test"); 50*b987b7ceSReid Spencer 51*b987b7ceSReid Spencer // Create the add1 function entry and insert this entry into module M. The 52*b987b7ceSReid Spencer // function will have a return type of "int" and take an argument of "int". 53*b987b7ceSReid Spencer // The '0' terminates the list of argument types. 54*b987b7ceSReid Spencer Function *Add1F = M->getOrInsertFunction("add1", Type::IntTy, Type::IntTy, 0); 55*b987b7ceSReid Spencer 56*b987b7ceSReid Spencer // Add a basic block to the function. As before, it automatically inserts 57*b987b7ceSReid Spencer // because of the last argument. 58*b987b7ceSReid Spencer BasicBlock *BB = new BasicBlock("EntryBlock", Add1F); 59*b987b7ceSReid Spencer 60*b987b7ceSReid Spencer // Get pointers to the constant `1'. 61*b987b7ceSReid Spencer Value *One = ConstantSInt::get(Type::IntTy, 1); 62*b987b7ceSReid Spencer 63*b987b7ceSReid Spencer // Get pointers to the integer argument of the add1 function... 64*b987b7ceSReid Spencer assert(Add1F->abegin() != Add1F->aend()); // Make sure there's an arg 65*b987b7ceSReid Spencer Argument *ArgX = Add1F->abegin(); // Get the arg 66*b987b7ceSReid Spencer ArgX->setName("AnArg"); // Give it a nice symbolic name for fun. 67*b987b7ceSReid Spencer 68*b987b7ceSReid Spencer // Create the add instruction, inserting it into the end of BB. 69*b987b7ceSReid Spencer Instruction *Add = BinaryOperator::createAdd(One, ArgX, "addresult", BB); 70*b987b7ceSReid Spencer 71*b987b7ceSReid Spencer // Create the return instruction and add it to the basic block 72*b987b7ceSReid Spencer new ReturnInst(Add, BB); 73*b987b7ceSReid Spencer 74*b987b7ceSReid Spencer // Now, function add1 is ready. 75*b987b7ceSReid Spencer 76*b987b7ceSReid Spencer 77*b987b7ceSReid Spencer // Now we going to create function `foo', which returns an int and takes no 78*b987b7ceSReid Spencer // arguments. 79*b987b7ceSReid Spencer Function *FooF = M->getOrInsertFunction("foo", Type::IntTy, 0); 80*b987b7ceSReid Spencer 81*b987b7ceSReid Spencer // Add a basic block to the FooF function. 82*b987b7ceSReid Spencer BB = new BasicBlock("EntryBlock", FooF); 83*b987b7ceSReid Spencer 84*b987b7ceSReid Spencer // Get pointers to the constant `10'. 85*b987b7ceSReid Spencer Value *Ten = ConstantSInt::get(Type::IntTy, 10); 86*b987b7ceSReid Spencer 87*b987b7ceSReid Spencer // Pass Ten to the call call: 88*b987b7ceSReid Spencer std::vector<Value*> Params; 89*b987b7ceSReid Spencer Params.push_back(Ten); 90*b987b7ceSReid Spencer CallInst * Add1CallRes = new CallInst(Add1F, Params, "add1", BB); 91*b987b7ceSReid Spencer 92*b987b7ceSReid Spencer // Create the return instruction and add it to the basic block. 93*b987b7ceSReid Spencer new ReturnInst(Add1CallRes, BB); 94*b987b7ceSReid Spencer 95*b987b7ceSReid Spencer // Now we create the JIT. 96*b987b7ceSReid Spencer ExistingModuleProvider* MP = new ExistingModuleProvider(M); 97*b987b7ceSReid Spencer ExecutionEngine* EE = ExecutionEngine::create(MP, false); 98*b987b7ceSReid Spencer 99*b987b7ceSReid Spencer std::cout << "We just constructed this LLVM module:\n\n" << *M; 100*b987b7ceSReid Spencer std::cout << "\n\nRunning foo: " << std::flush; 101*b987b7ceSReid Spencer 102*b987b7ceSReid Spencer // Call the `foo' function with no arguments: 103*b987b7ceSReid Spencer std::vector<GenericValue> noargs; 104*b987b7ceSReid Spencer GenericValue gv = EE->runFunction(FooF, noargs); 105*b987b7ceSReid Spencer 106*b987b7ceSReid Spencer // Import result of execution: 107*b987b7ceSReid Spencer std::cout << "Result: " << gv.IntVal << "\n"; 108*b987b7ceSReid Spencer return 0; 109*b987b7ceSReid Spencer } 110