Skip to content

IrBuilder_LoopUsingAlloca.cpp

ladangol edited this page Oct 2, 2015 · 1 revision
#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Instructions.h"
#include<string>
#include<vector>
using namespace llvm;
static AllocaInst *CreateEntryBlockAlloca(llvm::Function *TheFunction,
                                            const std::string &VarName) {
      IRBuilder<> TmpB(&TheFunction->getEntryBlock(),
                       TheFunction->getEntryBlock().begin());
      return TmpB.CreateAlloca(Type::getInt32Ty(llvm::getGlobalContext()), 0,
                               VarName.c_str());
    }
int main(){
     int array[5]= {16,2,40,25,1};
     int loopStart =0, loopEnd = 5, loopStep =1;
     LLVMContext & context = getGlobalContext();
     Module *module = new Module("hello", context);
     IRBuilder<> builder(context);
     
     FunctionType *funcType = FunctionType::get(builder.getInt32Ty(), false);
     Function *mainFunc = Function::Create(funcType, Function::ExternalLinkage, "main", module);  //This should be main, otherwise it cannot be run by lli

     BasicBlock *entry = BasicBlock::Create(context, "enterypoint", mainFunc);
     builder.SetInsertPoint(entry);
    
     Value *str = builder.CreateGlobalStringPtr("%d");
     Value *startVal = ConstantInt::get(context, APInt(32,loopStart));
     Value *stepVal = ConstantInt::get(context, APInt(32,loopStep));
     Value *endVal = ConstantInt::get(context, APInt(32, loopEnd));
     std::vector<Value*> myvals;

     for(int i = 0; i<5; i++){
          myvals.push_back(ConstantInt::get(context, APInt(32, array[i])));
     }     

     //This is printing the first element of array 
     
     std::vector<Type *> printfArgs;
     printfArgs.push_back(builder.getInt8Ty()->getPointerTo());
     Value *myInt = ConstantInt::get(context, APInt(32, array[0]));
     printfArgs.push_back(myInt->getType());
     ArrayRef<Type*> argsRef(printfArgs);

     FunctionType *printfType = FunctionType::get(builder.getInt32Ty(), argsRef, false);
     Constant *printfFunc = module->getOrInsertFunction("printf", printfType);
     
     

     //starting Loop body
     Function *TheFunction = builder.GetInsertBlock()->getParent();
     AllocaInst *Alloca = CreateEntryBlockAlloca(TheFunction, "arrayVal");
     BasicBlock *PreheaderBB = builder.GetInsertBlock();
     BasicBlock *LoopBB =
     BasicBlock::Create(getGlobalContext(), "loop", TheFunction);
    
     builder.CreateBr(LoopBB);
     builder.SetInsertPoint(LoopBB);
     
     PHINode *Variable = builder.CreatePHI(Type::getInt32Ty(getGlobalContext()),
                                        2, "loopvar");
   
      
     
     builder.CreateStore(myvals.back(), Alloca);
     myvals.pop_back();

     std::vector<Value *> argsV;
     argsV.push_back(str);
     Value* myInt2 = builder.CreateLoad(Alloca, "arrayVal");
     argsV.push_back(myInt2);
     Value* ret=  builder.CreateCall(printfFunc, argsV, "calltmp");
       
     Variable->addIncoming(startVal, PreheaderBB);
     //Next
     Value *nextVal = builder.CreateAdd(Variable, stepVal, "nextval");
     
     Value *SltE = builder.CreateICmpULT(nextVal, endVal, "loopcond");
     BasicBlock *LoopEndBB = builder.GetInsertBlock();
     BasicBlock *AfterBB =
     BasicBlock::Create(getGlobalContext(), "afterloop", TheFunction);
     
     builder.CreateCondBr(SltE, LoopBB, AfterBB);
    

     // Any new code will be inserted in AfterBB.
     builder.SetInsertPoint(AfterBB);
     Variable->addIncoming(nextVal, LoopEndBB);
  

    builder.CreateRet(ret);    

     module->dump();
}

Clone this wiki locally