Add constructors that take a BasicBlock to append to, to the rest of
authorAlkis Evlogimenos <alkis@evlogimenos.com>
Thu, 27 May 2004 00:15:23 +0000 (00:15 +0000)
committerAlkis Evlogimenos <alkis@evlogimenos.com>
Thu, 27 May 2004 00:15:23 +0000 (00:15 +0000)
the llvm::Instruction hierarchy.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@13800 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/InstrTypes.h
include/llvm/iMemory.h
include/llvm/iOperators.h
include/llvm/iOther.h
include/llvm/iPHINode.h
lib/VMCore/iCall.cpp
lib/VMCore/iMemory.cpp
lib/VMCore/iOperators.cpp

index df64c9bd0ee434f0a4983aabba04c5ace493e688..c615888d818fda9fbcb8a40be039234cc6d856b4 100644 (file)
@@ -76,8 +76,17 @@ public:
 
 class BinaryOperator : public Instruction {
 protected:
+  void init(BinaryOps iType, Value *S1, Value *S2);
   BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty,
-                 const std::string &Name, Instruction *InsertBefore);
+                 const std::string &Name, Instruction *InsertBefore)
+    : Instruction(Ty, iType, Name, InsertBefore) {
+    init(iType, S1, S2);
+  }
+  BinaryOperator(BinaryOps iType, Value *S1, Value *S2, const Type *Ty,
+                 const std::string &Name, BasicBlock *InsertAtEnd)
+    : Instruction(Ty, iType, Name, InsertAtEnd) {
+    init(iType, S1, S2);
+  }
 
 public:
 
@@ -90,6 +99,14 @@ public:
                                const std::string &Name = "",
                                 Instruction *InsertBefore = 0);
                                
+  /// create() - Construct a binary instruction, given the opcode and the two
+  /// operands.  Also automatically insert this instruction to the end of the
+  /// BasicBlock specified.
+  ///
+  static BinaryOperator *create(BinaryOps Op, Value *S1, Value *S2,
+                               const std::string &Name,
+                                BasicBlock *InsertAtEnd);
+                               
 
   /// Helper functions to construct and inspect unary operations (NEG and NOT)
   /// via binary operators SUB and XOR:
@@ -99,8 +116,12 @@ public:
   ///
   static BinaryOperator *createNeg(Value *Op, const std::string &Name = "",
                                    Instruction *InsertBefore = 0);
+  static BinaryOperator *createNeg(Value *Op, const std::string &Name,
+                                   BasicBlock *InsertAtEnd);
   static BinaryOperator *createNot(Value *Op, const std::string &Name = "",
                                    Instruction *InsertBefore = 0);
+  static BinaryOperator *createNot(Value *Op, const std::string &Name,
+                                   BasicBlock *InsertAtEnd);
 
   /// isNeg, isNot - Check if the given Value is a NEG or NOT instruction.
   ///
index a794ca54023e2f5309977ab192a9ddf0273d4895..1f9f25fce89cdc5ae2bdf7f2fb648edb687451e3 100644 (file)
@@ -30,8 +30,12 @@ class PointerType;
 ///
 class AllocationInst : public Instruction {
 protected:
+  void init(const Type *Ty, Value *ArraySize, unsigned iTy);
   AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, 
                 const std::string &Name = "", Instruction *InsertBefore = 0);
+  AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, 
+                const std::string &Name, BasicBlock *InsertAtEnd);
+
 public:
 
   /// isArrayAllocation - Return true if there is an allocation size parameter
