diff options
author | Chris Lattner <sabre@nondot.org> | 2005-08-17 19:00:20 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-08-17 19:00:20 +0000 |
commit | 8b8749f367fd30a8a3d57284576a6d59b60b69eb (patch) | |
tree | 25fe74bfdf04fbed0f7fa4bc96601ddb735a7ad5 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp | |
parent | 6542d950609208de3e1cde704c5f89aad864c0d9 (diff) |
Fix a bug in RemoveDeadNodes where it would crash when its "optional"
argument is not specified.
Implement ReplaceAllUsesWith.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22834 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index ef7ffb2460..6afa9d0894 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -152,7 +152,8 @@ void SelectionDAG::RemoveDeadNodes(SDNode *N) { // 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 @@ void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) { } } +/// 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 @@ void SelectionDAG::SelectNodeTo(SDNode *N, MVT::ValueType VT, 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 |