[llvm-commits] [llvm] r62995 - in /llvm/trunk: include/llvm/CodeGen/SelectionDAGNodes.h lib/CodeGen/SelectionDAG/DAGCombiner.cpp lib/CodeGen/SelectionDAG/LegalizeTypes.cpp lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Target/X86/X86ISelLowering.cpp

Dan Gohman gohman at apple.com
Sun Jan 25 20:35:07 PST 2009


Author: djg
Date: Sun Jan 25 22:35:06 2009
New Revision: 62995

URL: http://llvm.org/viewvc/llvm-project?rev=62995&view=rev
Log:
Take the next steps in making SDUse more consistent with LLVM Use, and
tidy up SDUse and related code.
 - Replace the operator= member functions with a set method, like
   LLVM Use has, and variants setInitial and setNode, which take
   care up updating use lists, like LLVM Use's does. This simplifies
   code that calls these functions.
 - getSDValue() is renamed to get(), as in LLVM Use, though most
   places can either use the implicit conversion to SDValue or the
   convenience functions instead.
 - Fix some more node vs. value terminology issues.

Also, eliminate the one remaining use of SDOperandPtr, and
SDOperandPtr itself.

Modified:
    llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h
    llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
    llvm/trunk/lib/Target/X86/X86ISelLowering.cpp

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

==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAGNodes.h Sun Jan 25 22:35:06 2009
@@ -955,63 +955,77 @@
   }
 };
 
