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