aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2009-01-26 04:35:06 +0000
committerDan Gohman <gohman@apple.com>2009-01-26 04:35:06 +0000
commite7852d014432a06c783de3c350eb96e686f10f92 (patch)
tree5a9acc1ca968f323231d23139a2687c984988243 /include
parent19c10e658a3bcf6e01e2a83ffe9b8dd75adcb182 (diff)
downloadexternal_llvm-e7852d014432a06c783de3c350eb96e686f10f92.zip
external_llvm-e7852d014432a06c783de3c350eb96e686f10f92.tar.gz
external_llvm-e7852d014432a06c783de3c350eb96e686f10f92.tar.bz2
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@62995 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h339
1 files changed, 161 insertions, 178 deletions
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index a429855..7a5cd3b 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -955,63 +955,77 @@ template<> struct simplify_type<const SDValue> {
}
};
-/// 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; }
+ /// getNext - Get the next SDUse in the use list.
+ SDUse *getNext() const { return Next; }
- const SDValue& getSDValue() const { return Operand; }
+ /// 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(); }
- SDValue &getSDValue() { return Operand; }
- SDNode *getVal() { return Operand.getNode(); }
- SDNode *getVal() const { return Operand.getNode(); } // FIXME: const correct?
-
- 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;
}
- 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 @@ protected:
}
};
-
/// 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 @@ private:
/// 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 @@ public:
/// 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 @@ public:
/// 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 @@ public:
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 @@ public:
///
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 @@ protected:
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;
-
+ 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].getNode()->addUse(OperandList[i]);
+ OperandList[i].setInitial(Ops[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;
-
- for (unsigned i = 0; i != NumOps; ++i) {
- OperandList[i] = Ops[i];
- OperandList[i].setUser(this);
- Ops[i].getVal()->addUse(OperandList[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 @@ inline bool SDValue::hasOneUse() const {
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 @@ class UnarySDNode : public SDNode {
public:
UnarySDNode(unsigned Opc, SDVTList VTs, SDValue X)
: SDNode(Opc, VTs) {
- Op = X;
- InitOperands(&Op, 1);
+ InitOperands(&Op, X);
}
};
@@ -1479,9 +1479,7 @@ class BinarySDNode : public SDNode {
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 @@ public:
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 @@ public:
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 @@ public:
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 @@ protected:
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 @@ protected:
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 @@ public:
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");