[llvm-commits] [llvm] r48822 - in /llvm/trunk: include/llvm/CodeGen/ScheduleDAG.h include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/SelectionDAG/LegalizeDAG.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.h lib/CodeGen/SelectionDAG/ScheduleDAG.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Target/PowerPC/PPCISelLowering.cpp lib/Target/X86/X86ISelDAGToDAG.cpp lib/Target/X86/X86ISelLowering.cpp

Roman Levenstein romix.llvm at googlemail.com
Wed Mar 26 05:39:28 PDT 2008


Author: romix
Date: Wed Mar 26 07:39:26 2008
New Revision: 48822

URL: http://llvm.org/viewvc/llvm-project?rev=48822&view=rev
Log:
Use a linked data structure for the uses lists of an SDNode, just like 
LLVM Value/Use does and MachineRegisterInfo/MachineOperand does.
This allows constant time for all uses list maintenance operations.

The idea was suggested by Chris. Reviewed by Evan and Dan.
Patch is tested and approved by Dan.

On normal use-cases compilation speed is not affected. On very big basic
blocks there are compilation speedups in the range of 15-20% or even better. 


Modified:
    llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h
    llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
    llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
    llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp

Modified: llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h?rev=48822&r1=48821&r2=48822&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/ScheduleDAG.h Wed Mar 26 07:39:26 2008
@@ -331,7 +331,7 @@
     /// register number for the results of the node.
     ///
     void EmitNode(SDNode *Node, unsigned InstNo,
-                  DenseMap<SDOperand, unsigned> &VRBaseMap);
+                  DenseMap<SDOperandImpl, unsigned> &VRBaseMap);
     
     /// EmitNoop - Emit a noop instruction.
     ///
@@ -343,11 +343,11 @@
     /// implicit physical register output.
     void EmitCopyFromReg(SDNode *Node, unsigned ResNo, unsigned InstNo,
                          unsigned SrcReg,
-                         DenseMap<SDOperand, unsigned> &VRBaseMap);
+                         DenseMap<SDOperandImpl, unsigned> &VRBaseMap);
     
     void CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
                                 const TargetInstrDesc &II,
-                                DenseMap<SDOperand, unsigned> &VRBaseMap);
+                                DenseMap<SDOperandImpl, unsigned> &VRBaseMap);
 
     /// EmitLiveInCopy - Emit a copy for a live in physical register. If the
     /// physical register has only a single copy use, then coalesced the copy
@@ -375,11 +375,11 @@
     /// EmitSubregNode - Generate machine code for subreg nodes.
     ///
     void EmitSubregNode(SDNode *Node, 
-                        DenseMap<SDOperand, unsigned> &VRBaseMap);
+                        DenseMap<SDOperandImpl, unsigned> &VRBaseMap);
   
     void AddOperand(MachineInstr *MI, SDOperand Op, unsigned IIOpNum,
                     const TargetInstrDesc *II,
-                    DenseMap<SDOperand, unsigned> &VRBaseMap);
+                    DenseMap<SDOperandImpl, unsigned> &VRBaseMap);
 
     void AddMemOperand(MachineInstr *MI, const MemOperand &MO);
   };

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h?rev=48822&r1=48821&r2=48822&view=diff

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Wed Mar 26 07:39:26 2008
@@ -779,7 +779,7 @@
 
 
 //===----------------------------------------------------------------------===//
-/// SDOperand - Unlike LLVM values, Selection DAG nodes may return multiple
+/// SDOperandImpl - Unlike LLVM values, Selection DAG nodes may return multiple
 /// values as the result of a computation.  Many nodes return multiple values,
 /// from loads (which define a token and a return value) to ADDC (which returns
 /// a result and a carry value), to calls (which may return an arbitrary number
@@ -787,28 +787,28 @@
 ///
 /// As such, each use of a SelectionDAG computation must indicate the node that
 /// computes it as well as which return value to use from that node.  This pair
-/// of information is represented with the SDOperand value type.
+/// of information is represented with the SDOperandImpl value type.
 ///