-/// SDUse - Represents a use of the SDNode referred by
-/// the SDValue.
+/// SDUse - Represents a use of a SDNode. This class holds an SDValue,
+/// which records the SDNode being used and the result number, a
+/// pointer to the SDNode using the value, and Next and Prev pointers,
+/// which link together all the uses of an SDNode.
+///
 class SDUse {
-  SDValue Operand;
-  /// User - Parent node of this operand.
-  SDNode    *User;
-  /// Prev, next - Pointers to the uses list of the SDNode referred by 
+  /// Val - The value being used.
+  SDValue Val;
+  /// User - The user of this value.
+  SDNode *User;
+  /// Prev, Next - Pointers to the uses list of the SDNode referred by 
   /// this operand.
   SDUse **Prev, *Next;
-public:
-  friend class SDNode;
-  SDUse(): Operand(), User(NULL), Prev(NULL), Next(NULL) {}
 
-  SDUse(SDNode *val, unsigned resno) : 
-    Operand(val,resno), User(NULL), Prev(NULL), Next(NULL) {}
-
-  SDUse& operator= (const SDValue& Op) {
-      Operand = Op;
-      Next = NULL;
-      Prev = NULL;
-      return *this;
-  }
+  SDUse(const SDUse &U);          // Do not implement
+  void operator=(const SDUse &U); // Do not implement
 
-  SDUse& operator= (const SDUse& Op) {
-      Operand = Op;
-      Next = NULL;
-      Prev = NULL;
-      return *this;
-  }
+public:
+  SDUse() : Val(), User(NULL), Prev(NULL), Next(NULL) {}
 
-  SDUse *getNext() { return Next; }
+  /// Normally SDUse will just implicitly convert to an SDValue that it holds.
+  operator const SDValue&() const { return Val; }
 
+  /// If implicit conversion to SDValue doesn't work, the get() method returns
+  /// the SDValue.
+  const SDValue &get() const { return Val; }
+  
+  /// getUser - This returns the SDNode that contains this Use.
   SDNode *getUser() { return User; }
 
-  void setUser(SDNode *p) { User = p; }
-
-  operator SDValue() const { return Operand; }
-
-  const SDValue& getSDValue() const { return Operand; }
-
-  SDValue &getSDValue() { return Operand; }
-  SDNode *getVal() { return Operand.getNode(); }
-  SDNode *getVal() const { return Operand.getNode(); } // FIXME: const correct?
+  /// getNext - Get the next SDUse in the use list.
+  SDUse *getNext() const { return Next; }
 
-  bool operator==(const SDValue &O) const {
-    return Operand == O;
+  /// getNode - Convenience function for get().getNode().
+  SDNode *getNode() const { return Val.getNode(); }
+  /// getResNo - Convenience function for get().getResNo().
+  unsigned getResNo() const { return Val.getResNo(); }
+  /// getValueType - Convenience function for get().getValueType().
+  MVT getValueType() const { return Val.getValueType(); }
+
+  /// operator== - Convenience function for get().operator==
+  bool operator==(const SDValue &V) const {
+    return Val == V;
   }
-
-  bool operator!=(const SDValue &O) const {
-    return !(Operand == O);
+  
+  /// operator!= - Convenience function for get().operator!=
+  bool operator!=(const SDValue &V) const {
+    return Val != V;
   }
 
-  bool operator<(const SDValue &O) const {
-    return Operand < O;
+  /// operator< - Convenience function for get().operator<
+  bool operator<(const SDValue &V) const {
+    return Val < V;
   }
 
-protected:
+private:
+  friend class SelectionDAG;
+  friend class SDNode;
+
+  void setUser(SDNode *p) { User = p; }
+
+  /// set - Remove this use from its existing use list, assign it the
+  /// given value, and add it to the new value's node's use list.
+  inline void set(const SDValue &V);
+  /// setInitial - like set, but only supports initializing a newly-allocated
+  /// SDUse with a non-null value.
+  inline void setInitial(const SDValue &V);
+  /// setNode - like set, but only sets the Node portion of the value,
+  /// leaving the ResNo portion unmodified.
+  inline void setNode(SDNode *N);
+
   void addToList(SDUse **List) {
     Next = *List;
     if (Next) Next->Prev = &Next;
@@ -1025,61 +1039,22 @@
   }
 };
 
-
 /// simplify_type specializations - Allow casting operators to work directly on
 /// SDValues as if they were SDNode*'s.
 template<> struct simplify_type<SDUse> {
   typedef SDNode* SimpleType;
   static SimpleType getSimplifiedValue(const SDUse &Val) {
-    return static_cast<SimpleType>(Val.getVal());
+    return static_cast<SimpleType>(Val.getNode());
   }
 };
 template<> struct simplify_type<const SDUse> {
   typedef SDNode* SimpleType;
   static SimpleType getSimplifiedValue(const SDUse &Val) {
-    return static_cast<SimpleType>(Val.getVal());
+    return static_cast<SimpleType>(Val.getNode());
   }
 };
 
 
-/// SDOperandPtr - A helper SDValue pointer class, that can handle
-/// arrays of SDUse and arrays of SDValue objects. This is required
-/// in many places inside the SelectionDAG.
-/// 
-class SDOperandPtr {
-  const SDValue *ptr; // The pointer to the SDValue object
-  int object_size;      // The size of the object containg the SDValue
-public:
-  SDOperandPtr() : ptr(0), object_size(0) {}
-
-  SDOperandPtr(SDUse * use_ptr) { 
-    ptr = &use_ptr->getSDValue(); 
-    object_size = (int)sizeof(SDUse); 
-  }
-
-  SDOperandPtr(const SDValue * op_ptr) { 
-    ptr = op_ptr; 
-    object_size = (int)sizeof(SDValue); 
-  }
-
-  const SDValue operator *() { return *ptr; }
-  const SDValue *operator ->() { return ptr; }
-  SDOperandPtr operator ++ () { 
-    ptr = (SDValue*)((char *)ptr + object_size); 
-    return *this; 
-  }
-
-  SDOperandPtr operator ++ (int) { 
-    SDOperandPtr tmp = *this;
-    ptr = (SDValue*)((char *)ptr + object_size); 
-    return tmp; 
-  }
-
-  SDValue operator[] (int idx) const {
-    return *(SDValue*)((char*) ptr + object_size * idx);
-  } 
-};
-
 /// SDNode - Represents one node in the SelectionDAG.
 ///
 class SDNode : public FoldingSetNode, public ilist_node<SDNode> {
@@ -1113,11 +1088,14 @@
   /// NumOperands/NumValues - The number of entries in the Operand/Value list.
   unsigned short NumOperands, NumValues;
   
-  /// Uses - List of uses for this SDNode.
-  SDUse *Uses;
+  /// UseList - List of uses for this SDNode.
+  SDUse *UseList;
 
-  /// addUse - add SDUse to the list of uses.
-  void addUse(SDUse &U) { U.addToList(&Uses); }
+  /// getValueTypeList - Return a pointer to the specified value type.
+  static const MVT *getValueTypeList(MVT VT);
+
+  friend class SelectionDAG;
+  friend struct ilist_traits<SDNode>;
 
 public:
   //===--------------------------------------------------------------------===//
@@ -1148,7 +1126,7 @@
 
   /// use_empty - Return true if there are no uses of this node.
   ///
-  bool use_empty() const { return Uses == NULL; }
+  bool use_empty() const { return UseList == NULL; }
 
   /// hasOneUse - Return true if there is exactly one use of this node.
   ///
@@ -1226,7 +1204,7 @@
   /// of an SDNode.
 
   use_iterator use_begin() const {
-    return use_iterator(Uses);
+    return use_iterator(UseList);
   }
 
   static use_iterator use_end() { return use_iterator(0); }
@@ -1265,14 +1243,13 @@
 
   const SDValue &getOperand(unsigned Num) const {
     assert(Num < NumOperands && "Invalid child # of SDNode!");
-    return OperandList[Num].getSDValue();
+    return OperandList[Num];
   }
 
   typedef SDUse* op_iterator;
   op_iterator op_begin() const { return OperandList; }
   op_iterator op_end() const { return OperandList+NumOperands; }
 
-
   SDVTList getVTList() const {
     SDVTList X = { ValueList, NumValues };
     return X;
@@ -1339,13 +1316,11 @@
   ///
   void Profile(FoldingSetNodeID &ID) const;
 
-protected:
-  friend class SelectionDAG;
-  friend struct ilist_traits<SDNode>;
-  
-  /// getValueTypeList - Return a pointer to the specified value type.
+  /// addUse - This method should only be used by the SDUse class.
   ///
-  static const MVT *getValueTypeList(MVT VT);
+  void addUse(SDUse &U) { U.addToList(&UseList); }
+
+protected:
   static SDVTList getSDVTList(MVT VT) {
     SDVTList Ret = { getValueTypeList(VT), 1 };
     return Ret;
@@ -1353,77 +1328,84 @@
 
   SDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps)
     : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0),
-      NodeId(-1), Uses(NULL) {
-    NumOperands = NumOps;
-    OperandList = NumOps ? new SDUse[NumOperands] : 0;
-    
-    for (unsigned i = 0; i != NumOps; ++i) {
-      OperandList[i] = Ops[i];
-      OperandList[i].setUser(this);
-      Ops[i].getNode()->addUse(OperandList[i]);
-    }
-    
-    ValueList = VTs.VTs;
-    NumValues = VTs.NumVTs;
-  }
-
-  SDNode(unsigned Opc, SDVTList VTs, const SDUse *Ops, unsigned NumOps)
-    : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0),
-      NodeId(-1), Uses(NULL) {
-    OperandsNeedDelete = true;
-    NumOperands = NumOps;
-    OperandList = NumOps ? new SDUse[NumOperands] : 0;
-    
+      NodeId(-1),
+      OperandList(NumOps ? new SDUse[NumOps] : 0),
+      ValueList(VTs.VTs),
+      NumOperands(NumOps), NumValues(VTs.NumVTs),
+      UseList(NULL) {
     for (unsigned i = 0; i != NumOps; ++i) {
-      OperandList[i] = Ops[i];
       OperandList[i].setUser(this);
-      Ops[i].getVal()->addUse(OperandList[i]);
+      OperandList[i].setInitial(Ops[i]);
     }
-    
-    ValueList = VTs.VTs;
-    NumValues = VTs.NumVTs;
   }
 
   /// This constructor adds no operands itself; operands can be
   /// set later with InitOperands.
   SDNode(unsigned Opc, SDVTList VTs)
     : NodeType(Opc), OperandsNeedDelete(false), SubclassData(0),
-      NodeId(-1), Uses(NULL) {
-    NumOperands = 0;
-    OperandList = 0;
-    ValueList = VTs.VTs;
-    NumValues = VTs.NumVTs;
-  }
+      NodeId(-1), OperandList(0), ValueList(VTs.VTs),
+      NumOperands(0), NumValues(VTs.NumVTs),
+      UseList(NULL) {}
   
-  /// InitOperands - Initialize the operands list of this node with the
-  /// specified values, which are part of the node (thus they don't need to be
-  /// copied in or allocated).
-  void InitOperands(SDUse *Ops, unsigned NumOps) {
-    assert(OperandList == 0 && "Operands already set!");
-    NumOperands = NumOps;
+  /// InitOperands - Initialize the operands list of this with 1 operand.
+  void InitOperands(SDUse *Ops, const SDValue &Op0) {
+    Ops[0].setUser(this);
+    Ops[0].setInitial(Op0);
+    NumOperands = 1;
     OperandList = Ops;
-    Uses = NULL;
-    
-    for (unsigned i = 0; i != NumOps; ++i) {
-      OperandList[i].setUser(this);
-      Ops[i].getVal()->addUse(OperandList[i]);
+  }
+
+  /// InitOperands - Initialize the operands list of this with 2 operands.
+  void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1) {
+    Ops[0].setUser(this);
+    Ops[0].setInitial(Op0);
+    Ops[1].setUser(this);
+    Ops[1].setInitial(Op1);
+    NumOperands = 2;
+    OperandList = Ops;
+  }
+
+  /// InitOperands - Initialize the operands list of this with 3 operands.
+  void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1,
+                    const SDValue &Op2) {
+    Ops[0].setUser(this);
+    Ops[0].setInitial(Op0);
+    Ops[1].setUser(this);
+    Ops[1].setInitial(Op1);
+    Ops[2].setUser(this);
+    Ops[2].setInitial(Op2);
+    NumOperands = 3;
+    OperandList = Ops;
+  }
+
+  /// InitOperands - Initialize the operands list of this with 4 operands.
+  void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1,
+                    const SDValue &Op2, const SDValue &Op3) {
+    Ops[0].setUser(this);
+    Ops[0].setInitial(Op0);
+    Ops[1].setUser(this);
+    Ops[1].setInitial(Op1);
+    Ops[2].setUser(this);
+    Ops[2].setInitial(Op2);
+    Ops[3].setUser(this);
+    Ops[3].setInitial(Op3);
+    NumOperands = 4;
+    OperandList = Ops;
+  }
+
+  /// InitOperands - Initialize the operands list of this with N operands.
+  void InitOperands(SDUse *Ops, const SDValue *Vals, unsigned N) {
+    for (unsigned i = 0; i != N; ++i) {
+      Ops[i].setUser(this);
+      Ops[i].setInitial(Vals[i]);
     }
+    NumOperands = N;
+    OperandList = Ops;
   }
 
   /// DropOperands - Release the operands and set this node to have
   /// zero operands.
   void DropOperands();
-  
-  void addUser(unsigned i, SDNode *User) {
-    assert(User->OperandList[i].getUser() && "Node without parent");
-    addUse(User->OperandList[i]);
-  }
-
-  void removeUser(unsigned i, SDNode *User) {
-    assert(User->OperandList[i].getUser() && "Node without parent");
-    SDUse &Op = User->OperandList[i];
-    Op.removeFromList();
-  }
 };
 
 
@@ -1460,6 +1442,25 @@
   return Node->hasNUsesOfValue(1, ResNo);
 }
 
+// Define inline functions from the SDUse class.
+
+inline void SDUse::set(const SDValue &V) {
+  if (Val.getNode()) removeFromList();
+  Val = V;
+  if (V.getNode()) V.getNode()->addUse(*this);
+}
+
+inline void SDUse::setInitial(const SDValue &V) {
+  Val = V;
+  V.getNode()->addUse(*this);
+}
+
+inline void SDUse::setNode(SDNode *N) {
+  if (Val.getNode()) removeFromList();
+  Val.setNode(N);
+  if (N) N->addUse(*this);
+}
+
 /// UnarySDNode - This class is used for single-operand SDNodes.  This is solely
 /// to allow co-allocation of node operands with the node itself.
 class UnarySDNode : public SDNode {
@@ -1467,8 +1468,7 @@
 public:
   UnarySDNode(unsigned Opc, SDVTList VTs, SDValue X)
     : SDNode(Opc, VTs) {
-    Op = X;
-    InitOperands(&Op, 1);
+    InitOperands(&Op, X);
   }
 };
 
@@ -1479,9 +1479,7 @@
 public:
   BinarySDNode(unsigned Opc, SDVTList VTs, SDValue X, SDValue Y)
     : SDNode(Opc, VTs) {
-    Ops[0] = X;
-    Ops[1] = Y;
-    InitOperands(Ops, 2);
+    InitOperands(Ops, X, Y);
   }
 };
 
