+/// MVTSDNode - This class is used for operators that require an extra
+/// value-type to be kept with the node.
+class MVTSDNode : public SDNode {
+ MVT::ValueType ExtraValueType;
+protected:
+ friend class SelectionDAG;
+ MVTSDNode(unsigned Opc, MVT::ValueType VT1, SDOperand Op0, MVT::ValueType EVT)
+ : SDNode(Opc, Op0), ExtraValueType(EVT) {
+ setValueTypes(VT1);
+ }
+ MVTSDNode(unsigned Opc, MVT::ValueType VT1, MVT::ValueType VT2,
+ SDOperand Op0, SDOperand Op1, MVT::ValueType EVT)
+ : SDNode(Opc, Op0, Op1), ExtraValueType(EVT) {
+ setValueTypes(VT1, VT2);
+ }
+ MVTSDNode(unsigned Opc, MVT::ValueType VT,
+ SDOperand Op0, SDOperand Op1, SDOperand Op2, MVT::ValueType EVT)
+ : SDNode(Opc, Op0, Op1, Op2), ExtraValueType(EVT) {
+ setValueTypes(VT);
+ }
+public:
+
+ MVT::ValueType getExtraValueType() const { return ExtraValueType; }
+
+ static bool classof(const MVTSDNode *) { return true; }
+ static bool classof(const SDNode *N) {
+ return
+ N->getOpcode() == ISD::SIGN_EXTEND_INREG ||
+ N->getOpcode() == ISD::FP_ROUND_INREG ||
+ N->getOpcode() == ISD::EXTLOAD ||
+ N->getOpcode() == ISD::SEXTLOAD ||
+ N->getOpcode() == ISD::ZEXTLOAD ||
+ N->getOpcode() == ISD::TRUNCSTORE;
+ }
+};
+
+class SDNodeIterator : public forward_iterator<SDNode, ptrdiff_t> {
+ SDNode *Node;
+ unsigned Operand;
+
+ SDNodeIterator(SDNode *N, unsigned Op) : Node(N), Operand(Op) {}
+public:
+ bool operator==(const SDNodeIterator& x) const {
+ return Operand == x.Operand;
+ }
+ bool operator!=(const SDNodeIterator& x) const { return !operator==(x); }
+
+ const SDNodeIterator &operator=(const SDNodeIterator &I) {
+ assert(I.Node == Node && "Cannot assign iterators to two different nodes!");
+ Operand = I.Operand;
+ return *this;
+ }
+
+ pointer operator*() const {
+ return Node->getOperand(Operand).Val;
+ }
+ pointer operator->() const { return operator*(); }
+
+ SDNodeIterator& operator++() { // Preincrement
+ ++Operand;
+ return *this;
+ }
+ SDNodeIterator operator++(int) { // Postincrement
+ SDNodeIterator tmp = *this; ++*this; return tmp;
+ }
+
+ static SDNodeIterator begin(SDNode *N) { return SDNodeIterator(N, 0); }
+ static SDNodeIterator end (SDNode *N) {
+ return SDNodeIterator(N, N->getNumOperands());
+ }
+
+ unsigned getOperand() const { return Operand; }
+ const SDNode *getNode() const { return Node; }
+};
+
+template <> struct GraphTraits<SDNode*> {
+ typedef SDNode NodeType;
+ typedef SDNodeIterator ChildIteratorType;
+ static inline NodeType *getEntryNode(SDNode *N) { return N; }
+ static inline ChildIteratorType child_begin(NodeType *N) {
+ return SDNodeIterator::begin(N);
+ }
+ static inline ChildIteratorType child_end(NodeType *N) {
+ return SDNodeIterator::end(N);
+ }
+};
+
+
+
+