[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Chris Lattner
lattner at cs.uiuc.edu
Sat Jan 28 01:32:57 PST 2006
Changes in directory llvm/lib/CodeGen/SelectionDAG:
SelectionDAG.cpp updated: 1.246 -> 1.247
---
Log message:
add some methods for updating nodes
---
Diffs of the changes: (+234 -0)
SelectionDAG.cpp | 234 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 234 insertions(+)
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.246 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.247
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.246 Fri Jan 27 18:18:58 2006
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Sat Jan 28 03:32:45 2006
@@ -440,6 +440,107 @@
return 0;
}
+/// FindModifiedNodeSlot - Find a slot for the specified node if its operands
+/// were replaced with those specified. If this node is never memoized,
+/// return null, otherwise return a pointer to the slot it would take. If a
+/// node already exists with these operands, the slot will be non-null.
+SDNode **SelectionDAG::FindModifiedNodeSlot(SDNode *N, SDOperand Op) {
+ if (N->getOpcode() == ISD::CALLSEQ_START ||
+ N->getOpcode() == ISD::CALLSEQ_END ||
+ N->getOpcode() == ISD::HANDLENODE || N->getValueType(0) == MVT::Flag)
+ return 0; // Never add these nodes.
+
+ // Check that remaining values produced are not flags.
+ for (unsigned i = 1, e = N->getNumValues(); i != e; ++i)
+ if (N->getValueType(i) == MVT::Flag)
+ return 0; // Never CSE anything that produces a flag.
+
+ if (N->getNumValues() == 1) {
+ return &UnaryOps[std::make_pair(N->getOpcode(),
+ std::make_pair(Op, N->getValueType(0)))];
+ } else {
+ // Remove the node from the ArbitraryNodes map.
+ std::vector<MVT::ValueType> RV(N->value_begin(), N->value_end());
+ std::vector<SDOperand> Ops;
+ Ops.push_back(Op);
+ return &ArbitraryNodes[std::make_pair(N->getOpcode(),
+ std::make_pair(RV, Ops))];
+ }
+ return 0;
+}
+
+/// FindModifiedNodeSlot - Find a slot for the specified node if its operands
+/// were replaced with those specified. If this node is never memoized,
+/// return null, otherwise return a pointer to the slot it would take. If a
+/// node already exists with these operands, the slot will be non-null.
+SDNode **SelectionDAG::FindModifiedNodeSlot(SDNode *N,
+ SDOperand Op1, SDOperand Op2) {
+ if (N->getOpcode() == ISD::CALLSEQ_START ||
+ N->getOpcode() == ISD::CALLSEQ_END ||
+ N->getOpcode() == ISD::HANDLENODE || N->getValueType(0) == MVT::Flag)
+ return 0; // Never add these nodes.
+
+ // Check that remaining values produced are not flags.
+ for (unsigned i = 1, e = N->getNumValues(); i != e; ++i)
+ if (N->getValueType(i) == MVT::Flag)
+ return 0; // Never CSE anything that produces a flag.
+
+ if (N->getNumValues() == 1) {
+ return &BinaryOps[std::make_pair(N->getOpcode(),
+ std::make_pair(Op1, Op2))];
+ } else {
+ std::vector<MVT::ValueType> RV(N->value_begin(), N->value_end());
+ std::vector<SDOperand> Ops;
+ Ops.push_back(Op1);
+ Ops.push_back(Op2);
+ return &ArbitraryNodes[std::make_pair(N->getOpcode(),
+ std::make_pair(RV, Ops))];
+ }
+ return 0;
+}
+
+
+/// FindModifiedNodeSlot - Find a slot for the specified node if its operands
+/// were replaced with those specified. If this node is never memoized,
+/// return null, otherwise return a pointer to the slot it would take. If a
+/// node already exists with these operands, the slot will be non-null.
+SDNode **SelectionDAG::FindModifiedNodeSlot(SDNode *N,
+ const std::vector<SDOperand> &Ops) {
+ if (N->getOpcode() == ISD::CALLSEQ_START ||
+ N->getOpcode() == ISD::CALLSEQ_END ||
+ N->getOpcode() == ISD::HANDLENODE || N->getValueType(0) == MVT::Flag)
+ return 0; // Never add these nodes.
+
+ // Check that remaining values produced are not flags.
+ for (unsigned i = 1, e = N->getNumValues(); i != e; ++i)
+ if (N->getValueType(i) == MVT::Flag)
+ return 0; // Never CSE anything that produces a flag.
+
+ if (N->getNumValues() == 1) {
+ if (N->getNumOperands() == 1) {
+ return &UnaryOps[std::make_pair(N->getOpcode(),
+ std::make_pair(Ops[0],
+ N->getValueType(0)))];
+ } else if (N->getNumOperands() == 2) {
+ return &BinaryOps[std::make_pair(N->getOpcode(),
+ std::make_pair(Ops[0], Ops[1]))];
+ } else {
+ return &OneResultNodes[std::make_pair(N->getOpcode(),
+ std::make_pair(N->getValueType(0),
+ Ops))];
+ }
+ } else {
+ if (N->getOpcode() == ISD::LOAD) {
+ return &Loads[std::make_pair(Ops[1],
+ std::make_pair(Ops[0], N->getValueType(0)))];
+ } else {
+ std::vector<MVT::ValueType> RV(N->value_begin(), N->value_end());
+ return &ArbitraryNodes[std::make_pair(N->getOpcode(),
+ std::make_pair(RV, Ops))];
+ }
+ }
+ return 0;
+}
SelectionDAG::~SelectionDAG() {
@@ -1537,6 +1638,139 @@
N->setValueTypes(&(*VTList.begin())[0], 2);
}
+/// UpdateNodeOperands - *Mutate* the specified node in-place to have the
+/// specified operands. If the resultant node already exists in the DAG,
+/// this does not modify the specified node, instead it returns the node that
+/// already exists. If the resultant node does not exist in the DAG, the
+/// input node is returned. As a degenerate case, if you specify the same
+/// input operands as the node already has, the input node is returned.
+SDOperand SelectionDAG::
+UpdateNodeOperands(SDOperand InN, SDOperand Op) {
+ SDNode *N = InN.Val;
+ assert(N->getNumOperands() == 1 && "Update with wrong number of operands");
+
+ // Check to see if there is no change.
+ if (Op == N->getOperand(0)) return InN;
+
+ // See if the modified node already exists.
+ SDNode **NewSlot = FindModifiedNodeSlot(N, Op);
+ if (NewSlot && *NewSlot)
+ return SDOperand(*NewSlot, InN.ResNo);
+
+ // Nope it doesn't. Remove the node from it's current place in the maps.
+ if (NewSlot)
+ RemoveNodeFromCSEMaps(N);
+
+ // Now we update the operands.
+ N->OperandList[0].Val->removeUser(N);
+ Op.Val->addUser(N);
+ N->OperandList[0] = Op;
+
+ // If this gets put into a CSE map, add it.
+ if (NewSlot) *NewSlot = N;
+ return InN;
+}
+
+SDOperand SelectionDAG::
+UpdateNodeOperands(SDOperand InN, SDOperand Op1, SDOperand Op2) {
+ SDNode *N = InN.Val;
+ assert(N->getNumOperands() == 2 && "Update with wrong number of operands");
+
+ // Check to see if there is no change.
+ bool AnyChange = false;
+ if (Op1 == N->getOperand(0) && Op2 == N->getOperand(1))
+ return InN; // No operands changed, just return the input node.
+
+ // See if the modified node already exists.
+ SDNode **NewSlot = FindModifiedNodeSlot(N, Op1, Op2);
+ if (NewSlot && *NewSlot)
+ return SDOperand(*NewSlot, InN.ResNo);
+
+ // Nope it doesn't. Remove the node from it's current place in the maps.
+ if (NewSlot)
+ RemoveNodeFromCSEMaps(N);
+
+ // Now we update the operands.
+ if (N->OperandList[0] != Op1) {
+ N->OperandList[0].Val->removeUser(N);
+ Op1.Val->addUser(N);
+ N->OperandList[0] = Op1;
+ }
+ if (N->OperandList[1] != Op2) {
+ N->OperandList[1].Val->removeUser(N);
+ Op2.Val->addUser(N);
+ N->OperandList[1] = Op2;
+ }
+
+ // If this gets put into a CSE map, add it.
+ if (NewSlot) *NewSlot = N;
+ return InN;
+}
+
+SDOperand SelectionDAG::
+UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2, SDOperand Op3) {
+ std::vector<SDOperand> Ops;
+ Ops.push_back(Op1);
+ Ops.push_back(Op2);
+ Ops.push_back(Op3);
+ return UpdateNodeOperands(N, Ops);
+}
+
+SDOperand SelectionDAG::
+UpdateNodeOperands(SDOperand N, SDOperand Op1, SDOperand Op2,
+ SDOperand Op3, SDOperand Op4) {
+ std::vector<SDOperand> Ops;
+ Ops.push_back(Op1);
+ Ops.push_back(Op2);
+ Ops.push_back(Op3);
+ Ops.push_back(Op4);
+ return UpdateNodeOperands(N, Ops);
+}
+
+SDOperand SelectionDAG::
+UpdateNodeOperands(SDOperand InN, const std::vector<SDOperand> &Ops) {
+ SDNode *N = InN.Val;
+ assert(N->getNumOperands() == Ops.size() &&
+ "Update with wrong number of operands");
+
+ // Check to see if there is no change.
+ unsigned NumOps = Ops.size();
+ bool AnyChange = false;
+ for (unsigned i = 0; i != NumOps; ++i) {
+ if (Ops[i] != N->getOperand(i)) {
+ AnyChange = true;
+ break;
+ }
+ }
+
+ // No operands changed, just return the input node.
+ if (!AnyChange) return InN;
+
+ // See if the modified node already exists.
+ SDNode **NewSlot = FindModifiedNodeSlot(N, Ops);
+ if (NewSlot && *NewSlot)
+ return SDOperand(*NewSlot, InN.ResNo);
+
+ // Nope it doesn't. Remove the node from it's current place in the maps.
+ if (NewSlot)
+ RemoveNodeFromCSEMaps(N);
+
+ // Now we update the operands.
+ for (unsigned i = 0; i != NumOps; ++i) {
+ if (N->OperandList[i] != Ops[i]) {
+ N->OperandList[i].Val->removeUser(N);
+ Ops[i].Val->addUser(N);
+ N->OperandList[i] = Ops[i];
+ }
+ }
+
+ // If this gets put into a CSE map, add it.
+ if (NewSlot) *NewSlot = N;
+ return InN;
+}
+
+
+
/// SelectNodeTo - These are used for target selectors to *mutate* the
/// specified node to have the specified return type, Target opcode, and
More information about the llvm-commits
mailing list