return Val->hasNUsesOfValue(1, ResNo);
}
+/// 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 {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Op;
+public:
+ UnarySDNode(unsigned Opc, SDVTList VTs, SDOperand X)
+ : SDNode(Opc, VTs), Op(X) {
+ InitOperands(&Op, 1);
+ }
+};
+
+/// BinarySDNode - This class is used for two-operand SDNodes. This is solely
+/// to allow co-allocation of node operands with the node itself.
+class BinarySDNode : public SDNode {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Ops[2];
+public:
+ BinarySDNode(unsigned Opc, SDVTList VTs, SDOperand X, SDOperand Y)
+ : SDNode(Opc, VTs) {
+ Ops[0] = X;
+ Ops[1] = Y;
+ InitOperands(Ops, 2);
+ }
+};
+
+/// TernarySDNode - This class is used for three-operand SDNodes. This is solely
+/// to allow co-allocation of node operands with the node itself.
+class TernarySDNode : public SDNode {
+ virtual void ANCHOR(); // Out-of-line virtual method to give class a home.
+ SDOperand Ops[3];
+public:
+ TernarySDNode(unsigned Opc, SDVTList VTs, SDOperand X, SDOperand Y,
+ SDOperand Z)
+ : SDNode(Opc, VTs) {
+ Ops[0] = X;
+ Ops[1] = Y;
+ Ops[2] = Z;
+ InitOperands(Ops, 3);
+ }
+};
+
+
/// HandleSDNode - This class is used to form a handle around another node that
/// is persistant and is updated across invocations of replaceAllUsesWith on its
/// operand. This node should be directly created by end-users and not added to
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDOperand(E, 0);
- SDNode *N = new SDNode(Opcode, SDNode::getSDVTList(VT), 0, 0);
+ SDNode *N = new SDNode(Opcode, SDNode::getSDVTList(VT));
CSEMap.InsertNode(N, IP);
AllNodes.push_back(N);
SDNode *N;
SDVTList VTs = getVTList(VT);
- SDOperand Ops[1] = { Operand };
if (VT != MVT::Flag) { // Don't CSE flag producing nodes
FoldingSetNodeID ID;
+ SDOperand Ops[1] = { Operand };
AddNodeIDNode(ID, Opcode, VTs, Ops, 1);
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDOperand(E, 0);
- N = new SDNode(Opcode, VTs, Ops, 1);
+ N = new UnarySDNode(Opcode, VTs, Operand);
CSEMap.InsertNode(N, IP);
} else {
- N = new SDNode(Opcode, VTs, Ops, 1);
+ N = new UnarySDNode(Opcode, VTs, Operand);
}
AllNodes.push_back(N);
return SDOperand(N, 0);
// Memoize this node if possible.
SDNode *N;
SDVTList VTs = getVTList(VT);
- SDOperand Ops[] = { N1, N2 };
if (VT != MVT::Flag) {
+ SDOperand Ops[] = { N1, N2 };
FoldingSetNodeID ID;
AddNodeIDNode(ID, Opcode, VTs, Ops, 2);
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDOperand(E, 0);
- N = new SDNode(Opcode, VTs, Ops, 2);
+ N = new BinarySDNode(Opcode, VTs, N1, N2);
CSEMap.InsertNode(N, IP);
} else {
- N = new SDNode(Opcode, VTs, Ops, 2);
+ N = new BinarySDNode(Opcode, VTs, N1, N2);
}
AllNodes.push_back(N);
// Memoize node if it doesn't produce a flag.
SDNode *N;
SDVTList VTs = getVTList(VT);
- SDOperand Ops[] = { N1, N2, N3 };
if (VT != MVT::Flag) {
+ SDOperand Ops[] = { N1, N2, N3 };
FoldingSetNodeID ID;
AddNodeIDNode(ID, Opcode, VTs, Ops, 3);
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDOperand(E, 0);
- N = new SDNode(Opcode, VTs, Ops, 3);
+ N = new TernarySDNode(Opcode, VTs, N1, N2, N3);
CSEMap.InsertNode(N, IP);
} else {
- N = new SDNode(Opcode, VTs, Ops, 3);
+ N = new TernarySDNode(Opcode, VTs, N1, N2, N3);
}
AllNodes.push_back(N);
return SDOperand(N, 0);
void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDOperand(E, 0);
- N = new SDNode(Opcode, VTList, Ops, NumOps);
+ if (NumOps == 1)
+ N = new UnarySDNode(Opcode, VTList, Ops[0]);
+ else if (NumOps == 2)
+ N = new BinarySDNode(Opcode, VTList, Ops[0], Ops[1]);
+ else if (NumOps == 3)
+ N = new TernarySDNode(Opcode, VTList, Ops[0], Ops[1], Ops[2]);
+ else
+ N = new SDNode(Opcode, VTList, Ops, NumOps);
CSEMap.InsertNode(N, IP);
} else {
- N = new SDNode(Opcode, VTList, Ops, NumOps);
+ if (NumOps == 1)
+ N = new UnarySDNode(Opcode, VTList, Ops[0]);
+ else if (NumOps == 2)
+ N = new BinarySDNode(Opcode, VTList, Ops[0], Ops[1]);
+ else if (NumOps == 3)
+ N = new TernarySDNode(Opcode, VTList, Ops[0], Ops[1], Ops[2]);
+ else
+ N = new SDNode(Opcode, VTList, Ops, NumOps);
}
AllNodes.push_back(N);
return SDOperand(N, 0);
// Out-of-line virtual method to give class a home.
void SDNode::ANCHOR() {}
+void UnarySDNode::ANCHOR() {}
+void BinarySDNode::ANCHOR() {}
+void TernarySDNode::ANCHOR() {}
void HandleSDNode::ANCHOR() {}
void StringSDNode::ANCHOR() {}
void ConstantSDNode::ANCHOR() {}