[LLVMdev] JIT API example (fibonacci)
Chris Lattner
sabre at nondot.org
Tue Aug 17 19:52:42 PDT 2004
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
--
http://llvm.org/
http://nondot.org/sabre/
More information about the llvm-dev
mailing list