make CreateFMul forward to CreateFMul, not CreateMul.
[oota-llvm.git] / include / llvm / Support / IRBuilder.h
index 09859092aee960da15ac9951391a02e42edad3a1..bdbd89854752fd57e64ff877581d51adc5129d0f 100644 (file)
 #ifndef LLVM_SUPPORT_IRBUILDER_H
 #define LLVM_SUPPORT_IRBUILDER_H
 
-#include "llvm/BasicBlock.h"
-#include "llvm/Instructions.h"
 #include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+#include "llvm/GlobalVariable.h"
+#include "llvm/Function.h"
+#include "llvm/Support/ConstantFolder.h"
 
 namespace llvm {
 
 /// IRBuilder - This provides a uniform API for creating instructions and
-/// inserting them into a basic block: either at the end of a BasicBlock, or 
+/// inserting them into a basic block: either at the end of a BasicBlock, or
 /// at a specific iterator location in a block.
 ///
 /// Note that the builder does not expose the full generality of LLVM
@@ -31,16 +33,28 @@ namespace llvm {
 /// supports nul-terminated C strings.  For fully generic names, use
 /// I->setName().  For access to extra instruction properties, use the mutators
 /// (e.g. setVolatile) on the instructions after they have been created.
-class IRBuilder {
+/// The first template argument handles whether or not to preserve names in the
+/// final instruction output. This defaults to on.  The second template argument
+/// specifies a class to use for creating constants.  This defaults to creating
+/// minimally folded constants.
+template <bool preserveNames=true, typename T = ConstantFolder> class IRBuilder{
   BasicBlock *BB;
   BasicBlock::iterator InsertPt;
+  T Folder;
 public:
-  IRBuilder() { ClearInsertionPoint(); }
-  explicit IRBuilder(BasicBlock *TheBB) { SetInsertPoint(TheBB); }
-  IRBuilder(BasicBlock *TheBB, BasicBlock::iterator IP) {
-    SetInsertPoint(TheBB, IP);
-  }
+  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); }
+
+  /// 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
   //===--------------------------------------------------------------------===//
@@ -50,39 +64,41 @@ public:
   void ClearInsertionPoint() {
     BB = 0;
   }
-  
+
   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) {
     BB = TheBB;
     InsertPt = BB->end();
   }
-  
+
   /// SetInsertPoint - This specifies that created instructions should be
   /// inserted at the specified point.
   void SetInsertPoint(BasicBlock *TheBB, BasicBlock::iterator IP) {
     BB = TheBB;
     InsertPt = IP;
   }
-  
+
   /// Insert - Insert and return the specified instruction.
   template<typename InstTy>
   InstTy *Insert(InstTy *I, const char *Name = "") const {
     InsertHelper(I, Name);
     return I;
   }
-  
+
   /// InsertHelper - Insert the specified instruction at the specified insertion
   /// point.  This is split out of Insert so that it isn't duplicated for every
   /// template instantiation.
   void InsertHelper(Instruction *I, const char *Name) const {
     if (BB) BB->getInstList().insert(InsertPt, I);
-    if (Name[0])
+    if (preserveNames && Name[0])
       I->setName(Name);
   }
-  
+
   //===--------------------------------------------------------------------===//
   // Instruction creation methods: Terminators
   //===--------------------------------------------------------------------===//
@@ -92,22 +108,28 @@ public:
     return Insert(ReturnInst::Create());
   }
 
-  /// @verbatim 
-  /// CreateRet - Create a 'ret <val>' instruction. 
+  /// @verbatim
+  /// CreateRet - Create a 'ret <val>' instruction.
   /// @endverbatim
   ReturnInst *CreateRet(Value *V) {
     return Insert(ReturnInst::Create(V));
   }
 
