Switch the operandlist/valuelist from being vectors to being just an array.

This saves 12 bytes from SDNode, but doesn't speed things up substantially
(our graphs apparently already fit within the cache on my g5).  In any case
this reduces memory usage.

llvm-svn: 24248
This commit is contained in:
Chris Lattner 2005-11-08 22:06:23 +00:00
parent 3ba38cba64
commit e406e481d3
1 changed files with 121 additions and 71 deletions

View File

@ -491,13 +491,16 @@ class SDNode {
/// depth of 2, etc. /// depth of 2, etc.
unsigned short NodeDepth; unsigned short NodeDepth;
/// Operands - The values that are used by this operation. /// OperandList - The values that are used by this operation.
/// ///
std::vector<SDOperand> Operands; SDOperand *OperandList;
/// Values - The types of the values this node defines. SDNode's may define /// ValueList - The types of the values this node defines. SDNode's may
/// multiple values simultaneously. /// define multiple values simultaneously.
std::vector<MVT::ValueType> Values; MVT::ValueType *ValueList;
/// NumOperands/NumValues - The number of entries in the Operand/Value list.
unsigned short NumOperands, NumValues;
/// Uses - These are all of the SDNode's that use a value produced by this /// Uses - These are all of the SDNode's that use a value produced by this
/// node. /// node.
@ -533,37 +536,32 @@ public:
/// getNumOperands - Return the number of values used by this operation. /// getNumOperands - Return the number of values used by this operation.
/// ///
unsigned getNumOperands() const { return Operands.size(); } unsigned getNumOperands() const { return NumOperands; }
const SDOperand &getOperand(unsigned Num) {
assert(Num < Operands.size() && "Invalid child # of SDNode!");
return Operands[Num];
}
const SDOperand &getOperand(unsigned Num) const { const SDOperand &getOperand(unsigned Num) const {
assert(Num < Operands.size() && "Invalid child # of SDNode!"); assert(Num < NumOperands && "Invalid child # of SDNode!");
return Operands[Num]; return OperandList[Num];
} }
typedef std::vector<SDOperand>::const_iterator op_iterator; typedef const SDOperand* op_iterator;
op_iterator op_begin() const { return Operands.begin(); } op_iterator op_begin() const { return OperandList; }
op_iterator op_end() const { return Operands.end(); } op_iterator op_end() const { return OperandList+NumOperands; }
/// getNumValues - Return the number of values defined/returned by this /// getNumValues - Return the number of values defined/returned by this
/// operator. /// operator.
/// ///
unsigned getNumValues() const { return Values.size(); } unsigned getNumValues() const { return NumValues; }
/// getValueType - Return the type of a specified result. /// getValueType - Return the type of a specified result.
/// ///
MVT::ValueType getValueType(unsigned ResNo) const { MVT::ValueType getValueType(unsigned ResNo) const {
assert(ResNo < Values.size() && "Illegal result number!"); assert(ResNo < NumValues && "Illegal result number!");
return Values[ResNo]; return ValueList[ResNo];
} }
typedef std::vector<MVT::ValueType>::const_iterator value_iterator; typedef const MVT::ValueType* value_iterator;
value_iterator value_begin() const { return Values.begin(); } value_iterator value_begin() const { return ValueList; }
value_iterator value_end() const { return Values.end(); } value_iterator value_end() const { return ValueList+NumValues; }
/// getOperationName - Return the opcode of this operation for printing. /// getOperationName - Return the opcode of this operation for printing.
/// ///
@ -581,13 +579,19 @@ protected:
friend class SelectionDAG; friend class SelectionDAG;
SDNode(unsigned NT, MVT::ValueType VT) : NodeType(NT), NodeDepth(1) { SDNode(unsigned NT, MVT::ValueType VT) : NodeType(NT), NodeDepth(1) {
Values.reserve(1); OperandList = 0; NumOperands = 0;
Values.push_back(VT); ValueList = new MVT::ValueType[1];
ValueList[0] = VT;
NumValues = 1;
} }
SDNode(unsigned NT, SDOperand Op) SDNode(unsigned NT, SDOperand Op)
: NodeType(NT), NodeDepth(Op.Val->getNodeDepth()+1) { : NodeType(NT), NodeDepth(Op.Val->getNodeDepth()+1) {
Operands.reserve(1); Operands.push_back(Op); OperandList = new SDOperand[1];
OperandList[0] = Op;
NumOperands = 1;
Op.Val->Uses.push_back(this); Op.Val->Uses.push_back(this);
ValueList = 0;
NumValues = 0;
} }
SDNode(unsigned NT, SDOperand N1, SDOperand N2) SDNode(unsigned NT, SDOperand N1, SDOperand N2)
: NodeType(NT) { : NodeType(NT) {
@ -595,8 +599,13 @@ protected:
NodeDepth = N1.Val->getNodeDepth()+1; NodeDepth = N1.Val->getNodeDepth()+1;
else else
NodeDepth = N2.Val->getNodeDepth()+1; NodeDepth = N2.Val->getNodeDepth()+1;
Operands.reserve(2); Operands.push_back(N1); Operands.push_back(N2); OperandList = new SDOperand[2];
OperandList[0] = N1;
OperandList[1] = N2;
NumOperands = 2;
N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this); N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this);
ValueList = 0;
NumValues = 0;
} }
SDNode(unsigned NT, SDOperand N1, SDOperand N2, SDOperand N3) SDNode(unsigned NT, SDOperand N1, SDOperand N2, SDOperand N3)
: NodeType(NT) { : NodeType(NT) {
@ -607,10 +616,16 @@ protected:
ND = N3.Val->getNodeDepth(); ND = N3.Val->getNodeDepth();
NodeDepth = ND+1; NodeDepth = ND+1;
Operands.reserve(3); Operands.push_back(N1); Operands.push_back(N2); OperandList = new SDOperand[3];
Operands.push_back(N3); OperandList[0] = N1;
OperandList[1] = N2;
OperandList[2] = N3;
NumOperands = 3;
N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this); N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this);
N3.Val->Uses.push_back(this); N3.Val->Uses.push_back(this);
ValueList = 0;
NumValues = 0;
} }
SDNode(unsigned NT, SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4) SDNode(unsigned NT, SDOperand N1, SDOperand N2, SDOperand N3, SDOperand N4)
: NodeType(NT) { : NodeType(NT) {
@ -623,90 +638,125 @@ protected:
ND = N4.Val->getNodeDepth(); ND = N4.Val->getNodeDepth();
NodeDepth = ND+1; NodeDepth = ND+1;
Operands.reserve(4); Operands.push_back(N1); Operands.push_back(N2); OperandList = new SDOperand[4];
Operands.push_back(N3); Operands.push_back(N4); OperandList[0] = N1;
OperandList[1] = N2;
OperandList[2] = N3;
OperandList[3] = N4;
NumOperands = 4;
N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this); N1.Val->Uses.push_back(this); N2.Val->Uses.push_back(this);
N3.Val->Uses.push_back(this); N4.Val->Uses.push_back(this); N3.Val->Uses.push_back(this); N4.Val->Uses.push_back(this);
ValueList = 0;
NumValues = 0;
} }
SDNode(unsigned NT, std::vector<SDOperand> &Nodes) : NodeType(NT) { SDNode(unsigned Opc, const std::vector<SDOperand> &Nodes) : NodeType(Opc) {
Operands.swap(Nodes); NumOperands = Nodes.size();
OperandList = new SDOperand[NumOperands];
unsigned ND = 0; unsigned ND = 0;
for (unsigned i = 0, e = Operands.size(); i != e; ++i) { for (unsigned i = 0, e = Nodes.size(); i != e; ++i) {
Operands[i].Val->Uses.push_back(this); OperandList[i] = Nodes[i];
if (ND < Operands[i].Val->getNodeDepth()) SDNode *N = OperandList[i].Val;
ND = Operands[i].Val->getNodeDepth(); N->Uses.push_back(this);
if (ND < N->getNodeDepth()) ND = N->getNodeDepth();
} }
NodeDepth = ND+1; NodeDepth = ND+1;
ValueList = 0;
NumValues = 0;
} }
virtual ~SDNode() {} virtual ~SDNode() {
assert(NumOperands == 0 && "Operand list not cleared before deletion");
delete [] ValueList;
}
/// MorphNodeTo - This clears the return value and operands list, and sets the /// MorphNodeTo - This clears the return value and operands list, and sets the
/// opcode of the node to the specified value. This should only be used by /// opcode of the node to the specified value. This should only be used by
/// the SelectionDAG class. /// the SelectionDAG class.
void MorphNodeTo(unsigned Opc) { void MorphNodeTo(unsigned Opc) {
NodeType = Opc; NodeType = Opc;
Values.clear(); delete [] ValueList;
ValueList = 0;
NumValues = 0;
// Clear the operands list, updating used nodes to remove this from their // Clear the operands list, updating used nodes to remove this from their
// use list. // use list.
while (!Operands.empty()) { for (op_iterator I = op_begin(), E = op_end(); I != E; ++I)
SDNode *O = Operands.back().Val; I->Val->removeUser(this);
Operands.pop_back(); delete [] OperandList;
O->removeUser(this); OperandList = 0;
} NumOperands = 0;
} }
void setValueTypes(MVT::ValueType VT) { void setValueTypes(MVT::ValueType VT) {
Values.reserve(1); assert(NumValues == 0 && "Should not have values yet!");
Values.push_back(VT); ValueList = new MVT::ValueType[1];
ValueList[0] = VT;
NumValues = 1;
} }
void setValueTypes(MVT::ValueType VT1, MVT::ValueType VT2) { void setValueTypes(MVT::ValueType VT1, MVT::ValueType VT2) {
Values.reserve(2); assert(NumValues == 0 && "Should not have values yet!");
Values.push_back(VT1); ValueList = new MVT::ValueType[2];
Values.push_back(VT2); ValueList[0] = VT1;
ValueList[1] = VT2;
NumValues = 2;
} }
/// Note: this method destroys the vector passed in. void setValueTypes(const std::vector<MVT::ValueType> &VTs) {
void setValueTypes(std::vector<MVT::ValueType> &VTs) { assert(NumValues == 0 && "Should not have values yet!");
std::swap(Values, VTs); if (VTs.size() == 0) return; // don't alloc memory.
ValueList = new MVT::ValueType[VTs.size()];
for (unsigned i = 0, e = VTs.size(); i != e; ++i)
ValueList[i] = VTs[i];
NumValues = VTs.size();
} }
void setOperands(SDOperand Op0) { void setOperands(SDOperand Op0) {
Operands.reserve(1); assert(NumOperands == 0 && "Should not have operands yet!");
Operands.push_back(Op0); OperandList = new SDOperand[1];
OperandList[0] = Op0;
NumOperands = 1;
Op0.Val->Uses.push_back(this); Op0.Val->Uses.push_back(this);
} }
void setOperands(SDOperand Op0, SDOperand Op1) { void setOperands(SDOperand Op0, SDOperand Op1) {
Operands.reserve(2); assert(NumOperands == 0 && "Should not have operands yet!");
Operands.push_back(Op0); OperandList = new SDOperand[2];
Operands.push_back(Op1); OperandList[0] = Op0;
OperandList[1] = Op1;
NumOperands = 2;
Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this); Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this);
} }
void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2) { void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2) {
Operands.reserve(3); assert(NumOperands == 0 && "Should not have operands yet!");
Operands.push_back(Op0); OperandList = new SDOperand[3];
Operands.push_back(Op1); OperandList[0] = Op0;
Operands.push_back(Op2); OperandList[1] = Op1;
OperandList[2] = Op2;
NumOperands = 3;
Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this); Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this);
Op2.Val->Uses.push_back(this); Op2.Val->Uses.push_back(this);
} }
void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2, SDOperand Op3) { void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2, SDOperand Op3) {
Operands.reserve(4); assert(NumOperands == 0 && "Should not have operands yet!");
Operands.push_back(Op0); OperandList = new SDOperand[4];
Operands.push_back(Op1); OperandList[0] = Op0;
Operands.push_back(Op2); OperandList[1] = Op1;
Operands.push_back(Op3); OperandList[2] = Op2;
OperandList[3] = Op3;
NumOperands = 4;
Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this); Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this);
Op2.Val->Uses.push_back(this); Op3.Val->Uses.push_back(this); Op2.Val->Uses.push_back(this); Op3.Val->Uses.push_back(this);
} }
void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2, SDOperand Op3, void setOperands(SDOperand Op0, SDOperand Op1, SDOperand Op2, SDOperand Op3,
SDOperand Op4) { SDOperand Op4) {
Operands.reserve(5); assert(NumOperands == 0 && "Should not have operands yet!");
Operands.push_back(Op0); OperandList = new SDOperand[5];
Operands.push_back(Op1); OperandList[0] = Op0;
Operands.push_back(Op2); OperandList[1] = Op1;
Operands.push_back(Op3); OperandList[2] = Op2;
Operands.push_back(Op4); OperandList[3] = Op3;
OperandList[4] = Op4;
NumOperands = 5;
Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this); Op0.Val->Uses.push_back(this); Op1.Val->Uses.push_back(this);
Op2.Val->Uses.push_back(this); Op3.Val->Uses.push_back(this); Op2.Val->Uses.push_back(this); Op3.Val->Uses.push_back(this);
Op4.Val->Uses.push_back(this); Op4.Val->Uses.push_back(this);