Introduce new UnarySDNode/BinarySDNode/TernarySDNode nodes, which coallocate
authorChris Lattner <sabre@nondot.org>
Sun, 4 Feb 2007 08:35:21 +0000 (08:35 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 4 Feb 2007 08:35:21 +0000 (08:35 +0000)
their operands with the node itself.  This reduces malloc traffic for operand
lists.  This reduces isel time on kc++ from 2.6164 to 2.5570s, about 2.3%.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33878 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/SelectionDAGNodes.h
lib/CodeGen/SelectionDAG/SelectionDAG.cpp

index 006bf6e8f2cc6ed8a4383d7db532081c2c5480f3..b5a1e993962b5eae68def1806a7e422cabc62d56 100644 (file)
@@ -995,6 +995,49 @@ inline bool SDOperand::hasOneUse() const {
   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
index c154d7941150af175534f7bd707d0ebf30134e77..92c84d85e84f5f60582e38f184459b4bcb3d4372 100644 (file)
@@ -939,7 +939,7 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT) {
   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);
@@ -1113,17 +1113,17 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
 
   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);
@@ -1413,17 +1413,17 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
   // 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);
@@ -1470,17 +1470,17 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
   // 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);
@@ -1809,10 +1809,24 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
     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);
@@ -2490,6 +2504,9 @@ unsigned SelectionDAG::AssignTopologicalOrder(std::vector<SDNode*> &TopOrder) {
 
 // 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() {}