X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=examples%2FBrainF%2FBrainF.cpp;h=d8c54b50b854902cd78f7e3b35a6c8e6468f22c0;hp=e7e11aca0b11baa2f7c0d18f7e80cdc6e038cef7;hb=HEAD;hpb=bef8e0b0a7afe602ddf09165ff4dbb8fa5f696a9 diff --git a/examples/BrainF/BrainF.cpp b/examples/BrainF/BrainF.cpp index e7e11aca0b1..d8c54b50b85 100644 --- a/examples/BrainF/BrainF.cpp +++ b/examples/BrainF/BrainF.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Sterling Stein and is distributed under the -// University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===--------------------------------------------------------------------===// // @@ -24,8 +24,11 @@ //===--------------------------------------------------------------------===// #include "BrainF.h" -#include "llvm/Constants.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Intrinsics.h" +#include using namespace llvm; @@ -35,117 +38,120 @@ const char *BrainF::headreg = "head"; const char *BrainF::label = "brainf"; const char *BrainF::testreg = "test"; -Module *BrainF::parse(std::istream *in1, int mem, CompileFlags cf) { +Module *BrainF::parse(std::istream *in1, int mem, CompileFlags cf, + LLVMContext& Context) { in = in1; memtotal = mem; comflag = cf; - header(); - readloop(0, 0, 0); + header(Context); + readloop(nullptr, nullptr, nullptr, Context); delete builder; return module; } -void BrainF::header() { - module = new Module("BrainF"); +void BrainF::header(LLVMContext& C) { + module = new Module("BrainF", C); //Function prototypes - //declare void @llvm.memset.i32(i8 *, i8, i32, i32) - Function *memset_func = cast(module-> - getOrInsertFunction("llvm.memset.i32", Type::VoidTy, - PointerType::get(IntegerType::Int8Ty), - IntegerType::Int8Ty, IntegerType::Int32Ty, - IntegerType::Int32Ty, NULL)); + //declare void @llvm.memset.p0i8.i32(i8 *, i8, i32, i32, i1) + Type *Tys[] = { Type::getInt8PtrTy(C), Type::getInt32Ty(C) }; + Function *memset_func = Intrinsic::getDeclaration(module, Intrinsic::memset, + Tys); //declare i32 @getchar() getchar_func = cast(module-> - getOrInsertFunction("getchar", IntegerType::Int32Ty, NULL)); + getOrInsertFunction("getchar", IntegerType::getInt32Ty(C), NULL)); //declare i32 @putchar(i32) putchar_func = cast(module-> - getOrInsertFunction("putchar", IntegerType::Int32Ty, - IntegerType::Int32Ty, NULL)); - + getOrInsertFunction("putchar", IntegerType::getInt32Ty(C), + IntegerType::getInt32Ty(C), NULL)); //Function header //define void @brainf() brainf_func = cast(module-> - getOrInsertFunction("brainf", Type::VoidTy, NULL)); + getOrInsertFunction("brainf", Type::getVoidTy(C), NULL)); - builder = new LLVMBuilder(new BasicBlock(label, brainf_func)); + builder = new IRBuilder<>(BasicBlock::Create(C, label, brainf_func)); //%arr = malloc i8, i32 %d - ConstantInt *val_mem = ConstantInt::get(APInt(32, memtotal)); - ptr_arr = builder->CreateMalloc(IntegerType::Int8Ty, val_mem, "arr"); - - //call void @llvm.memset.i32(i8 *%arr, i8 0, i32 %d, i32 1) + ConstantInt *val_mem = ConstantInt::get(C, APInt(32, memtotal)); + BasicBlock* BB = builder->GetInsertBlock(); + Type* IntPtrTy = IntegerType::getInt32Ty(C); + Type* Int8Ty = IntegerType::getInt8Ty(C); + Constant* allocsize = ConstantExpr::getSizeOf(Int8Ty); + allocsize = ConstantExpr::getTruncOrBitCast(allocsize, IntPtrTy); + ptr_arr = CallInst::CreateMalloc(BB, IntPtrTy, Int8Ty, allocsize, val_mem, + nullptr, "arr"); + BB->getInstList().push_back(cast(ptr_arr)); + + //call void @llvm.memset.p0i8.i32(i8 *%arr, i8 0, i32 %d, i32 1, i1 0) { Value *memset_params[] = { ptr_arr, - ConstantInt::get(APInt(8, 0)), + ConstantInt::get(C, APInt(8, 0)), val_mem, - ConstantInt::get(APInt(32, 1)) + ConstantInt::get(C, APInt(32, 1)), + ConstantInt::get(C, APInt(1, 0)) }; CallInst *memset_call = builder-> - CreateCall(memset_func, memset_params, array_endof(memset_params)); + CreateCall(memset_func, memset_params); memset_call->setTailCall(false); } //%arrmax = getelementptr i8 *%arr, i32 %d if (comflag & flag_arraybounds) { ptr_arrmax = builder-> - CreateGEP(ptr_arr, ConstantInt::get(APInt(32, memtotal)), "arrmax"); + CreateGEP(ptr_arr, ConstantInt::get(C, APInt(32, memtotal)), "arrmax"); } //%head.%d = getelementptr i8 *%arr, i32 %d curhead = builder->CreateGEP(ptr_arr, - ConstantInt::get(APInt(32, memtotal/2)), + ConstantInt::get(C, APInt(32, memtotal/2)), headreg); - - //Function footer //brainf.end: - endbb = new BasicBlock(label, brainf_func); + endbb = BasicBlock::Create(C, label, brainf_func); - //free i8 *%arr - new FreeInst(ptr_arr, endbb); + //call free(i8 *%arr) + endbb->getInstList().push_back(CallInst::CreateFree(ptr_arr, endbb)); //ret void - new ReturnInst(endbb); - - + ReturnInst::Create(C, endbb); //Error block for array out of bounds if (comflag & flag_arraybounds) { //@aberrormsg = internal constant [%d x i8] c"\00" - Constant *msg_0 = ConstantArray:: - get("Error: The head has left the tape.", true); + Constant *msg_0 = + ConstantDataArray::getString(C, "Error: The head has left the tape.", + true); GlobalVariable *aberrormsg = new GlobalVariable( + *module, msg_0->getType(), true, GlobalValue::InternalLinkage, msg_0, - "aberrormsg", - module); + "aberrormsg"); //declare i32 @puts(i8 *) Function *puts_func = cast(module-> - getOrInsertFunction("puts", IntegerType::Int32Ty, - PointerType::get(IntegerType::Int8Ty), NULL)); + getOrInsertFunction("puts", IntegerType::getInt32Ty(C), + PointerType::getUnqual(IntegerType::getInt8Ty(C)), NULL)); //brainf.aberror: - aberrorbb = new BasicBlock(label, brainf_func); + aberrorbb = BasicBlock::Create(C, label, brainf_func); //call i32 @puts(i8 *getelementptr([%d x i8] *@aberrormsg, i32 0, i32 0)) { - Constant *zero_32 = Constant::getNullValue(IntegerType::Int32Ty); + Constant *zero_32 = Constant::getNullValue(IntegerType::getInt32Ty(C)); Constant *gep_params[] = { zero_32, @@ -153,26 +159,26 @@ void BrainF::header() { }; Constant *msgptr = ConstantExpr:: - getGetElementPtr(aberrormsg, gep_params, - array_lengthof(gep_params)); + getGetElementPtr(aberrormsg->getValueType(), aberrormsg, gep_params); Value *puts_params[] = { msgptr }; CallInst *puts_call = - new CallInst(puts_func, - puts_params, array_endof(puts_params), - "", aberrorbb); + CallInst::Create(puts_func, + puts_params, + "", aberrorbb); puts_call->setTailCall(false); } //br label %brainf.end - new BranchInst(endbb, aberrorbb); + BranchInst::Create(endbb, aberrorbb); } } -void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) { +void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb, + LLVMContext &C) { Symbol cursym = SYM_NONE; int curvalue = 0; Symbol nextsym = SYM_NONE; @@ -191,13 +197,14 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) { case SYM_READ: { //%tape.%d = call i32 @getchar() - CallInst *getchar_call = builder->CreateCall(getchar_func, tapereg); + CallInst *getchar_call = + builder->CreateCall(getchar_func, {}, tapereg); getchar_call->setTailCall(false); Value *tape_0 = getchar_call; //%tape.%d = trunc i32 %tape.%d to i8 - TruncInst *tape_1 = builder-> - CreateTrunc(tape_0, IntegerType::Int8Ty, tapereg); + Value *tape_1 = builder-> + CreateTrunc(tape_0, IntegerType::getInt8Ty(C), tapereg); //store i8 %tape.%d, i8 *%head.%d builder->CreateStore(tape_1, curhead); @@ -210,8 +217,8 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) { LoadInst *tape_0 = builder->CreateLoad(curhead, tapereg); //%tape.%d = sext i8 %tape.%d to i32 - SExtInst *tape_1 = builder-> - CreateSExt(tape_0, IntegerType::Int32Ty, tapereg); + Value *tape_1 = builder-> + CreateSExt(tape_0, IntegerType::getInt32Ty(C), tapereg); //call i32 @putchar(i32 %tape.%d) Value *putchar_params[] = { @@ -219,7 +226,7 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) { }; CallInst *putchar_call = builder-> CreateCall(putchar_func, - putchar_params, array_endof(putchar_params)); + putchar_params); putchar_call->setTailCall(false); } break; @@ -228,26 +235,26 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) { { //%head.%d = getelementptr i8 *%head.%d, i32 %d curhead = builder-> - CreateGEP(curhead, ConstantInt::get(APInt(32, curvalue)), + CreateGEP(curhead, ConstantInt::get(C, APInt(32, curvalue)), headreg); //Error block for array out of bounds if (comflag & flag_arraybounds) { //%test.%d = icmp uge i8 *%head.%d, %arrmax - ICmpInst *test_0 = builder-> + Value *test_0 = builder-> CreateICmpUGE(curhead, ptr_arrmax, testreg); //%test.%d = icmp ult i8 *%head.%d, %arr - ICmpInst *test_1 = builder-> + Value *test_1 = builder-> CreateICmpULT(curhead, ptr_arr, testreg); //%test.%d = or i1 %test.%d, %test.%d - BinaryOperator *test_2 = builder-> + Value *test_2 = builder-> CreateOr(test_0, test_1, testreg); //br i1 %test.%d, label %main.%d, label %main.%d - BasicBlock *nextbb = new BasicBlock(label, brainf_func); + BasicBlock *nextbb = BasicBlock::Create(C, label, brainf_func); builder->CreateCondBr(test_2, aberrorbb, nextbb); //main.%d: @@ -262,8 +269,8 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) { LoadInst *tape_0 = builder->CreateLoad(curhead, tapereg); //%tape.%d = add i8 %tape.%d, %d - BinaryOperator *tape_1 = builder-> - CreateAdd(tape_0, ConstantInt::get(APInt(8, curvalue)), tapereg); + Value *tape_1 = builder-> + CreateAdd(tape_0, ConstantInt::get(C, APInt(8, curvalue)), tapereg); //store i8 %tape.%d, i8 *%head.%d\n" builder->CreateStore(tape_1, curhead); @@ -273,27 +280,27 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) { case SYM_LOOP: { //br label %main.%d - BasicBlock *testbb = new BasicBlock(label, brainf_func); + BasicBlock *testbb = BasicBlock::Create(C, label, brainf_func); builder->CreateBr(testbb); //main.%d: BasicBlock *bb_0 = builder->GetInsertBlock(); - BasicBlock *bb_1 = new BasicBlock(label, brainf_func); + BasicBlock *bb_1 = BasicBlock::Create(C, label, brainf_func); builder->SetInsertPoint(bb_1); - //Make part of PHI instruction now, wait until end of loop to finish - PHINode *phi_0 = new PHINode(PointerType::get(IntegerType::Int8Ty), - headreg, testbb); - phi_0->reserveOperandSpace(2); + // Make part of PHI instruction now, wait until end of loop to finish + PHINode *phi_0 = + PHINode::Create(PointerType::getUnqual(IntegerType::getInt8Ty(C)), + 2, headreg, testbb); phi_0->addIncoming(curhead, bb_0); curhead = phi_0; - readloop(phi_0, bb_1, testbb); + readloop(phi_0, bb_1, testbb, C); } break; default: - cerr<<"Error: Unknown symbol.\n"; + std::cerr << "Error: Unknown symbol.\n"; abort(); break; } @@ -406,7 +413,7 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) { if (cursym == SYM_ENDLOOP) { if (!phi) { - cerr<<"Error: Extra ']'\n"; + std::cerr << "Error: Extra ']'\n"; abort(); } @@ -426,21 +433,20 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) { LoadInst *tape_0 = new LoadInst(head_0, tapereg, testbb); //%test.%d = icmp eq i8 %tape.%d, 0 - ICmpInst *test_0 = new ICmpInst(ICmpInst::ICMP_EQ, tape_0, - ConstantInt::get(APInt(8, 0)), testreg, - testbb); + ICmpInst *test_0 = new ICmpInst(*testbb, ICmpInst::ICMP_EQ, tape_0, + ConstantInt::get(C, APInt(8, 0)), testreg); //br i1 %test.%d, label %main.%d, label %main.%d - BasicBlock *bb_0 = new BasicBlock(label, brainf_func); - new BranchInst(bb_0, oldbb, test_0, testbb); + BasicBlock *bb_0 = BasicBlock::Create(C, label, brainf_func); + BranchInst::Create(bb_0, oldbb, test_0, testbb); //main.%d: builder->SetInsertPoint(bb_0); //%head.%d = phi i8 *[%head.%d, %main.%d] PHINode *phi_1 = builder-> - CreatePHI(PointerType::get(IntegerType::Int8Ty), headreg); - phi_1->reserveOperandSpace(1); + CreatePHI(PointerType::getUnqual(IntegerType::getInt8Ty(C)), 1, + headreg); phi_1->addIncoming(head_0, testbb); curhead = phi_1; } @@ -452,7 +458,7 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) { builder->CreateBr(endbb); if (phi) { - cerr<<"Error: Missing ']'\n"; + std::cerr << "Error: Missing ']'\n"; abort(); } }