#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/JIT.h"
#include "llvm/ExecutionEngine/Interpreter.h"
#include "llvm/ExecutionEngine/GenericValue.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
static Function *CreateFibFunction(Module *M) {
Function *FibF =
cast<Function>(M->getOrInsertFunction("fib", Type::Int32Ty, Type::Int32Ty,
(Type *)0));
BasicBlock *BB = BasicBlock::Create("EntryBlock", FibF);
Value *One = ConstantInt::get(Type::Int32Ty, 1);
Value *Two = ConstantInt::get(Type::Int32Ty, 2);
Argument *ArgX = FibF->arg_begin(); ArgX->setName("AnArg");
BasicBlock *RetBB = BasicBlock::Create("return", FibF);
BasicBlock* RecurseBB = BasicBlock::Create("recurse", FibF);
Value *CondInst = new ICmpInst(ICmpInst::ICMP_SLE, ArgX, Two, "cond", BB);
BranchInst::Create(RetBB, RecurseBB, CondInst, BB);
ReturnInst::Create(One, RetBB);
Value *Sub = BinaryOperator::CreateSub(ArgX, One, "arg", RecurseBB);
CallInst *CallFibX1 = CallInst::Create(FibF, Sub, "fibx1", RecurseBB);
CallFibX1->setTailCall();
Sub = BinaryOperator::CreateSub(ArgX, Two, "arg", RecurseBB);
CallInst *CallFibX2 = CallInst::Create(FibF, Sub, "fibx2", RecurseBB);
CallFibX2->setTailCall();
Value *Sum = BinaryOperator::CreateAdd(CallFibX1, CallFibX2,
"addresult", RecurseBB);
ReturnInst::Create(Sum, RecurseBB);
return FibF;
}
int main(int argc, char **argv) {
int n = argc > 1 ? atol(argv[1]) : 24;
Module *M = new Module("test");
Function *FibF = CreateFibFunction(M);
ExistingModuleProvider *MP = new ExistingModuleProvider(M);
ExecutionEngine *EE = ExecutionEngine::create(MP, false);
errs() << "verifying... ";
if (verifyModule(*M)) {
errs() << argv[0] << ": Error constructing function!\n";
return 1;
}
errs() << "OK\n";
errs() << "We just constructed this LLVM module:\n\n---------\n" << *M;
errs() << "---------\nstarting fibonacci(" << n << ") with JIT...\n";
std::vector<GenericValue> Args(1);
Args[0].IntVal = APInt(32, n);
GenericValue GV = EE->runFunction(FibF, Args);
outs() << "Result: " << GV.IntVal << "\n";
return 0;
}