Move more code back to 2.5 APIs.
[oota-llvm.git] / include / llvm / Support / IRBuilder.h
index 1156825efb34590a0d2e7891076140c70afeba0a..223fe028e209376013a4f8a502c058ec765f2c8e 100644 (file)
 #ifndef LLVM_SUPPORT_IRBUILDER_H
 #define LLVM_SUPPORT_IRBUILDER_H
 
-#include "llvm/BasicBlock.h"
 #include "llvm/Constants.h"
 #include "llvm/Instructions.h"
+#include "llvm/GlobalAlias.h"
 #include "llvm/GlobalVariable.h"
 #include "llvm/Function.h"
+#include "llvm/LLVMContext.h"
 #include "llvm/Support/ConstantFolder.h"
 
 namespace llvm {
@@ -41,17 +42,41 @@ namespace llvm {
 template <bool preserveNames=true, typename T = ConstantFolder> class IRBuilder{
   BasicBlock *BB;
   BasicBlock::iterator InsertPt;
+  LLVMContext &Context;
   T Folder;
 public:
-  IRBuilder(const T& F = T()) : Folder(F) { ClearInsertionPoint(); }
-  explicit IRBuilder(BasicBlock *TheBB, const T& F = T())
-    : Folder(F) { SetInsertPoint(TheBB); }
-  IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F = T())
-    : Folder(F) { SetInsertPoint(TheBB, IP); }
+  IRBuilder(LLVMContext &C, const T& F) :
+    Context(C), Folder(F) { ClearInsertionPoint(); }
+  
+  IRBuilder(LLVMContext &C) : Context(C), Folder(C) { ClearInsertionPoint(); }
+  
+  explicit IRBuilder(BasicBlock *TheBB, const T& F)
+      : Context(TheBB->getContext()), Folder(F) {
+    SetInsertPoint(TheBB);
+  }
+  
+  explicit IRBuilder(BasicBlock *TheBB)
+      : Context(TheBB->getContext()), Folder(Context) {
+    SetInsertPoint(TheBB);
+  }
+  
+  IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP, const T& F)
+      : Context(TheBB->getContext()), Folder(F) {
+    SetInsertPoint(TheBB, IP);
+  }
+  
+  IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP)
+      : Context(TheBB->getContext()), Folder(Context) {
+    SetInsertPoint(TheBB, IP);
+  }
 
   /// getFolder - Get the constant folder being used.
   const T& getFolder() { return Folder; }
 
+  /// isNamePreserving - Return true if this builder is configured to actually
+  /// add the requested names to IR created through it.
+  bool isNamePreserving() const { return preserveNames; }
+  
   //===--------------------------------------------------------------------===//
   // Builder configuration methods
   //===--------------------------------------------------------------------===//
@@ -64,6 +89,8 @@ public:
 
   BasicBlock *GetInsertBlock() const { return BB; }
 
+  BasicBlock::iterator GetInsertPoint() const { return InsertPt; }
+
   /// SetInsertPoint - This specifies that created instructions should be
   /// appended to the end of the specified block.
   void SetInsertPoint(BasicBlock *TheBB) {
@@ -170,18 +197,36 @@ public:
         return Folder.CreateAdd(LC, RC);
     return Insert(BinaryOperator::CreateAdd(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))
+        return Folder.CreateFAdd(LC, RC);
+    return Insert(BinaryOperator::CreateFAdd(LHS, RHS), Name);
+  }
   Value *CreateSub(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
         return Folder.CreateSub(LC, RC);
     return Insert(BinaryOperator::CreateSub(LHS, RHS), Name);
   }
+  Value *CreateFSub(Value *LHS, Value *RHS, const char *Name = "") {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Folder.CreateFSub(LC, RC);
+    return Insert(BinaryOperator::CreateFSub(LHS, RHS), Name);
+  }
   Value *CreateMul(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
         return Folder.CreateMul(LC, RC);
     return Insert(BinaryOperator::CreateMul(LHS, RHS), Name);
   }