-class SDOperand {
+class SDOperandImpl {
 public:
   SDNode *Val;        // The node defining the value we are using.
   unsigned ResNo;     // Which return value of the node we are using.
 
-  SDOperand() : Val(0), ResNo(0) {}
-  SDOperand(SDNode *val, unsigned resno) : Val(val), ResNo(resno) {}
+  SDOperandImpl() : Val(0), ResNo(0) {}
+  SDOperandImpl(SDNode *val, unsigned resno) : Val(val), ResNo(resno) {}
 
-  bool operator==(const SDOperand &O) const {
+  bool operator==(const SDOperandImpl &O) const {
     return Val == O.Val && ResNo == O.ResNo;
   }
-  bool operator!=(const SDOperand &O) const {
+  bool operator!=(const SDOperandImpl &O) const {
     return !operator==(O);
   }
-  bool operator<(const SDOperand &O) const {
+  bool operator<(const SDOperandImpl &O) const {
     return Val < O.Val || (Val == O.Val && ResNo < O.ResNo);
   }
 
-  SDOperand getValue(unsigned R) const {
-    return SDOperand(Val, R);
+  SDOperandImpl getValue(unsigned R) const {
+    return SDOperandImpl(Val, R);
   }
 
   // isOperandOf - Return true if this node is an operand of N.
@@ -827,7 +827,7 @@
   // Forwarding methods - These forward to the corresponding methods in SDNode.
   inline unsigned getOpcode() const;
   inline unsigned getNumOperands() const;
-  inline const SDOperand &getOperand(unsigned i) const;
+  inline const SDOperandImpl &getOperand(unsigned i) const;
   inline uint64_t getConstantOperandVal(unsigned i) const;
   inline bool isTargetOpcode() const;
   inline unsigned getTargetOpcode() const;
@@ -838,7 +838,8 @@
   /// side-effecting instructions.  In practice, this looks through token
   /// factors and non-volatile loads.  In order to remain efficient, this only
   /// looks a couple of nodes in, it does not do an exhaustive search.
-  bool reachesChainWithoutSideEffects(SDOperand Dest, unsigned Depth = 2) const;
+  bool reachesChainWithoutSideEffects(SDOperandImpl Dest, 
+                                      unsigned Depth = 2) const;
   
   /// hasOneUse - Return true if there is exactly one operation using this
   /// result value of the defining operator.
@@ -850,14 +851,18 @@
 };
 
 
-template<> struct DenseMapInfo<SDOperand> {
-  static inline SDOperand getEmptyKey() { return SDOperand((SDNode*)-1, -1U); }
-  static inline SDOperand getTombstoneKey() { return SDOperand((SDNode*)-1, 0);}
-  static unsigned getHashValue(const SDOperand &Val) {
+template<> struct DenseMapInfo<SDOperandImpl> {
+  static inline SDOperandImpl getEmptyKey() { 
+    return SDOperandImpl((SDNode*)-1, -1U); 
+  }
+  static inline SDOperandImpl getTombstoneKey() { 
+    return SDOperandImpl((SDNode*)-1, 0);
+  }
+  static unsigned getHashValue(const SDOperandImpl &Val) {
     return ((unsigned)((uintptr_t)Val.Val >> 4) ^
             (unsigned)((uintptr_t)Val.Val >> 9)) + Val.ResNo;
   }
-  static bool isEqual(const SDOperand &LHS, const SDOperand &RHS) {
+  static bool isEqual(const SDOperandImpl &LHS, const SDOperandImpl &RHS) {
     return LHS == RHS;
   }
   static bool isPod() { return true; }
@@ -865,6 +870,88 @@
 
 /// simplify_type specializations - Allow casting operators to work directly on
 /// SDOperands as if they were SDNode*'s.
+template<> struct simplify_type<SDOperandImpl> {
+  typedef SDNode* SimpleType;
+  static SimpleType getSimplifiedValue(const SDOperandImpl &Val) {
+    return static_cast<SimpleType>(Val.Val);
+  }
+};
+template<> struct simplify_type<const SDOperandImpl> {
+  typedef SDNode* SimpleType;
+  static SimpleType getSimplifiedValue(const SDOperandImpl &Val) {
+    return static_cast<SimpleType>(Val.Val);
+  }
+};
+
+/// SDOperand - Represents a use of the SDNode referred by
+/// the SDOperandImpl.
+class SDOperand: public SDOperandImpl {
+  /// parent - Parent node of this operand.
+  SDNode    *parent;
+  /// Prev, next - Pointers to the uses list of the SDNode referred by 
+  /// this operand.
+  SDOperand **Prev, *Next;
+public:
+  friend class SDNode;
+  SDOperand(): SDOperandImpl(), parent(NULL), Prev(NULL), Next(NULL) {}
+
+  SDOperand(SDNode *val, unsigned resno) : 
+    SDOperandImpl(val,resno), parent(NULL), Prev(NULL), Next(NULL) {}
+
+  SDOperand(const SDOperandImpl& Op): SDOperandImpl(Op),parent(NULL),
+      Prev(NULL), Next(NULL)  {
+  }
+
+  SDOperand& operator= (SDOperandImpl& Op) {
+      *(SDOperandImpl*)this = Op;
+      Next = NULL;
+      Prev = NULL;
+      return *this;
+  }
+
+  SDOperand& operator= (const SDOperandImpl& Op) {
+      *(SDOperandImpl*)this = Op;
+      Next = NULL;
+      Prev = NULL;
+      return *this;
+  }
+
+  SDOperand& operator= (SDOperand& Op) {
+      *(SDOperandImpl*)this = Op;
+      Next = NULL;
+      Prev = NULL;
+      return *this;
+  }
+
+  SDOperand& operator= (const SDOperand& Op) {
+      *(SDOperandImpl*)this = Op;
+      Next = NULL;
+      Prev = NULL;
+      return *this;
+  }
+
+  SDOperand * getNext() { return Next; }
+
+  SDNode *getUser() { return parent; }
+  void setUser(SDNode *p) { parent = p; }
+
+protected:
+  void addToList(SDOperand **List) {
+    Next = *List;
+    if (Next) Next->Prev = &Next;
+    Prev = List;
+    *List = this;
+  }
+
+  void removeFromList() {
+    *Prev = Next;
+    if (Next) Next->Prev = Prev;
+  }
+};
+
+
+/// simplify_type specializations - Allow casting operators to work directly on
+/// SDOperands as if they were SDNode*'s.
 template<> struct simplify_type<SDOperand> {
   typedef SDNode* SimpleType;
   static SimpleType getSimplifiedValue(const SDOperand &Val) {
@@ -882,6 +969,7 @@
 /// SDNode - Represents one node in the SelectionDAG.
 ///
 class SDNode : public FoldingSetNode {
+private:
   /// NodeType - The operation that this node performs.
   ///
   unsigned short NodeType;
@@ -909,10 +997,15 @@
   SDNode *Prev, *Next;
   friend struct ilist_traits<SDNode>;
 
-  /// Uses - These are all of the SDNode's that use a value produced by this
-  /// node.
-  SmallVector<SDNode*,3> Uses;
-  
+  /// UsesSize - The size of the uses list.
+  unsigned UsesSize;
+
+  /// Uses - List of uses for this SDNode.
+  SDOperand *Uses;
+
+  /// addUse - add SDOperand to the list of uses.
+  void addUse(SDOperand &U) { U.addToList(&Uses); }
+
   // Out-of-line virtual method to give class a home.
   virtual void ANCHOR();
 public:
@@ -931,9 +1024,9 @@
     return NodeType - ISD::BUILTIN_OP_END;
   }
 
-  size_t use_size() const { return Uses.size(); }
-  bool use_empty() const { return Uses.empty(); }
-  bool hasOneUse() const { return Uses.size() == 1; }
+  size_t use_size() const { return UsesSize; }
+  bool use_empty() const { return Uses == NULL; }
+  bool hasOneUse() const { return use_size() == 1; }
 
   /// getNodeId - Return the unique node id.
   ///
@@ -942,9 +1035,75 @@
   /// setNodeId - Set unique node id.
   void setNodeId(int Id) { NodeId = Id; }
 
-  typedef SmallVector<SDNode*,3>::const_iterator use_iterator;
-  use_iterator use_begin() const { return Uses.begin(); }
-  use_iterator use_end() const { return Uses.end(); }
+  /// use_iterator - This class provides iterator support for SDOperand
+  /// operands that use a specific SDNode. 
+  class use_iterator
+    : public forward_iterator<SDOperand, ptrdiff_t> {
+    SDOperand *Op;
+    explicit use_iterator(SDOperand *op) : Op(op) {
+    }
+    friend class SDNode;
+  public:
+    typedef forward_iterator<SDOperand, ptrdiff_t>::reference reference;
+    typedef forward_iterator<SDOperand, ptrdiff_t>::pointer pointer;
+
+    use_iterator(const use_iterator &I) : Op(I.Op) {}
+    use_iterator() : Op(0) {}
+
+    bool operator==(const use_iterator &x) const {
+      return Op == x.Op;
+    }
+    bool operator!=(const use_iterator &x) const {
+      return !operator==(x);
+    }
+ 
+    /// atEnd - return true if this iterator is at the end of uses list.
+    bool atEnd() const { return Op == 0; }
+
+    // Iterator traversal: forward iteration only.
+    use_iterator &operator++() {          // Preincrement
+      assert(Op && "Cannot increment end iterator!");
+      Op = Op->getNext();
+      return *this;
+    }
+
+    use_iterator operator++(int) {        // Postincrement
+      use_iterator tmp = *this; ++*this; return tmp;
+    }
+
+
+    /// getOperandNum - Retrive a number of a current operand.
+    unsigned getOperandNum() const {
+      assert(Op && "Cannot dereference end iterator!");
+      return (Op - Op->getUser()->OperandList);
+    }
+
+    /// Retrieve a reference to the current operand.
+    SDOperand &operator*() const {
+      assert(Op && "Cannot dereference end iterator!");
+      return *Op;
+    }
+
+    /// Retrieve a pointer to the current operand.
+    SDOperand *operator->() const {
+      assert(Op && "Cannot dereference end iterator!");
+      return Op;
+    }
+  };
+
+  /// use_begin/use_end - Provide iteration support to walk over all uses
+  /// of an SDNode.
+
+  use_iterator use_begin(SDNode *node) const {
+    return use_iterator(node->Uses);
+  }
+
+  use_iterator use_begin() const {
+    return use_iterator(Uses);
+  }
+
+  static use_iterator use_end() { return use_iterator(0); }
+
 
   /// hasNUsesOfValue - Return true if there are exactly NUSES uses of the
   /// indicated value.  This method ignores uses of other values defined by this
@@ -982,7 +1141,7 @@
     return OperandList[Num];
   }
 
-  typedef const SDOperand* op_iterator;
+  typedef SDOperand* op_iterator;
   op_iterator op_begin() const { return OperandList; }
   op_iterator op_end() const { return OperandList+NumOperands; }
 
@@ -1039,25 +1198,28 @@
   }
 
   SDNode(unsigned Opc, SDVTList VTs, const SDOperand *Ops, unsigned NumOps)
-    : NodeType(Opc), NodeId(-1) {
+    : NodeType(Opc), NodeId(-1), UsesSize(0), Uses(NULL) {
     OperandsNeedDelete = true;
     NumOperands = NumOps;
     OperandList = NumOps ? new SDOperand[NumOperands] : 0;
     
     for (unsigned i = 0; i != NumOps; ++i) {
       OperandList[i] = Ops[i];
-      Ops[i].Val->Uses.push_back(this);
+      OperandList[i].setUser(this);
+      Ops[i].Val->addUse(OperandList[i]);
+      ++Ops[i].Val->UsesSize;
     }
     
     ValueList = VTs.VTs;
     NumValues = VTs.NumVTs;
     Prev = 0; Next = 0;
   }
-  SDNode(unsigned Opc, SDVTList VTs) : NodeType(Opc), NodeId(-1) {
+
+  SDNode(unsigned Opc, SDVTList VTs)
+    : NodeType(Opc), NodeId(-1), UsesSize(0), Uses(NULL) {
     OperandsNeedDelete = false;  // Operands set with InitOperands.
     NumOperands = 0;
     OperandList = 0;
-    
     ValueList = VTs.VTs;
     NumValues = VTs.NumVTs;
     Prev = 0; Next = 0;
@@ -1070,9 +1232,14 @@
     assert(OperandList == 0 && "Operands already set!");
     NumOperands = NumOps;
     OperandList = Ops;
+    UsesSize = 0;
+    Uses = NULL;
     
-    for (unsigned i = 0; i != NumOps; ++i)
-      Ops[i].Val->Uses.push_back(this);
+    for (unsigned i = 0; i != NumOps; ++i) {
+      OperandList[i].setUser(this);
+      Ops[i].Val->addUse(OperandList[i]);
+      ++Ops[i].Val->UsesSize;
+    }
   }
   
   /// MorphNodeTo - This frees the operands of the current node, resets the
@@ -1081,50 +1248,48 @@
   void MorphNodeTo(unsigned Opc, SDVTList L,
                    const SDOperand *Ops, unsigned NumOps);
   
-  void addUser(SDNode *User) {
-    Uses.push_back(User);
+  void addUser(unsigned i, SDNode *User) {
+    assert(User->OperandList[i].getUser() && "Node without parent");
+    addUse(User->OperandList[i]);
+    ++UsesSize;
   }
-  void removeUser(SDNode *User) {
-    // Remove this user from the operand's use list.
-    for (unsigned i = Uses.size(); ; --i) {
-      assert(i != 0 && "Didn't find user!");
-      if (Uses[i-1] == User) {
-        Uses[i-1] = Uses.back();
-        Uses.pop_back();
-        return;
-      }
-    }
+
+  void removeUser(unsigned i, SDNode *User) {
+    assert(User->OperandList[i].getUser() && "Node without parent");
+    SDOperand &Op = User->OperandList[i];
+    Op.removeFromList();
+    --UsesSize;
   }
 };
 
 
-// Define inline functions from the SDOperand class.
+// Define inline functions from the SDOperandImpl class.
 
-inline unsigned SDOperand::getOpcode() const {
+inline unsigned SDOperandImpl::getOpcode() const {
   return Val->getOpcode();
 }
-inline MVT::ValueType SDOperand::getValueType() const {
+inline MVT::ValueType SDOperandImpl::getValueType() const {
   return Val->getValueType(ResNo);
 }
-inline unsigned SDOperand::getNumOperands() const {
+inline unsigned SDOperandImpl::getNumOperands() const {
   return Val->getNumOperands();
 }
-inline const SDOperand &SDOperand::getOperand(unsigned i) const {
+inline const SDOperandImpl &SDOperandImpl::getOperand(unsigned i) const {
   return Val->getOperand(i);
 }
-inline uint64_t SDOperand::getConstantOperandVal(unsigned i) const {
+inline uint64_t SDOperandImpl::getConstantOperandVal(unsigned i) const {
   return Val->getConstantOperandVal(i);
 }
-inline bool SDOperand::isTargetOpcode() const {
+inline bool SDOperandImpl::isTargetOpcode() const {
   return Val->isTargetOpcode();
 }
-inline unsigned SDOperand::getTargetOpcode() const {
+inline unsigned SDOperandImpl::getTargetOpcode() const {
   return Val->getTargetOpcode();
 }
-inline bool SDOperand::hasOneUse() const {
+inline bool SDOperandImpl::hasOneUse() const {
   return Val->hasNUsesOfValue(1, ResNo);
 }
-inline bool SDOperand::use_empty() const {
+inline bool SDOperandImpl::use_empty() const {
   return !Val->hasAnyUseOfValue(ResNo);
 }
 

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp?rev=48822&r1=48821&r2=48822&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Wed Mar 26 07:39:26 2008
@@ -78,7 +78,7 @@
     void AddUsersToWorkList(SDNode *N) {
       for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end();
            UI != UE; ++UI)
-        AddToWorkList(*UI);
+        AddToWorkList(UI->getUser());
     }
 
     /// visit - call the node-specific routine that knows how to fold each
@@ -2704,7 +2704,7 @@
   bool isTruncFree = TLI.isTruncateFree(N->getValueType(0), N0.getValueType());
   for (SDNode::use_iterator UI = N0.Val->use_begin(), UE = N0.Val->use_end();
        UI != UE; ++UI) {
-    SDNode *User = *UI;
+    SDNode *User = UI->getUser();
     if (User == N)
       continue;
     // FIXME: Only extend SETCC N, N and SETCC N, c for now.
@@ -2743,7 +2743,7 @@
     bool BothLiveOut = false;
     for (SDNode::use_iterator UI = N->use_begin(), UE = N->use_end();
          UI != UE; ++UI) {
-      SDNode *User = *UI;
+      SDNode *User = UI->getUser();
       for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
         SDOperand UseOp = User->getOperand(i);
         if (UseOp.Val == N && UseOp.ResNo == 0) {
@@ -3880,7 +3880,7 @@
   MVT::ValueType VT = N->getValueType(0);
   
   // If this is fp_round(fpextend), don't fold it, allow ourselves to be folded.
-  if (N->hasOneUse() && (*N->use_begin())->getOpcode() == ISD::FP_ROUND)
+  if (N->hasOneUse() && (N->use_begin())->getOpcode() == ISD::FP_ROUND)
     return SDOperand();
 
   // fold (fp_extend c1fp) -> c1fp
@@ -4101,7 +4101,7 @@
   bool RealUse = false;
   for (SDNode::use_iterator I = Ptr.Val->use_begin(),
          E = Ptr.Val->use_end(); I != E; ++I) {
-    SDNode *Use = *I;
+    SDNode *Use = I->getUser();
     if (Use == N)
       continue;
     if (Use->isPredecessorOf(N))
@@ -4186,7 +4186,7 @@
   
   for (SDNode::use_iterator I = Ptr.Val->use_begin(),
          E = Ptr.Val->use_end(); I != E; ++I) {
-    SDNode *Op = *I;
+    SDNode *Op = I->getUser();
     if (Op == N ||
         (Op->getOpcode() != ISD::ADD && Op->getOpcode() != ISD::SUB))
       continue;
@@ -4214,7 +4214,7 @@
       bool TryNext = false;
       for (SDNode::use_iterator II = BasePtr.Val->use_begin(),
              EE = BasePtr.Val->use_end(); II != EE; ++II) {
-        SDNode *Use = *II;
+        SDNode *Use = II->getUser();
         if (Use == Ptr.Val)
           continue;
 
@@ -4224,7 +4224,7 @@
           bool RealUse = false;
           for (SDNode::use_iterator III = Use->use_begin(),
                  EEE = Use->use_end(); III != EEE; ++III) {
-            SDNode *UseUse = *III;
+            SDNode *UseUse = III->getUser();
             if (!((UseUse->getOpcode() == ISD::LOAD &&
                    cast<LoadSDNode>(UseUse)->getBasePtr().Val == Use) ||
                   (UseUse->getOpcode() == ISD::STORE &&

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp?rev=48822&r1=48821&r2=48822&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Mar 26 07:39:26 2008
@@ -85,17 +85,17 @@
   /// LegalizedNodes - For nodes that are of legal width, and that have more
   /// than one use, this map indicates what regularized operand to use.  This
   /// allows us to avoid legalizing the same thing more than once.
-  DenseMap<SDOperand, SDOperand> LegalizedNodes;
+  DenseMap<SDOperandImpl, SDOperand> LegalizedNodes;
 
   /// PromotedNodes - For nodes that are below legal width, and that have more
   /// than one use, this map indicates what promoted value to use.  This allows
   /// us to avoid promoting the same thing more than once.
-  DenseMap<SDOperand, SDOperand> PromotedNodes;
+  DenseMap<SDOperandImpl, SDOperand> PromotedNodes;
 
   /// ExpandedNodes - For nodes that need to be expanded this map indicates
   /// which which operands are the expanded version of the input.  This allows
   /// us to avoid expanding the same node more than once.
-  DenseMap<SDOperand, std::pair<SDOperand, SDOperand> > ExpandedNodes;
+  DenseMap<SDOperandImpl, std::pair<SDOperand, SDOperand> > ExpandedNodes;
 
   /// SplitNodes - For vector nodes that need to be split, this map indicates
   /// which which operands are the split version of the input.  This allows us
@@ -308,7 +308,7 @@
     // are now done.
     for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end();
          UI != E; ++UI)
-      Worklist.push_back(*UI);
+      Worklist.push_back(UI->getUser());
   }
 
   assert(Order.size() == Visited.size() &&
@@ -381,7 +381,7 @@
        E = Node->use_end(); UI != E; ++UI) {
     
     // Make sure to only follow users of our token chain.
-    SDNode *User = *UI;
+    SDNode *User = UI->getUser();
     for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i)
       if (User->getOperand(i) == TheChain)
         if (SDNode *Result = FindCallEndFromCallStart(User))
@@ -783,7 +783,7 @@
 
   // Note that LegalizeOp may be reentered even from single-use nodes, which
   // means that we always must cache transformed nodes.
-  DenseMap<SDOperand, SDOperand>::iterator I = LegalizedNodes.find(Op);
+  DenseMap<SDOperandImpl, SDOperand>::iterator I = LegalizedNodes.find(Op);
   if (I != LegalizedNodes.end()) return I->second;
 
   SDOperand Tmp1, Tmp2, Tmp3, Tmp4;
@@ -1599,7 +1599,7 @@
     // will cause this node to be legalized as well as handling libcalls right.
     if (LastCALLSEQ_END.Val != Node) {
       LegalizeOp(SDOperand(FindCallStartFromCallEnd(Node), 0));
-      DenseMap<SDOperand, SDOperand>::iterator I = LegalizedNodes.find(Op);
+      DenseMap<SDOperandImpl, SDOperand>::iterator I = LegalizedNodes.find(Op);
       assert(I != LegalizedNodes.end() &&
              "Legalizing the call start should have legalized this node!");
       return I->second;
@@ -4136,7 +4136,7 @@
   SDOperand Result;
   SDNode *Node = Op.Val;
 
-  DenseMap<SDOperand, SDOperand>::iterator I = PromotedNodes.find(Op);
+  DenseMap<SDOperandImpl, SDOperand>::iterator I = PromotedNodes.find(Op);
   if (I != PromotedNodes.end()) return I->second;
 
   switch (Node->getOpcode()) {
@@ -5833,7 +5833,7 @@
          "Cannot expand to FP value or to larger int value!");
 
   // See if we already expanded it.
-  DenseMap<SDOperand, std::pair<SDOperand, SDOperand> >::iterator I
+  DenseMap<SDOperandImpl, std::pair<SDOperand, SDOperand> >::iterator I
     = ExpandedNodes.find(Op);
   if (I != ExpandedNodes.end()) {
     Lo = I->second.first;

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=48822&r1=48821&r2=48822&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Wed Mar 26 07:39:26 2008
@@ -137,7 +137,7 @@
     
     for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end();
          UI != E; ++UI) {
-      SDNode *User = *UI;
+      SDNode *User = UI->getUser();
       int NodeID = User->getNodeId();
       assert(NodeID != ReadyToProcess && NodeID != Processed &&
              "Invalid node id for user of unprocessed node!");
@@ -344,7 +344,7 @@
 /// RemapNode - If the specified value was already legalized to another value,
 /// replace it by that value.
 void DAGTypeLegalizer::RemapNode(SDOperand &N) {
-  DenseMap<SDOperand, SDOperand>::iterator I = ReplacedNodes.find(N);
+  DenseMap<SDOperandImpl, SDOperand>::iterator I = ReplacedNodes.find(N);
   if (I != ReplacedNodes.end()) {
     // Use path compression to speed up future lookups if values get multiply
     // replaced with other values.

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=48822&r1=48821&r2=48822&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Wed Mar 26 07:39:26 2008
@@ -110,27 +110,27 @@
 
   /// PromotedNodes - For nodes that are below legal width, this map indicates
   /// what promoted value to use.
-  DenseMap<SDOperand, SDOperand> PromotedNodes;
+  DenseMap<SDOperandImpl, SDOperand> PromotedNodes;
   
   /// ExpandedNodes - For nodes that need to be expanded this map indicates
   /// which operands are the expanded version of the input.
-  DenseMap<SDOperand, std::pair<SDOperand, SDOperand> > ExpandedNodes;
+  DenseMap<SDOperandImpl, std::pair<SDOperand, SDOperand> > ExpandedNodes;
 
   /// FloatToIntedNodes - For floating point nodes converted to integers of
   /// the same size, this map indicates the converted value to use.
-  DenseMap<SDOperand, SDOperand> FloatToIntedNodes;
+  DenseMap<SDOperandImpl, SDOperand> FloatToIntedNodes;
 
   /// ScalarizedNodes - For nodes that are <1 x ty>, this map indicates the
   /// scalar value of type 'ty' to use.
-  DenseMap<SDOperand, SDOperand> ScalarizedNodes;
+  DenseMap<SDOperandImpl, SDOperand> ScalarizedNodes;
 
   /// SplitNodes - For nodes that need to be split this map indicates
   /// which operands are the expanded version of the input.
-  DenseMap<SDOperand, std::pair<SDOperand, SDOperand> > SplitNodes;
+  DenseMap<SDOperandImpl, std::pair<SDOperand, SDOperand> > SplitNodes;
   
   /// ReplacedNodes - For nodes that have been replaced with another,
   /// indicates the replacement node to use.
-  DenseMap<SDOperand, SDOperand> ReplacedNodes;
+  DenseMap<SDOperandImpl, SDOperand> ReplacedNodes;
 
   /// Worklist - This defines a worklist of nodes to process.  In order to be
   /// pushed onto this worklist, all operands of a node must have already been

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp?rev=48822&r1=48821&r2=48822&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/ScheduleDAG.cpp Wed Mar 26 07:39:26 2008
@@ -135,11 +135,11 @@
       bool HasFlagUse = false;
       for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); 
            UI != E; ++UI)
-        if (FlagVal.isOperandOf(*UI)) {
+        if (FlagVal.isOperandOf(UI->getUser())) {
           HasFlagUse = true;
           NodeSUnit->FlaggedNodes.push_back(N);
           SUnitMap[N].push_back(NodeSUnit);
-          N = *UI;
+          N = UI->getUser();
           break;
         }
       if (!HasFlagUse) break;
@@ -398,7 +398,7 @@
 
 void ScheduleDAG::EmitCopyFromReg(SDNode *Node, unsigned ResNo,
                                   unsigned InstanceNo, unsigned SrcReg,
-                                  DenseMap<SDOperand, unsigned> &VRBaseMap) {
+                                  DenseMap<SDOperandImpl, unsigned> &VRBaseMap) {
   unsigned VRBase = 0;
   if (TargetRegisterInfo::isVirtualRegister(SrcReg)) {
     // Just use the input register directly!
@@ -414,7 +414,7 @@
   bool MatchReg = true;
   for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
        UI != E; ++UI) {
-    SDNode *Use = *UI;
+    SDNode *Use = UI->getUser();
     bool Match = true;
     if (Use->getOpcode() == ISD::CopyToReg && 
         Use->getOperand(2).Val == Node &&
@@ -469,7 +469,7 @@
 
 void ScheduleDAG::CreateVirtualRegisters(SDNode *Node, MachineInstr *MI,
                                          const TargetInstrDesc &II,
-                                     DenseMap<SDOperand, unsigned> &VRBaseMap) {
+                                     DenseMap<SDOperandImpl, unsigned> &VRBaseMap) {
   for (unsigned i = 0; i < II.getNumDefs(); ++i) {
     // If the specific node value is only used by a CopyToReg and the dest reg
     // is a vreg, use the CopyToReg'd destination register instead of creating
@@ -477,7 +477,7 @@
     unsigned VRBase = 0;
     for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
          UI != E; ++UI) {
-      SDNode *Use = *UI;
+      SDNode *Use = UI->getUser();
       if (Use->getOpcode() == ISD::CopyToReg && 
           Use->getOperand(2).Val == Node &&
           Use->getOperand(2).ResNo == i) {
@@ -512,8 +512,8 @@
 
 /// getVR - Return the virtual register corresponding to the specified result
 /// of the specified node.
-static unsigned getVR(SDOperand Op, DenseMap<SDOperand, unsigned> &VRBaseMap) {
-  DenseMap<SDOperand, unsigned>::iterator I = VRBaseMap.find(Op);
+static unsigned getVR(SDOperand Op, DenseMap<SDOperandImpl, unsigned> &VRBaseMap) {
+  DenseMap<SDOperandImpl, unsigned>::iterator I = VRBaseMap.find(Op);
   assert(I != VRBaseMap.end() && "Node emitted out of order - late");
   return I->second;
 }
@@ -526,7 +526,7 @@
 void ScheduleDAG::AddOperand(MachineInstr *MI, SDOperand Op,
                              unsigned IIOpNum,
                              const TargetInstrDesc *II,
-                             DenseMap<SDOperand, unsigned> &VRBaseMap) {
+                             DenseMap<SDOperandImpl, unsigned> &VRBaseMap) {
   if (Op.isTargetOpcode()) {
     // Note that this case is redundant with the final else block, but we
     // include it because it is the most common and it makes the logic
@@ -658,7 +658,7 @@
 /// EmitSubregNode - Generate machine code for subreg nodes.
 ///
 void ScheduleDAG::EmitSubregNode(SDNode *Node, 
-                           DenseMap<SDOperand, unsigned> &VRBaseMap) {
+                           DenseMap<SDOperandImpl, unsigned> &VRBaseMap) {
   unsigned VRBase = 0;
   unsigned Opc = Node->getTargetOpcode();
   
@@ -666,7 +666,7 @@
   // the CopyToReg'd destination register instead of creating a new vreg.
   for (SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
        UI != E; ++UI) {
-    SDNode *Use = *UI;
+    SDNode *Use = UI->getUser();
     if (Use->getOpcode() == ISD::CopyToReg && 
         Use->getOperand(2).Val == Node) {
       unsigned DestReg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
@@ -750,7 +750,7 @@
 /// EmitNode - Generate machine code for an node and needed dependencies.
 ///
 void ScheduleDAG::EmitNode(SDNode *Node, unsigned InstanceNo,
-                           DenseMap<SDOperand, unsigned> &VRBaseMap) {
+                           DenseMap<SDOperandImpl, unsigned> &VRBaseMap) {
   // If machine instruction
   if (Node->isTargetOpcode()) {
     unsigned Opc = Node->getTargetOpcode();
@@ -1067,7 +1067,7 @@
   }
 
   // Finally, emit the code for all of the scheduled instructions.
-  DenseMap<SDOperand, unsigned> VRBaseMap;
+  DenseMap<SDOperandImpl, unsigned> VRBaseMap;
   DenseMap<SUnit*, unsigned> CopyVRBaseMap;
   for (unsigned i = 0, e = Sequence.size(); i != e; i++) {
     if (SUnit *SU = Sequence[i]) {

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=48822&r1=48821&r2=48822&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Mar 26 07:39:26 2008
@@ -10,7 +10,6 @@
 // This implements the SelectionDAG class.
 //
 //===----------------------------------------------------------------------===//
-
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/Constants.h"
 #include "llvm/GlobalAlias.h"
@@ -465,14 +464,15 @@
     // no cycles in the graph.
     for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) {
       SDNode *Operand = I->Val;
-      Operand->removeUser(N);
+      Operand->removeUser(std::distance(N->op_begin(), I), N);
       
       // Now that we removed this operand, see if there are no uses of it left.
       if (Operand->use_empty())
         DeadNodes.push_back(Operand);
     }
-    if (N->OperandsNeedDelete)
+    if (N->OperandsNeedDelete) {
       delete[] N->OperandList;
+    }
     N->OperandList = 0;
     N->NumOperands = 0;
     
@@ -504,14 +504,15 @@
     // no cycles in the graph.
     for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) {
       SDNode *Operand = I->Val;
-      Operand->removeUser(N);
+      Operand->removeUser(std::distance(N->op_begin(), I), N);
       
       // Now that we removed this operand, see if there are no uses of it left.
       if (Operand->use_empty())
         DeadNodes.push_back(Operand);
     }
-    if (N->OperandsNeedDelete)
+    if (N->OperandsNeedDelete) {
       delete[] N->OperandList;
+    }
     N->OperandList = 0;
     N->NumOperands = 0;
     
@@ -538,9 +539,10 @@
     
   // Drop all of the operands and decrement used nodes use counts.
   for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I)
-    I->Val->removeUser(N);
-  if (N->OperandsNeedDelete)
+    I->Val->removeUser(std::distance(N->op_begin(), I), N);
+  if (N->OperandsNeedDelete) {
     delete[] N->OperandList;
+  }
   N->OperandList = 0;
   N->NumOperands = 0;
   
@@ -701,8 +703,9 @@
   while (!AllNodes.empty()) {
     SDNode *N = AllNodes.begin();
     N->SetNextInBucket(0);
-    if (N->OperandsNeedDelete)
+    if (N->OperandsNeedDelete) {
       delete [] N->OperandList;
+    }
     N->OperandList = 0;
     N->NumOperands = 0;
     AllNodes.pop_front();
@@ -2920,9 +2923,10 @@
     RemoveNodeFromCSEMaps(N);
   
   // Now we update the operands.
-  N->OperandList[0].Val->removeUser(N);
-  Op.Val->addUser(N);
+  N->OperandList[0].Val->removeUser(0, N);
   N->OperandList[0] = Op;
+  N->OperandList[0].setUser(N);
+  Op.Val->addUser(0, N);
   
   // If this gets put into a CSE map, add it.
   if (InsertPos) CSEMap.InsertNode(N, InsertPos);
@@ -2949,14 +2953,16 @@
   
   // Now we update the operands.
   if (N->OperandList[0] != Op1) {
-    N->OperandList[0].Val->removeUser(N);
-    Op1.Val->addUser(N);
+    N->OperandList[0].Val->removeUser(0, N);
     N->OperandList[0] = Op1;
+    N->OperandList[0].setUser(N);
+    Op1.Val->addUser(0, N);
   }
   if (N->OperandList[1] != Op2) {
-    N->OperandList[1].Val->removeUser(N);
-    Op2.Val->addUser(N);
+    N->OperandList[1].Val->removeUser(1, N);
     N->OperandList[1] = Op2;
+    N->OperandList[1].setUser(N);
+    Op2.Val->addUser(1, N);
   }
   
   // If this gets put into a CSE map, add it.
@@ -2984,7 +2990,6 @@
   return UpdateNodeOperands(N, Ops, 5);
 }
 
-
 SDOperand SelectionDAG::
 UpdateNodeOperands(SDOperand InN, SDOperand *Ops, unsigned NumOps) {
   SDNode *N = InN.Val;
@@ -3015,9 +3020,10 @@
   // Now we update the operands.
   for (unsigned i = 0; i != NumOps; ++i) {
     if (N->OperandList[i] != Ops[i]) {
-      N->OperandList[i].Val->removeUser(N);
-      Ops[i].Val->addUser(N);
+      N->OperandList[i].Val->removeUser(i, N);
       N->OperandList[i] = Ops[i];
+      N->OperandList[i].setUser(N);
+      Ops[i].Val->addUser(i, N);
     }
   }
 
@@ -3026,7 +3032,6 @@
   return InN;
 }
 
-
 /// MorphNodeTo - This frees the operands of the current node, resets the
 /// opcode, types, and operands to the specified value.  This should only be
 /// used by the SelectionDAG class.
@@ -3039,13 +3044,14 @@
   // Clear the operands list, updating used nodes to remove this from their
   // use list.
   for (op_iterator I = op_begin(), E = op_end(); I != E; ++I)
-    I->Val->removeUser(this);
+    I->Val->removeUser(std::distance(op_begin(), I), this);
   
   // If NumOps is larger than the # of operands we currently have, reallocate
   // the operand list.
   if (NumOps > NumOperands) {
-    if (OperandsNeedDelete)
+    if (OperandsNeedDelete) {
       delete [] OperandList;
+    }
     OperandList = new SDOperand[NumOps];
     OperandsNeedDelete = true;
   }
@@ -3055,8 +3061,10 @@
   
   for (unsigned i = 0, e = NumOps; i != e; ++i) {
     OperandList[i] = Ops[i];
+    OperandList[i].setUser(this);
     SDNode *N = OperandList[i].Val;
-    N->Uses.push_back(this);
+    N->addUser(i, this);
+    ++N->UsesSize;
   }
 }
 
@@ -3324,21 +3332,27 @@
   assert(From->getNumValues() == 1 && FromN.ResNo == 0 && 
          "Cannot replace with this method!");
   assert(From != To.Val && "Cannot replace uses of with self");
-  
+
+  SmallSetVector<SDNode*, 16> Users;
   while (!From->use_empty()) {
-    // Process users until they are all gone.
-    SDNode *U = *From->use_begin();
-    
+    SDNode::use_iterator UI = From->use_begin();
+    SDNode *U = UI->getUser();
+
+    // Remember that this node is about to morph.
+    if (Users.count(U)) 
+      continue;
+    Users.insert(U);
     // This node is about to morph, remove its old self from the CSE maps.
     RemoveNodeFromCSEMaps(U);
-    
-    for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands;
-         I != E; ++I)
+    int operandNum = 0;
+    for (SDNode::op_iterator I = U->op_begin(), E = U->op_end();
+         I != E; ++I, ++operandNum)
       if (I->Val == From) {
-        From->removeUser(U);
+        From->removeUser(operandNum, U);
         *I = To;
-        To.Val->addUser(U);
-      }
+        I->setUser(U);
+        To.Val->addUser(operandNum, U);
+      }    
 
     // Now that we have modified U, add it back to the CSE maps.  If it already
     // exists there, recursively merge the results together.
@@ -3372,21 +3386,26 @@
     return ReplaceAllUsesWith(SDOperand(From, 0), SDOperand(To, 0),
                               UpdateListener);
   
+  SmallSetVector<SDNode*, 16> Users;
   while (!From->use_empty()) {
-    // Process users until they are all gone.
-    SDNode *U = *From->use_begin();
-    
+    SDNode::use_iterator UI = From->use_begin();
+    SDNode *U = UI->getUser();
+
+    // Remember that this node is about to morph.
+    if (Users.count(U)) 
+      continue;
+    Users.insert(U);
     // This node is about to morph, remove its old self from the CSE maps.
     RemoveNodeFromCSEMaps(U);
-    
-    for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands;
-         I != E; ++I)
+    int operandNum = 0;
+    for (SDNode::op_iterator I = U->op_begin(), E = U->op_end();
+         I != E; ++I, ++operandNum)
       if (I->Val == From) {
-        From->removeUser(U);
+        From->removeUser(operandNum, U);
         I->Val = To;
-        To->addUser(U);
+        To->addUser(operandNum, U);
       }
-        
+
     // Now that we have modified U, add it back to the CSE maps.  If it already
     // exists there, recursively merge the results together.
     if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) {
@@ -3415,22 +3434,28 @@
   if (From->getNumValues() == 1)  // Handle the simple case efficiently.
     return ReplaceAllUsesWith(SDOperand(From, 0), To[0], UpdateListener);
 
+  SmallSetVector<SDNode*, 16> Users;
   while (!From->use_empty()) {
-    // Process users until they are all gone.
-    SDNode *U = *From->use_begin();
-    
+    SDNode::use_iterator UI = From->use_begin();
+    SDNode *U = UI->getUser();
+
+    // Remember that this node is about to morph.
+    if (Users.count(U)) 
+      continue;
+    Users.insert(U);
     // This node is about to morph, remove its old self from the CSE maps.
     RemoveNodeFromCSEMaps(U);
-    
-    for (SDOperand *I = U->OperandList, *E = U->OperandList+U->NumOperands;
-         I != E; ++I)
+    int operandNum = 0;
+    for (SDNode::op_iterator I = U->op_begin(), E = U->op_end();
+         I != E; ++I, ++operandNum)
       if (I->Val == From) {
         const SDOperand &ToOp = To[I->ResNo];
-        From->removeUser(U);
+        From->removeUser(operandNum, U);
         *I = ToOp;
-        ToOp.Val->addUser(U);
+        I->setUser(U);
+        ToOp.Val->addUser(operandNum, U);
       }
-        
+
     // Now that we have modified U, add it back to the CSE maps.  If it already
     // exists there, recursively merge the results together.
     if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) {
@@ -3460,7 +3485,7 @@
     ChainedSetUpdaterListener(SmallSetVector<SDNode*, 16> &set,
                               SelectionDAG::DAGUpdateListener *chain)
       : Set(set), Chain(chain) {}
-    
+ 
     virtual void NodeDeleted(SDNode *N) {
       Set.remove(N);
       if (Chain) Chain->NodeDeleted(N);
@@ -3488,7 +3513,13 @@
 
   // Get all of the users of From.Val.  We want these in a nice,
   // deterministically ordered and uniqued set, so we use a SmallSetVector.
-  SmallSetVector<SDNode*, 16> Users(From.Val->use_begin(), From.Val->use_end());
+  SmallSetVector<SDNode*, 16> Users;
+  for (SDNode::use_iterator UI = From.Val->use_begin(), 
+      E = From.Val->use_end(); UI != E; ++UI) {
+    SDNode *User = UI->getUser();
+    if (!Users.count(User))
+    Users.insert(User);
+  }
 
   // When one of the recursive merges deletes nodes from the graph, we need to
   // make sure that UpdateListener is notified *and* that the node is removed
@@ -3502,7 +3533,7 @@
     Users.pop_back();
     
     // Scan for an operand that matches From.
-    SDOperand *Op = User->OperandList, *E = User->OperandList+User->NumOperands;
+    SDNode::op_iterator Op = User->op_begin(), E = User->op_end();
     for (; Op != E; ++Op)
       if (*Op == From) break;
     
@@ -3516,9 +3547,10 @@
     // Update all operands that match "From" in case there are multiple uses.
     for (; Op != E; ++Op) {
       if (*Op == From) {
-        From.Val->removeUser(User);
-        *Op = To;
-        To.Val->addUser(User);
+        From.Val->removeUser(Op-User->op_begin(), User);
+	*Op = To;
+        Op->setUser(User);
+        To.Val->addUser(Op-User->op_begin(), User);
       }
     }
                
@@ -3698,16 +3730,13 @@
 
   SmallPtrSet<SDNode*, 32> UsersHandled;
 
-  for (SDNode::use_iterator UI = Uses.begin(), E = Uses.end(); UI != E; ++UI) {
-    SDNode *User = *UI;
-    if (User->getNumOperands() == 1 ||
-        UsersHandled.insert(User))     // First time we've seen this?
-      for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i)
-        if (User->getOperand(i) == TheValue) {
-          if (NUses == 0)
-            return false;   // too many uses
-          --NUses;
-        }
+  // TODO: Only iterate over uses of a given value of the node
+	for (SDNode::use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) {
+	  if (*UI == TheValue) {
+	    if (NUses == 0)
+	      return false;
+      --NUses;
+    }
   }
 
   // Found exactly the right number of uses?
@@ -3726,8 +3755,8 @@
 
   SmallPtrSet<SDNode*, 32> UsersHandled;
 
-  for (SDNode::use_iterator UI = Uses.begin(), E = Uses.end(); UI != E; ++UI) {
-    SDNode *User = *UI;
+  for (SDNode::use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) {
+    SDNode *User = UI->getUser();
     if (User->getNumOperands() == 1 ||
         UsersHandled.insert(User))     // First time we've seen this?
       for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i)
@@ -3745,7 +3774,7 @@
 bool SDNode::isOnlyUseOf(SDNode *N) const {
   bool Seen = false;
   for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
-    SDNode *User = *I;
+    SDNode *User = I->getUser();
     if (User == this)
       Seen = true;
     else
@@ -3757,7 +3786,7 @@
 
 /// isOperand - Return true if this node is an operand of N.
 ///
-bool SDOperand::isOperandOf(SDNode *N) const {
+bool SDOperandImpl::isOperandOf(SDNode *N) const {
   for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
     if (*this == N->getOperand(i))
       return true;
@@ -3776,7 +3805,7 @@
 /// side-effecting instructions.  In practice, this looks through token
 /// factors and non-volatile loads.  In order to remain efficient, this only
 /// looks a couple of nodes in, it does not do an exhaustive search.
-bool SDOperand::reachesChainWithoutSideEffects(SDOperand Dest, 
+bool SDOperandImpl::reachesChainWithoutSideEffects(SDOperandImpl Dest, 
                                                unsigned Depth) const {
   if (*this == Dest) return true;
   

Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=48822&r1=48821&r2=48822&view=diff

==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Wed Mar 26 07:39:26 2008
@@ -3660,11 +3660,11 @@
       SDNode *LHSN = N->getOperand(0).Val;
       for (SDNode::use_iterator UI = LHSN->use_begin(), E = LHSN->use_end();
            UI != E; ++UI)
-        if ((*UI)->getOpcode() == PPCISD::VCMPo &&
-            (*UI)->getOperand(1) == N->getOperand(1) &&
-            (*UI)->getOperand(2) == N->getOperand(2) &&
-            (*UI)->getOperand(0) == N->getOperand(0)) {
-          VCMPoNode = *UI;
+        if ((*UI).getUser()->getOpcode() == PPCISD::VCMPo &&
+            (*UI).getUser()->getOperand(1) == N->getOperand(1) &&
+            (*UI).getUser()->getOperand(2) == N->getOperand(2) &&
+            (*UI).getUser()->getOperand(0) == N->getOperand(0)) {
+          VCMPoNode = UI->getUser();
           break;
         }
       
@@ -3680,7 +3680,7 @@
       for (SDNode::use_iterator UI = VCMPoNode->use_begin(); 
            FlagUser == 0; ++UI) {
         assert(UI != VCMPoNode->use_end() && "Didn't find user!");
-        SDNode *User = *UI;
+        SDNode *User = UI->getUser();
         for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
           if (User->getOperand(i) == SDOperand(VCMPoNode, 1)) {
             FlagUser = User;

Modified: llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp?rev=48822&r1=48821&r2=48822&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelDAGToDAG.cpp Wed Mar 26 07:39:26 2008
@@ -225,7 +225,7 @@
 static SDNode *findFlagUse(SDNode *N) {
   unsigned FlagResNo = N->getNumValues()-1;
   for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
-    SDNode *User = *I;
+    SDNode *User = I->getUser();
     for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
       SDOperand Op = User->getOperand(i);
       if (Op.Val == N && Op.ResNo == FlagResNo)

Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=48822&r1=48821&r2=48822&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Wed Mar 26 07:39:26 2008
@@ -3724,7 +3724,7 @@
     // result has a single use which is a store.
     if (!Op.hasOneUse())
       return SDOperand();
-    SDNode *User = *Op.Val->use_begin();
+    SDNode *User = Op.Val->use_begin()->getUser();
     if (User->getOpcode() != ISD::STORE)
       return SDOperand();
     SDOperand Extract = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32,





More information about the llvm-commits mailing list