@@ -1493,10 +1491,7 @@
   TernarySDNode(unsigned Opc, SDVTList VTs, SDValue X, SDValue Y,
                 SDValue Z)
     : SDNode(Opc, VTs) {
-    Ops[0] = X;
-    Ops[1] = Y;
-    Ops[2] = Z;
-    InitOperands(Ops, 3);
+    InitOperands(Ops, X, Y, Z);
   }
 };
 
@@ -1516,11 +1511,10 @@
   explicit HandleSDNode(SDValue X)
 #endif
     : SDNode(ISD::HANDLENODE, getSDVTList(MVT::Other)) {
-    Op = X;
-    InitOperands(&Op, 1);
+    InitOperands(&Op, X);
   }
   ~HandleSDNode();  
-  const SDValue &getValue() const { return Op.getSDValue(); }
+  const SDValue &getValue() const { return Op; }
 };
 
 /// Abstact virtual class for operations for memory operations
@@ -1617,21 +1611,14 @@
                unsigned Align=0)
     : MemSDNode(Opc, VTL, MemVT, SrcVal, /*SVOffset=*/0,
                 Align, /*isVolatile=*/true) {
-    Ops[0] = Chain;
-    Ops[1] = Ptr;
-    Ops[2] = Cmp;
-    Ops[3] = Swp;
-    InitOperands(Ops, 4);
+    InitOperands(Ops, Chain, Ptr, Cmp, Swp);
   }
   AtomicSDNode(unsigned Opc, SDVTList VTL, MVT MemVT,
                SDValue Chain, SDValue Ptr, 
                SDValue Val, const Value* SrcVal, unsigned Align=0)
     : MemSDNode(Opc, VTL, MemVT, SrcVal, /*SVOffset=*/0,
                 Align, /*isVolatile=*/true) {
-    Ops[0] = Chain;
-    Ops[1] = Ptr;
-    Ops[2] = Val;
-    InitOperands(Ops, 3);
+    InitOperands(Ops, Chain, Ptr, Val);
   }
   
   const SDValue &getBasePtr() const { return getOperand(1); }