@@ -79,9 +83,13 @@ public:
 class MallocInst : public AllocationInst {
   MallocInst(const MallocInst &MI);
 public:
-  MallocInst(const Type *Ty, Value *ArraySize = 0, const std::string &Name = "",
-             Instruction *InsertBefore = 0)
+  explicit MallocInst(const Type *Ty, Value *ArraySize = 0,
+                      const std::string &Name = "",
+                      Instruction *InsertBefore = 0)
     : AllocationInst(Ty, ArraySize, Malloc, Name, InsertBefore) {}
+  MallocInst(const Type *Ty, Value *ArraySize, const std::string &Name,
+             BasicBlock *InsertAtEnd)
+    : AllocationInst(Ty, ArraySize, Malloc, Name, InsertAtEnd) {}
 
   virtual Instruction *clone() const { 
     return new MallocInst(*this);
@@ -107,9 +115,13 @@ public:
 class AllocaInst : public AllocationInst {
   AllocaInst(const AllocaInst &);
 public:
-  AllocaInst(const Type *Ty, Value *ArraySize = 0, const std::string &Name = "",
-             Instruction *InsertBefore = 0)
+  explicit AllocaInst(const Type *Ty, Value *ArraySize = 0,
+                      const std::string &Name = "",
+                      Instruction *InsertBefore = 0)
     : AllocationInst(Ty, ArraySize, Alloca, Name, InsertBefore) {}
+  AllocaInst(const Type *Ty, Value *ArraySize, const std::string &Name,
+             BasicBlock *InsertAtEnd)
+    : AllocationInst(Ty, ArraySize, Alloca, Name, InsertAtEnd) {}
 
   virtual Instruction *clone() const { 
     return new AllocaInst(*this);
@@ -132,8 +144,12 @@ public:
 
 /// FreeInst - an instruction to deallocate memory
 ///
-struct FreeInst : public Instruction {
-  FreeInst(Value *Ptr, Instruction *InsertBefore = 0);
+class FreeInst : public Instruction {
+  void init(Value *Ptr);
+
+public:
+  explicit FreeInst(Value *Ptr, Instruction *InsertBefore = 0);
+  FreeInst(Value *Ptr, BasicBlock *InsertAfter);
 
   virtual Instruction *clone() const { return new FreeInst(Operands[0]); }
 
@@ -169,8 +185,11 @@ class LoadInst : public Instruction {
   }
 public:
   LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBefore);
+  LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAtEnd);
   LoadInst(Value *Ptr, const std::string &Name = "", bool isVolatile = false,
            Instruction *InsertBefore = 0);
+  LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
+           BasicBlock *InsertAtEnd);
 
   /// isVolatile - Return true if this is a load from a volatile memory
   /// location.
@@ -221,8 +240,10 @@ class StoreInst : public Instruction {
   }
 public:
   StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore);
+  StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd);
   StoreInst(Value *Val, Value *Ptr, bool isVolatile = false,
             Instruction *InsertBefore = 0);
+  StoreInst(Value *Val, Value *Ptr, bool isVolatile, BasicBlock *InsertAtEnd);
 
 
   /// isVolatile - Return true if this is a load from a volatile memory
@@ -272,6 +293,8 @@ class GetElementPtrInst : public Instruction {
 public:
   GetElementPtrInst(Value *Ptr, const std::vector<Value*> &Idx,
                    const std::string &Name = "", Instruction *InsertBefore =0);
+  GetElementPtrInst(Value *Ptr, const std::vector<Value*> &Idx,
+                   const std::string &Name, BasicBlock *InsertAtEnd);
   virtual Instruction *clone() const { return new GetElementPtrInst(*this); }
   
   // getType - Overload to return most specific pointer type...
index ecf99172a1e218a37f83ef62c624a9db08ec3b31..e384e051d8eefdd33ee0708221c965d5c3f87758 100644 (file)
@@ -26,6 +26,8 @@ class SetCondInst : public BinaryOperator {
 public:
   SetCondInst(BinaryOps Opcode, Value *LHS, Value *RHS,
              const std::string &Name = "", Instruction *InsertBefore = 0);
+  SetCondInst(BinaryOps Opcode, Value *LHS, Value *RHS,
+             const std::string &Name, BasicBlock *InsertAtEnd);
 
   /// getInverseCondition - Return the inverse of the current condition opcode.
   /// For example seteq -> setne, setgt -> setle, setlt -> setge, etc...
index ba76227e4ab41111d77af06d56a2c5ea074a19aa..18779f9c328f71281d7489a511aacf4995eb4668 100644 (file)
@@ -31,12 +31,20 @@ class CastInst : public Instruction {
     Operands.reserve(1);
     Operands.push_back(Use(CI.Operands[0], this));
   }
+  void init(Value *S) {
+    Operands.reserve(1);
+    Operands.push_back(Use(S, this));
+  }
 public:
   CastInst(Value *S, const Type *Ty, const std::string &Name = "",
            Instruction *InsertBefore = 0)
     : Instruction(Ty, Cast, Name, InsertBefore) {
-    Operands.reserve(1);
-    Operands.push_back(Use(S, this));
+    init(S);
+  }
+  CastInst(Value *S, const Type *Ty, const std::string &Name,
+           BasicBlock *InsertAtEnd)
+    : Instruction(Ty, Cast, Name, InsertAtEnd) {
+    init(S);
   }
 
   virtual Instruction *clone() const { return new CastInst(*this); }
@@ -61,15 +69,25 @@ public:
 ///
 class CallInst : public Instruction {
   CallInst(const CallInst &CI);
+  void init(Value *Func, const std::vector<Value*> &Params);
+  void init(Value *Func, Value *Actual);
+  void init(Value *Func);
+
 public:
   CallInst(Value *F, const std::vector<Value*> &Par,
            const std::string &Name = "", Instruction *InsertBefore = 0);
+  CallInst(Value *F, const std::vector<Value*> &Par,
+           const std::string &Name, BasicBlock *InsertAtEnd);
 
-  // Alternate CallInst ctors w/ no actuals & one actual, respectively.
-  CallInst(Value *F, const std::string &Name = "", 
-           Instruction *InsertBefore = 0);
+  // Alternate CallInst ctors w/ one actual & no actuals, respectively.
   CallInst(Value *F, Value *Actual, const std::string& Name = "",
            Instruction *InsertBefore = 0);
+  CallInst(Value *F, Value *Actual, const std::string& Name,
+           BasicBlock *InsertAtEnd);
+  explicit CallInst(Value *F, const std::string &Name = "", 
+                    Instruction *InsertBefore = 0);
+  explicit CallInst(Value *F, const std::string &Name, 
+                    BasicBlock *InsertAtEnd);
 
   virtual Instruction *clone() const { return new CallInst(*this); }
   bool mayWriteToMemory() const { return true; }
@@ -106,16 +124,25 @@ class ShiftInst : public Instruction {
     Operands.push_back(Use(SI.Operands[0], this));
     Operands.push_back(Use(SI.Operands[1], this));
   }
-public:
-  ShiftInst(OtherOps Opcode, Value *S, Value *SA, const std::string &Name = "",
-            Instruction *InsertBefore = 0)
-    : Instruction(S->getType(), Opcode, Name, InsertBefore) {
+  void init(OtherOps Opcode, Value *S, Value *SA) {
     assert((Opcode == Shl || Opcode == Shr) && "ShiftInst Opcode invalid!");
     Operands.reserve(2);
     Operands.push_back(Use(S, this));
     Operands.push_back(Use(SA, this));
   }
 
+public:
+  ShiftInst(OtherOps Opcode, Value *S, Value *SA, const std::string &Name = "",
+            Instruction *InsertBefore = 0)
+    : Instruction(S->getType(), Opcode, Name, InsertBefore) {
+    init(Opcode, S, SA);
+  }
+  ShiftInst(OtherOps Opcode, Value *S, Value *SA, const std::string &Name,
+            BasicBlock *InsertAtEnd)
+    : Instruction(S->getType(), Opcode, Name, InsertAtEnd) {
+    init(Opcode, S, SA);
+  }
+
   OtherOps getOpcode() const {
     return static_cast<OtherOps>(Instruction::getOpcode());
   }
@@ -146,16 +173,25 @@ class SelectInst : public Instruction {
     Operands.push_back(Use(SI.Operands[1], this));
     Operands.push_back(Use(SI.Operands[2], this));
   }
-public:
-  SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name = "",
-             Instruction *InsertBefore = 0)
-    : Instruction(S1->getType(), Instruction::Select, Name, InsertBefore) {
+  void init(Value *C, Value *S1, Value *S2) {
     Operands.reserve(3);
     Operands.push_back(Use(C, this));
     Operands.push_back(Use(S1, this));
     Operands.push_back(Use(S2, this));
   }
 
+public:
+  SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name = "",
+             Instruction *InsertBefore = 0)
+    : Instruction(S1->getType(), Instruction::Select, Name, InsertBefore) {
+    init(C, S1, S2);
+  }
+  SelectInst(Value *C, Value *S1, Value *S2, const std::string &Name,
+             BasicBlock *InsertAtEnd)
+    : Instruction(S1->getType(), Instruction::Select, Name, InsertAtEnd) {
+    init(C, S1, S2);
+  }
+
   Value *getCondition() const { return Operands[0]; }
   Value *getTrueValue() const { return Operands[1]; }
   Value *getFalseValue() const { return Operands[2]; }
@@ -187,17 +223,25 @@ public:
 ///
 class VANextInst : public Instruction {
   PATypeHolder ArgTy;
+  void init(Value *List) {
+    Operands.reserve(1);
+    Operands.push_back(Use(List, this));
+  }
   VANextInst(const VANextInst &VAN)
     : Instruction(VAN.getType(), VANext), ArgTy(VAN.getArgType()) {
-    Operands.reserve(1);
-    Operands.push_back(Use(VAN.Operands[0], this));
+    init(VAN.Operands[0]);
   }
+
 public:
   VANextInst(Value *List, const Type *Ty, const std::string &Name = "",
              Instruction *InsertBefore = 0)
     : Instruction(List->getType(), VANext, Name, InsertBefore), ArgTy(Ty) {
-    Operands.reserve(1);
-    Operands.push_back(Use(List, this));
+    init(List);
+  }
+  VANextInst(Value *List, const Type *Ty, const std::string &Name,
+             BasicBlock *InsertAtEnd)
+    : Instruction(List->getType(), VANext, Name, InsertAtEnd), ArgTy(Ty) {
+    init(List);
   }
 
   const Type *getArgType() const { return ArgTy; }
@@ -223,17 +267,24 @@ public:
 /// an argument of the specified type given a va_list.
 ///
 class VAArgInst : public Instruction {
+  void init(Value* List) {
+    Operands.reserve(1);
+    Operands.push_back(Use(List, this));
+  }
   VAArgInst(const VAArgInst &VAA)
     : Instruction(VAA.getType(), VAArg) {
-    Operands.reserve(1);
-    Operands.push_back(Use(VAA.Operands[0], this));
+    init(VAA.Operands[0]);
   }
 public:
   VAArgInst(Value *List, const Type *Ty, const std::string &Name = "",
              Instruction *InsertBefore = 0)
     : Instruction(Ty, VAArg, Name, InsertBefore) {
-    Operands.reserve(1);
-    Operands.push_back(Use(List, this));
+    init(List);
+  }
+  VAArgInst(Value *List, const Type *Ty, const std::string &Name,
+            BasicBlock *InsertAtEnd)
+    : Instruction(Ty, VAArg, Name, InsertAtEnd) {
+    init(List);
   }
 
   virtual Instruction *clone() const { return new VAArgInst(*this); }
index 8899dd95ded6c478f7fe00a877fa34344392007f..22ba9a0578ddef577762ea770045cef9a09c6ec4 100644 (file)
@@ -36,6 +36,10 @@ public:
     : Instruction(Ty, Instruction::PHI, Name, InsertBefore) {
   }
 
+  PHINode(const Type *Ty, const std::string &Name, BasicBlock *InsertAtEnd)
+    : Instruction(Ty, Instruction::PHI, Name, InsertAtEnd) {
+  }
+
   virtual Instruction *clone() const { return new PHINode(*this); }
 
   /// getNumIncomingValues - Return the number of incoming edges
index edd5593301432380d7c6d36a7251bcc5a11cde57..9a81f7948f9f4fb210c03ee73a3a52c0c946d886 100644 (file)
@@ -23,29 +23,37 @@ using namespace llvm;
 //                        CallInst Implementation
 //===----------------------------------------------------------------------===//
 
-CallInst::CallInst(Value *Func, const std::vector<Value*> &params, 
-                   const std::string &Name, Instruction *InsertBefore) 
-  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
-                                ->getElementType())->getReturnType(),
-               Instruction::Call, Name, InsertBefore) {
-  Operands.reserve(1+params.size());
+void CallInst::init(Value *Func, const std::vector<Value*> &Params)
+{
+  Operands.reserve(1+Params.size());
   Operands.push_back(Use(Func, this));
 
   const FunctionType *FTy = 
     cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
 
-  assert((params.size() == FTy->getNumParams() || 
-          (FTy->isVarArg() && params.size() > FTy->getNumParams())) &&
+  assert((Params.size() == FTy->getNumParams() || 
+          (FTy->isVarArg() && Params.size() > FTy->getNumParams())) &&
         "Calling a function with bad signature");
-  for (unsigned i = 0; i != params.size(); i++)
-    Operands.push_back(Use(params[i], this));
+  for (unsigned i = 0; i != Params.size(); i++)
+    Operands.push_back(Use(Params[i], this));
 }
 
-CallInst::CallInst(Value *Func, const std::string &Name,
-                   Instruction *InsertBefore)
-  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
-                                   ->getElementType())->getReturnType(),
-                Instruction::Call, Name, InsertBefore) {
+void CallInst::init(Value *Func, Value *Actual)
+{
+  Operands.reserve(2);
+  Operands.push_back(Use(Func, this));
+  
+  const FunctionType *MTy = 
+    cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
+
+  assert((MTy->getNumParams() == 1 ||
+          (MTy->isVarArg() && MTy->getNumParams() == 0)) &&
+        "Calling a function with bad signature");
+  Operands.push_back(Use(Actual, this));
+}
+
+void CallInst::init(Value *Func)
+{
   Operands.reserve(1);
   Operands.push_back(Use(Func, this));
   
@@ -55,21 +63,52 @@ CallInst::CallInst(Value *Func, const std::string &Name,
   assert(MTy->getNumParams() == 0 && "Calling a function with bad signature");
 }
 
-CallInst::CallInst(Value *Func, Value* A, const std::string &Name,
+CallInst::CallInst(Value *Func, const std::vector<Value*> &Params, 
+                   const std::string &Name, Instruction *InsertBefore) 
+  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                ->getElementType())->getReturnType(),
+               Instruction::Call, Name, InsertBefore) {
+  init(Func, Params);
+}
+
+CallInst::CallInst(Value *Func, const std::vector<Value*> &Params, 
+                   const std::string &Name, BasicBlock *InsertAtEnd) 
+  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                ->getElementType())->getReturnType(),
+               Instruction::Call, Name, InsertAtEnd) {
+  init(Func, Params);
+}
+
+CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name,
                    Instruction  *InsertBefore)
   : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
                                    ->getElementType())->getReturnType(),
                 Instruction::Call, Name, InsertBefore) {
-  Operands.reserve(2);
-  Operands.push_back(Use(Func, this));
-  
-  const FunctionType *MTy = 
-    cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
+  init(Func, Actual);
+}
 
