[DAG] Set up infrastructure to avoid smart constructor-based dangling nodes
Summary: Various SelectionDAG non-combine operations (e.g. the getNode smart constructor and legalization) may leave dangling nodes by applying optimizations without fully pruning unused result values. This results in nodes that are never added to the worklist and therefore can not be pruned. Add a node inserter for the combiner to make sure such nodes have the chance of being pruned. This allows a number of additional peephole optimizations. Reviewers: efriedma, RKSimon, craig.topper, jyknight Reviewed By: jyknight Subscribers: msearles, jyknight, sdardis, nemanjai, javed.absar, hiraditya, jrtc27, atanasyan, jsji, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D58068 llvm-svn: 357279
This commit is contained in:
parent
4e00a93558
commit
610036c506
|
@ -297,6 +297,9 @@ public:
|
|||
|
||||
/// The node N that was updated.
|
||||
virtual void NodeUpdated(SDNode *N);
|
||||
|
||||
/// The node N that was inserted.
|
||||
virtual void NodeInserted(SDNode *N);
|
||||
};
|
||||
|
||||
struct DAGNodeDeletedListener : public DAGUpdateListener {
|
||||
|
|
|
@ -647,6 +647,17 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class WorklistInserter : public SelectionDAG::DAGUpdateListener {
|
||||
DAGCombiner &DC;
|
||||
|
||||
public:
|
||||
explicit WorklistInserter(DAGCombiner &dc)
|
||||
: SelectionDAG::DAGUpdateListener(dc.getDAG()), DC(dc) {}
|
||||
|
||||
// This should eventually be pruning.
|
||||
void NodeInserted(SDNode *N) override { }
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1399,6 +1410,8 @@ void DAGCombiner::Run(CombineLevel AtLevel) {
|
|||
LegalOperations = Level >= AfterLegalizeVectorOps;
|
||||
LegalTypes = Level >= AfterLegalizeTypes;
|
||||
|
||||
WorklistInserter AddNodes(*this);
|
||||
|
||||
// Add all the dag nodes to the worklist.
|
||||
for (SDNode &Node : DAG.allnodes())
|
||||
AddToWorklist(&Node);
|
||||
|
|
|
@ -85,6 +85,7 @@ static SDVTList makeVTList(const EVT *VTs, unsigned NumVTs) {
|
|||
// Default null implementations of the callbacks.
|
||||
void SelectionDAG::DAGUpdateListener::NodeDeleted(SDNode*, SDNode*) {}
|
||||
void SelectionDAG::DAGUpdateListener::NodeUpdated(SDNode*) {}
|
||||
void SelectionDAG::DAGUpdateListener::NodeInserted(SDNode *) {}
|
||||
|
||||
void SelectionDAG::DAGNodeDeletedListener::anchor() {}
|
||||
|
||||
|
@ -840,6 +841,8 @@ void SelectionDAG::InsertNode(SDNode *N) {
|
|||
N->PersistentId = NextPersistentId++;
|
||||
VerifySDNode(N);
|
||||
#endif
|
||||
for (DAGUpdateListener *DUL = UpdateListeners; DUL; DUL = DUL->Next)
|
||||
DUL->NodeInserted(N);
|
||||
}
|
||||
|
||||
/// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that
|
||||
|
|
Loading…
Reference in New Issue