@@ -1979,8 +1966,7 @@
                      Value *cu)
     : SDNode(ISD::DBG_STOPPOINT, getSDVTList(MVT::Other)),
       Line(l), Column(c), CU(cu) {
-    Chain = ch;
-    InitOperands(&Chain, 1);
+    InitOperands(&Chain, ch);
   }
 public:
   unsigned getLine() const { return Line; }
@@ -2000,8 +1986,7 @@
   friend class SelectionDAG;
   LabelSDNode(unsigned NodeTy, SDValue ch, unsigned id)
     : SDNode(NodeTy, getSDVTList(MVT::Other)), LabelID(id) {
-    Chain = ch;
-    InitOperands(&Chain, 1);
+    InitOperands(&Chain, ch);
   }
 public:
   unsigned getLabelID() const { return LabelID; }
@@ -2256,9 +2241,7 @@
                const Value *SV, int SVO, unsigned Align, bool Vol)
     : MemSDNode(NodeTy, VTs, VT, SV, SVO, Align, Vol) {
     SubclassData = AM;
-    for (unsigned i = 0; i != numOperands; ++i)
-      Ops[i] = Operands[i];
-    InitOperands(Ops, numOperands);
+    InitOperands(Ops, Operands, numOperands);
     assert(Align != 0 && "Loads and stores should have non-zero aligment");
     assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) &&
            "Only indexed loads and stores have a non-undef offset operand");

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

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/DAGCombiner.cpp Sun Jan 25 22:35:06 2009
@@ -4138,7 +4138,7 @@
   
   // If this is fp_round(fpextend), don't fold it, allow ourselves to be folded.
   if (N->hasOneUse() && 
-      N->use_begin().getUse().getSDValue().getOpcode() == ISD::FP_ROUND)
+      N->use_begin()->getOpcode() == ISD::FP_ROUND)
     return SDValue();
 
   // fold (fp_extend c1fp) -> c1fp

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

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Sun Jan 25 22:35:06 2009
@@ -81,7 +81,7 @@
         // Check that remapped values are only used by nodes marked NewNode.
         for (SDNode::use_iterator UI = I->use_begin(), UE = I->use_end();
              UI != UE; ++UI)
