mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-04-04 00:31:54 +00:00
Implement RemoveDeadNodes
llvm-svn: 19345
This commit is contained in:
parent
6182c88b85
commit
16faa6501a
@ -17,6 +17,7 @@
|
|||||||
#include "llvm/Assembly/Writer.h"
|
#include "llvm/Assembly/Writer.h"
|
||||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <set>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
@ -98,6 +99,124 @@ ISD::CondCode ISD::getSetCCAndOperation(ISD::CondCode Op1, ISD::CondCode Op2,
|
|||||||
return ISD::CondCode(Op1 & Op2);
|
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() {
|
SelectionDAG::~SelectionDAG() {
|
||||||
for (unsigned i = 0, e = AllNodes.size(); i != e; ++i)
|
for (unsigned i = 0, e = AllNodes.size(); i != e; ++i)
|
||||||
delete AllNodes[i];
|
delete AllNodes[i];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user