Add helpers for fetching basic types.
[oota-llvm.git] / include / llvm / Support / IRBuilder.h
index 835a28622f144d7e1c2501cc24f44e1736550a3c..549b89eda5255934304106b492be04388a3d0065 100644 (file)
@@ -48,7 +48,9 @@ public:
   IRBuilder(LLVMContext &C, const T& F) :
     Context(C), Folder(F) { ClearInsertionPoint(); }
   
-  IRBuilder(LLVMContext &C) : Context(C), Folder(C) { ClearInsertionPoint(); }
+  explicit IRBuilder(LLVMContext &C) : Context(C), Folder(C) {
+    ClearInsertionPoint();
+  }
   
   explicit IRBuilder(BasicBlock *TheBB, const T& F)
       : Context(TheBB->getContext()), Folder(F) {
@@ -121,20 +123,56 @@ public:
       I->setName(Name);
   }
 
+  //===--------------------------------------------------------------------===//
+  // Type creation methods
+  //===--------------------------------------------------------------------===//
+
+  const Type *getInt1Ty() {
+    return Type::getInt1Ty(Context);
+  }
+  
+  const Type *getInt8Ty() {
+    return Type::getInt8Ty(Context);
+  }
+  
+  const Type *getInt16Ty() {
+    return Type::getInt16Ty(Context);
+  }
+  
+  const Type *getInt32Ty() {
+    return Type::getInt32Ty(Context);
+  }
+  
+  const Type *getInt64Ty() {
+    return Type::getInt64Ty(Context);
+  }
+
+  const Type *getFloatTy() {
+    return Type::getFloatTy(Context);
+  }
+  
+  const Type *getDoubleTy() {
+    return Type::getDoubleTy(Context);
+  }
+  
+  const Type *getVoidTy() {
+    return Type::getVoidTy(Context);
+  }
+
   //===--------------------------------------------------------------------===//
   // Instruction creation methods: Terminators
   //===--------------------------------------------------------------------===//
 
   /// CreateRetVoid - Create a 'ret void' instruction.
   ReturnInst *CreateRetVoid() {
-    return Insert(ReturnInst::Create());
+    return Insert(ReturnInst::Create(getGlobalContext()));
   }
 
   /// @verbatim
   /// CreateRet - Create a 'ret <val>' instruction.
   /// @endverbatim
   ReturnInst *CreateRet(Value *V) {
-    return Insert(ReturnInst::Create(V));
+    return Insert(ReturnInst::Create(getGlobalContext(), V));
   }
 
   /// CreateAggregateRet - Create a sequence of N insertvalue instructions,
@@ -146,10 +184,10 @@ public:
   ///
   ReturnInst *CreateAggregateRet(Value * const* retVals, unsigned N) {
     const Type *RetType = BB->getParent()->getReturnType();
-    Value *V = Context.getUndef(RetType);
+    Value *V = UndefValue::get(RetType);
     for (unsigned i = 0; i != N; ++i)
       V = CreateInsertValue(V, retVals[i], i, "mrv");
-    return Insert(ReturnInst::Create(V));
+    return Insert(ReturnInst::Create(getGlobalContext(), V));
   }
 
   /// CreateBr - Create an unconditional 'br label X' instruction.
@@ -180,11 +218,11 @@ public:
   }
 
   UnwindInst *CreateUnwind() {
-    return Insert(new UnwindInst());
+    return Insert(new UnwindInst(Context));
   }
 
   UnreachableInst *CreateUnreachable() {
-    return Insert(new UnreachableInst());
+    return Insert(new UnreachableInst(Context));
   }
 
   //===--------------------------------------------------------------------===//
@@ -197,6 +235,12 @@ public:
         return Folder.CreateAdd(LC, RC);
     return Insert(BinaryOperator::CreateAdd(LHS, RHS), Name);
   }
+  Value *CreateNSWAdd(Value *LHS, Value *RHS, const char *Name = "") {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Folder.CreateNSWAdd(LC, RC);
+    return Insert(BinaryOperator::CreateNSWAdd(LHS, RHS), Name);
+  }
   Value *CreateFAdd(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
@@ -239,6 +283,12 @@ public:
         return Folder.CreateSDiv(LC, RC);
     return Insert(BinaryOperator::CreateSDiv(LHS, RHS), Name);
   }