-  ReturnInst *CreateRet(Value * const* retVals, unsigned N) {
-    return Insert(ReturnInst::Create(retVals, N));
-  }
-  
-  GetResultInst *CreateGetResult(Value *V, unsigned Index, 
-                                 const char *Name = "") {
-    return Insert(new GetResultInst(V, Index), Name);
+  /// CreateAggregateRet - Create a sequence of N insertvalue instructions,
+  /// with one Value from the retVals array each, that build a aggregate
+  /// return value one value at a time, and a ret instruction to return
+  /// the resulting aggregate value. This is a convenience function for
+  /// code that uses aggregate return values as a vehicle for having
+  /// multiple return values.
+  ///
+  ReturnInst *CreateAggregateRet(Value * const* retVals, unsigned N) {
+    const Type *RetType = BB->getParent()->getReturnType();
+    Value *V = UndefValue::get(RetType);
+    for (unsigned i = 0; i != N; ++i)
+      V = CreateInsertValue(V, retVals[i], i, "mrv");
+    return Insert(ReturnInst::Create(V));
   }
-    
+
   /// CreateBr - Create an unconditional 'br label X' instruction.
   BranchInst *CreateBr(BasicBlock *Dest) {
     return Insert(BranchInst::Create(Dest));
@@ -118,23 +140,23 @@ public:
   BranchInst *CreateCondBr(Value *Cond, BasicBlock *True, BasicBlock *False) {
     return Insert(BranchInst::Create(True, False, Cond));
   }
-  
+
   /// CreateSwitch - Create a switch instruction with the specified value,
   /// default dest, and with a hint for the number of cases that will be added
   /// (for efficient allocation).
   SwitchInst *CreateSwitch(Value *V, BasicBlock *Dest, unsigned NumCases = 10) {
     return Insert(SwitchInst::Create(V, Dest, NumCases));
   }
-  
+
   /// CreateInvoke - Create an invoke instruction.
   template<typename InputIterator>
-  InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest, 
-                           BasicBlock *UnwindDest, InputIterator ArgBegin, 
+  InvokeInst *CreateInvoke(Value *Callee, BasicBlock *NormalDest,
+                           BasicBlock *UnwindDest, InputIterator ArgBegin,
                            InputIterator ArgEnd, const char *Name = "") {
     return Insert(InvokeInst::Create(Callee, NormalDest, UnwindDest,
                                      ArgBegin, ArgEnd), Name);
   }
-  
+
   UnwindInst *CreateUnwind() {
     return Insert(new UnwindInst());
   }
@@ -142,7 +164,7 @@ public:
   UnreachableInst *CreateUnreachable() {
     return Insert(new UnreachableInst());
   }
-  
+
   //===--------------------------------------------------------------------===//
   // Instruction creation methods: Binary Operators
   //===--------------------------------------------------------------------===//
@@ -150,110 +172,140 @@ public:
   Value *CreateAdd(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
-        return ConstantExpr::getAdd(LC, RC);      
+        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 ConstantExpr::getSub(LC, RC);
+        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 ConstantExpr::getMul(LC, RC);
+        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))
-        return ConstantExpr::getUDiv(LC, RC);
+        return Folder.CreateUDiv(LC, RC);
     return Insert(BinaryOperator::CreateUDiv(LHS, RHS), Name);
   }
   Value *CreateSDiv(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
-        return ConstantExpr::getSDiv(LC, RC);      
+        return Folder.CreateSDiv(LC, RC);
     return Insert(BinaryOperator::CreateSDiv(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))
-        return ConstantExpr::getFDiv(LC, RC);      
+        return Folder.CreateFDiv(LC, RC);
     return Insert(BinaryOperator::CreateFDiv(LHS, RHS), Name);
   }
   Value *CreateURem(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
-        return ConstantExpr::getURem(LC, RC);
+        return Folder.CreateURem(LC, RC);
     return Insert(BinaryOperator::CreateURem(LHS, RHS), Name);
   }
   Value *CreateSRem(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
-        return ConstantExpr::getSRem(LC, RC);
+        return Folder.CreateSRem(LC, RC);
     return Insert(BinaryOperator::CreateSRem(LHS, RHS), Name);
   }
   Value *CreateFRem(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
-        return ConstantExpr::getFRem(LC, RC);
+        return Folder.CreateFRem(LC, RC);
     return Insert(BinaryOperator::CreateFRem(LHS, RHS), Name);
   }
   Value *CreateShl(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
-        return ConstantExpr::getShl(LC, RC);
+        return Folder.CreateShl(LC, RC);
     return Insert(BinaryOperator::CreateShl(LHS, RHS), Name);
   }
   Value *CreateLShr(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
-        return ConstantExpr::getLShr(LC, RC);
+        return Folder.CreateLShr(LC, RC);
     return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name);
   }
   Value *CreateAShr(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
-        return ConstantExpr::getAShr(LC, RC);
+        return Folder.CreateAShr(LC, RC);
     return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name);
   }
   Value *CreateAnd(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
-        return ConstantExpr::getAnd(LC, RC);
+        return Folder.CreateAnd(LC, RC);
     return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name);
   }
   Value *CreateOr(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
-        return ConstantExpr::getOr(LC, RC);
+        return Folder.CreateOr(LC, RC);
     return Insert(BinaryOperator::CreateOr(LHS, RHS), Name);
   }
   Value *CreateXor(Value *LHS, Value *RHS, const char *Name = "") {
     if (Constant *LC = dyn_cast<Constant>(LHS))
       if (Constant *RC = dyn_cast<Constant>(RHS))
-        return ConstantExpr::getXor(LC, RC);
+        return Folder.CreateXor(LC, RC);
     return Insert(BinaryOperator::CreateXor(LHS, RHS), Name);
   }
 
