From 38f024daea1f27b6a8b610e3f8d21596f3e928d8 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 3 Nov 2004 21:43:03 +0000 Subject: Cleanup this example, simplifying it and making it conform to LLVM coding standards git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17459 91177308-0d34-0410-b5e6-96231b3b80d8 --- examples/Fibonacci/fibonacci.cpp | 223 +++++++++++++-------------------------- 1 file changed, 76 insertions(+), 147 deletions(-) (limited to 'examples') diff --git a/examples/Fibonacci/fibonacci.cpp b/examples/Fibonacci/fibonacci.cpp index f34aed762a..43c73bad59 100644 --- a/examples/Fibonacci/fibonacci.cpp +++ b/examples/Fibonacci/fibonacci.cpp @@ -7,182 +7,111 @@ // //===----------------------------------------------------------------------===// // -// This small program provides an example of how to build quickly a small -// module with function Fibonacci and execute it with the JIT. +// 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+ . +// The goal of this snippet is to create in the memory the LLVM module +// consisting of one function as follow: // -// (Modified from HowToUseJIT.cpp and Stacker/lib/compiler/StackerCompiler.cpp) +// int fib(int x) { +// if(x<=2) return 1; +// return fib(x-1)+fib(x-2); +// } // -//===------------------------------------------------------------------------=== -// 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' +// Once we have this, we compile the module via JIT, then execute the `fib' // function and return result to a driver, i.e. to a "host program". // +//===----------------------------------------------------------------------===// -#include - -#include -#include -#include -#include -#include -#include +#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" - - +#include 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 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); +static Function *CreateFibFunction(Module *M) { + // Create the fib function and insert it into module M. This function is said + // to return an int and take an int parameter. + Function *FibF = M->getOrInsertFunction("fib", Type::IntTy, Type::IntTy, 0); - // 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. + // Add a basic block to the function. + BasicBlock *BB = new BasicBlock("EntryBlock", FibF); + + // Get pointers to the constants. + Value *One = ConstantSInt::get(Type::IntTy, 1); + Value *Two = ConstantSInt::get(Type::IntTy, 2); - SetCondInst* CondInst - = new SetCondInst( Instruction::SetLE, - &ArgX, Two ); + // Get pointer to the integer argument of the add1 function... + Argument *ArgX = FibF->abegin(); // Get the arg. + ArgX->setName("AnArg"); // Give it a nice symbolic name for fun. - BB->getInstList().push_back(CondInst); - // Create the true_block - BasicBlock* true_bb = new BasicBlock("arg<=2"); + // Create the true_block. + BasicBlock *RetBB = new BasicBlock("return", FibF); + // Create an exit block. + BasicBlock* RecurseBB = new BasicBlock("recurse", FibF); + // Create the "if (arg < 2) goto exitbb" + Value *CondInst = BinaryOperator::createSetLE(ArgX, Two, "cond", BB); + new BranchInst(RetBB, RecurseBB, CondInst, BB); - // 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"); + // Create: ret int 1 + new ReturnInst(One, RetBB); + + // create fib(x-1) + Value *Sub = BinaryOperator::createSub(ArgX, One, "arg", RecurseBB); + Value *CallFibX1 = new CallInst(FibF, Sub, "fibx1", RecurseBB); - // explicitly insert it into the basic block... - exit_bb->getInstList().push_back(Add); + // create fib(x-2) + Sub = BinaryOperator::createSub(ArgX, Two, "arg", RecurseBB); + Value *CallFibX2 = new CallInst(FibF, Sub, "fibx2", RecurseBB); + + // fib(x-1)+fib(x-2) + Value *Sum = BinaryOperator::createAdd(CallFibX1, CallFibX2, + "addresult", RecurseBB); - // Create the return instruction and add it to the basic block - exit_bb->getInstList().push_back(new ReturnInst(Add)); - } + // Create the return instruction and add it to the basic block + new ReturnInst(Sum, RecurseBB); - // Create a branch on the SetCond - BranchInst* br_inst = - new BranchInst( true_bb, exit_bb, CondInst ); + return FibF; +} - 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 ); +int main(int argc, char **argv) { + int n = argc > 1 ? atol(argv[1]) : 24; - // Call the `foo' function with argument n: - std::vector args(1); - args[0].IntVal = n; + // Create some module to put our function into it. + Module *M = new Module("test"); + + // We are about to create the "fib" function: + Function *FibF = CreateFibFunction(M); + // Now we going to create JIT + ExistingModuleProvider *MP = new ExistingModuleProvider(M); + ExecutionEngine *EE = ExecutionEngine::create(MP, false); - std::clog << "verifying... "; + std::cerr << "verifying... "; if (verifyModule(*M)) { - std::cerr << argv[0] - << ": assembly parsed, but does not verify as correct!\n"; + std::cerr << argv[0] << ": Error constructing function!\n"; return 1; } - else - std::clog << "OK\n"; + std::cerr << "OK\n"; + std::cerr << "We just constructed this LLVM module:\n\n---------\n" << *M; + std::cerr << "---------\nstarting fibonacci(" + << n << ") with JIT...\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; + // Call the `foo' function with argument n: + std::vector Args(1); + args[0].IntVal = n; + GenericValue GV = EE->runFunction(FibF, Args); + // import result of execution + std::cout << "Result: " << GV.IntVal << "\n"; return 0; } -- cgit v1.2.3