+  Value *CreateFMul(Value *LHS, Value *RHS, const char *Name = "") {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Folder.CreateFMul(LC, RC);
+    return Insert(BinaryOperator::CreateFMul(LHS, RHS), Name);
+  }
   Value *CreateUDiv(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
@@ -266,12 +311,17 @@ public:
   Value *CreateNeg(Value *V, const char *Name = "") {
     if (Constant *VC = dyn_cast<Constant>(V))
       return Folder.CreateNeg(VC);
-    return Insert(BinaryOperator::CreateNeg(V), Name);
+    return Insert(BinaryOperator::CreateNeg(Context, 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);
   }
   Value *CreateNot(Value *V, const char *Name = "") {
     if (Constant *VC = dyn_cast<Constant>(V))
       return Folder.CreateNot(VC);
-    return Insert(BinaryOperator::CreateNot(V), Name);
+    return Insert(BinaryOperator::CreateNot(Context, V), Name);
   }
 
   //===--------------------------------------------------------------------===//
@@ -299,9 +349,8 @@ public:
     return Insert(new StoreInst(Val, Ptr, isVolatile));
   }
   template<typename InputIterator>
-  Value *CreateGEP(Value *Ptr, InputIterator IdxBegin,
-                               InputIterator IdxEnd, const char *Name = "") {
-
+  Value *CreateGEP(Value *Ptr, InputIterator IdxBegin, InputIterator IdxEnd,
+                   const char *Name = "") {
     if (Constant *PC = dyn_cast<Constant>(Ptr)) {
       // Every index must be constant.
       InputIterator i;
@@ -320,32 +369,66 @@ public:
         return Folder.CreateGetElementPtr(PC, &IC, 1);
     return Insert(GetElementPtrInst::Create(Ptr, Idx), Name);
   }
-  Value *CreateStructGEP(Value *Ptr, unsigned Idx, const char *Name = "") {
-    llvm::Value *Idxs[] = {
-      ConstantInt::get(llvm::Type::Int32Ty, 0),
-      ConstantInt::get(llvm::Type::Int32Ty, Idx)
+  Value *CreateConstGEP1_32(Value *Ptr, unsigned Idx0, const char *Name = "") {
+    Value *Idx = ConstantInt::get(Type::Int32Ty, 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_32(Value *Ptr, unsigned Idx0, unsigned Idx1, 
+                    const char *Name = "") {
+    Value *Idxs[] = {
+      ConstantInt::get(Type::Int32Ty, Idx0),
+      ConstantInt::get(Type::Int32Ty, Idx1)
+    };
+
+    if (Constant *PC = dyn_cast<Constant>(Ptr))
+      return Folder.CreateGetElementPtr(PC, Idxs, 2);
+
+    return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name);    
+  }
+  Value *CreateConstGEP1_64(Value *Ptr, uint64_t Idx0, const char *Name = "") {
+    Value *Idx = ConstantInt::get(Type::Int64Ty, 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, 
+                    const char *Name = "") {
+    Value *Idxs[] = {
+      ConstantInt::get(Type::Int64Ty, Idx0),
+      ConstantInt::get(Type::Int64Ty, Idx1)
     };
 
     if (Constant *PC = dyn_cast<Constant>(Ptr))
       return Folder.CreateGetElementPtr(PC, Idxs, 2);
 
-    return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name);
+    return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name);    
+  }
+  Value *CreateStructGEP(Value *Ptr, unsigned Idx, const char *Name = "") {
+    return CreateConstGEP2_32(Ptr, 0, Idx, Name);
   }
   Value *CreateGlobalString(const char *Str = "", const char *Name = "") {
     Constant *StrConstant = ConstantArray::get(Str, true);
-    GlobalVariable *gv = new llvm::GlobalVariable(StrConstant->getType(),
-                                                  true,
-                                                  GlobalValue::InternalLinkage,
-                                                  StrConstant,
-                                                  "",
-                                                  BB->getParent()->getParent(),
-                                                  false);
+    Module &M = *BB->getParent()->getParent();
+    GlobalVariable *gv = new GlobalVariable(M,
+                                            StrConstant->getType(),
+                                            true,
+                                            GlobalValue::InternalLinkage,
+                                            StrConstant,
+                                            "",
+                                            0,
+                                            false);
     gv->setName(Name);
     return gv;
   }
   Value *CreateGlobalStringPtr(const char *Str = "", const char *Name = "") {
     Value *gv = CreateGlobalString(Str, Name);
-    Value *zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0);
+    Value *zero = ConstantInt::get(Type::Int32Ty, 0);
     Value *Args[] = { zero, zero };
     return CreateGEP(gv, Args, Args+2, Name);
   }
@@ -395,7 +478,7 @@ public:
   }
 
   Value *CreateCast(Instruction::CastOps Op, Value *V, const Type *DestTy,
-                     const char *Name = "") {
+                    const char *Name = "") {
     if (V->getType() == DestTy)
       return V;
     if (Constant *VC = dyn_cast<Constant>(V))
@@ -403,7 +486,7 @@ public:
     return Insert(CastInst::Create(Op, V, DestTy), Name);
   }
   Value *CreateIntCast(Value *V, const Type *DestTy, bool isSigned,
-                        const char *Name = "") {
+                       const char *Name = "") {
     if (V->getType() == DestTy)
       return V;
     if (Constant *VC = dyn_cast<Constant>(V))
@@ -494,29 +577,14 @@ public:
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
         return Folder.CreateICmp(P, LC, RC);
-    return Insert(new ICmpInst(P, LHS, RHS), Name);
+    return Insert(new ICmpInst(Context, P, LHS, RHS), Name);
   }
   Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
                     const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
         return Folder.CreateFCmp(P, LC, RC);
-    return Insert(new FCmpInst(P, LHS, RHS), Name);
-  }
-
-  Value *CreateVICmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
-                     const char *Name = "") {
-    if (Constant *LC = dyn_cast<Constant>(LHS))
-      if (Constant *RC = dyn_cast<Constant>(RHS))
-        return Folder.CreateVICmp(P, LC, RC);
-    return Insert(new VICmpInst(P, LHS, RHS), Name);
-  }
-  Value *CreateVFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS,
-                     const char *Name = "") {
-    if (Constant *LC = dyn_cast<Constant>(LHS))
-      if (Constant *RC = dyn_cast<Constant>(RHS))
-        return Folder.CreateVFCmp(P, LC, RC);
-    return Insert(new VFCmpInst(P, LHS, RHS), Name);
+    return Insert(new FCmpInst(Context, P, LHS, RHS), Name);
   }
 
   //===--------------------------------------------------------------------===//
