llvm/examples/BrainF: Give an explicit pointee type to ConstantExpr::getGetElementPtr...
[oota-llvm.git] / examples / BrainF / BrainF.cpp
index a79c44ef0f0ac529432ce8d064d5362ff32a63ad..81c48b9ef8a8afddc8cee970ef72276bfbd9253b 100644 (file)
 //===--------------------------------------------------------------------===//
 
 #include "BrainF.h"
-#include "llvm/Constants.h"
-#include "llvm/Intrinsics.h"
 #include "llvm/ADT/STLExtras.h"
-
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Intrinsics.h"
+#include <iostream>
 using namespace llvm;
 
 //Set the constants for naming
@@ -36,70 +37,81 @@ 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(0, 0, 0, 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 = Intrinsic::getDeclaration(module, Intrinsic::memset_i32);
+  //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<Function>(module->
-    getOrInsertFunction("getchar", IntegerType::Int32Ty, NULL));
+    getOrInsertFunction("getchar", IntegerType::getInt32Ty(C), NULL));
 
   //declare i32 @putchar(i32)
   putchar_func = cast<Function>(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<Function>(module->
-    getOrInsertFunction("brainf", Type::VoidTy, NULL));
+    getOrInsertFunction("brainf", Type::getVoidTy(C), NULL));
 
-  builder = new IRBuilder(BasicBlock::Create(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, 
+                                   NULL, "arr");
+  BB->getInstList().push_back(cast<Instruction>(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);
 
 
@@ -107,13 +119,13 @@ void BrainF::header() {
   //Function footer
 
   //brainf.end:
-  endbb = BasicBlock::Create(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
-  ReturnInst::Create(endbb);
+  ReturnInst::Create(C, endbb);
 
 
 
@@ -121,28 +133,29 @@ void BrainF::header() {
   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<Function>(module->
-      getOrInsertFunction("puts", IntegerType::Int32Ty,
-                          PointerType::getUnqual(IntegerType::Int8Ty), NULL));
+      getOrInsertFunction("puts", IntegerType::getInt32Ty(C),
+                      PointerType::getUnqual(IntegerType::getInt8Ty(C)), NULL));
 
     //brainf.aberror:
-    aberrorbb = BasicBlock::Create(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,
@@ -150,8 +163,7 @@ void BrainF::header() {
       };
 
       Constant *msgptr = ConstantExpr::
-        getGetElementPtr(aberrormsg, gep_params,
-                         array_lengthof(gep_params));
+        getGetElementPtr(aberrormsg->getValueType(), aberrormsg, gep_params);
 
       Value *puts_params[] = {
         msgptr
@@ -159,7 +171,7 @@ void BrainF::header() {
 
       CallInst *puts_call =
         CallInst::Create(puts_func,
-                         puts_params, array_endof(puts_params),
+                         puts_params,
                          "", aberrorbb);
       puts_call->setTailCall(false);
     }
@@ -169,7 +181,8 @@ void BrainF::header() {
   }
 }
 
-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;
@@ -194,7 +207,7 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) {
 
           //%tape.%d = trunc i32 %tape.%d to i8
           Value *tape_1 = builder->
-            CreateTrunc(tape_0, IntegerType::Int8Ty, tapereg);
+            CreateTrunc(tape_0, IntegerType::getInt8Ty(C), tapereg);
 
           //store i8 %tape.%d, i8 *%head.%d
           builder->CreateStore(tape_1, curhead);
@@ -208,7 +221,7 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) {
 
           //%tape.%d = sext i8 %tape.%d to i32
           Value *tape_1 = builder->
-            CreateSExt(tape_0, IntegerType::Int32Ty, tapereg);
+            CreateSExt(tape_0, IntegerType::getInt32Ty(C), tapereg);
 
           //call i32 @putchar(i32 %tape.%d)
           Value *putchar_params[] = {
@@ -216,7 +229,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;
@@ -225,7 +238,7 @@ 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
@@ -244,7 +257,7 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) {
               CreateOr(test_0, test_1, testreg);
 
             //br i1 %test.%d, label %main.%d, label %main.%d
-            BasicBlock *nextbb = BasicBlock::Create(label, brainf_func);
+            BasicBlock *nextbb = BasicBlock::Create(C, label, brainf_func);
             builder->CreateCondBr(test_2, aberrorbb, nextbb);
 
             //main.%d:
@@ -260,7 +273,7 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) {
 
           //%tape.%d = add i8 %tape.%d, %d
           Value *tape_1 = builder->
-            CreateAdd(tape_0, ConstantInt::get(APInt(8, curvalue)), tapereg);
+            CreateAdd(tape_0, ConstantInt::get(C, APInt(8, curvalue)), tapereg);
 
           //store i8 %tape.%d, i8 *%head.%d\n"
           builder->CreateStore(tape_1, curhead);
@@ -270,28 +283,27 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) {
       case SYM_LOOP:
         {
           //br label %main.%d
-          BasicBlock *testbb = BasicBlock::Create(label, brainf_func);
+          BasicBlock *testbb = BasicBlock::Create(C, label, brainf_func);
           builder->CreateBr(testbb);
 
           //main.%d:
           BasicBlock *bb_0 = builder->GetInsertBlock();
-          BasicBlock *bb_1 = BasicBlock::Create(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 =
-            PHINode::Create(PointerType::getUnqual(IntegerType::Int8Ty),
-                            headreg, testbb);
-          phi_0->reserveOperandSpace(2);
+            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;
     }
@@ -404,7 +416,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();
     }
 
@@ -424,12 +436,11 @@ 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 = BasicBlock::Create(label, brainf_func);
+      BasicBlock *bb_0 = BasicBlock::Create(C, label, brainf_func);
       BranchInst::Create(bb_0, oldbb, test_0, testbb);
 
       //main.%d:
@@ -437,8 +448,8 @@ void BrainF::readloop(PHINode *phi, BasicBlock *oldbb, BasicBlock *testbb) {
 
       //%head.%d = phi i8 *[%head.%d, %main.%d]
       PHINode *phi_1 = builder->
-        CreatePHI(PointerType::getUnqual(IntegerType::Int8Ty), headreg);
-      phi_1->reserveOperandSpace(1);
+        CreatePHI(PointerType::getUnqual(IntegerType::getInt8Ty(C)), 1,
+                  headreg);
       phi_1->addIncoming(head_0, testbb);
       curhead = phi_1;
     }
@@ -450,7 +461,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();
   }
 }