Merging r258436:
[oota-llvm.git] / examples / BrainF / BrainF.cpp
index a92079364860d27c2f3abb404e2bf683ac9f2a66..d8c54b50b854902cd78f7e3b35a6c8e6468f22c0 100644 (file)
 //===--------------------------------------------------------------------===//
 
 #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 <iostream>
 
 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<Function>(module->
-    getOrInsertFunction("llvm.memset.i32", Type::VoidTy,
-                        PointerType::getUnqual(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<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 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<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);
 
-
-
   //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<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 = 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::getUnqual(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::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;
     }
@@ -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();
   }
 }