@@ -569,11 +637,11 @@ public:
   }
 
   Value *CreateExtractElement(Value *Vec, Value *Idx,
-                                         const char *Name = "") {
+                              const char *Name = "") {
     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,
@@ -586,7 +654,7 @@ public:
   }
 
   Value *CreateShuffleVector(Value *V1, Value *V2, Value *Mask,
-                                       const char *Name = "") {
+                             const char *Name = "") {
     if (Constant *V1C = dyn_cast<Constant>(V1))
       if (Constant *V2C = dyn_cast<Constant>(V2))
         if (Constant *MC = dyn_cast<Constant>(Mask))
@@ -637,16 +705,30 @@ public:
 
   /// CreateIsNull - Return an i1 value testing if \arg Arg is null.
   Value *CreateIsNull(Value *Arg, const char *Name = "") {
-    return CreateICmpEQ(Arg, llvm::Constant::getNullValue(Arg->getType()), 
+    return CreateICmpEQ(Arg, Context.getNullValue(Arg->getType()),
                         Name);
   }
 
-  /// CreateIsNonNull - Return an i1 value testing if \arg Arg is not null.
-  Value *CreateIsNonNull(Value *Arg, const char *Name = "") {
-    return CreateICmpNE(Arg, llvm::Constant::getNullValue(Arg->getType()), 
+  /// 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()),
                         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.
+  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 *Difference = CreateSub(LHS_int, RHS_int);
+    return CreateSDiv(Difference,
+                      ConstantExpr::getSizeOf(ArgType->getElementType()),
+                      Name);
+  }
 };
 
 }