-          if (UI.getUse().getSDValue().getResNo() == i)
+          if (UI.getUse().getResNo() == i)
             assert(UI->getNodeId() == NewNode &&
                    "Remapped value has non-trivial use!");
 

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

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sun Jan 25 22:35:06 2009
@@ -342,8 +342,8 @@
 static void AddNodeIDOperands(FoldingSetNodeID &ID,
                               const SDUse *Ops, unsigned NumOps) {
   for (; NumOps; --NumOps, ++Ops) {
-    ID.AddPointer(Ops->getVal());
-    ID.AddInteger(Ops->getSDValue().getResNo());
+    ID.AddPointer(Ops->getNode());
+    ID.AddInteger(Ops->getResNo());
   }
 }
 
@@ -538,8 +538,7 @@
   // Process the worklist, deleting the nodes and adding their uses to the
   // worklist.
   while (!DeadNodes.empty()) {
-    SDNode *N = DeadNodes.back();
-    DeadNodes.pop_back();
+    SDNode *N = DeadNodes.pop_back_val();
     
     if (UpdateListener)
       UpdateListener->NodeDeleted(N, 0);
@@ -549,10 +548,11 @@
 
     // Next, brutally remove the operand list.  This is safe to do, as there are
     // no cycles in the graph.
-    for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) {
-      SDNode *Operand = I->getVal();
-      Operand->removeUser(std::distance(N->op_begin(), I), N);
-      
+    for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ) {
+      SDUse &Use = *I++;
+      SDNode *Operand = Use.getNode();
+      Use.set(SDValue());
+
       // Now that we removed this operand, see if there are no uses of it left.
       if (Operand->use_empty())
         DeadNodes.push_back(Operand);
@@ -581,8 +581,7 @@
   assert(N->use_empty() && "Cannot delete a node that is not dead!");
 
   // Drop all of the operands and decrement used node's use counts.
-  for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I)
-    I->getVal()->removeUser(std::distance(N->op_begin(), I), N);
+  N->DropOperands();
 
   DeallocateNode(N);
 }
@@ -763,7 +762,7 @@
     // following checks at least makes it possible to legalize most of the time.
 //    MVT EltVT = N->getValueType(0).getVectorElementType();
 //    for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I)
-//      assert(I->getSDValue().getValueType() == EltVT &&
+//      assert(I->getValueType() == EltVT &&
 //             "Wrong operand type!");
     break;
   }
@@ -819,7 +818,7 @@
   std::fill(ValueTypeNodes.begin(), ValueTypeNodes.end(),
             static_cast<SDNode*>(0));
 
-  EntryNode.Uses = 0;
+  EntryNode.UseList = 0;
   AllNodes.push_back(&EntryNode);
   Root = getEntryNode();
 }