+  Value *CreateExactSDiv(Value *LHS, Value *RHS, const char *Name = "") {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Folder.CreateExactSDiv(LC, RC);
+    return Insert(BinaryOperator::CreateExactSDiv(LHS, RHS), Name);
+  }
   Value *CreateFDiv(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
@@ -311,17 +361,17 @@ public:
   Value *CreateNeg(Value *V, const char *Name = "") {
     if (Constant *VC = dyn_cast<Constant>(V))
       return Folder.CreateNeg(VC);
-    return Insert(BinaryOperator::CreateNeg(Context, V), Name);
+    return Insert(BinaryOperator::CreateNeg(V), Name);
   }
   Value *CreateFNeg(Value *V, const char *Name = "") {
     if (Constant *VC = dyn_cast<Constant>(V))
       return Folder.CreateFNeg(VC);
-    return Insert(BinaryOperator::CreateFNeg(Context, V), Name);
+    return Insert(BinaryOperator::CreateFNeg(V), Name);
   }
   Value *CreateNot(Value *V, const char *Name = "") {
     if (Constant *VC = dyn_cast<Constant>(V))
       return Folder.CreateNot(VC);
-    return Insert(BinaryOperator::CreateNot(Context, V), Name);
+    return Insert(BinaryOperator::CreateNot(V), Name);
   }
 
   //===--------------------------------------------------------------------===//
@@ -354,34 +404,65 @@ public:
     if (Constant *PC = dyn_cast<Constant>(Ptr)) {
       // Every index must be constant.
       InputIterator i;
-      for (i = IdxBegin; i < IdxEnd; ++i) {
-        if (!dyn_cast<Constant>(*i))
+      for (i = IdxBegin; i < IdxEnd; ++i)
+        if (!isa<Constant>(*i))
           break;
-      }
       if (i == IdxEnd)
         return Folder.CreateGetElementPtr(PC, &IdxBegin[0], IdxEnd - IdxBegin);
     }
     return Insert(GetElementPtrInst::Create(Ptr, IdxBegin, IdxEnd), Name);
   }
+  template<typename InputIterator>
+  Value *CreateInBoundsGEP(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd,
+                           const char *Name = "") {
+    if (Constant *PC = dyn_cast<Constant>(Ptr)) {
+      // Every index must be constant.
+      InputIterator i;
+      for (i = IdxBegin; i < IdxEnd; ++i)
+        if (!isa<Constant>(*i))
+          break;
+      if (i == IdxEnd)
+        return Folder.CreateInBoundsGetElementPtr(PC,
+                                                  &IdxBegin[0],
+                                                  IdxEnd - IdxBegin);
+    }
+    return Insert(GetElementPtrInst::CreateInBounds(Ptr, IdxBegin, IdxEnd),
+                  Name);
+  }
   Value *CreateGEP(Value *Ptr, Value *Idx, const char *Name = "") {
     if (Constant *PC = dyn_cast<Constant>(Ptr))
       if (Constant *IC = dyn_cast<Constant>(Idx))
         return Folder.CreateGetElementPtr(PC, &IC, 1);
     return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
   }
+  Value *CreateInBoundsGEP(Value *Ptr, Value *Idx, const char *Name = "") {
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      if (Constant *IC = dyn_cast<Constant>(Idx))
+        return Folder.CreateInBoundsGetElementPtr(PC, &IC, 1);
+    return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idx), Name);
+  }
   Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const char *Name = "") {
-    Value *Idx = Context.getConstantInt(Type::Int32Ty, Idx0);
+    Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
 
     if (Constant *PC = dyn_cast<Constant>(Ptr))
       return Folder.CreateGetElementPtr(PC, &Idx, 1);
 
     return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name);    
   }
+  Value *CreateConstInBoundsGEP1_32(Value *Ptr, unsigned Idx0,
+                                    const char *Name = "") {
+    Value *Idx = ConstantInt::get(Type::getInt32Ty(Context), Idx0);
+
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      return Folder.CreateInBoundsGetElementPtr(PC, &Idx, 1);
+
+    return Insert(GetElementPtrInst::CreateInBounds(Ptr, &Idx, &Idx+1), Name);
+  }
   Value *CreateConstGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1, 
                     const char *Name = "") {
     Value *Idxs[] = {
-      Context.getConstantInt(Type::Int32Ty, Idx0),
-      Context.getConstantInt(Type::Int32Ty, Idx1)
+      ConstantInt::get(Type::getInt32Ty(Context), Idx0),
+      ConstantInt::get(Type::getInt32Ty(Context), Idx1)
     };
 
     if (Constant *PC = dyn_cast<Constant>(Ptr))
@@ -389,19 +470,40 @@ public:
 
     return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name);    
   }
+  Value *CreateConstInBoundsGEP2_32(Value *Ptr, unsigned Idx0, unsigned Idx1,
+                                    const char *Name = "") {
+    Value *Idxs[] = {
+      ConstantInt::get(Type::getInt32Ty(Context), Idx0),
+      ConstantInt::get(Type::getInt32Ty(Context), Idx1)
+    };
+
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      return Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2);
+
+    return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs, Idxs+2), Name);
+  }
   Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const char *Name = "") {
-    Value *Idx = Context.getConstantInt(Type::Int64Ty, Idx0);
+    Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
 
     if (Constant *PC = dyn_cast<Constant>(Ptr))
       return Folder.CreateGetElementPtr(PC, &Idx, 1);
 
     return Insert(GetElementPtrInst::Create(Ptr, &Idx, &Idx+1), Name);    
   }
