[LLVMdev] JIT API example (fibonacci)

Reid Spencer reid at x10sys.com
Tue Aug 17 19:49:34 PDT 2004


Okay. I'll send you a ,v copying script when I'm done.

On Tue, 2004-08-17 at 19:52, Chris Lattner wrote:
> On Tue, 17 Aug 2004, Reid Spencer wrote:
> 
> > On second thought, the makefiles don't (easily) allow this do they? You can
> > only build one program per directory. Were you suggesting that you wanted me to
> > move the entire directories under a "small examples" directory?
> 
> You're right.  The simples way to do this would be to have:
>   projects/
>            SmallExamples/
>                          ModuleMaker/
>                          HowToUseTheJIT/
>                          FibBuilder/
> 
> etc.  Each subsubdir would have a makefile and a .cpp file.
> 
> -Chris
> 
> > Chris Lattner wrote:
> >
> > > On Tue, 17 Aug 2004, Reid Spencer wrote:
> > >
> > >
> > >>That's pretty cute actually. Do you want this "brilliant" :) example in the cvs
> > >>repository? I'd be happy to put it in.
> > >
> > >
> > > Here's an idea: how about we take the ModuleMaker, Valery's previous
> > > example, and this one and put them all in one "small examples" project?
> > >
> > > -Chris
> > >
> > >
> > >>Valery A.Khamenya wrote:
> > >>
> > >>
> > >>>Hi LLVMers,
> > >>>
> > >>>  the example attached I have used to prove that JIT and some visible
> > >>>  optimizations are really invoked.
> > >>>
> > >>>  Proved OK. I got 30% speed-up in comparison to gcc 3.3.3
> > >>>  on my Athlon XP 1500.
> > >>>
> > >>>  Nice.
> > >>>
> > >>>  P.S. guys, no fears, I don't plan to flood the cvs repository
> > >>>  with my "brilliant" examples ;)
> > >>>
> > >>>---
> > >>>Valery A.Khamenya
> > >>>
> > >>>
> > >>>
> > >>>
> > >>>------------------------------------------------------------------------
> > >>>
> > >>>//===--- fibonacci.cpp - An example use of the JIT ----------------------===//
> > >>>//
> > >>>//                     The LLVM Compiler Infrastructure
> > >>>//
> > >>>// This file was developed by Valery A. Khamenya and is distributed under the
> > >>>// University of Illinois Open Source License. See LICENSE.TXT for details.
> > >>>//
> > >>>//===----------------------------------------------------------------------===//
> > >>>//
> > >>>// This small program provides an example of how to build quickly a small
> > >>>// module with function Fibonacci and execute it with the JIT.
> > >>>//
> > >>>// This simple example shows as well 30% speed up with LLVM 1.3
> > >>>// in comparison to gcc 3.3.3 at AMD Athlon XP 1500+ .
> > >>>//
> > >>>// (Modified from HowToUseJIT.cpp and Stacker/lib/compiler/StackerCompiler.cpp)
> > >>>//
> > >>>//===------------------------------------------------------------------------===
> > >>>// Goal:
> > >>>//  The goal of this snippet is to create in the memory
> > >>>//  the LLVM module consisting of one function as follow:
> > >>>//
> > >>>// int fib(int x) {
> > >>>//   if(x<=2) return 1;
> > >>>//   return fib(x-1)+fib(x-2);
> > >>>// }
> > >>>//
> > >>>// then compile the module via JIT, then execute the `fib'
> > >>>// function and return result to a driver, i.e. to a "host program".
> > >>>//
> > >>>
> > >>>#include <iostream>
> > >>>
> > >>>#include <llvm/Module.h>
> > >>>#include <llvm/DerivedTypes.h>
> > >>>#include <llvm/Constants.h>
> > >>>#include <llvm/Instructions.h>
> > >>>#include <llvm/ModuleProvider.h>
> > >>>#include <llvm/Analysis/Verifier.h>
> > >>>#include "llvm/ExecutionEngine/ExecutionEngine.h"
> > >>>#include "llvm/ExecutionEngine/GenericValue.h"
> > >>>
> > >>>
> > >>>using namespace llvm;
> > >>>
> > >>>int main(int argc, char**argv) {
> > >>>
> > >>>  int n = argc > 1 ? atol(argv[1]) : 44;
> > >>>
> > >>>  // Create some module to put our function into it.
> > >>>  Module *M = new Module("test");
> > >>>
> > >>>
> > >>>  // We are about to create the "fib" function:
> > >>>  Function *FibF;
> > >>>
> > >>>  {
> > >>>    // first create type for the single argument of fib function:
> > >>>    // the type is 'int ()'
> > >>>    std::vector<const Type*> ArgT(1);
> > >>>    ArgT[0] = Type::IntTy;
> > >>>
> > >>>    // now create full type of the "fib" function:
> > >>>    FunctionType *FibT = FunctionType::get(Type::IntTy, // type of result
> > >>>					   ArgT,
> > >>>					   /*not vararg*/false);
> > >>>
> > >>>    // Now create the fib function entry and
> > >>>    // insert this entry into module M
> > >>>    // (By passing a module as the last parameter to the Function constructor,
> > >>>    // it automatically gets appended to the Module.)
> > >>>    FibF = new Function(FibT,
> > >>>			Function::ExternalLinkage, // maybe too much
> > >>>			"fib", M);
> > >>>
> > >>>    // Add a basic block to the function... (again, it automatically inserts
> > >>>    // because of the last argument.)
> > >>>    BasicBlock *BB = new BasicBlock("EntryBlock of fib function", FibF);
> > >>>
> > >>>    // Get pointers to the constants ...
> > >>>    Value *One = ConstantSInt::get(Type::IntTy, 1);
> > >>>    Value *Two = ConstantSInt::get(Type::IntTy, 2);
> > >>>
> > >>>    // Get pointers to the integer argument of the add1 function...
> > >>>    assert(FibF->abegin() != FibF->aend()); // Make sure there's an arg
> > >>>
> > >>>    Argument &ArgX = FibF->afront();  // Get the arg
> > >>>    ArgX.setName("AnArg");            // Give it a nice symbolic name for fun.
> > >>>
> > >>>    SetCondInst* CondInst
> > >>>      = new SetCondInst( Instruction::SetLE,
> > >>>			 &ArgX, Two );
> > >>>
> > >>>    BB->getInstList().push_back(CondInst);
> > >>>
> > >>>    // Create the true_block
> > >>>    BasicBlock* true_bb = new BasicBlock("arg<=2");
> > >>>
> > >>>
> > >>>    // Create the return instruction and add it
> > >>>    // to the basic block for true case:
> > >>>    true_bb->getInstList().push_back(new ReturnInst(One));
> > >>>
> > >>>    // Create an exit block
> > >>>    BasicBlock* exit_bb = new BasicBlock("arg>2");
> > >>>
> > >>>    {
> > >>>
> > >>>      // create fib(x-1)
> > >>>      CallInst* CallFibX1;
> > >>>      {
> > >>>	// Create the sub instruction... does not insert...
> > >>>	Instruction *Sub
> > >>>	  = BinaryOperator::create(Instruction::Sub, &ArgX, One,
> > >>>						"arg");
> > >>>
> > >>>	exit_bb->getInstList().push_back(Sub);
> > >>>
> > >>>	CallFibX1 = new CallInst(FibF, Sub, "fib(x-1)");
> > >>>	exit_bb->getInstList().push_back(CallFibX1);
> > >>>
> > >>>      }
> > >>>
> > >>>      // create fib(x-2)
> > >>>      CallInst* CallFibX2;
> > >>>      {
> > >>>	// Create the sub instruction... does not insert...
> > >>>	Instruction * Sub
> > >>>	  = BinaryOperator::create(Instruction::Sub, &ArgX, Two,
> > >>>						"arg");
> > >>>
> > >>>	exit_bb->getInstList().push_back(Sub);
> > >>>	CallFibX2 = new CallInst(FibF, Sub, "fib(x-2)");
> > >>>	exit_bb->getInstList().push_back(CallFibX2);
> > >>>
> > >>>      }
> > >>>
> > >>>      // Create the add instruction... does not insert...
> > >>>      Instruction *Add =
> > >>>	BinaryOperator::create(Instruction::Add,
> > >>>			       CallFibX1, CallFibX2, "addresult");
> > >>>
> > >>>      // explicitly insert it into the basic block...
> > >>>      exit_bb->getInstList().push_back(Add);
> > >>>
> > >>>      // Create the return instruction and add it to the basic block
> > >>>      exit_bb->getInstList().push_back(new ReturnInst(Add));
> > >>>    }
> > >>>
> > >>>    // Create a branch on the SetCond
> > >>>    BranchInst* br_inst =
> > >>>      new BranchInst( true_bb, exit_bb, CondInst );
> > >>>
> > >>>    BB->getInstList().push_back( br_inst );
> > >>>    FibF->getBasicBlockList().push_back(true_bb);
> > >>>    FibF->getBasicBlockList().push_back(exit_bb);
> > >>>  }
> > >>>
> > >>>  // Now we going to create JIT
> > >>>  ExistingModuleProvider* MP = new ExistingModuleProvider(M);
> > >>>  ExecutionEngine* EE = ExecutionEngine::create( MP, false );
> > >>>
> > >>>  // Call the `foo' function with argument n:
> > >>>  std::vector<GenericValue> args(1);
> > >>>  args[0].IntVal = n;
> > >>>
> > >>>
> > >>>  std::clog << "verifying... ";
> > >>>  if (verifyModule(*M)) {
> > >>>    std::cerr << argv[0]
> > >>>	      << ": assembly parsed, but does not verify as correct!\n";
> > >>>    return 1;
> > >>>  }
> > >>>  else
> > >>>    std::clog << "OK\n";
> > >>>
> > >>>
> > >>>  std::clog << "We just constructed this LLVM module:\n\n---------\n" << *M;
> > >>>  std::clog << "---------\nstarting fibonacci("
> > >>>	    << n << ") with JIT...\n" << std::flush;
> > >>>
> > >>>  GenericValue gv = EE->runFunction(FibF, args);
> > >>>
> > >>>  // import result of execution:
> > >>>  std::cout << "Result: " << gv.IntVal << std:: endl;
> > >>>
> > >>>  return 0;
> > >>>}
> > >>>
> > >>>
> > >>>------------------------------------------------------------------------
> > >>>
> > >>>_______________________________________________
> > >>>LLVM Developers mailing list
> > >>>LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> > >>>http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
> > >>
> > >>_______________________________________________
> > >>LLVM Developers mailing list
> > >>LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> > >>http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
> > >>
> > >
> > >
> > > -Chris
> > >
> >
> > _______________________________________________
> > LLVM Developers mailing list
> > LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> > http://mail.cs.uiuc.edu/mailman/listinfo/llvmdev
> >
> 
> -Chris
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20040817/d6c693fc/attachment.sig>


More information about the llvm-dev mailing list