@@ -3915,9 +3914,7 @@
       InsertPos = 0;
   
   // Now we update the operands.
-  N->OperandList[0].getVal()->removeUser(0, N);
-  N->OperandList[0].getSDValue() = Op;
-  Op.getNode()->addUser(0, N);
+  N->OperandList[0].set(Op);
   
   // If this gets put into a CSE map, add it.
   if (InsertPos) CSEMap.InsertNode(N, InsertPos);
@@ -3944,16 +3941,10 @@
       InsertPos = 0;
   
   // Now we update the operands.
-  if (N->OperandList[0] != Op1) {
-    N->OperandList[0].getVal()->removeUser(0, N);
-    N->OperandList[0].getSDValue() = Op1;
-    Op1.getNode()->addUser(0, N);
-  }
-  if (N->OperandList[1] != Op2) {
-    N->OperandList[1].getVal()->removeUser(1, N);
-    N->OperandList[1].getSDValue() = Op2;
-    Op2.getNode()->addUser(1, N);
-  }
+  if (N->OperandList[0] != Op1)
+    N->OperandList[0].set(Op1);
+  if (N->OperandList[1] != Op2)
+    N->OperandList[1].set(Op2);
   
   // If this gets put into a CSE map, add it.
   if (InsertPos) CSEMap.InsertNode(N, InsertPos);
@@ -4009,13 +4000,9 @@
       InsertPos = 0;
   
   // Now we update the operands.
-  for (unsigned i = 0; i != NumOps; ++i) {
-    if (N->OperandList[i] != Ops[i]) {
-      N->OperandList[i].getVal()->removeUser(i, N);
-      N->OperandList[i].getSDValue() = Ops[i];
-      Ops[i].getNode()->addUser(i, N);
-    }
-  }
+  for (unsigned i = 0; i != NumOps; ++i)
+    if (N->OperandList[i] != Ops[i])
+      N->OperandList[i].set(Ops[i]);
 
   // If this gets put into a CSE map, add it.
   if (InsertPos) CSEMap.InsertNode(N, InsertPos);
@@ -4027,10 +4014,10 @@
 void SDNode::DropOperands() {
   // Unlike the code in MorphNodeTo that does this, we don't need to
   // watch for dead nodes here.
-  for (op_iterator I = op_begin(), E = op_end(); I != E; ++I)
-    I->getVal()->removeUser(std::distance(op_begin(), I), this);
-
-  NumOperands = 0;
+  for (op_iterator I = op_begin(), E = op_end(); I != E; ) {
+    SDUse &Use = *I++;
+    Use.set(SDValue());
+  }
 }
 
 /// SelectNodeTo - These are wrappers around MorphNodeTo that accept a
@@ -4255,10 +4242,10 @@
   // Clear the operands list, updating used nodes to remove this from their
   // use list.  Keep track of any operands that become dead as a result.
   SmallPtrSet<SDNode*, 16> DeadNodeSet;
-  for (SDNode::op_iterator B = N->op_begin(), I = B, E = N->op_end();
-       I != E; ++I) {
-    SDNode *Used = I->getVal();
-    Used->removeUser(std::distance(B, I), N);
+  for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ) {
+    SDUse &Use = *I++;
+    SDNode *Used = Use.getNode();
+    Use.set(SDValue());
     if (Used->use_empty())
       DeadNodeSet.insert(Used);
   }
@@ -4284,10 +4271,8 @@
   // Assign the new operands.
   N->NumOperands = NumOps;
   for (unsigned i = 0, e = NumOps; i != e; ++i) {
-    N->OperandList[i].getSDValue() = Ops[i];
     N->OperandList[i].setUser(N);
-    SDNode *ToUse = N->OperandList[i].getVal();
-    ToUse->addUser(i, N);
+    N->OperandList[i].setInitial(Ops[i]);
   }
 
   // Delete any nodes that are still dead after adding the uses for the
@@ -4441,11 +4426,9 @@
     // To help reduce the number of CSE recomputations, process all
     // the uses of this user that we can find this way.
     do {
-      unsigned operandNum = UI.getOperandNo();
+      SDUse &Use = UI.getUse();
       ++UI;
-      From->removeUser(operandNum, User);
-      User->OperandList[operandNum].getSDValue() = To;
-      To.getNode()->addUser(operandNum, User);
+      Use.set(To);
     } while (UI != UE && *UI == User);
 
     // Now that we have modified User, add it back to the CSE maps.  If it
@@ -4484,11 +4467,9 @@
     // To help reduce the number of CSE recomputations, process all
     // the uses of this user that we can find this way.
     do {
-      unsigned operandNum = UI.getOperandNo();
+      SDUse &Use = UI.getUse();
       ++UI;
-      From->removeUser(operandNum, User);
-      User->OperandList[operandNum].getSDValue().setNode(To);
-      To->addUser(operandNum, User);
+      Use.setNode(To);
     } while (UI != UE && *UI == User);
 
     // Now that we have modified User, add it back to the CSE maps.  If it
