Skip to content
Arindam Nandi edited this page Oct 9, 2015 · 2 revisions
#include "llvm/ADT/ArrayRef.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/IRBuilder.h"

#include "iostream"

#define SIZE 5

using namespace llvm;
using namespace std;

int main(){

    LLVMContext &context = getGlobalContext();
    Module *module = new Module("looper", context);
    IRBuilder<> builder(context);
    Type *intType = Type::getInt32Ty(context);

    // Globals
//    uint32_t arr[SIZE];
//    for(uint32_t i=0; i<SIZE; i++) {
//        arr[i] = i*10;
//    }
//    ArrayRef<uint32_t> arrayRef(arr);
//    Constant *conArray = ConstantDataArray::get(context, arrayRef);

    // Main - This should be main, otherwise it cannot be run by lli
    FunctionType *mainType = FunctionType::get(builder.getInt32Ty(), false);
    Function *mainFunc = Function::Create(mainType, Function::ExternalLinkage, "main", module);

    // Declare printf
    std::vector<Type *> printfArgsTypes({Type::getInt8PtrTy(context)});
    FunctionType *printfType = FunctionType::get(builder.getInt32Ty(), printfArgsTypes, true);
    Constant *printfFunc = module->getOrInsertFunction("printf", printfType);
    Constant *conArray = module->getOrInsertGlobal("array", ArrayType::get(intType, 5));

    // entry block
    BasicBlock *entry = BasicBlock::Create(context, "entry", mainFunc);
    builder.SetInsertPoint(entry);

    Value *str = builder.CreateGlobalStringPtr("%d\n", "str");

    Value *loopVar = builder.CreateAlloca(intType);
    builder.CreateStore(ConstantInt::get(intType, 0), loopVar);

    BasicBlock *LoopBB = BasicBlock::Create(getGlobalContext(), "loop", mainFunc);
    builder.CreateBr(LoopBB);
    builder.SetInsertPoint(LoopBB);

    // loop block
    Value *i = builder.CreateLoad(loopVar);

    Value* indices[2];
    indices[0] = ConstantInt::get(intType, 0);
    indices[1] = i;
    ArrayRef<Value *> indicesRef(indices);

    Value *v = builder.CreateLoad(builder.CreateGEP(conArray, indicesRef, "arr"));

    std::vector<Value *> argsV({str, v});
    Value* call = builder.CreateCall(printfFunc, argsV, "calltmp");

    Value *iplusplus = builder.CreateAdd(builder.CreateLoad(loopVar), ConstantInt::get(intType, 1));
    builder.CreateStore(iplusplus, loopVar);
    Value *SltE = builder.CreateICmpULT(builder.CreateLoad(loopVar), ConstantInt::get(intType, SIZE));
    BasicBlock *AfterBB =
         BasicBlock::Create(getGlobalContext(), "afterloop", mainFunc);

    builder.CreateCondBr(SltE, LoopBB, AfterBB);


    // after block
    builder.SetInsertPoint(AfterBB);
    builder.CreateRet(ConstantInt::get(intType, 0));

    module->dump();
}

Clone this wiki locally