Changed the fundemental architecture of Operands for Instructions. Now
authorChris Lattner <sabre@nondot.org>
Sat, 7 Jul 2001 08:36:50 +0000 (08:36 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 7 Jul 2001 08:36:50 +0000 (08:36 +0000)
Operands are maintained as a vector<Use> in the User class, and operator
iterators are provided as before.  Getting an operand no longer requires
a virtual function call.

WARNING: getOperand(x) where x >= getNumOperands() will now assert instead
of returning null!

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

25 files changed:
include/llvm/BasicBlock.h
include/llvm/ConstPoolVals.h
include/llvm/Function.h
include/llvm/InstrTypes.h
include/llvm/Instruction.h
include/llvm/User.h
include/llvm/iMemory.h
include/llvm/iOther.h
include/llvm/iTerminators.h
lib/Bytecode/Reader/InstructionReader.cpp
lib/Bytecode/Reader/ReaderInternals.h
lib/Bytecode/Writer/ConstantWriter.cpp
lib/Bytecode/Writer/InstructionWriter.cpp
lib/Transforms/IPO/InlineSimple.cpp
lib/Transforms/Scalar/ConstantProp.cpp
lib/Transforms/Scalar/DCE.cpp
lib/Transforms/Scalar/SCCP.cpp
lib/VMCore/AsmWriter.cpp
lib/VMCore/ConstantPool.cpp
lib/VMCore/InstrTypes.cpp
lib/VMCore/Value.cpp
lib/VMCore/iBranch.cpp
lib/VMCore/iCall.cpp
lib/VMCore/iReturn.cpp
lib/VMCore/iSwitch.cpp

index d7f286ec5616c088187466402517e1cf37869377..402b1fd0875e430672cbda1f180f309a90d0d018 100644 (file)
 
 class Instruction;
 class Method;
-class BasicBlock;
 class TerminatorInst;
 
-typedef UseTy<BasicBlock> BasicBlockUse;
-
 class BasicBlock : public Value {       // Basic blocks are data objects also
 public:
   typedef ValueHolder<Instruction, BasicBlock> InstListType;
index dbdda62f92dbb8bd45afc0e0abc75a4ac40c0826..d21ad8b6da9a1238a9ce6661aa1e479018c0aa0c 100644 (file)
@@ -20,9 +20,6 @@ class StructType;
 //                            ConstPoolVal Class
 //===----------------------------------------------------------------------===//
 
-class ConstPoolVal;
-typedef UseTy<ConstPoolVal> ConstPoolUse;
-
 class ConstPoolVal : public User {
   SymTabValue *Parent;
 
@@ -53,17 +50,6 @@ public:
 
   inline const SymTabValue *getParent() const { return Parent; }
   inline       SymTabValue *getParent()       { return Parent; }
-
-  // if i > the number of operands, then getOperand() returns 0, and setOperand
-  // returns false.  setOperand() may also return false if the operand is of
-  // the wrong type.
-  //
-  // Note that some subclasses may change this default no argument behavior
-  //
-  virtual Value *getOperand(unsigned i) { return 0; }
-  virtual const Value *getOperand(unsigned i) const { return 0; }
-  virtual bool setOperand(unsigned i, Value *Val) { return false; }
-  virtual void dropAllReferences() {}
 };
 
 
@@ -172,7 +158,6 @@ public:
 // ConstPoolArray - Constant Array Declarations
 //
 class ConstPoolArray : public ConstPoolVal {
-  vector<ConstPoolUse> Val;
   ConstPoolArray(const ConstPoolArray &CPT);
 public:
   ConstPoolArray(const ArrayType *T, vector<ConstPoolVal*> &V, 
@@ -183,20 +168,7 @@ public:
   virtual string getStrValue() const;
   virtual bool equals(const ConstPoolVal *V) const;
 
-  inline const vector<ConstPoolUse> &getValues() const { return Val; }
-
-  // Implement User stuff...
-  //
-  virtual Value *getOperand(unsigned i) { 
-    return (i < Val.size()) ? Val[i] : 0; 
-  }
-  virtual const Value *getOperand(unsigned i) const {
-    return (i < Val.size()) ? Val[i] : 0; 
-  }
-
-  // setOperand fails! You can't change a constant!
-  virtual bool setOperand(unsigned i, Value *Val) { return false; }
-  virtual void dropAllReferences() { Val.clear(); }
+  inline const vector<Use> &getValues() const { return Operands; }
 };
 
 
@@ -204,7 +176,6 @@ public:
 // ConstPoolStruct - Constant Struct Declarations
 //
 class ConstPoolStruct : public ConstPoolVal {
-  vector<ConstPoolUse> Val;
   ConstPoolStruct(const ConstPoolStruct &CPT);
 public:
   ConstPoolStruct(const StructType *T, vector<ConstPoolVal*> &V, 
@@ -215,20 +186,7 @@ public:
   virtual string getStrValue() const;
   virtual bool equals(const ConstPoolVal *V) const;
 
-  inline const vector<ConstPoolUse> &getValues() const { return Val; }
-
-  // Implement User stuff...
-  //
-  virtual Value *getOperand(unsigned i) { 
-    return (i < Val.size()) ? Val[i] : 0; 
-  }
-  virtual const Value *getOperand(unsigned i) const {
-    return (i < Val.size()) ? Val[i] : 0; 
-  }
-
-  // setOperand fails! You can't change a constant!
-  virtual bool setOperand(unsigned i, Value *Val) { return false; }
-  virtual void dropAllReferences() { Val.clear(); }
+  inline const vector<Use> &getValues() const { return Operands; }
 };
 
 #endif
index 51dbd646b318e11d084952666ea256c81fe7de07..b7aa855b2c2aad89fc241cfad6cc71c52d2cf663 100644 (file)
@@ -19,11 +19,8 @@ class Instruction;
 class BasicBlock;
 class MethodArgument;
 class MethodType;
-class Method;
 class Module;
 
-typedef UseTy<Method> MethodUse;
-
 class Method : public SymTabValue {
 public:
   typedef ValueHolder<MethodArgument, Method> ArgumentListType;
index 6d35ed5d50f5d19b96442f006d0a891972ed1c71..8ec0da54d2e158f90be8d60fc19b7fee37326994 100644 (file)
@@ -30,15 +30,8 @@ public:
 
   // Terminators must implement the methods required by Instruction...
   virtual Instruction *clone() const = 0;
-  virtual void dropAllReferences() = 0;
   virtual string getOpcode() const = 0;
 
-  virtual bool setOperand(unsigned i, Value *Val) = 0;
-  virtual const Value *getOperand(unsigned i) const = 0;
-  inline Value *getOperand(unsigned i) {
-    return (Value*)((const Instruction *)this)->getOperand(i);
-  }
-
   // Additionally, they must provide a method to get at the successors of this
   // terminator instruction.  If 'idx' is out of range, a null pointer shall be
   // returned.
@@ -57,7 +50,6 @@ public:
 //===----------------------------------------------------------------------===//
 
 class UnaryOperator : public Instruction {
-  Use Source;
 public:
 
   // create() - Construct a unary instruction, given the opcode
@@ -66,33 +58,17 @@ public:
   static UnaryOperator *create(unsigned Op, Value *Source);
 
   UnaryOperator(Value *S, unsigned iType, const string &Name = "")
-      : Instruction(S->getType(), iType, Name), Source(S, this) {
+      : Instruction(S->getType(), iType, Name) {
+    Operands.reserve(1);
+    Operands.push_back(Use(S, this));
   }
   inline ~UnaryOperator() { dropAllReferences(); }
 
   virtual Instruction *clone() const { 
-    return create(getInstType(), Source);
-  }
-
-  virtual void dropAllReferences() {
-    Source = 0;
+    return create(getInstType(), Operands[0]);
   }
 
   virtual string getOpcode() const = 0;
-
-  virtual unsigned getNumOperands() const { return 1; }
-  inline Value *getOperand(unsigned i) {
-    return (i == 0) ? Source : 0;
-  }
-  virtual const Value *getOperand(unsigned i) const {
-    return (i == 0) ? Source : 0;
-  }
-  virtual bool setOperand(unsigned i, Value *Val) {
-    // assert(Val && "operand must not be null!");
-    if (i) return false;
-    Source = Val;
-    return true;
-  }
 };
 
 
@@ -102,7 +78,6 @@ public:
 //===----------------------------------------------------------------------===//
 
 class BinaryOperator : public Instruction {
-  Use Source1, Source2;
 public:
 
   // create() - Construct a binary instruction, given the opcode
@@ -113,41 +88,20 @@ public:
 
   BinaryOperator(unsigned iType, Value *S1, Value *S2, 
                  const string &Name = "") 
-    : Instruction(S1->getType(), iType, Name), Source1(S1, this), 
-      Source2(S2, this){
-    assert(S1 && S2 && S1->getType() == S2->getType());
+    : Instruction(S1->getType(), iType, Name) {
+    Operands.reserve(2);
+    Operands.push_back(Use(S1, this));
+    Operands.push_back(Use(S2, this));
+    assert(Operands[0] && Operands[1] && 
+          Operands[0]->getType() == Operands[1]->getType());
   }
   inline ~BinaryOperator() { dropAllReferences(); }
 
   virtual Instruction *clone() const {
-    return create(getInstType(), Source1, Source2);
-  }
-
-  virtual void dropAllReferences() {
-    Source1 = Source2 = 0;
+    return create(getInstType(), Operands[0], Operands[1]);
   }
 
   virtual string getOpcode() const = 0;
-
-  virtual unsigned getNumOperands() const { return 2; }
-  virtual const Value *getOperand(unsigned i) const {
-    return (i == 0) ? Source1 : ((i == 1) ? Source2 : 0);
-  }
-  inline Value *getOperand(unsigned i) {
-    return (i == 0) ? Source1 : ((i == 1) ? Source2 : 0);
-  }
-
-  virtual bool setOperand(unsigned i, Value *Val) {
-    // assert(Val && "operand must not be null!");
-    if (i == 0) {
-      Source1 = Val; //assert(Val->getType() == Source2->getType());
-    } else if (i == 1) {
-      Source2 = Val; //assert(Val->getType() == Source1->getType());
-    } else {
-      return false;
-    }
-    return true;
-  }
 };
 
 #endif
index 871ed037ef1d27762cb26046042ee7c5637eb128..70665232cd5481bd14fa93b9f3ade3258f91b588 100644 (file)
@@ -41,32 +41,6 @@ public:
   inline       BasicBlock *getParent()       { return Parent; }
   bool hasSideEffects() const { return false; }  // Memory & Call insts = true
 
-  // ---------------------------------------------------------------------------
-  // Implement the User interface 
-  // if i > the number of operands, then getOperand() returns 0, and setOperand
-  // returns false.  setOperand() may also return false if the operand is of
-  // the wrong type.
-  //
-  inline Value *getOperand(unsigned i) {
-    return (Value*)((const Instruction *)this)->getOperand(i);
-  }
-  virtual const Value *getOperand(unsigned i) const = 0;
-  virtual bool setOperand(unsigned i, Value *Val) = 0;
-  virtual unsigned getNumOperands() const = 0;
-
-  // ---------------------------------------------------------------------------
-  // Operand Iterator interface...
-  //
-  template <class _Inst, class _Val> class OperandIterator;
-  typedef OperandIterator<Instruction *, Value *> op_iterator;
-  typedef OperandIterator<const Instruction *, const Value *> op_const_iterator;
-
-  inline op_iterator       op_begin()      ;
-  inline op_const_iterator op_begin() const;
-  inline op_iterator       op_end()        ;
-  inline op_const_iterator op_end()   const;
-
-
   // ---------------------------------------------------------------------------
   // Subclass classification... getInstType() returns a member of 
   // one of the enums that is coming soon (down below)...
@@ -148,52 +122,6 @@ public:
     NumOps,                          // Must be the last 'op' defined.
     UserOp1, UserOp2                 // May be used internally to a pass...
   };
-
-public:
-  template <class _Inst, class _Val>         // Operand Iterator Implementation
-  class OperandIterator {
-    const _Inst Inst;
-    unsigned idx;
-  public:
-    typedef OperandIterator<_Inst, _Val> _Self;
-    typedef bidirectional_iterator_tag iterator_category;
-    typedef _Val pointer;
-    
-    inline OperandIterator(_Inst T) : Inst(T), idx(0) {}    // begin iterator
-    inline OperandIterator(_Inst T, bool) 
-      : Inst(T), idx(Inst->getNumOperands()) {}             // end iterator
-    
-    inline bool operator==(const _Self& x) const { return idx == x.idx; }
-    inline bool operator!=(const _Self& x) const { return !operator==(x); }
-
-    inline pointer operator*() const { return Inst->getOperand(idx); }
-    inline pointer *operator->() const { return &(operator*()); }
-    
-    inline _Self& operator++() { ++idx; return *this; } // Preincrement
-    inline _Self operator++(int) { // Postincrement
-      _Self tmp = *this; ++*this; return tmp; 
-    }
-
-    inline _Self& operator--() { --idx; return *this; }  // Predecrement
-    inline _Self operator--(int) { // Postdecrement
-      _Self tmp = *this; --*this; return tmp;
-    }
-  };
-
 };
 
-inline Instruction::op_iterator       Instruction::op_begin()       {
-  return op_iterator(this);
-}
-inline Instruction::op_const_iterator Instruction::op_begin() const {
-  return op_const_iterator(this);
-}
-inline Instruction::op_iterator       Instruction::op_end()         {
-  return op_iterator(this,true);
-}
-inline Instruction::op_const_iterator Instruction::op_end()   const {
-  return op_const_iterator(this,true);
-}
-
-
 #endif
index 58e0dec22bb9f50f0752932846392cf06dcbaa28..7f2e3e39d8ddcf4da155a0211c31d5fc88533b49 100644 (file)
 #define LLVM_USER_H
 
 #include "llvm/Value.h"
+#include <vector>
 
 class User : public Value {
   User(const User &);             // Do not implement
+protected:
+  vector<Use> Operands;
 public:
   User(const Type *Ty, ValueTy vty, const string &name = "");
-  virtual ~User() {}
+  virtual ~User() { dropAllReferences(); }
 
-  // if i > the number of operands, then getOperand() returns 0, and setOperand
-  // returns false.  setOperand() may also return false if the operand is of
-  // the wrong type.
+  inline Value *getOperand(unsigned i) { 
+    assert(i < Operands.size() && "getOperand() out of range!");
+    return Operands[i]; 
+  }
+  inline const Value *getOperand(unsigned i) const {
+    assert(i < Operands.size() && "getOperand() const out of range!");
+    return Operands[i]; 
+  }
+  inline void setOperand(unsigned i, Value *Val) {
+    assert(i < Operands.size() && "setOperand() out of range!");
+    Operands[i] = Val;
+  }
+  inline unsigned getNumOperands() const { return Operands.size(); }
+
+  // ---------------------------------------------------------------------------
+  // Operand Iterator interface...
   //
-  virtual Value *getOperand(unsigned i) = 0;
-  virtual const Value *getOperand(unsigned i) const = 0;
-  virtual bool setOperand(unsigned i, Value *Val) = 0;
+  typedef vector<Use>::iterator       op_iterator;
+  typedef vector<Use>::const_iterator op_const_iterator;
+
+  inline op_iterator       op_begin()       { return Operands.begin(); }
+  inline op_const_iterator op_begin() const { return Operands.end(); }
+  inline op_iterator       op_end()         { return Operands.end(); }
+  inline op_const_iterator op_end()   const { return Operands.end(); }
 
   // dropAllReferences() - This virtual function should be overridden to "let
   // go" of all references that this user is maintaining.  This allows one to 
@@ -36,7 +56,9 @@ public:
   // valid on an object that has "dropped all references", except operator 
   // delete.
   //
-  virtual void dropAllReferences() = 0;
+  virtual void dropAllReferences() {
+    Operands.clear();
+  }
 
   // replaceUsesOfWith - Replaces all references to the "From" definition with
   // references to the "To" definition.  (defined in Value.cpp)
index 077266de94cb58d7a87ed995b00935389b51884d..fafe4c311a16e9708e81b767fca9dd18f78480b1 100644 (file)
 
 #include "llvm/Instruction.h"
 #include "llvm/DerivedTypes.h"
-#include "llvm/ConstPoolVals.h"
-
-class ConstPoolType;
 
 class AllocationInst : public Instruction {
-protected:
-  UseTy<ConstPoolType> TyVal;
-  Use ArraySize;
 public:
-  AllocationInst(ConstPoolType *tyVal, Value *arrSize, unsigned iTy, 
-                const string &Name = "") 
-    : Instruction(tyVal->getValue(), iTy, Name),
-      TyVal(tyVal, this), ArraySize(arrSize, this) {
-
-    // Make sure they didn't try to specify a size for an invalid type...
-    assert(arrSize == 0 || 
-          (getType()->getValueType()->isArrayType() && 
-           ((const ArrayType*)getType()->getValueType())->isUnsized()) && 
-          "Trying to allocate something other than unsized array, with size!");
-
-    // Make sure that if a size is specified, that it is a uint!
-    assert(arrSize == 0 || arrSize->getType() == Type::UIntTy &&
-          "Malloc SIZE is not a 'uint'!");
+  AllocationInst(const Type *Ty, Value *ArraySize, unsigned iTy, 
+                const string &Name = "")
+    : Instruction(Ty, iTy, Name) {
+    assert(Ty->isPointerType() && "Can't allocate a non pointer type!");
+
+    if (ArraySize) {
+      // Make sure they didn't try to specify a size for !(unsized array) type...
+      assert((getType()->getValueType()->isArrayType() && 
+             ((const ArrayType*)getType()->getValueType())->isUnsized()) && 
+            "Trying to allocate something other than unsized array, with size!");
+
+      Operands.reserve(1);
+      Operands.push_back(Use(ArraySize, this));
+    }
   }
-  inline ~AllocationInst() {}
 
   // getType - Overload to return most specific pointer type...
   inline const PointerType *getType() const {
@@ -42,46 +35,15 @@ public:
   }
 
   virtual Instruction *clone() const = 0;
-
-  inline virtual void dropAllReferences() { TyVal = 0; ArraySize = 0; }
-  virtual bool setOperand(unsigned i, Value *Val) { 
-    if (i == 0) {
-      assert(!Val || Val->getValueType() == Value::ConstantVal);
-      TyVal = (ConstPoolType*)Val;
-      return true;
-    } else if (i == 1) {
-      // Make sure they didn't try to specify a size for an invalid type...
-      assert(Val == 0 || 
-            (getType()->getValueType()->isArrayType() && 
-             ((const ArrayType*)getType()->getValueType())->isUnsized()) && 
-           "Trying to allocate something other than unsized array, with size!");
-      
-      // Make sure that if a size is specified, that it is a uint!
-      assert(Val == 0 || Val->getType() == Type::UIntTy &&
-            "Malloc SIZE is not a 'uint'!");
-      
-      ArraySize = Val;
-      return true;
-    }
-    return false; 
-  }
-
-  virtual unsigned getNumOperands() const { return 2; }
-
-  virtual const Value *getOperand(unsigned i) const { 
-    return i == 0 ? TyVal : (i == 1 ? ArraySize : 0); 
-  }
 };
 
 class MallocInst : public AllocationInst {
 public:
-  MallocInst(ConstPoolType *tyVal, Value *ArraySize = 0, 
-            const string &Name = "") 
-    : AllocationInst(tyVal, ArraySize, Instruction::Malloc, Name) {}
-  inline ~MallocInst() {}
+  MallocInst(const Type *Ty, Value *ArraySize = 0, const string &Name = "") 
+    : AllocationInst(Ty, ArraySize, Instruction::Malloc, Name) {}
 
   virtual Instruction *clone() const { 
-    return new MallocInst(TyVal, ArraySize);
+    return new MallocInst(getType(), Operands.size() ? Operands[1] : 0);
   }
 
   virtual string getOpcode() const { return "malloc"; }
@@ -89,13 +51,11 @@ public:
 
 class AllocaInst : public AllocationInst {
 public:
-  AllocaInst(ConstPoolType *tyVal, Value *ArraySize = 0, 
-            const string &Name = "") 
-    : AllocationInst(tyVal, ArraySize, Instruction::Alloca, Name) {}
-  inline ~AllocaInst() {}
+  AllocaInst(const Type *Ty, Value *ArraySize = 0, const string &Name = "") 
+    : AllocationInst(Ty, ArraySize, Instruction::Alloca, Name) {}
 
   virtual Instruction *clone() const { 
-    return new AllocaInst(TyVal, ArraySize);
+    return new AllocaInst(getType(), Operands.size() ? Operands[1] : 0);
   }
 
   virtual string getOpcode() const { return "alloca"; }
@@ -104,35 +64,16 @@ public:
 
 
 class FreeInst : public Instruction {
-protected:
-  Use Pointer;
 public:
   FreeInst(Value *Ptr, const string &Name = "") 
-    : Instruction(Type::VoidTy, Instruction::Free, Name),
-      Pointer(Ptr, this) {
-
+    : Instruction(Type::VoidTy, Instruction::Free, Name) {
     assert(Ptr->getType()->isPointerType() && "Can't free nonpointer!");
+    Operands.reserve(1);
+    Operands.push_back(Use(Ptr, this));
   }
   inline ~FreeInst() {}
 
-  virtual Instruction *clone() const { return new FreeInst(Pointer); }
-
-  inline virtual void dropAllReferences() { Pointer = 0;  }
-
-  virtual bool setOperand(unsigned i, Value *Val) { 
-    if (i == 0) {
-      assert(!Val || Val->getType()->isPointerType() &&
-            "Can't free nonpointer!");
-      Pointer = Val;
-      return true;
-    }
-    return false; 
-  }
-
-  virtual unsigned getNumOperands() const { return 1; }
-  virtual const Value *getOperand(unsigned i) const { 
-    return i == 0 ? Pointer : 0;
-  }
+  virtual Instruction *clone() const { return new FreeInst(Operands[0]); }
 
   virtual string getOpcode() const { return "free"; }
 };
index 23bc5462a8ca18725c0ff62b91d581e0c044a7c7..15c52729b339bbca5a667987d50cbc15ef1c2f98 100644 (file)
 // scientist's overactive imagination.
 //
 class PHINode : public Instruction {
-  typedef pair<Use,BasicBlockUse> PairTy;
-  vector<PairTy> IncomingValues;
-
   PHINode(const PHINode &PN);
 public:
   PHINode(const Type *Ty, const string &Name = "");
   inline ~PHINode() { dropAllReferences(); }
 
   virtual Instruction *clone() const { return new PHINode(*this); }
-
-  // Implement all of the functionality required by User...
-  //
-  virtual void dropAllReferences();
-  virtual const Value *getOperand(unsigned i) const {
-    if (i >= IncomingValues.size()*2) return 0;
-    if (i & 1) return IncomingValues[i/2].second;
-    else       return IncomingValues[i/2].first;
-  }
-  inline Value *getOperand(unsigned i) {
-    return (Value*)((const PHINode*)this)->getOperand(i);
-  }
-  virtual unsigned getNumOperands() const { return IncomingValues.size()*2; }
-  virtual bool setOperand(unsigned i, Value *Val);
   virtual string getOpcode() const { return "phi"; }
 
   // getNumIncomingValues - Return the number of incoming edges the PHI node has
-  inline unsigned getNumIncomingValues() const { return IncomingValues.size(); }
+  inline unsigned getNumIncomingValues() const { return Operands.size()/2; }
 
   // getIncomingValue - Return incoming value #x
-  inline Value *getIncomingValue(unsigned i) const { 
-    return IncomingValues[i].first; 
+  inline const Value *getIncomingValue(unsigned i) const {
+    return Operands[i*2];
+  }
+  inline Value *getIncomingValue(unsigned i) {
+    return Operands[i*2];
   }
 
   // getIncomingBlock - Return incoming basic block #x
-  inline BasicBlock *getIncomingBlock(unsigned i) const { 
-    return IncomingValues[i].second; 
+  inline const BasicBlock *getIncomingBlock(unsigned i) const { 
+    return Operands[i*2+1]->castBasicBlockAsserting();
+  }
+  inline BasicBlock *getIncomingBlock(unsigned i) { 
+    return Operands[i*2+1]->castBasicBlockAsserting();
   }
 
   // addIncoming - Add an incoming value to the end of the PHI list
@@ -97,8 +86,6 @@ public:
 //===----------------------------------------------------------------------===//
 
 class CallInst : public Instruction {
-  MethodUse M;
-  vector<Use> Params;
   CallInst(const CallInst &CI);
 public:
   CallInst(Method *M, vector<Value*> &params, const string &Name = "");
@@ -110,21 +97,12 @@ public:
   bool hasSideEffects() const { return true; }
 
 
-  const Method *getCalledMethod() const { return M; }
-        Method *getCalledMethod()       { return M; }
-
-  // Implement all of the functionality required by Instruction...
-  //
-  virtual void dropAllReferences();
-  virtual const Value *getOperand(unsigned i) const { 
-    return i == 0 ? M : ((i <= Params.size()) ? Params[i-1] : 0);
+  const Method *getCalledMethod() const {
+    return Operands[0]->castMethodAsserting(); 
   }
-  inline Value *getOperand(unsigned i) {
-    return (Value*)((const CallInst*)this)->getOperand(i);
+  Method *getCalledMethod() {
+    return Operands[0]->castMethodAsserting(); 
   }
-  virtual unsigned getNumOperands() const { return Params.size()+1; }
-
-  virtual bool setOperand(unsigned i, Value *Val);
 };
 
 #endif
index 168d91d0270e48cb1005257c9cf093a32dedce25..0d154eab3957e0a40fa2249675f07cb36bff05e9 100644 (file)
 //              not continue in this method any longer.
 //
 class ReturnInst : public TerminatorInst {
-  Use Val;   // Will be null if returning void...
-  ReturnInst(const ReturnInst &RI);
+  ReturnInst(const ReturnInst &RI) : TerminatorInst(Instruction::Ret) {
+    if (RI.Operands.size()) {
+      assert(RI.Operands.size() == 1 && "Return insn can only have 1 operand!");
+      Operands.reserve(1);
+      Operands.push_back(Use(RI.Operands[0], this));
+    }
+  }
 public:
-  ReturnInst(Value *value = 0);
+  ReturnInst(Value *RetVal = 0) : TerminatorInst(Instruction::Ret) {
+    if (RetVal) {
+      Operands.reserve(1);
+      Operands.push_back(Use(RetVal, this));
+    }
+  }
   inline ~ReturnInst() { dropAllReferences(); }
 
   virtual Instruction *clone() const { return new ReturnInst(*this); }
 
   virtual string getOpcode() const { return "ret"; }
 
-  inline const Value *getReturnValue() const { return Val; }
-  inline       Value *getReturnValue()       { return Val; }
-
-  virtual void dropAllReferences();
-  virtual const Value *getOperand(unsigned i) const {
-    return (i == 0) ? Val : 0;
+  inline const Value *getReturnValue() const {
+    return Operands.size() ? Operands[0] : 0; 
+  }
+  inline       Value *getReturnValue()       {
+    return Operands.size() ? Operands[0] : 0;
   }
-  inline Value *getOperand(unsigned i) { return (i == 0) ? Val : 0;  }
-  virtual bool setOperand(unsigned i, Value *Val);
-  virtual unsigned getNumOperands() const { return Val != 0; }
 
   // Additionally, they must provide a method to get at the successors of this
   // terminator instruction.  If 'idx' is out of range, a null pointer shall be
@@ -58,9 +64,6 @@ public:
 // BranchInst - Conditional or Unconditional Branch instruction.
 //
 class BranchInst : public TerminatorInst {
-  BasicBlockUse TrueDest, FalseDest;
-  Use Condition;
-
   BranchInst(const BranchInst &BI);
 public:
   // If cond = null, then is an unconditional br...
@@ -69,32 +72,40 @@ public:
 
   virtual Instruction *clone() const { return new BranchInst(*this); }
 
-  virtual void dropAllReferences();
-  inline const Value *getCondition() const { return Condition; }
-  inline       Value *getCondition()       { return Condition; }
-
   inline bool isUnconditional() const {
-    return Condition == 0 || !FalseDest;
+    return Operands.size() == 1;
+  }
+
+  inline const Value *getCondition() const {
+    return isUnconditional() ? 0 : Operands[2];
+  }
+  inline       Value *getCondition()       {
+    return isUnconditional() ? 0 : Operands[2];
   }
 
   virtual string getOpcode() const { return "br"; }
 
-  inline Value *getOperand(unsigned i) {
-    return (Value*)((const BranchInst *)this)->getOperand(i);
+  // setUnconditionalDest - Change the current branch to an unconditional branch
+  // targeting the specified block.
+  //
+  void setUnconditionalDest(BasicBlock *Dest) {
+    if (Operands.size() == 3)
+      Operands.erase(Operands.begin()+1, Operands.end());
+    Operands[0] = Dest;
+  }
+
+  // Additionally, they must provide a method to get at the successors of this
+  // terminator instruction.
+  //
+  virtual const BasicBlock *getSuccessor(unsigned i) const {
+    return (i == 0) ? Operands[0]->castBasicBlockAsserting() : 
+          ((i == 1 && Operands.size() > 1) 
+               ? Operands[1]->castBasicBlockAsserting() : 0);
   }
-  virtual const Value *getOperand(unsigned i) const;
-  virtual bool setOperand(unsigned i, Value *Val);
-  virtual unsigned getNumOperands() const { return isUnconditional() ? 1 : 3; }
   inline BasicBlock *getSuccessor(unsigned idx) {
     return (BasicBlock*)((const BranchInst *)this)->getSuccessor(idx);
   }
 
-  // Additionally, they must provide a method to get at the successors of this
-  // terminator instruction.  If 'idx' is out of range, a null pointer shall be
-  // returned.
-  //
-  virtual const BasicBlock *getSuccessor(unsigned idx) const;
   virtual unsigned getNumSuccessors() const { return 1+!isUnconditional(); }
 };
 
@@ -103,17 +114,12 @@ public:
 // SwitchInst - Multiway switch
 //
 class SwitchInst : public TerminatorInst {
-public:
-  typedef pair<ConstPoolUse, BasicBlockUse> dest_value;
-private:
-  BasicBlockUse DefaultDest;
-  Use Val;
-  vector<dest_value> Destinations;
-
+  // Operand[0] = Value to switch on
+  // Operand[1] = Default basic block destination
   SwitchInst(const SwitchInst &RI);
 public:
-  typedef vector<dest_value>::iterator       dest_iterator;
-  typedef vector<dest_value>::const_iterator dest_const_iterator;
+  //typedef vector<dest_value>::iterator       dest_iterator;
+  //typedef vector<dest_value>::const_iterator dest_const_iterator;
 
   SwitchInst(Value *Value, BasicBlock *Default);
   inline ~SwitchInst() { dropAllReferences(); }
@@ -122,36 +128,50 @@ public:
 
   // Accessor Methods for Switch stmt
   //
+  /*
   inline dest_iterator dest_begin() { return Destinations.begin(); }
   inline dest_iterator dest_end  () { return Destinations.end(); }
   inline dest_const_iterator dest_begin() const { return Destinations.begin(); }
   inline dest_const_iterator dest_end  () const { return Destinations.end(); }
+  */
 
-  inline const Value *getCondition() const { return Val; }
-  inline       Value *getCondition()       { return Val; }
-  inline const BasicBlock *getDefaultDest() const { return DefaultDest; }
-  inline       BasicBlock *getDefaultDest()       { return DefaultDest; }
+  inline const Value *getCondition() const { return Operands[0]; }
+  inline       Value *getCondition()       { return Operands[0]; }
+  inline const BasicBlock *getDefaultDest() const {
+    return Operands[1]->castBasicBlockAsserting();
+  }
+  inline       BasicBlock *getDefaultDest()       {
+    return Operands[1]->castBasicBlockAsserting();
+  }
 
   void dest_push_back(ConstPoolVal *OnVal, BasicBlock *Dest);
 
   virtual string getOpcode() const { return "switch"; }
-  inline Value *getOperand(unsigned i) {
-    return (Value*)((const SwitchInst*)this)->getOperand(i);
-  }
-  virtual const Value *getOperand(unsigned i) const;
-  virtual bool setOperand(unsigned i, Value *Val);
-  virtual unsigned getNumOperands() const;
-  virtual void dropAllReferences();  
 
   // Additionally, they must provide a method to get at the successors of this
   // terminator instruction.  If 'idx' is out of range, a null pointer shall be
   // returned.
   //
-  virtual const BasicBlock *getSuccessor(unsigned idx) const;
-  virtual unsigned getNumSuccessors() const { return 1+Destinations.size(); }
+  virtual const BasicBlock *getSuccessor(unsigned idx) const {
+    if (idx >= Operands.size()/2) return 0;
+    return Operands[idx*2+1]->castBasicBlockAsserting();
+  }
   inline BasicBlock *getSuccessor(unsigned idx) {
-    return (BasicBlock*)((const SwitchInst *)this)->getSuccessor(idx);
+    if (idx >= Operands.size()/2) return 0;
+    return Operands[idx*2+1]->castBasicBlockAsserting();
+  }
+
+  // getSuccessorValue - Return the value associated with the specified successor
+  // WARNING: This does not gracefully accept idx's out of range!
+  inline const ConstPoolVal *getSuccessorValue(unsigned idx) const {
+    assert(idx < getNumSuccessors() && "Successor # out of range!");
+    return Operands[idx*2]->castConstantAsserting();
+  }
+  inline ConstPoolVal *getSuccessorValue(unsigned idx) {
+    assert(idx < getNumSuccessors() && "Successor # out of range!");
+    return Operands[idx*2]->castConstantAsserting();
   }
+  virtual unsigned getNumSuccessors() const { return Operands.size()/2; }
 };
 
 #endif
index fd919c92a262abddc3ede3f842f43d16592979ea..dac7d37415874d647c1ab4fa04017508d9e7567f 100644 (file)
@@ -80,8 +80,11 @@ bool BytecodeParser::ParseRawInst(const uchar *&Buf, const uchar *EndBuf,
     break;
   }
 
-  //cerr << "NO: "  << Result.NumOperands   << " opcode: " << Result.Opcode 
-  //   << " Ty: " << Result.Ty->getName() << " arg1: "   << Result.Arg1 << endl;
+#if 0
+  cerr << "NO: "  << Result.NumOperands   << " opcode: " << Result.Opcode 
+       << " Ty: " << Result.Ty->getName() << " arg1: "   << Result.Arg1 
+       << " arg2: "   << Result.Arg2 << " arg3: "   << Result.Arg3 << endl;
+#endif
   return false;
 }
 
@@ -198,13 +201,13 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
     return false;
   } else if (Raw.Opcode == Instruction::Malloc) {
     if (Raw.NumOperands > 2) return true;
-    Value *Sz = (Raw.NumOperands == 2) ? getValue(Type::UIntTy, Raw.Arg2) : 0;
-    Res = new MallocInst((ConstPoolType*)getValue(Type::TypeTy, Raw.Arg1), Sz);
+    Value *Sz = Raw.NumOperands ? getValue(Type::UIntTy, Raw.Arg1) : 0;
+    Res = new MallocInst(Raw.Ty, Sz);
     return false;
   } else if (Raw.Opcode == Instruction::Alloca) {
     if (Raw.NumOperands > 2) return true;
-    Value *Sz = (Raw.NumOperands == 2) ? getValue(Type::UIntTy, Raw.Arg2) : 0;
-    Res = new AllocaInst((ConstPoolType*)getValue(Type::TypeTy, Raw.Arg1), Sz);
+    Value *Sz = Raw.NumOperands ? getValue(Type::UIntTy, Raw.Arg1) : 0;
+    Res = new AllocaInst(Raw.Ty, Sz);
     return false;
   } else if (Raw.Opcode == Instruction::Free) {
     Value *Val = getValue(Raw.Ty, Raw.Arg1);
@@ -213,6 +216,7 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
     return false;
   }
 
-  cerr << "Unrecognized instruction! " << Raw.Opcode << endl;
+  cerr << "Unrecognized instruction! " << Raw.Opcode 
+       << " ADDR = 0x" << (void*)Buf << endl;
   return true;
 }
index 3bb047267437f4ca7b3317e222f55dab41eced0a..fffcdb83c7ac042c1c816f0e81c220874b86c91d 100644 (file)
@@ -94,16 +94,9 @@ public:
 
 struct InstPlaceHolderHelper : public Instruction {
   InstPlaceHolderHelper(const Type *Ty) : Instruction(Ty, UserOp1, "") {}
-  inline virtual void dropAllReferences() {}
   virtual string getOpcode() const { return "placeholder"; }
 
   virtual Instruction *clone() const { abort(); return 0; }
-
-  // No "operands"...
-  virtual Value *getOperand(unsigned i) { return 0; }
-  virtual const Value *getOperand(unsigned i) const { return 0; }
-  virtual bool setOperand(unsigned i, Value *Val) { return false; }
-  virtual unsigned getNumOperands() const { return 0; }
 };
 
 struct BBPlaceHolderHelper : public BasicBlock {
index e65ea45067419e850eaf8fd8e969e187bdab3218..5ca0fca0d1219c56356ad9cc6d7fc1e9ec16fad2 100644 (file)
@@ -128,7 +128,7 @@ bool BytecodeWriter::outputConstant(const ConstPoolVal *CPV) {
 
   case Type::StructTyID: {
     const ConstPoolStruct *CPS = (const ConstPoolStruct*)CPV;
-    const vector<ConstPoolUse> &Vals = CPS->getValues();
+    const vector<Use> &Vals = CPS->getValues();
 
     for (unsigned i = 0; i < Vals.size(); ++i) {
       int Slot = Table.getValSlot(Vals[i]);
index c7c04efb731bd5b6fd791ab4e22e3d592a3e2c15..0cd93c04fdb7c2b9bebecfd4bcf7f5d2156ab9bf 100644 (file)
@@ -32,14 +32,13 @@ static void outputInstructionFormat0(const Instruction *I,
   output_vbr(I->getInstType(), Out);             // Instruction Opcode ID
   output_vbr(Type, Out);                         // Result type
 
-  unsigned NumArgs;  // Count the number of arguments to the instruction
-  for (NumArgs = 0; I->getOperand(NumArgs); NumArgs++) /*empty*/;
+  unsigned NumArgs = I->getNumOperands();
   output_vbr(NumArgs, Out);
 
-  for (unsigned i = 0; const Value *N = I->getOperand(i); i++) {
-    assert(i < NumArgs && "Count of arguments failed!");
-
+  for (unsigned i = 0; i < NumArgs; ++i) {
+    const Value *N = I->getOperand(i);
     int Slot = Table.getValSlot(N);
+    assert(Slot >= 0 && "No slot number for value!?!?");      
     output_vbr((unsigned)Slot, Out);
   }
   align32(Out);    // We must maintain correct alignment!
@@ -110,25 +109,24 @@ static void outputInstructionFormat3(const Instruction *I,
   //
   unsigned Opcode = (3 << 30) | (IType << 24) | (Type << 18) |
                     (Slots[0] << 12) | (Slots[1] << 6) | (Slots[2] << 0);
-  //  cerr << "3 " << IType << " " << Type << " " << Slots[0] << " " 
-  //       << Slots[1] << " " << Slots[2] << endl;
+  //cerr << "3 " << IType << " " << Type << " " << Slots[0] << " " 
+  //     << Slots[1] << " " << Slots[2] << endl;
   output(Opcode, Out);
 }
 
 bool BytecodeWriter::processInstruction(const Instruction *I) {
   assert(I->getInstType() < 64 && "Opcode too big???");
 
-  unsigned NumOperands = 0;
+  unsigned NumOperands = I->getNumOperands();
   int MaxOpSlot = 0;
-  int Slots[3]; Slots[0] = (1 << 12)-1;
+  int Slots[3]; Slots[0] = (1 << 12)-1;   // Marker to signify 0 operands
 
-  const Value *Def;
-  while ((Def = I->getOperand(NumOperands))) {
+  for (unsigned i = 0; i < NumOperands; ++i) {
+    const Value *Def = I->getOperand(i);
     int slot = Table.getValSlot(Def);
     assert(slot != -1 && "Broken bytecode!");
     if (slot > MaxOpSlot) MaxOpSlot = slot;
-    if (NumOperands < 3) Slots[NumOperands] = slot;
-    NumOperands++;
+    if (i < 3) Slots[i] = slot;
   }
 
   // Figure out which type to encode with the instruction.  Typically we want
@@ -137,12 +135,10 @@ bool BytecodeWriter::processInstruction(const Instruction *I) {
   // the first param is actually interesting).  But if we have no arguments
   // we take the type of the instruction itself.  
   //
-
-  const Type *Ty;
-  if (NumOperands)
-    Ty = I->getOperand(0)->getType();
-  else
-    Ty = I->getType();
+  const Type *Ty = NumOperands ? I->getOperand(0)->getType() : I->getType();
+  if (I->getInstType() == Instruction::Malloc || 
+      I->getInstType() == Instruction::Alloca)
+    Ty = I->getType();  // Malloc & Alloca ALWAYS want to encode the return type
 
   unsigned Type;
   int Slot = Table.getValSlot(Ty);
@@ -179,6 +175,8 @@ bool BytecodeWriter::processInstruction(const Instruction *I) {
     break;
   }
 
+  // If we weren't handled before here, we either have a large number of operands
+  // or a large operand index that we are refering to.
   outputInstructionFormat0(I, Table, Type, Out);
   return false;
 }
index d85b33dffd1e56648d5091c8b89b62e0156f84a5..de76dcd52dcd6b181574fc74d57fb649eca38629 100644 (file)
@@ -37,7 +37,8 @@ using namespace opt;
 static inline void RemapInstruction(Instruction *I, 
                                    map<const Value *, Value*> &ValueMap) {
 
-  for (unsigned op = 0; const Value *Op = I->getOperand(op); ++op) {
+  for (unsigned op = 0, E = I->getNumOperands(); op != E; ++op) {
+    const Value *Op = I->getOperand(op);
     Value *V = ValueMap[Op];
     if (!V && Op->isMethod()) 
       continue;  // Methods don't get relocated
@@ -115,11 +116,9 @@ bool opt::InlineMethod(BasicBlock::iterator CIIt) {
   //
   Method::ArgumentListType::const_iterator PTI = 
     CalledMeth->getArgumentList().begin();
-  for (unsigned a = 1; Value *Operand = CI->getOperand(a); ++a, ++PTI) {
-    ValueMap[*PTI] = Operand;
-  }
+  for (unsigned a = 1, E = CI->getNumOperands(); a != E; ++a, ++PTI)
+    ValueMap[*PTI] = CI->getOperand(a);
   
-
   ValueMap[NewBB] = NewBB;  // Returns get converted to reference NewBB
 
   // Loop over all of the basic blocks in the method, inlining them as 
index 7a0254bca7a2cea7b5060a9d397fcf046a2992c8..91a21c3c6b4ac7674f480bbd9fe88c5035a3829d 100644 (file)
@@ -132,9 +132,9 @@ bool opt::ConstantFoldTerminator(TerminatorInst *T) {
     BasicBlock *Dest1 = BI->getOperand(0)->castBasicBlockAsserting();
     BasicBlock *Dest2 = BI->getOperand(1)->castBasicBlockAsserting();
 
-    if (BI->getOperand(2)->isConstant()) {    // Are we branching on constant?
+    if (BI->getCondition()->isConstant()) {    // Are we branching on constant?
       // YES.  Change to unconditional branch...
-      ConstPoolBool *Cond = (ConstPoolBool*)BI->getOperand(2);
+      ConstPoolBool *Cond = (ConstPoolBool*)BI->getCondition();
       BasicBlock *Destination = Cond->getValue() ? Dest1 : Dest2;
       BasicBlock *OldDest     = Cond->getValue() ? Dest2 : Dest1;
 
@@ -147,9 +147,9 @@ bool opt::ConstantFoldTerminator(TerminatorInst *T) {
       assert(BI->getParent() && "Terminator not inserted in block!");
       OldDest->removePredecessor(BI->getParent());
 
-      BI->setOperand(0, Destination);  // Set the unconditional destination
-      BI->setOperand(1, 0);            // Clear the conditional destination
-      BI->setOperand(2, 0);            // Clear the condition...
+      // Set the unconditional destination, and change the insn to be an
+      // unconditional branch.
+      BI->setUnconditionalDest(Destination);
       return true;
     } else if (Dest2 == Dest1) {       // Conditional branch to same location?
       // This branch matches something like this:  
@@ -160,9 +160,8 @@ bool opt::ConstantFoldTerminator(TerminatorInst *T) {
       assert(BI->getParent() && "Terminator not inserted in block!");
       Dest1->removePredecessor(BI->getParent());
 
-      // Nuke the second destination, and the use of the condition variable
-      BI->setOperand(1, 0);            // Clear the conditional destination
-      BI->setOperand(2, 0);            // Clear the condition...
+      // Change a conditional branch to unconditional.
+      BI->setUnconditionalDest(Dest1);
       return true;
     }
   }
@@ -192,7 +191,7 @@ ConstantFoldInstruction(Method *M, Method::inst_iterator &II) {
     PHINode *PN = (PHINode*)Inst; // If it's a PHI node and only has one operand
                                   // Then replace it directly with that operand.
     assert(PN->getOperand(0) && "PHI Node must have at least one operand!");
-    if (PN->getOperand(1) == 0) {       // If the PHI Node has exactly 1 operand
+    if (PN->getNumOperands() == 1) {    // If the PHI Node has exactly 1 operand
       Value *V = PN->getOperand(0);
       PN->replaceAllUsesWith(V);                 // Replace all uses of this PHI
                                                  // Unlink from basic block
index 8e37279178d0cf2bd6a4eb0e6b3985bf2ba4b3e0..fa2c9c7221516e3e9b2bccc7599c9caa225723d2 100644 (file)
@@ -91,7 +91,7 @@ static bool RemoveSingularPHIs(BasicBlock *BB) {
 
   do {
     PHINode *PN = (PHINode*)I;
-    assert(PN->getOperand(2) == 0 && "PHI node should only have one value!");
+    assert(PN->getNumOperands() == 2 && "PHI node should only have one value!");
     Value *V = PN->getOperand(0);
 
     PN->replaceAllUsesWith(V);      // Replace PHI node with its single value.
index 8b59e19c1c7a1052bb6129c2c5bba107beb46e4e..5bb75c7008aebc04196836fa524f4b8358162ade 100644 (file)
@@ -408,10 +408,10 @@ void SCCP::UpdateInstruction(Instruction *I) {
        markExecutable(Succ);
     } else if (SCValue.isConstant()) {
       ConstPoolVal *CPV = SCValue.getConstant();
-      for (SwitchInst::dest_iterator I = SI->dest_begin(), E = SI->dest_end();
-          I != E; ++I) {
-       if (I->first->equals(CPV)) {   // Found the right branch...
-         markExecutable(I->second);
+      // Make sure to skip the "default value" which isn't a value
+      for (unsigned i = 1, E = SI->getNumSuccessors(); i != E; ++i) {
+       if (SI->getSuccessorValue(i)->equals(CPV)) {// Found the right branch...
+         markExecutable(SI->getSuccessor(i));
          return;
        }
       }
index c68cd796f1a89146b2371df574fdc804c15631cd..e2b2495605833c5381a31f2c7d1677c2e560ddc1 100644 (file)
@@ -157,10 +157,10 @@ bool AssemblyWriter::processInstruction(const Instruction *I) {
   Out << I->getOpcode();
 
   // Print out the type of the operands...
-  const Value *Operand = I->getOperand(0);
+  const Value *Operand = I->getNumOperands() ? I->getOperand(0) : 0;
 
   // Special case conditional branches to swizzle the condition out to the front
-  if (I->getInstType() == Instruction::Br && I->getOperand(1)) {
+  if (I->getInstType() == Instruction::Br && I->getNumOperands() > 1) {
     writeOperand(I->getOperand(2), true);
     Out << ",";
     writeOperand(Operand, true);
@@ -172,9 +172,9 @@ bool AssemblyWriter::processInstruction(const Instruction *I) {
     writeOperand(Operand         , true); Out << ",";
     writeOperand(I->getOperand(1), true); Out << " [";
 
-    for (unsigned op = 2; (Operand = I->getOperand(op)); op += 2) {
+    for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) {
       Out << "\n\t\t";
-      writeOperand(Operand, true); Out << ",";
+      writeOperand(I->getOperand(op  ), true); Out << ",";
       writeOperand(I->getOperand(op+1), true);
     }
     Out << "\n\t]";
@@ -183,8 +183,9 @@ bool AssemblyWriter::processInstruction(const Instruction *I) {
 
     Out << " [";  writeOperand(Operand, false); Out << ",";
     writeOperand(I->getOperand(1), false); Out << " ]";
-    for (unsigned op = 2; (Operand = I->getOperand(op)); op += 2) {
-      Out << ", [";  writeOperand(Operand, false); Out << ",";
+    for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; op += 2) {
+      Out << ", [";  
+      writeOperand(I->getOperand(op  ), false); Out << ",";
       writeOperand(I->getOperand(op+1), false); Out << " ]";
     }
   } else if (I->getInstType() == Instruction::Ret && !Operand) {
@@ -192,20 +193,19 @@ bool AssemblyWriter::processInstruction(const Instruction *I) {
   } else if (I->getInstType() == Instruction::Call) {
     writeOperand(Operand, true);
     Out << "(";
-    Operand = I->getOperand(1);
-    if (Operand) writeOperand(Operand, true);
-    for (unsigned op = 2; (Operand = I->getOperand(op)); ++op) {
+    if (I->getNumOperands() > 1) writeOperand(I->getOperand(1), true);
+    for (unsigned op = 2, Eop = I->getNumOperands(); op < Eop; ++op) {
       Out << ",";
-      writeOperand(Operand, true);
+      writeOperand(I->getOperand(op), true);
     }
 
     Out << " )";
   } else if (I->getInstType() == Instruction::Malloc || 
             I->getInstType() == Instruction::Alloca) {
-    Out << " " << ((const PointerType*)((ConstPoolType*)Operand)
-                  ->getValue())->getValueType();
-    if ((Operand = I->getOperand(1))) {
-      Out << ","; writeOperand(Operand, true);
+    Out << " " << ((const PointerType*)I->getType())->getValueType();
+    if (I->getNumOperands()) {
+      Out << ",";
+      writeOperand(I->getOperand(0), true);
     }
 
   } else if (Operand) {   // Print the normal way...
@@ -215,9 +215,9 @@ bool AssemblyWriter::processInstruction(const Instruction *I) {
     // different type operands (for example br), then they are all printed.
     bool PrintAllTypes = false;
     const Type *TheType = Operand->getType();
-    unsigned i;
 
-    for (i = 1; (Operand = I->getOperand(i)); i++) {
+    for (unsigned i = 1, E = I->getNumOperands(); i != E; ++i) {
+      Operand = I->getOperand(i);
       if (Operand->getType() != TheType) {
        PrintAllTypes = true;       // We have differing types!  Print them all!
        break;
@@ -227,9 +227,9 @@ bool AssemblyWriter::processInstruction(const Instruction *I) {
     if (!PrintAllTypes)
       Out << " " << I->getOperand(0)->getType();
 
-    for (unsigned i = 0; (Operand = I->getOperand(i)); i++) {
+    for (unsigned i = 0, E = I->getNumOperands(); i != E; ++i) {
       if (i) Out << ",";
-      writeOperand(Operand, PrintAllTypes);
+      writeOperand(I->getOperand(i), PrintAllTypes);
     }
   }
 
@@ -262,8 +262,8 @@ void AssemblyWriter::writeOperand(const Value *Operand, bool PrintType,
   } else {
     int Slot = Table.getValSlot(Operand);
     
-    if (Operand->isConstant()) {
-      Out << " " << ((ConstPoolVal*)Operand)->getStrValue();
+    if (const ConstPoolVal *CPV = Operand->castConstant()) {
+      Out << " " << CPV->getStrValue();
     } else {
       if (Slot >= 0)  Out << " %" << Slot;
       else if (PrintName)
index 77ed50ae26db510f45f9546bdd1230a8bd06d265..13463a17344403af8b926d0b9bf26e1c3aca4b2e 100644 (file)
@@ -219,7 +219,7 @@ ConstPoolArray::ConstPoolArray(const ArrayType *T,
   : ConstPoolVal(T, Name) {
   for (unsigned i = 0; i < V.size(); i++) {
     assert(V[i]->getType() == T->getElementType());
-    Val.push_back(ConstPoolUse(V[i], this));
+    Operands.push_back(Use(V[i], this));
   }
 }
 
@@ -231,7 +231,7 @@ ConstPoolStruct::ConstPoolStruct(const StructType *T,
 
   for (unsigned i = 0; i < V.size(); i++) {
     assert(V[i]->getType() == ETypes[i]);
-    Val.push_back(ConstPoolUse(V[i], this));
+    Operands.push_back(Use(V[i], this));
   }
 }
 
@@ -265,14 +265,14 @@ ConstPoolType::ConstPoolType(const ConstPoolType &CPT)
 
 ConstPoolArray::ConstPoolArray(const ConstPoolArray &CPA)
   : ConstPoolVal(CPA.getType()) {
-  for (unsigned i = 0; i < CPA.Val.size(); i++)
-    Val.push_back(ConstPoolUse((ConstPoolVal*)CPA.Val[i], this));
+  for (unsigned i = 0; i < CPA.Operands.size(); i++)
+    Operands.push_back(Use(CPA.Operands[i], this));
 }
 
 ConstPoolStruct::ConstPoolStruct(const ConstPoolStruct &CPS)
   : ConstPoolVal(CPS.getType()) {
-  for (unsigned i = 0; i < CPS.Val.size(); i++)
-    Val.push_back(ConstPoolUse((ConstPoolVal*)CPS.Val[i], this));
+  for (unsigned i = 0; i < CPS.Operands.size(); i++)
+    Operands.push_back(Use(CPS.Operands[i], this));
 }
 
 //===----------------------------------------------------------------------===//
@@ -301,12 +301,12 @@ string ConstPoolType::getStrValue() const {
 
 string ConstPoolArray::getStrValue() const {
   string Result = "[";
-  if (Val.size()) {
-    Result += " " + Val[0]->getType()->getName() + 
-             " " + Val[0]->getStrValue();
-    for (unsigned i = 1; i < Val.size(); i++)
-      Result += ", " + Val[i]->getType()->getName() + 
-                " " + Val[i]->getStrValue();
+  if (Operands.size()) {
+    Result += " " + Operands[0]->getType()->getName() + 
+             " " + Operands[0]->castConstantAsserting()->getStrValue();
+    for (unsigned i = 1; i < Operands.size(); i++)
+      Result += ", " + Operands[i]->getType()->getName() + 
+                " " + Operands[i]->castConstantAsserting()->getStrValue();
   }
 
   return Result + " ]";
@@ -314,12 +314,12 @@ string ConstPoolArray::getStrValue() const {
 
 string ConstPoolStruct::getStrValue() const {
   string Result = "{";
-  if (Val.size()) {
-    Result += " " + Val[0]->getType()->getName() + 
-             " " + Val[0]->getStrValue();
-    for (unsigned i = 1; i < Val.size(); i++)
-      Result += ", " + Val[i]->getType()->getName() + 
-                " " + Val[i]->getStrValue();
+  if (Operands.size()) {
+    Result += " " + Operands[0]->getType()->getName() + 
+             " " + Operands[0]->castConstantAsserting()->getStrValue();
+    for (unsigned i = 1; i < Operands.size(); i++)
+      Result += ", " + Operands[i]->getType()->getName() + 
+                " " + Operands[i]->castConstantAsserting()->getStrValue();
   }
 
   return Result + " }";
@@ -356,9 +356,11 @@ bool ConstPoolType::equals(const ConstPoolVal *V) const {
 bool ConstPoolArray::equals(const ConstPoolVal *V) const {
   assert(getType() == V->getType());
   ConstPoolArray *AV = (ConstPoolArray*)V;
-  if (Val.size() != AV->Val.size()) return false;
-  for (unsigned i = 0; i < Val.size(); i++)
-    if (!Val[i]->equals(AV->Val[i])) return false;
+  if (Operands.size() != AV->Operands.size()) return false;
+  for (unsigned i = 0; i < Operands.size(); i++)
+    if (!Operands[i]->castConstantAsserting()->equals(
+               AV->Operands[i]->castConstantAsserting()))
+      return false;
 
   return true;
 }
@@ -366,9 +368,11 @@ bool ConstPoolArray::equals(const ConstPoolVal *V) const {
 bool ConstPoolStruct::equals(const ConstPoolVal *V) const {
   assert(getType() == V->getType());
   ConstPoolStruct *SV = (ConstPoolStruct*)V;
-  if (Val.size() != SV->Val.size()) return false;
-  for (unsigned i = 0; i < Val.size(); i++)
-    if (!Val[i]->equals(SV->Val[i])) return false;
+  if (Operands.size() != SV->Operands.size()) return false;
+  for (unsigned i = 0; i < Operands.size(); i++)
+    if (!Operands[i]->castConstantAsserting()->equals(
+           SV->Operands[i]->castConstantAsserting()))
+      return false;
 
   return true;
 }
index baafe0bc13108692e83cb4dddb3c958903dbd58b..cda99a9446a5be88a625d689cd389d2e73e220cb 100644 (file)
@@ -9,7 +9,7 @@
 #include "llvm/Method.h"
 #include "llvm/SymbolTable.h"
 #include "llvm/Type.h"
-#include <algorithm>
+#include <algorithm>  // find
 
 // TODO: Move to getUnaryOperator iUnary.cpp when and if it exists!
 UnaryOperator *UnaryOperator::create(unsigned Op, Value *Source) {
@@ -52,49 +52,25 @@ PHINode::PHINode(const Type *Ty, const string &name)
 
 PHINode::PHINode(const PHINode &PN) 
   : Instruction(PN.getType(), Instruction::PHINode) {
-  
-  for (unsigned i = 0; i < PN.IncomingValues.size(); i++)
-    IncomingValues.push_back(
-       make_pair(Use(PN.IncomingValues[i].first, this),
-                 BasicBlockUse(PN.IncomingValues[i].second, this)));
-}
-
-void PHINode::dropAllReferences() {
-  IncomingValues.clear();
-}
-
-bool PHINode::setOperand(unsigned i, Value *Val) {
-  assert(Val && "PHI node must only reference nonnull definitions!");
-  if (i >= IncomingValues.size()*2) return false;
-
-  if (i & 1) {
-    IncomingValues[i/2].second = Val->castBasicBlockAsserting();
-  } else {
-    IncomingValues[i/2].first  = Val;
+  Operands.reserve(PN.Operands.size());
+  for (unsigned i = 0; i < PN.Operands.size(); i+=2) {
+    Operands.push_back(Use(PN.Operands[i], this));
+    Operands.push_back(Use(PN.Operands[i+1], this));
   }
-  return true;
 }
 
 void PHINode::addIncoming(Value *D, BasicBlock *BB) {
-  IncomingValues.push_back(make_pair(Use(D, this), BasicBlockUse(BB, this)));
+  Operands.push_back(Use(D, this));
+  Operands.push_back(Use(BB, this));
 }
 
-struct FindBBEntry {
-  const BasicBlock *BB;
-  inline FindBBEntry(const BasicBlock *bb) : BB(bb) {}
-  inline bool operator()(const pair<Use,BasicBlockUse> &Entry) {
-    return Entry.second == BB;
-  }
-};
-
-
 // removeIncomingValue - Remove an incoming value.  This is useful if a
 // predecessor basic block is deleted.
 Value *PHINode::removeIncomingValue(const BasicBlock *BB) {
-  vector<PairTy>::iterator Idx = find_if(IncomingValues.begin(), 
-                                        IncomingValues.end(), FindBBEntry(BB));
-  assert(Idx != IncomingValues.end() && "BB not in PHI node!");
-  Value *Removed = Idx->first;
-  IncomingValues.erase(Idx);
+  op_iterator Idx = find(Operands.begin(), Operands.end(), (const Value*)BB);
+  assert(Idx != Operands.end() && "BB not in PHI node!");
+  --Idx;  // Back up to value prior to Basic block
+  Value *Removed = *Idx;
+  Operands.erase(Idx, Idx+2);  // Erase Value and BasicBlock
   return Removed;
 }
index fa3c0f60fb4fe773fd44e085113b9805b33c1882..a051bcb3cc6d36e2833c5c92fa600585c74e8f53 100644 (file)
@@ -89,14 +89,13 @@ User::User(const Type *Ty, ValueTy vty, const string &name)
 void User::replaceUsesOfWith(Value *From, Value *To) {
   if (From == To) return;   // Duh what?
 
-  for (unsigned OpNum = 0; Value *D = getOperand(OpNum); ++OpNum) {   
-    if (D == From) {  // Okay, this operand is pointing to our fake def.
+  for (unsigned i = 0, E = getNumOperands(); i != E; ++i)
+    if (getOperand(i) == From) {  // Is This operand is pointing to oldval?
       // The side effects of this setOperand call include linking to
       // "To", adding "this" to the uses list of To, and
       // most importantly, removing "this" from the use list of "From".
-      setOperand(OpNum, To); // Fix it now...
+      setOperand(i, To); // Fix it now...
     }
-  }
 }
 
 
index 05f35059a546e2007f571fb007b97a258da49470..d0f437e293b87667ada8c0e9a7dc049b2fbe8cbc 100644 (file)
 #endif
 
 BranchInst::BranchInst(BasicBlock *True, BasicBlock *False, Value *Cond) 
-  : TerminatorInst(Instruction::Br), TrueDest(True, this), 
-    FalseDest(False, this), Condition(Cond, this) {
+  : TerminatorInst(Instruction::Br) {
   assert(True != 0 && "True branch destination may not be null!!!");
+  Operands.reserve(False ? 3 : 1);
+  Operands.push_back(Use(True, this));
+  if (False) {
+    Operands.push_back(Use(False, this));
+    Operands.push_back(Use(Cond, this));
+  }
+
+  assert(!!False == !!Cond &&
+        "Either both cond and false or neither can be specified!");
 
 #ifndef NDEBUG
   if (Cond != 0 && Cond->getType() != Type::BoolTy)
@@ -25,45 +33,12 @@ BranchInst::BranchInst(BasicBlock *True, BasicBlock *False, Value *Cond)
          "May only branch on boolean predicates!!!!");
 }
 
-BranchInst::BranchInst(const BranchInst &BI) 
-  : TerminatorInst(Instruction::Br), TrueDest(BI.TrueDest, this), 
-    FalseDest(BI.FalseDest, this), Condition(BI.Condition, this) {
-}
-
-
-void BranchInst::dropAllReferences() {
-  Condition = 0;
-  TrueDest = FalseDest = 0;
-}
-
-const Value *BranchInst::getOperand(unsigned i) const {
-    return (i == 0) ? (Value*)TrueDest : 
-          ((i == 1) ? (Value*)FalseDest : 
-          ((i == 2) ? (Value*)Condition : 0));
-}
-
-const BasicBlock *BranchInst::getSuccessor(unsigned i) const {
-  return (i == 0) ? (const BasicBlock*)TrueDest : 
-        ((i == 1) ? (const BasicBlock*)FalseDest : 0);
-}
-
-bool BranchInst::setOperand(unsigned i, Value *Val) { 
-  switch (i) {
-  case 0:
-    assert(Val && "Can't change primary direction to 0!");
-    assert(Val->getType() == Type::LabelTy);
-    TrueDest = (BasicBlock*)Val;
-    return true;
-  case 1:
-    assert(Val == 0 || Val->getType() == Type::LabelTy);
-    FalseDest = (BasicBlock*)Val;
-    return true;
-  case 2:
-    Condition = Val;
-    assert(!Condition || Condition->getType() == Type::BoolTy && 
-           "Condition expr must be a boolean expression!");
-    return true;
-  } 
-
-  return false;
+BranchInst::BranchInst(const BranchInst &BI) : TerminatorInst(Instruction::Br) {
+  Operands.reserve(BI.Operands.size());
+  Operands.push_back(Use(BI.Operands[0], this));
+  if (BI.Operands.size() != 1) {
+    assert(BI.Operands.size() == 3 && "BR can have 1 or 3 operands!");
+    Operands.push_back(Use(BI.Operands[1], this));
+    Operands.push_back(Use(BI.Operands[2], this));
+  }
 }
index 7632798c66a9c2b89e438427fbb6fb6890baeca0..67826ff4bcb5168d46c9f7c07945ab7a51eafc67 100644 (file)
@@ -1,6 +1,6 @@
-//===-- iCall.cpp - Implement the Call & Invoke instructions -----*- C++ -*--=//
+//===-- iCall.cpp - Implement the call & icall instructions ------*- C++ -*--=//
 //
-// This file implements the call and invoke instructions.
+// This file implements the call and icall instructions.
 //
 //===----------------------------------------------------------------------===//
 
@@ -8,9 +8,12 @@
 #include "llvm/DerivedTypes.h"
 #include "llvm/Method.h"
 
-CallInst::CallInst(Method *m, vector<Value*> &params, 
+CallInst::CallInst(Method *M, vector<Value*> &params, 
                    const string &Name) 
-  : Instruction(m->getReturnType(), Instruction::Call, Name), M(m, this) {
+  : Instruction(M->getReturnType(), Instruction::Call, Name) {
+
+  Operands.reserve(1+params.size());
+  Operands.push_back(Use(M, this));
 
   const MethodType* MT = M->getMethodType();
   const MethodType::ParamTypes &PL = MT->getParamTypes();
@@ -19,29 +22,15 @@ CallInst::CallInst(Method *m, vector<Value*> &params,
   MethodType::ParamTypes::const_iterator It = PL.begin();
 #endif
   for (unsigned i = 0; i < params.size(); i++) {
-    assert(*It++ == params[i]->getType());
-    Params.push_back(Use(params[i], this));
+    assert(*It++ == params[i]->getType() && "Call Operands not correct type!");
+    Operands.push_back(Use(params[i], this));
   }
 }
 
 CallInst::CallInst(const CallInst &CI) 
-  : Instruction(CI.getType(), Instruction::Call), M(CI.M, this) {
-  for (unsigned i = 0; i < CI.Params.size(); i++)
-    Params.push_back(Use(CI.Params[i], this));
-}
-
-void CallInst::dropAllReferences() { 
-  M = 0;
-  Params.clear(); 
+  : Instruction(CI.getType(), Instruction::Call) {
+  Operands.reserve(CI.Operands.size());
+  for (unsigned i = 0; i < CI.Operands.size(); ++i)
+    Operands.push_back(Use(CI.Operands[i], this));
 }
 
-bool CallInst::setOperand(unsigned i, Value *Val) {
-  if (i > Params.size()) return false;
-  if (i == 0) {
-    M = Val->castMethodAsserting();
-  } else {
-    // TODO: assert = method arg type
-    Params[i-1] = Val;
-  }
-  return true;
-}
index 7fa04fb42c68e2c0687ff7fb5147b099d5118796..b28b04f643122b019e912540f228c8ed20be9eeb 100644 (file)
@@ -1,25 +1,3 @@
-//===-- iReturn.cpp - Implement the Return instruction -----------*- C++ -*--=//
-//
-// This file implements the Return instruction...
-//
-//===----------------------------------------------------------------------===//
 
-#include "llvm/iTerminators.h"
 
-ReturnInst::ReturnInst(Value *V)
-  : TerminatorInst(Instruction::Ret), Val(V, this) {
-}
 
-ReturnInst::ReturnInst(const ReturnInst &RI)
-  : TerminatorInst(Instruction::Ret), Val(RI.Val, this) {
-}
-
-void ReturnInst::dropAllReferences() {
-  Val = 0;
-}
-
-bool ReturnInst::setOperand(unsigned i, Value *V) { 
-  if (i) return false; 
-  Val = V;
-  return true;
-}
index 2a1eec263911d69038a376ef0d13aab70e933fb8..e5e3c50cfd5efa0c3916cc29f9f7d4151cc0ec36 100644 (file)
 #include "llvm/Type.h"
 #endif
 
-SwitchInst::SwitchInst(Value *V, BasicBlock *DefV) 
-  : TerminatorInst(Instruction::Switch), 
-    DefaultDest(DefV, this), Val(V, this) {
-  assert(Val && DefV);
+SwitchInst::SwitchInst(Value *V, BasicBlock *DefDest) 
+  : TerminatorInst(Instruction::Switch) {
+  assert(V && DefDest);
+  Operands.push_back(Use(V, this));
+  Operands.push_back(Use(DefDest, this));
 }
 
 SwitchInst::SwitchInst(const SwitchInst &SI) 
-  : TerminatorInst(Instruction::Switch), DefaultDest(SI.DefaultDest), 
-    Val(SI.Val) {
+  : TerminatorInst(Instruction::Switch) {
+  Operands.reserve(SI.Operands.size());
 
-  for (dest_const_iterator I = SI.Destinations.begin(), 
-                        end = SI.Destinations.end(); I != end; ++I)
-    Destinations.push_back(dest_value(ConstPoolUse(I->first, this), 
-                                     BasicBlockUse(I->second, this)));
+  for (unsigned i = 0, E = SI.Operands.size(); i != E; i+=2) {
+    Operands.push_back(Use(SI.Operands[i], this));
+    Operands.push_back(Use(SI.Operands[i+1], this));
+  }
 }
 
-
 void SwitchInst::dest_push_back(ConstPoolVal *OnVal, BasicBlock *Dest) {
-  Destinations.push_back(dest_value(ConstPoolUse(OnVal, this), 
-                                    BasicBlockUse(Dest, this)));
-}
-
-void SwitchInst::dropAllReferences() {
-  Val = 0;
-  DefaultDest = 0;
-  Destinations.clear();
-}
-
-const BasicBlock *SwitchInst::getSuccessor(unsigned idx) const {
-  if (idx == 0) return DefaultDest;
-  if (idx > Destinations.size()) return 0;
-  return Destinations[idx-1].second;
-}
-
-unsigned SwitchInst::getNumOperands() const {
-  return 2+Destinations.size();
-}
-
-const Value *SwitchInst::getOperand(unsigned i) const {
-  if (i == 0) return Val;
-  else if (i == 1) return DefaultDest;
-
-  unsigned slot = (i-2) >> 1;
-  if (slot >= Destinations.size()) return 0;
-  
-  if (i & 1) return Destinations[slot].second;
-  return Destinations[slot].first;
-}
-
-bool SwitchInst::setOperand(unsigned i, Value *V) {
-  if (i == 0) { Val = V; return true; }
-  else if (i == 1) { 
-    assert(V->getType() == Type::LabelTy); 
-    DefaultDest = (BasicBlock*)V;
-    return true; 
-  }
-
-  unsigned slot = (i-2) >> 1;
-  if (slot >= Destinations.size()) return 0;
-
-  if (i & 1) {
-    assert(V->getType() == Type::LabelTy);
-    Destinations[slot].second = (BasicBlock*)V;
-  } else {
-    // TODO: assert constant
-    Destinations[slot].first = (ConstPoolVal*)V;
-  }
-  return true;
+  Operands.push_back(Use(OnVal, this));
+  Operands.push_back(Use(Dest, this));
 }