llvm.org GIT mirror llvm / release_27 examples / HowToUseJIT / HowToUseJIT.cpp
release_27

Tree @release_27 (Download .tar.gz)

HowToUseJIT.cpp @release_27

66e7cd0
237cef4
26a4ba7
 
fc001bb
 
237cef4
26a4ba7
 
54706d6
237cef4
 
 
26a4ba7
f9fba30
26a4ba7
 
 
 
237cef4
26a4ba7
 
 
237cef4
 
26a4ba7
237cef4
26a4ba7
237cef4
26a4ba7
237cef4
26a4ba7
 
237cef4
e8bf58c
26a4ba7
8b477ed
e8bf58c
 
bc0895a
e8bf58c
afebb44
 
26a4ba7
da06288
eb55f3e
944fac7
26a4ba7
 
 
da06288
 
8b477ed
 
da06288
26a4ba7
31895e7
26a4ba7
e8bf58c
 
 
6a98754
1d0be15
 
6a98754
26a4ba7
e8bf58c
 
1d0be15
237cef4
e8bf58c
1d0be15
26a4ba7
e8bf58c
1d9f262
 
e8bf58c
26a4ba7
e8bf58c
7cbd8a3
237cef4
e8bf58c
1d0be15
26a4ba7
e8bf58c
26a4ba7
 
e8bf58c
 
6a98754
1d0be15
 
26a4ba7
e8bf58c
1d0be15
26a4ba7
e8bf58c
1d0be15
26a4ba7
e8bf58c
051a950
47968e4
237cef4
e8bf58c
1d0be15
26a4ba7
e8bf58c
4b1511b
e8bf58c
944fac7
 
 
26a4ba7
 
 
 
 
e8bf58c
944fac7
eb55f3e
 
 
26a4ba7
 
//===-- examples/HowToUseJIT/HowToUseJIT.cpp - An example use of the JIT --===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This small program provides an example of how to quickly build a small
//  module with two functions and execute it with the JIT.
//
// Goal:
//  The goal of this snippet is to create in the memory
//  the LLVM module consisting of two functions as follow: 
//
// int add1(int x) {
//   return x+1;
// }
//
// int foo() {
//   return add1(10);
// }
//
// then compile the module via JIT, then execute the `foo'
// function and return result to a driver, i.e. to a "host program".
//
// Some remarks and questions:
//
// - could we invoke some code using noname functions too?
//   e.g. evaluate "foo()+foo()" without fears to introduce
//   conflict of temporary function name with some real
//   existing function name?
//
//===----------------------------------------------------------------------===//

#include "llvm/LLVMContext.h"
#include "llvm/Module.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Target/TargetSelect.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

int main() {
  
  InitializeNativeTarget();

  LLVMContext Context;
  
  // Create some module to put our function into it.
  Module *M = new Module("test", Context);

  // Create the add1 function entry and insert this entry into module M.  The
  // function will have a return type of "int" and take an argument of "int".
  // The '0' terminates the list of argument types.
  Function *Add1F =
    cast<Function>(M->getOrInsertFunction("add1", Type::getInt32Ty(Context),
                                          Type::getInt32Ty(Context),
                                          (Type *)0));

  // Add a basic block to the function. As before, it automatically inserts
  // because of the last argument.
  BasicBlock *BB = BasicBlock::Create(Context, "EntryBlock", Add1F);

  // Get pointers to the constant `1'.
  Value *One = ConstantInt::get(Type::getInt32Ty(Context), 1);

  // Get pointers to the integer argument of the add1 function...
  assert(Add1F->arg_begin() != Add1F->arg_end()); // Make sure there's an arg
  Argument *ArgX = Add1F->arg_begin();  // Get the arg
  ArgX->setName("AnArg");            // Give it a nice symbolic name for fun.

  // Create the add instruction, inserting it into the end of BB.
  Instruction *Add = BinaryOperator::CreateAdd(One, ArgX, "addresult", BB);

  // Create the return instruction and add it to the basic block
  ReturnInst::Create(Context, Add, BB);

  // Now, function add1 is ready.


  // Now we going to create function `foo', which returns an int and takes no
  // arguments.
  Function *FooF =
    cast<Function>(M->getOrInsertFunction("foo", Type::getInt32Ty(Context),
                                          (Type *)0));

  // Add a basic block to the FooF function.
  BB = BasicBlock::Create(Context, "EntryBlock", FooF);

  // Get pointers to the constant `10'.
  Value *Ten = ConstantInt::get(Type::getInt32Ty(Context), 10);

  // Pass Ten to the call call:
  CallInst *Add1CallRes = CallInst::Create(Add1F, Ten, "add1", BB);
  Add1CallRes->setTailCall(true);

  // Create the return instruction and add it to the basic block.
  ReturnInst::Create(Context, Add1CallRes, BB);

  // Now we create the JIT.
  ExecutionEngine* EE = EngineBuilder(M).create();

  outs() << "We just constructed this LLVM module:\n\n" << *M;
  outs() << "\n\nRunning foo: ";
  outs().flush();

  // Call the `foo' function with no arguments:
  std::vector<GenericValue> noargs;
  GenericValue gv = EE->runFunction(FooF, noargs);

  // Import result of execution:
  outs() << "Result: " << gv.IntVal << "\n";
  EE->freeMachineCodeForFunction(FooF);
  delete EE;
  llvm_shutdown();
  return 0;
}