-  BinaryOperator *CreateBinOp(Instruction::BinaryOps Opc,
-                              Value *LHS, Value *RHS, const char *Name = "") {
+  Value *CreateBinOp(Instruction::BinaryOps Opc,
+                     Value *LHS, Value *RHS, const char *Name = "") {
+    if (Constant *LC = dyn_cast<Constant>(LHS))
+      if (Constant *RC = dyn_cast<Constant>(RHS))
+        return Folder.CreateBinOp(Opc, LC, RC);
     return Insert(BinaryOperator::Create(Opc, LHS, RHS), Name);
   }
-  
-  BinaryOperator *CreateNeg(Value *V, const char *Name = "") {
+
+  Value *CreateNeg(Value *V, const char *Name = "") {
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return Folder.CreateNeg(VC);
     return Insert(BinaryOperator::CreateNeg(V), Name);
   }
-  BinaryOperator *CreateNot(Value *V, const char *Name = "") {
+  Value *CreateFNeg(Value *V, const char *Name = "") {
+    if (Constant *VC = dyn_cast<Constant>(V))
+      return Folder.CreateFNeg(VC);
+    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(V), Name);
   }
-  
+
   //===--------------------------------------------------------------------===//
   // Instruction creation methods: Memory Instructions
   //===--------------------------------------------------------------------===//
-  
+
   MallocInst *CreateMalloc(const Type *Ty, Value *ArraySize = 0,
                            const char *Name = "") {
     return Insert(new MallocInst(Ty, ArraySize), Name);
@@ -265,19 +317,18 @@ public:
   FreeInst *CreateFree(Value *Ptr) {
     return Insert(new FreeInst(Ptr));
   }
-  LoadInst *CreateLoad(Value *Ptr, const char *Name = 0) {
-    return Insert(new LoadInst(Ptr, Name));
+  LoadInst *CreateLoad(Value *Ptr, const char *Name = "") {
+    return Insert(new LoadInst(Ptr), Name);
   }
-  LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const char *Name = 0) {
-    return Insert(new LoadInst(Ptr, Name, isVolatile));
+  LoadInst *CreateLoad(Value *Ptr, bool isVolatile, const char *Name = "") {
+    return Insert(new LoadInst(Ptr, 0, isVolatile), Name);
   }
   StoreInst *CreateStore(Value *Val, Value *Ptr, bool isVolatile = false) {
     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;
@@ -286,33 +337,81 @@ public:
           break;
       }
       if (i == IdxEnd)
-        return ConstantExpr::getGetElementPtr(PC, &IdxBegin[0], 
-                                              IdxEnd - IdxBegin);
-    }      
-    return(Insert(GetElementPtrInst::Create(Ptr, IdxBegin, IdxEnd), Name));
+        return Folder.CreateGetElementPtr(PC, &IdxBegin[0], IdxEnd - IdxBegin);
+    }
+    return Insert(GetElementPtrInst::Create(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 ConstantExpr::getGetElementPtr(PC, &IC, 1);
+        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 ConstantExpr::getGetElementPtr(PC, Idxs, 2);
-    
-    return Insert(GetElementPtrInst::Create(Ptr, Idxs, Idxs+2), Name);
+      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);    
+  }
+  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 GlobalVariable(StrConstant->getType(),
+                                            true,
+                                            GlobalValue::InternalLinkage,
+                                            StrConstant,
+                                            "",
+                                            BB->getParent()->getParent(),
+                                            false);
+    gv->setName(Name);
+    return gv;
+  }
+  Value *CreateGlobalStringPtr(const char *Str = "", const char *Name = "") {
+    Value *gv = CreateGlobalString(Str, Name);
+    Value *zero = ConstantInt::get(Type::Int32Ty, 0);
+    Value *Args[] = { zero, zero };
+    return CreateGEP(gv, Args, Args+2, Name);
   }
-  
   //===--------------------------------------------------------------------===//
   // Instruction creation methods: Cast/Conversion Operators
   //===--------------------------------------------------------------------===//
-    
+
   Value *CreateTrunc(Value *V, const Type *DestTy, const char *Name = "") {
     return CreateCast(Instruction::Trunc, V, DestTy, Name);
   }
@@ -355,26 +454,26 @@ 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))
-      return ConstantExpr::getCast(Op, VC, DestTy);      
+      return Folder.CreateCast(Op, VC, DestTy);
     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))
