summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-11-03 21:43:03 +0000
committerChris Lattner <sabre@nondot.org>2004-11-03 21:43:03 +0000
commit38f024daea1f27b6a8b610e3f8d21596f3e928d8 (patch)
treea94f92326d366ed0707b9296789f77351f21e890
parent82962de3b92c1df483430e5b03804a56c8c652dd (diff)
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
-rw-r--r--examples/Fibonacci/fibonacci.cpp223
1 files changed, 76 insertions, 147 deletions
diff --git a/examples/Fibonacci/fibonacci.cpp b/examples/Fibonacci/fibonacci.cpp
index f34aed762a2..43c73bad599 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 <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/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 <iostream>
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);
+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<GenericValue> 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<GenericValue> Args(1);
+ args[0].IntVal = n;
+ GenericValue GV = EE->runFunction(FibF, Args);
+ // import result of execution
+ std::cout << "Result: " << GV.IntVal << "\n";
return 0;
}