-  assert((MTy->getNumParams() == 1 ||
-          (MTy->isVarArg() && MTy->getNumParams() == 0)) &&
-        "Calling a function with bad signature");
-  Operands.push_back(Use(A, this));
+CallInst::CallInst(Value *Func, Value* Actual, const std::string &Name,
+                   BasicBlock  *InsertAtEnd)
+  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                   ->getElementType())->getReturnType(),
+                Instruction::Call, Name, InsertAtEnd) {
+  init(Func, Actual);
+}
+
+CallInst::CallInst(Value *Func, const std::string &Name,
+                   Instruction *InsertBefore)
+  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                   ->getElementType())->getReturnType(),
+                Instruction::Call, Name, InsertBefore) {
+  init(Func);
+}
+
+CallInst::CallInst(Value *Func, const std::string &Name,
+                   BasicBlock *InsertAtEnd)
+  : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
+                                   ->getElementType())->getReturnType(),
+                Instruction::Call, Name, InsertAtEnd) {
+  init(Func);
 }
 
 CallInst::CallInst(const CallInst &CI) 
index 2b731b45c5ac1407a967ac54aff03f01b3fdfc12..bcba93e253a16a6bfcfccb1b7b9b9419fc74518f 100644 (file)
 #include "llvm/DerivedTypes.h"
 using namespace llvm;
 
-AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, 
-                               const std::string &Name, Instruction *InsertBef)
-  : Instruction(PointerType::get(Ty), iTy, Name, InsertBef) {
-
+void AllocationInst::init(const Type *Ty, Value *ArraySize, unsigned iTy)
+{
   // ArraySize defaults to 1.
   if (!ArraySize) ArraySize = ConstantUInt::get(Type::UIntTy, 1);
 
@@ -30,6 +28,20 @@ AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy,
   Operands.push_back(Use(ArraySize, this));
 }
 
+AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, 
+                               const std::string &Name,
+                               Instruction *InsertBefore)
+  : Instruction(PointerType::get(Ty), iTy, Name, InsertBefore) {
+  init(Ty, ArraySize, iTy);
+}
+
+AllocationInst::AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, 
+                               const std::string &Name,
+                               BasicBlock *InsertAtEnd)
+  : Instruction(PointerType::get(Ty), iTy, Name, InsertAtEnd) {
+  init(Ty, ArraySize, iTy);
+}
+
 bool AllocationInst::isArrayAllocation() const {
   return getOperand(0) != ConstantUInt::get(Type::UIntTy, 1);
 }
@@ -52,13 +64,23 @@ MallocInst::MallocInst(const MallocInst &MI)
 //                             FreeInst Implementation
 //===----------------------------------------------------------------------===//
 
