[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Chris Lattner
lattner at cs.uiuc.edu
Wed Aug 17 12:00:31 PDT 2005
Changes in directory llvm/lib/CodeGen/SelectionDAG:
SelectionDAG.cpp updated: 1.144 -> 1.145
---
Log message:
Fix a bug in RemoveDeadNodes where it would crash when its "optional"
argument is not specified.
Implement ReplaceAllUsesWith.
---
Diffs of the changes: (+77 -1)
SelectionDAG.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 77 insertions(+), 1 deletion(-)
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.144 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.145
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.144 Tue Aug 16 19:34:06 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Wed Aug 17 14:00:20 2005
@@ -152,7 +152,8 @@
// to the root node, preventing it from being deleted.
SDNode *DummyNode = new SDNode(ISD::EntryToken, getRoot());
- DeleteNodeIfDead(N, &AllNodeSet);
+ // If we have a hint to start from, use it.
+ if (N) DeleteNodeIfDead(N, &AllNodeSet);
Restart:
unsigned NumNodes = AllNodeSet.size();
@@ -292,6 +293,51 @@
}
}
+/// AddNonLeafNodeToCSEMaps - Add the specified node back to the CSE maps. It
+/// has been taken out and modified in some way. If the specified node already
+/// exists in the CSE maps, do not modify the maps, but return the existing node
+/// instead. If it doesn't exist, add it and return null.
+///
+SDNode *SelectionDAG::AddNonLeafNodeToCSEMaps(SDNode *N) {
+ assert(N->getNumOperands() && "This is a leaf node!");
+ if (N->getOpcode() == ISD::LOAD) {
+ SDNode *&L = Loads[std::make_pair(N->getOperand(1),
+ std::make_pair(N->getOperand(0),
+ N->getValueType(0)))];
+ if (L) return L;
+ L = N;
+ } else if (N->getNumOperands() == 1) {
+ SDNode *&U = UnaryOps[std::make_pair(N->getOpcode(),
+ std::make_pair(N->getOperand(0),
+ N->getValueType(0)))];
+ if (U) return U;
+ U = N;
+ } else if (N->getNumOperands() == 2) {
+ SDNode *&B = BinaryOps[std::make_pair(N->getOpcode(),
+ std::make_pair(N->getOperand(0),
+ N->getOperand(1)))];
+ if (B) return B;
+ B = N;
+ } else if (N->getNumValues() == 1) {
+ std::vector<SDOperand> Ops(N->op_begin(), N->op_end());
+ SDNode *&ORN = OneResultNodes[std::make_pair(N->getOpcode(),
+ std::make_pair(N->getValueType(0), Ops))];
+ if (ORN) return ORN;
+ ORN = N;
+ } else {
+ // Remove the node from the ArbitraryNodes map.
+ std::vector<MVT::ValueType> RV(N->value_begin(), N->value_end());
+ std::vector<SDOperand> Ops(N->op_begin(), N->op_end());
+ SDNode *&AN = ArbitraryNodes[std::make_pair(N->getOpcode(),
+ std::make_pair(RV, Ops))];
+ if (AN) return AN;
+ AN = N;
+ }
+ return 0;
+
+}
+
+
SelectionDAG::~SelectionDAG() {
for (unsigned i = 0, e = AllNodes.size(); i != e; ++i)
@@ -1758,6 +1804,36 @@
N->setOperands(Op1, Op2, Op3);
}
+/// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead.
+/// This can cause recursive merging of nodes in the DAG.
+///
+void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To) {
+ assert(From != To && "Cannot replace uses of with self");
+ while (!From->use_empty()) {
+ // Process users until they are all gone.
+ SDNode *U = *From->use_begin();
+
+ // This node is about to morph, remove its old self from the CSE maps.
+ RemoveNodeFromCSEMaps(U);
+
+ for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i)
+ if (U->getOperand(i).Val == From) {
+ assert(From->getValueType(U->getOperand(i).ResNo) ==
+ To->getValueType(U->getOperand(i).ResNo));
+ From->removeUser(U);
+ U->Operands[i].Val = To;
+ To->addUser(U);
+ }
+
+ // Now that we have modified U, add it back to the CSE maps. If it already
+ // exists there, recursively merge the results together.
+ if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U))
+ ReplaceAllUsesWith(U, Existing);
+ // U is now dead.
+ }
+}
+
+
/// hasNUsesOfValue - Return true if there are exactly NUSES uses of the
/// indicated value. This method ignores uses of other values defined by this
More information about the llvm-commits
mailing list