@@ -4522,13 +4503,10 @@
     // To help reduce the number of CSE recomputations, process all
     // the uses of this user that we can find this way.
     do {
-      unsigned operandNum = UI.getOperandNo();
-      const SDValue &ToOp =
-        To[User->OperandList[operandNum].getSDValue().getResNo()];
+      SDUse &Use = UI.getUse();
+      const SDValue &ToOp = To[Use.getResNo()];
       ++UI;
-      From->removeUser(operandNum, User);
-      User->OperandList[operandNum].getSDValue() = ToOp;
-      ToOp.getNode()->addUser(operandNum, User);
+      Use.set(ToOp);
     } while (UI != UE && *UI == User);
 
     // Now that we have modified User, add it back to the CSE maps.  If it
@@ -4538,8 +4516,8 @@
 }
 
 /// ReplaceAllUsesOfValueWith - Replace any uses of From with To, leaving
-/// uses of other values produced by From.getVal() alone.  The Deleted vector is
-/// handled the same way as for ReplaceAllUsesWith.
+/// uses of other values produced by From.getNode() alone.  The Deleted
+/// vector is handled the same way as for ReplaceAllUsesWith.
 void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To,
                                              DAGUpdateListener *UpdateListener){
   // Handle the really simple, really trivial case efficiently.
@@ -4564,11 +4542,10 @@
     // To help reduce the number of CSE recomputations, process all
     // the uses of this user that we can find this way.
     do {
-      unsigned operandNum = UI.getOperandNo();
+      SDUse &Use = UI.getUse();
 
       // Skip uses of different values from the same node.
-      if (User->OperandList[operandNum].getSDValue().getResNo() !=
-            From.getResNo()) {
+      if (Use.getResNo() != From.getResNo()) {
         ++UI;
         continue;
       }
@@ -4581,9 +4558,7 @@
       }
 
       ++UI;
-      From.getNode()->removeUser(operandNum, User);
-      User->OperandList[operandNum].getSDValue() = To;
-      To.getNode()->addUser(operandNum, User);
+      Use.set(To);
     } while (UI != UE && *UI == User);
 
     // We are iterating over all uses of the From node, so if a use
@@ -4603,13 +4578,18 @@
   struct UseMemo {
     SDNode *User;
     unsigned Index;
-    unsigned operandNum;
+    SDUse *Use;
   };
+
+  /// operator< - Sort Memos by User.
+  bool operator<(const UseMemo &L, const UseMemo &R) {
+    return (intptr_t)L.User < (intptr_t)R.User;
+  }
 }
 
 /// ReplaceAllUsesOfValuesWith - Replace any uses of From with To, leaving
-/// uses of other values produced by From.getVal() alone.  The same value may
-/// appear in both the From and To list.  The Deleted vector is
+/// uses of other values produced by From.getNode() alone.  The same value
+/// may appear in both the From and To list.  The Deleted vector is
 /// handled the same way as for ReplaceAllUsesWith.
 void SelectionDAG::ReplaceAllUsesOfValuesWith(const SDValue *From,
                                               const SDValue *To,
@@ -4627,13 +4607,18 @@
     unsigned FromResNo = From[i].getResNo();
     SDNode *FromNode = From[i].getNode();
     for (SDNode::use_iterator UI = FromNode->use_begin(), 
-         E = FromNode->use_end(); UI != E; ++UI)
-      if (UI.getUse().getSDValue().getResNo() == FromResNo) {
-        UseMemo Memo = { *UI, i, UI.getOperandNo() };
+         E = FromNode->use_end(); UI != E; ++UI) {
+      SDUse &Use = UI.getUse();
+      if (Use.getResNo() == FromResNo) {
+        UseMemo Memo = { *UI, i, &Use };
         Uses.push_back(Memo);
       }
+    }
   }
 