-FreeInst::FreeInst(Value *Ptr, Instruction *InsertBefore)
-  : Instruction(Type::VoidTy, Free, "", InsertBefore) {
-  assert(isa<PointerType>(Ptr->getType()) && "Can't free nonpointer!");
+void FreeInst::init(Value *Ptr)
+{
+  assert(Ptr && isa<PointerType>(Ptr->getType()) && "Can't free nonpointer!");
   Operands.reserve(1);
   Operands.push_back(Use(Ptr, this));
 }
 
+FreeInst::FreeInst(Value *Ptr, Instruction *InsertBefore)
+  : Instruction(Type::VoidTy, Free, "", InsertBefore) {
+  init(Ptr);
+}
+
+FreeInst::FreeInst(Value *Ptr, BasicBlock *InsertAtEnd)
+  : Instruction(Type::VoidTy, Free, "", InsertAtEnd) {
+  init(Ptr);
+}
+
 
 //===----------------------------------------------------------------------===//
 //                           LoadInst Implementation
@@ -70,6 +92,12 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, Instruction *InsertBef)
   init(Ptr);
 }
 
+LoadInst::LoadInst(Value *Ptr, const std::string &Name, BasicBlock *InsertAE)
+  : Instruction(cast<PointerType>(Ptr->getType())->getElementType(),
+                Load, Name, InsertAE), Volatile(false) {
+  init(Ptr);
+}
+
 LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
                    Instruction *InsertBef)
   : Instruction(cast<PointerType>(Ptr->getType())->getElementType(),
@@ -77,6 +105,13 @@ LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
   init(Ptr);
 }
 
