mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-10 02:36:06 +00:00
Use the new infrastructure for listening to node updates to
keep the LegalizeTypes node flags up to date when doing a RAUW. This fixes a nasty bug that Duncan ran into and makes the previous (nonbuggy case) more efficent. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46679 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d8cd3be370
commit
42bd25f8ec
@ -217,6 +217,29 @@ void DAGTypeLegalizer::MarkNewNodes(SDNode *N) {
|
||||
Worklist.push_back(N);
|
||||
}
|
||||
|
||||
namespace {
|
||||
/// NodeUpdateListener - This class is a DAGUpdateListener that listens for
|
||||
/// updates to nodes and recomputes their ready state.
|
||||
class VISIBILITY_HIDDEN NodeUpdateListener :
|
||||
public SelectionDAG::DAGUpdateListener {
|
||||
DAGTypeLegalizer &DTL;
|
||||
public:
|
||||
NodeUpdateListener(DAGTypeLegalizer &dtl) : DTL(dtl) {}
|
||||
|
||||
virtual void NodeDeleted(SDNode *N) {
|
||||
// Ignore deletes.
|
||||
}
|
||||
|
||||
virtual void NodeUpdated(SDNode *N) {
|
||||
// Node updates can mean pretty much anything. It is possible that an
|
||||
// operand was set to something already processed (f.e.) in which case
|
||||
// this node could become ready. Recompoute its flags.
|
||||
DTL.ReanalyzeNodeFlags(N);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// ReplaceValueWith - The specified value was legalized to the specified other
|
||||
/// value. If they are different, update the DAG and NodeIDs replacing any uses
|
||||
/// of From to use To instead.
|
||||
@ -229,26 +252,12 @@ void DAGTypeLegalizer::ReplaceValueWith(SDOperand From, SDOperand To) {
|
||||
|
||||
// Anything that used the old node should now use the new one. Note that this
|
||||
// can potentially cause recursive merging.
|
||||
DAG.ReplaceAllUsesOfValueWith(From, To);
|
||||
NodeUpdateListener NUL(*this);
|
||||
DAG.ReplaceAllUsesOfValueWith(From, To, &NUL);
|
||||
|
||||
// The old node may still be present in ExpandedNodes or PromotedNodes.
|
||||
// Inform them about the replacement.
|
||||
ReplacedNodes[From] = To;
|
||||
|
||||
// Since we just made an unstructured update to the DAG, which could wreak
|
||||
// general havoc on anything that once used From and now uses To, walk all
|
||||
// users of the result, updating their flags.
|
||||
for (SDNode::use_iterator I = To.Val->use_begin(), E = To.Val->use_end();
|
||||
I != E; ++I) {
|
||||
SDNode *User = *I;
|
||||
// If the node isn't already processed or in the worklist, mark it as new,
|
||||
// then use MarkNewNodes to recompute its ID.
|
||||
int NodeId = User->getNodeId();
|
||||
if (NodeId != ReadyToProcess && NodeId != Processed) {
|
||||
User->setNodeId(NewNode);
|
||||
MarkNewNodes(User);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// ReplaceNodeWith - Replace uses of the 'from' node's results with the 'to'
|
||||
@ -264,7 +273,8 @@ void DAGTypeLegalizer::ReplaceNodeWith(SDNode *From, SDNode *To) {
|
||||
|
||||
// Anything that used the old node should now use the new one. Note that this
|
||||
// can potentially cause recursive merging.
|
||||
DAG.ReplaceAllUsesWith(From, To);
|
||||
NodeUpdateListener NUL(*this);
|
||||
DAG.ReplaceAllUsesWith(From, To, &NUL);
|
||||
|
||||
// The old node may still be present in ExpandedNodes or PromotedNodes.
|
||||
// Inform them about the replacement.
|
||||
@ -273,20 +283,6 @@ void DAGTypeLegalizer::ReplaceNodeWith(SDNode *From, SDNode *To) {
|
||||
"Node results don't match");
|
||||
ReplacedNodes[SDOperand(From, i)] = SDOperand(To, i);
|
||||
}
|
||||
|
||||
// Since we just made an unstructured update to the DAG, which could wreak
|
||||
// general havoc on anything that once used From and now uses To, walk all
|
||||
// users of the result, updating their flags.
|
||||
for (SDNode::use_iterator I = To->use_begin(), E = To->use_end();I != E; ++I){
|
||||
SDNode *User = *I;
|
||||
// If the node isn't already processed or in the worklist, mark it as new,
|
||||
// then use MarkNewNodes to recompute its ID.
|
||||
int NodeId = User->getNodeId();
|
||||
if (NodeId != ReadyToProcess && NodeId != Processed) {
|
||||
User->setNodeId(NewNode);
|
||||
MarkNewNodes(User);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -117,6 +117,13 @@ public:
|
||||
|
||||
void run();
|
||||
|
||||
/// ReanalyzeNodeFlags - Recompute the NodeID flags for the specified node,
|
||||
/// adding it to the worklist if ready.
|
||||
void ReanalyzeNodeFlags(SDNode *N) {
|
||||
N->setNodeId(NewNode);
|
||||
MarkNewNodes(N);
|
||||
}
|
||||
|
||||
private:
|
||||
void MarkNewNodes(SDNode *N);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user