From 3f97eb449b08069e3370d4ba7566c60bdbf0babd Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 4 Feb 2007 08:35:21 +0000 Subject: [PATCH] Introduce new UnarySDNode/BinarySDNode/TernarySDNode nodes, which coallocate 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 | 43 +++++++++++++++++++++++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 41 ++++++++++++++------- 2 files changed, 72 insertions(+), 12 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h index 006bf6e8f2c..b5a1e993962 100644 --- a/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/include/llvm/CodeGen/SelectionDAGNodes.h @@ -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 diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index c154d794115..92c84d85e84 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -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 &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() {}