+LoadInst::LoadInst(Value *Ptr, const std::string &Name, bool isVolatile,
+                   BasicBlock *InsertAE)
+  : Instruction(cast<PointerType>(Ptr->getType())->getElementType(),
+                Load, Name, InsertAE), Volatile(isVolatile) {
+  init(Ptr);
+}
+
 //===----------------------------------------------------------------------===//
 //                           StoreInst Implementation
 //===----------------------------------------------------------------------===//
@@ -86,12 +121,23 @@ StoreInst::StoreInst(Value *Val, Value *Ptr, Instruction *InsertBefore)
   init(Val, Ptr);
 }
 
+StoreInst::StoreInst(Value *Val, Value *Ptr, BasicBlock *InsertAtEnd)
+  : Instruction(Type::VoidTy, Store, "", InsertAtEnd), Volatile(false) {
+  init(Val, Ptr);
+}
+
 StoreInst::StoreInst(Value *Val, Value *Ptr, bool isVolatile, 
                      Instruction *InsertBefore)
   : Instruction(Type::VoidTy, Store, "", InsertBefore), Volatile(isVolatile) {
   init(Val, Ptr);
 }
 
+StoreInst::StoreInst(Value *Val, Value *Ptr, bool isVolatile, 
+                     BasicBlock *InsertAtEnd)
+  : Instruction(Type::VoidTy, Store, "", InsertAtEnd), Volatile(isVolatile) {
+  init(Val, Ptr);
+}
+
 
 //===----------------------------------------------------------------------===//
 //                       GetElementPtrInst Implementation
@@ -122,6 +168,14 @@ GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector<Value*> &Idx,
   init(Ptr, Idx);
 }
 
+GetElementPtrInst::GetElementPtrInst(Value *Ptr, const std::vector<Value*> &Idx,
+                                    const std::string &Name, BasicBlock *IAE)
+  : Instruction(PointerType::get(checkType(getIndexedType(Ptr->getType(),
+                                                          Idx, true))),
+                GetElementPtr, Name, IAE) {
+  init(Ptr, Idx);
+}
+
 // getIndexedType - Returns the type of the element that would be loaded with
 // a load instruction with the specified parameters.
 //
index 977849e22cc315ee3c9f5a562594fa8cc0d6c7cd..b2569e61836d97013d2c20fc904d82be902107c7 100644 (file)
@@ -21,11 +21,8 @@ using namespace llvm;
 //                             BinaryOperator Class
 //===----------------------------------------------------------------------===//
 
-BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2, 
-                               const Type *Ty, const std::string &Name,
-                               Instruction *InsertBefore)
-  : Instruction(Ty, iType, Name, InsertBefore) {
-
+void BinaryOperator::init(BinaryOps iType, Value *S1, Value *S2)
+{
   Operands.reserve(2);
   Operands.push_back(Use(S1, this));
   Operands.push_back(Use(S2, this));
@@ -36,30 +33,27 @@ BinaryOperator::BinaryOperator(BinaryOps iType, Value *S1, Value *S2,
   case Add: case Sub:
   case Mul: case Div:
   case Rem:
-    assert(Ty == S1->getType() &&
+    assert(getType() == S1->getType() &&
            "Arithmetic operation should return same type as operands!");
-    assert((Ty->isInteger() || Ty->isFloatingPoint()) && 
+    assert((getType()->isInteger() || getType()->isFloatingPoint()) && 
            "Tried to create an arithmetic operation on a non-arithmetic type!");
     break;
   case And: case Or:
   case Xor:
-    assert(Ty == S1->getType() &&
+    assert(getType() == S1->getType() &&
            "Logical operation should return same type as operands!");
-    assert(Ty->isIntegral() &&
+    assert(getType()->isIntegral() &&
            "Tried to create an logical operation on a non-integral type!");
     break;
   case SetLT: case SetGT: case SetLE:
   case SetGE: case SetEQ: case SetNE:
-    assert(Ty == Type::BoolTy && "Setcc must return bool!");
+    assert(getType() == Type::BoolTy && "Setcc must return bool!");
   default:
     break;
   }
 #endif
 }
 
-
-
-
 BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2,
                                       const std::string &Name,
                                        Instruction *InsertBefore) {
@@ -76,6 +70,22 @@ BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2,
   }
 }
 
+BinaryOperator *BinaryOperator::create(BinaryOps Op, Value *S1, Value *S2,
+                                      const std::string &Name,
+                                       BasicBlock *InsertAtEnd) {
+  assert(S1->getType() == S2->getType() &&
+         "Cannot create binary operator with two operands of differing type!");
+  switch (Op) {
+  // Binary comparison operators...
+  case SetLT: case SetGT: case SetLE:
+  case SetGE: case SetEQ: case SetNE:
+    return new SetCondInst(Op, S1, S2, Name, InsertAtEnd);
+
+  default:
+    return new BinaryOperator(Op, S1, S2, S1->getType(), Name, InsertAtEnd);
+  }
+}
+
 BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name,
                                           Instruction *InsertBefore) {
   if (!Op->getType()->isFloatingPoint())
@@ -88,6 +98,18 @@ BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name,
                               Op->getType(), Name, InsertBefore);
 }
 
+BinaryOperator *BinaryOperator::createNeg(Value *Op, const std::string &Name,
+                                          BasicBlock *InsertAtEnd) {
+  if (!Op->getType()->isFloatingPoint())
+    return new BinaryOperator(Instruction::Sub,
+                              Constant::getNullValue(Op->getType()), Op,
+                              Op->getType(), Name, InsertAtEnd);
+  else
+    return new BinaryOperator(Instruction::Sub,
+                              ConstantFP::get(Op->getType(), -0.0), Op,
+                              Op->getType(), Name, InsertAtEnd);
+}
+
 BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name,
                                           Instruction *InsertBefore) {
   return new BinaryOperator(Instruction::Xor, Op,
@@ -95,6 +117,13 @@ BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name,
                             Op->getType(), Name, InsertBefore);
 }
 
+BinaryOperator *BinaryOperator::createNot(Value *Op, const std::string &Name,
+                                          BasicBlock *InsertAtEnd) {
+  return new BinaryOperator(Instruction::Xor, Op,
+                            ConstantIntegral::getAllOnesValue(Op->getType()),
+                            Op->getType(), Name, InsertAtEnd);
+}
+
 
 // isConstantAllOnes - Helper function for several functions below
 static inline bool isConstantAllOnes(const Value *V) {
@@ -173,6 +202,14 @@ SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2,
   assert(getInverseCondition(Opcode));
 }
 
+SetCondInst::SetCondInst(BinaryOps Opcode, Value *S1, Value *S2, 
+                         const std::string &Name, BasicBlock *InsertAtEnd)
+  : BinaryOperator(Opcode, S1, S2, Type::BoolTy, Name, InsertAtEnd) {
+
+  // Make sure it's a valid type... getInverseCondition will assert out if not.
+  assert(getInverseCondition(Opcode));
+}
+
 // getInverseCondition - Return the inverse of the current condition opcode.
 // For example seteq -> setne, setgt -> setle, setlt -> setge, etc...
 //