+  // Sort the uses, so that all the uses from a given User are together.
+  std::sort(Uses.begin(), Uses.end());
+
   for (unsigned UseIndex = 0, UseIndexEnd = Uses.size();
        UseIndex != UseIndexEnd; ) {
     // We know that this user uses some value of From.  If it is the right
@@ -4643,18 +4628,16 @@
     // This node is about to morph, remove its old self from the CSE maps.
     RemoveNodeFromCSEMaps(User);
 
-    // A user can appear in a use list multiple times, and when this
-    // happens the uses are usually next to each other in the list.
+    // The Uses array is sorted, so all the uses for a given User
+    // are next to each other in the list.
     // To help reduce the number of CSE recomputations, process all
     // the uses of this user that we can find this way.
     do {
       unsigned i = Uses[UseIndex].Index;
-      unsigned operandNum = Uses[UseIndex].operandNum;
+      SDUse &Use = *Uses[UseIndex].Use;
       ++UseIndex;
 
-      From[i].getNode()->removeUser(operandNum, User);
-      User->OperandList[operandNum].getSDValue() = To[i];
-      To[i].getNode()->addUser(operandNum, User);
+      Use.set(To[i]);
     } while (UseIndex != UseIndexEnd && Uses[UseIndex].User == User);
 
     // Now that we have modified User, add it back to the CSE maps.  If it
@@ -4839,7 +4822,7 @@
 
   // 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.getUse().getSDValue().getResNo() == Value) {
+    if (UI.getUse().getResNo() == Value) {
       if (NUses == 0)
         return false;
       --NUses;
@@ -4857,7 +4840,7 @@
   assert(Value < getNumValues() && "Bad value!");
 
   for (SDNode::use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI)
-    if (UI.getUse().getSDValue().getResNo() == Value)
+    if (UI.getUse().getResNo() == Value)
       return true;
 
   return false;
@@ -4890,7 +4873,7 @@
 
 bool SDNode::isOperandOf(SDNode *N) const {
   for (unsigned i = 0, e = N->NumOperands; i != e; ++i)
-    if (this == N->OperandList[i].getVal())
+    if (this == N->OperandList[i].getNode())
       return true;
   return false;
 }

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

==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Sun Jan 25 22:35:06 2009
@@ -2160,7 +2160,8 @@
 
 /// isSHUFPMask - Return true if the specified VECTOR_SHUFFLE operand
 /// specifies a shuffle of elements that is suitable for input to SHUFP*.
-static bool isSHUFPMask(SDOperandPtr Elems, unsigned NumElems) {
+template<class SDOperand>
+static bool isSHUFPMask(SDOperand *Elems, unsigned NumElems) {
   if (NumElems != 2 && NumElems != 4) return false;
 
   unsigned Half = NumElems / 2;
@@ -2183,7 +2184,8 @@
 /// the reverse of what x86 shuffles want. x86 shuffles requires the lower
 /// half elements to come from vector 1 (which would equal the dest.) and
 /// the upper half to come from vector 2.
-static bool isCommutedSHUFP(SDOperandPtr Ops, unsigned NumOps) {
+template<class SDOperand>
+static bool isCommutedSHUFP(SDOperand *Ops, unsigned NumOps) {
   if (NumOps != 2 && NumOps != 4) return false;
 
   unsigned Half = NumOps / 2;
@@ -2277,7 +2279,8 @@
 
 /// isUNPCKLMask - Return true if the specified VECTOR_SHUFFLE operand
 /// specifies a shuffle of elements that is suitable for input to UNPCKL.
-bool static isUNPCKLMask(SDOperandPtr Elts, unsigned NumElts,
+template<class SDOperand>
+bool static isUNPCKLMask(SDOperand *Elts, unsigned NumElts,
                          bool V2IsSplat = false) {
   if (NumElts != 2 && NumElts != 4 && NumElts != 8 && NumElts != 16)
     return false;
@@ -2306,7 +2309,8 @@
 
 /// isUNPCKHMask - Return true if the specified VECTOR_SHUFFLE operand
 /// specifies a shuffle of elements that is suitable for input to UNPCKH.
-bool static isUNPCKHMask(SDOperandPtr Elts, unsigned NumElts,
+template<class SDOperand>
+bool static isUNPCKHMask(SDOperand *Elts, unsigned NumElts,
                          bool V2IsSplat = false) {
   if (NumElts != 2 && NumElts != 4 && NumElts != 8 && NumElts != 16)
     return false;
@@ -2382,7 +2386,8 @@
 /// isMOVLMask - Return true if the specified VECTOR_SHUFFLE operand
 /// specifies a shuffle of elements that is suitable for input to MOVSS,
 /// MOVSD, and MOVD, i.e. setting the lowest element.
-static bool isMOVLMask(SDOperandPtr Elts, unsigned NumElts) {
+template<class SDOperand>
+static bool isMOVLMask(SDOperand *Elts, unsigned NumElts) {
   if (NumElts != 2 && NumElts != 4)
     return false;
 
@@ -2405,7 +2410,8 @@
 /// isCommutedMOVL - Returns true if the shuffle mask is except the reverse
 /// of what x86 movss want. X86 movs requires the lowest  element to be lowest
 /// element of vector 2 and the other elements to come from vector 1 in order.
-static bool isCommutedMOVL(SDOperandPtr Ops, unsigned NumOps,
+template<class SDOperand>
+static bool isCommutedMOVL(SDOperand *Ops, unsigned NumOps,
                            bool V2IsSplat = false,
                            bool V2IsUndef = false) {
   if (NumOps != 2 && NumOps != 4 && NumOps != 8 && NumOps != 16)





More information about the llvm-commits mailing list