[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Chris Lattner
lattner at cs.uiuc.edu
Fri Jan 7 13:09:59 PST 2005
Changes in directory llvm/lib/CodeGen/SelectionDAG:
SelectionDAG.cpp updated: 1.8 -> 1.9
---
Log message:
Implement RemoveDeadNodes
---
Diffs of the changes: (+119 -0)
Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.8 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.9
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.8 Fri Jan 7 01:46:32 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Jan 7 15:09:16 2005
@@ -17,6 +17,7 @@
#include "llvm/Assembly/Writer.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include <iostream>
+#include <set>
#include <cmath>
using namespace llvm;
@@ -98,6 +99,124 @@
return ISD::CondCode(Op1 & Op2);
}
+/// RemoveDeadNodes - This method deletes all unreachable nodes in the
+/// SelectionDAG, including nodes (like loads) that have uses of their token
+/// chain but no other uses and no side effect. If a node is passed in as an
+/// argument, it is used as the seed for node deletion.
+void SelectionDAG::RemoveDeadNodes(SDNode *N) {
+ std::set<SDNode*> AllNodeSet(AllNodes.begin(), AllNodes.end());
+
+ // Create a dummy node (which is not added to allnodes), that adds a reference
+ // to the root node, preventing it from being deleted.
+ SDNode *DummyNode = new SDNode(ISD::EntryToken, getRoot());
+
+ DeleteNodeIfDead(N, &AllNodeSet);
+
+ Restart:
+ unsigned NumNodes = AllNodeSet.size();
+ for (std::set<SDNode*>::iterator I = AllNodeSet.begin(), E = AllNodeSet.end();
+ I != E; ++I) {
+ // Try to delete this node.
+ DeleteNodeIfDead(*I, &AllNodeSet);
+
+ // If we actually deleted any nodes, do not use invalid iterators in
+ // AllNodeSet.
+ if (AllNodeSet.size() != NumNodes)
+ goto Restart;
+ }
+
+ // Restore AllNodes.
+ if (AllNodes.size() != NumNodes)
+ AllNodes.assign(AllNodeSet.begin(), AllNodeSet.end());
+
+ // If the root changed (e.g. it was a dead load, update the root).
+ setRoot(DummyNode->getOperand(0));
+
+ // Now that we are done with the dummy node, delete it.
+ DummyNode->getOperand(0).Val->removeUser(DummyNode);
+ delete DummyNode;
+}
+
+void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) {
+ if (!N->use_empty())
+ return;
+
+ // Okay, we really are going to delete this node. First take this out of the
+ // appropriate CSE map.
+ switch (N->getOpcode()) {
+ case ISD::Constant:
+ Constants.erase(std::make_pair(cast<ConstantSDNode>(N)->getValue(),
+ N->getValueType(0)));
+ break;
+ case ISD::ConstantFP:
+ ConstantFPs.erase(std::make_pair(cast<ConstantFPSDNode>(N)->getValue(),
+ N->getValueType(0)));
+ break;
+ case ISD::GlobalAddress:
+ GlobalValues.erase(cast<GlobalAddressSDNode>(N)->getGlobal());
+ break;
+ case ISD::FrameIndex:
+ FrameIndices.erase(cast<FrameIndexSDNode>(N)->getIndex());
+ break;
+ case ISD::ConstantPool:
+ ConstantPoolIndices.erase(cast<ConstantPoolSDNode>(N)->getIndex());
+ break;
+ case ISD::BasicBlock:
+ BBNodes.erase(cast<BasicBlockSDNode>(N)->getBasicBlock());
+ break;
+ case ISD::ExternalSymbol:
+ ExternalSymbols.erase(cast<ExternalSymbolSDNode>(N)->getSymbol());
+ break;
+
+ case ISD::LOAD:
+ Loads.erase(std::make_pair(N->getOperand(1),
+ std::make_pair(N->getOperand(0),
+ N->getValueType(0))));
+ break;
+ case ISD::SETCC:
+ SetCCs.erase(std::make_pair(std::make_pair(N->getOperand(0),
+ N->getOperand(1)),
+ cast<SetCCSDNode>(N)->getCondition()));
+ break;
+ default:
+ if (N->getNumOperands() == 1)
+ UnaryOps.erase(std::make_pair(N->getOpcode(),
+ std::make_pair(N->getOperand(0),
+ N->getValueType(0))));
+ else if (N->getNumOperands() == 2)
+ BinaryOps.erase(std::make_pair(N->getOpcode(),
+ std::make_pair(N->getOperand(0),
+ N->getOperand(1))));
+ break;
+ }
+
+ // Next, brutally remove the operand list.
+ std::vector<SDNode*> Operands;
+ while (!N->Operands.empty()) {
+ SDOperand O = N->Operands.back();
+ N->Operands.pop_back();
+ Operands.push_back(O.Val);
+ O.Val->removeUser(N);
+ }
+
+ // Remove the node from the nodes set and delete it.
+ std::set<SDNode*> &AllNodeSet = *(std::set<SDNode*>*)NodeSet;
+ AllNodeSet.erase(N);
+ delete N;
+
+ // Now that the node is gone, check to see if any of the operands of this node
+ // are dead now.
+
+ // Remove duplicate operand entries.
+ std::sort(Operands.begin(), Operands.end());
+ Operands.erase(std::unique(Operands.begin(), Operands.end()),
+ Operands.end());
+
+ for (unsigned i = 0, e = Operands.size(); i != e; ++i)
+ DeleteNodeIfDead(Operands[i], NodeSet);
+}
+
+
SelectionDAG::~SelectionDAG() {
for (unsigned i = 0, e = AllNodes.size(); i != e; ++i)
delete AllNodes[i];
More information about the llvm-commits
mailing list