-  Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1, 
+  Value *CreateConstInBoundsGEP1_64(Value *Ptr, uint64_t Idx0,
+                                    const char *Name = "") {
+    Value *Idx = ConstantInt::get(Type::getInt64Ty(Context), Idx0);
+
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      return Folder.CreateInBoundsGetElementPtr(PC, &Idx, 1);
+
+    return Insert(GetElementPtrInst::CreateInBounds(Ptr, &Idx, &Idx+1), Name);
+  }
+  Value *CreateConstGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
                     const char *Name = "") {
     Value *Idxs[] = {
-      Context.getConstantInt(Type::Int64Ty, Idx0),
-      Context.getConstantInt(Type::Int64Ty, Idx1)
+      ConstantInt::get(Type::getInt64Ty(Context), Idx0),
+      ConstantInt::get(Type::getInt64Ty(Context), Idx1)
     };
 
     if (Constant *PC = dyn_cast<Constant>(Ptr))
@@ -409,11 +511,23 @@ public:
 
     return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name);    
   }
+  Value *CreateConstInBoundsGEP2_64(Value *Ptr, uint64_t Idx0, uint64_t Idx1,
+                                    const char *Name = "") {
+    Value *Idxs[] = {
+      ConstantInt::get(Type::getInt64Ty(Context), Idx0),
+      ConstantInt::get(Type::getInt64Ty(Context), Idx1)
+    };
+
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      return Folder.CreateInBoundsGetElementPtr(PC, Idxs, 2);
+
+    return Insert(GetElementPtrInst::CreateInBounds(Ptr, Idxs, Idxs+2), Name);
+  }
   Value *CreateStructGEP(Value *Ptr, unsigned Idx, const char *Name = "") {
-    return CreateConstGEP2_32(Ptr, 0, Idx, Name);
+    return CreateConstInBoundsGEP2_32(Ptr, 0, Idx, Name);
   }
   Value *CreateGlobalString(const char *Str = "", const char *Name = "") {
-    Constant *StrConstant = Context.getConstantArray(Str, true);
+    Constant *StrConstant = ConstantArray::get(Context, Str, true);
     Module &M = *BB->getParent()->getParent();
     GlobalVariable *gv = new GlobalVariable(M,
                                             StrConstant->getType(),
@@ -428,9 +542,9 @@ public:
   }
   Value *CreateGlobalStringPtr(const char *Str = "", const char *Name = "") {
     Value *gv = CreateGlobalString(Str, Name);
-    Value *zero = Context.getConstantInt(Type::Int32Ty, 0);
+    Value *zero = ConstantInt::get(Type::getInt32Ty(Context), 0);
     Value *Args[] = { zero, zero };
-    return CreateGEP(gv, Args, Args+2, Name);
+    return CreateInBoundsGEP(gv, Args, Args+2, Name);
   }
   //===--------------------------------------------------------------------===//
   // Instruction creation methods: Cast/Conversion Operators
@@ -641,7 +755,7 @@ public:
     if (Constant *VC = dyn_cast<Constant>(Vec))
       if (Constant *IC = dyn_cast<Constant>(Idx))
         return Folder.CreateExtractElement(VC, IC);
-    return Insert(new ExtractElementInst(Vec, Idx), Name);
+    return Insert(ExtractElementInst::Create(Vec, Idx), Name);
   }
 
   Value *CreateInsertElement(Value *Vec, Value *NewElt, Value *Idx,
@@ -705,29 +819,31 @@ public:
 
   /// CreateIsNull - Return an i1 value testing if \arg Arg is null.
   Value *CreateIsNull(Value *Arg, const char *Name = "") {
-    return CreateICmpEQ(Arg, Context.getNullValue(Arg->getType()),
+    return CreateICmpEQ(Arg, Constant::getNullValue(Arg->getType()),
                         Name);
   }
 
   /// CreateIsNotNull - Return an i1 value testing if \arg Arg is not null.
   Value *CreateIsNotNull(Value *Arg, const char *Name = "") {
-    return CreateICmpNE(Arg, Context.getNullValue(Arg->getType()),
+    return CreateICmpNE(Arg, Constant::getNullValue(Arg->getType()),
                         Name);
   }
 
   /// CreatePtrDiff - Return the i64 difference between two pointer values,
   /// dividing out the size of the pointed-to objects.  This is intended to
-  /// implement C-style pointer subtraction.
+  /// implement C-style pointer subtraction. As such, the pointers must be
+  /// appropriately aligned for their element types and pointing into the
+  /// same object.
   Value *CreatePtrDiff(Value *LHS, Value *RHS, const char *Name = "") {
     assert(LHS->getType() == RHS->getType() &&
            "Pointer subtraction operand types must match!");
     const PointerType *ArgType = cast<PointerType>(LHS->getType());
-    Value *LHS_int = CreatePtrToInt(LHS, Type::Int64Ty);
-    Value *RHS_int = CreatePtrToInt(RHS, Type::Int64Ty);
+    Value *LHS_int = CreatePtrToInt(LHS, Type::getInt64Ty(Context));
+    Value *RHS_int = CreatePtrToInt(RHS, Type::getInt64Ty(Context));
     Value *Difference = CreateSub(LHS_int, RHS_int);
-    return CreateSDiv(Difference,
-                      Context.getConstantExprSizeOf(ArgType->getElementType()),
-                      Name);
+    return CreateExactSDiv(Difference,
+                           ConstantExpr::getSizeOf(ArgType->getElementType()),
+                           Name);
   }
 };