-      return ConstantExpr::getIntegerCast(VC, DestTy, isSigned);
+      return Folder.CreateIntCast(VC, DestTy, isSigned);
     return Insert(CastInst::CreateIntegerCast(V, DestTy, isSigned), Name);
   }
 
   //===--------------------------------------------------------------------===//
   // Instruction creation methods: Compare Instructions
   //===--------------------------------------------------------------------===//
-  
+
   Value *CreateICmpEQ(Value *LHS, Value *RHS, const char *Name = "") {
     return CreateICmp(ICmpInst::ICMP_EQ, LHS, RHS, Name);
   }
@@ -405,7 +504,7 @@ public:
   Value *CreateICmpSLE(Value *LHS, Value *RHS, const char *Name = "") {
     return CreateICmp(ICmpInst::ICMP_SLE, LHS, RHS, Name);
   }
-  
+
   Value *CreateFCmpOEQ(Value *LHS, Value *RHS, const char *Name = "") {
     return CreateFCmp(FCmpInst::FCMP_OEQ, LHS, RHS, Name);
   }
@@ -449,33 +548,33 @@ public:
     return CreateFCmp(FCmpInst::FCMP_UNE, LHS, RHS, Name);
   }
 
-  Value *CreateICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, 
+  Value *CreateICmp(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 ConstantExpr::getCompare(P, LC, RC);      
+        return Folder.CreateICmp(P, LC, RC);
     return Insert(new ICmpInst(P, LHS, RHS), Name);
   }
-  Value *CreateFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, 
+  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 ConstantExpr::getCompare(P, LC, RC);
+        return Folder.CreateFCmp(P, LC, RC);
     return Insert(new FCmpInst(P, LHS, RHS), Name);
   }
 
-  Value *CreateVICmp(CmpInst::Predicate P, Value *LHS, Value *RHS, 
+  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 ConstantExpr::getCompare(P, LC, RC);      
+        return Folder.CreateVICmp(P, LC, RC);
     return Insert(new VICmpInst(P, LHS, RHS), Name);
   }
-  Value *CreateVFCmp(CmpInst::Predicate P, Value *LHS, Value *RHS, 
+  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 ConstantExpr::getCompare(P, LC, RC);
+        return Folder.CreateVFCmp(P, LC, RC);
     return Insert(new VFCmpInst(P, LHS, RHS), Name);
   }
 
@@ -508,9 +607,9 @@ public:
     Value *Args[] = { Arg1, Arg2, Arg3, Arg4 };
     return Insert(CallInst::Create(Callee, Args, Args+4), Name);
   }
-  
+
   template<typename InputIterator>
-  CallInst *CreateCall(Value *Callee, InputIterator ArgBegin, 
+  CallInst *CreateCall(Value *Callee, InputIterator ArgBegin,
                        InputIterator ArgEnd, const char *Name = "") {
     return Insert(CallInst::Create(Callee, ArgBegin, ArgEnd), Name);
   }
@@ -520,7 +619,7 @@ public:
     if (Constant *CC = dyn_cast<Constant>(C))
       if (Constant *TC = dyn_cast<Constant>(True))
         if (Constant *FC = dyn_cast<Constant>(False))
-          return ConstantExpr::getSelect(CC, TC, FC);      
+          return Folder.CreateSelect(CC, TC, FC);
     return Insert(SelectInst::Create(C, True, False), Name);
   }
 
@@ -529,10 +628,10 @@ 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 ConstantExpr::getExtractElement(VC, IC);
+        return Folder.CreateExtractElement(VC, IC);
     return Insert(new ExtractElementInst(Vec, Idx), Name);
   }
 
@@ -541,20 +640,88 @@ public:
     if (Constant *VC = dyn_cast<Constant>(Vec))
       if (Constant *NC = dyn_cast<Constant>(NewElt))
         if (Constant *IC = dyn_cast<Constant>(Idx))
-          return ConstantExpr::getInsertElement(VC, NC, IC);
+          return Folder.CreateInsertElement(VC, NC, IC);
     return Insert(InsertElementInst::Create(Vec, NewElt, Idx), Name);
   }
 
   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))
-          return ConstantExpr::getShuffleVector(V1C, V2C, MC);      
+          return Folder.CreateShuffleVector(V1C, V2C, MC);
     return Insert(new ShuffleVectorInst(V1, V2, Mask), Name);
   }
+
+  Value *CreateExtractValue(Value *Agg, unsigned Idx,
+                            const char *Name = "") {
+    if (Constant *AggC = dyn_cast<Constant>(Agg))
+      return Folder.CreateExtractValue(AggC, &Idx, 1);
+    return Insert(ExtractValueInst::Create(Agg, Idx), Name);
+  }
+
+  template<typename InputIterator>
+  Value *CreateExtractValue(Value *Agg,
+                            InputIterator IdxBegin,
+                            InputIterator IdxEnd,
+                            const char *Name = "") {
+    if (Constant *AggC = dyn_cast<Constant>(Agg))
+      return Folder.CreateExtractValue(AggC, IdxBegin, IdxEnd - IdxBegin);
+    return Insert(ExtractValueInst::Create(Agg, IdxBegin, IdxEnd), Name);
+  }
+
+  Value *CreateInsertValue(Value *Agg, Value *Val, unsigned Idx,
+                           const char *Name = "") {
+    if (Constant *AggC = dyn_cast<Constant>(Agg))
+      if (Constant *ValC = dyn_cast<Constant>(Val))
+        return Folder.CreateInsertValue(AggC, ValC, &Idx, 1);
+    return Insert(InsertValueInst::Create(Agg, Val, Idx), Name);
+  }
+
+  template<typename InputIterator>
+  Value *CreateInsertValue(Value *Agg, Value *Val,
+                           InputIterator IdxBegin,
+                           InputIterator IdxEnd,
+                           const char *Name = "") {
+    if (Constant *AggC = dyn_cast<Constant>(Agg))
+      if (Constant *ValC = dyn_cast<Constant>(Val))
+        return Folder.CreateInsertValue(AggC, ValC,
+                                            IdxBegin, IdxEnd - IdxBegin);
+    return Insert(InsertValueInst::Create(Agg, Val, IdxBegin, IdxEnd), Name);
+  }
+
+  //===--------------------------------------------------------------------===//
+  // Utility creation methods
+  //===--------------------------------------------------------------------===//
+
+  /// CreateIsNull - Return an i1 value testing if \arg Arg is null.
+  Value *CreateIsNull(Value *Arg, const char *Name = "") {
+    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, 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.
+  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);
+  }
 };
-  
+
 }
 
 #endif