[llvm] [CodeGen][SDAG] Remove CombinedNodes SmallPtrSet (PR #94609)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 6 05:53:37 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-selectiondag
Author: None (aengelke)
<details>
<summary>Changes</summary>
This "small" set grows quite large and it's more performant to store whether a node has been combined before in the node itself.
As this information is only relevant for nodes that are currently not in the worklist, add a second state to the CombinerWorklistIndex (-2) to indicate that a node is currently not in a worklist, but was combined before.
This brings a substantial performance improvement, see [here](http://llvm-compile-time-tracker.com/compare.php?from=6150e84cfc87d118f8cd2794e40dd021c8779e9d&to=eb6eecb3fbefe62622014e47453f816ec1a621c6&stat=instructions:u).
---
Full diff: https://github.com/llvm/llvm-project/pull/94609.diff
2 Files Affected:
- (modified) llvm/include/llvm/CodeGen/SelectionDAGNodes.h (+3-1)
- (modified) llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp (+17-16)
``````````diff
diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
index 9a54dbd434d92..2edb039cbbfd2 100644
--- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -649,7 +649,9 @@ END_TWO_BYTE_PACK()
/// Return a pointer to the specified value type.
static const EVT *getValueTypeList(EVT VT);
- /// Index in worklist of DAGCombiner, or -1.
+ /// Index in worklist of DAGCombiner, or negative if the node is not in the
+ /// worklist. -1 = not in worklist; -2 = not in worklist, but has already been
+ /// combined at least once.
int CombinerWorklistIndex = -1;
uint32_t CFIType = 0;
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 9a5359015439e..caf609637593f 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -180,12 +180,6 @@ namespace {
/// in the worklist, this is different from the tail of the worklist.
SmallSetVector<SDNode *, 32> PruningList;
- /// Set of nodes which have been combined (at least once).
- ///
- /// This is used to allow us to reliably add any operands of a DAG node
- /// which have not yet been combined to the worklist.
- SmallPtrSet<SDNode *, 32> CombinedNodes;
-
/// Map from candidate StoreNode to the pair of RootNode and count.
/// The count is used to track how many times we have seen the StoreNode
/// with the same RootNode bail out in dependence check. If we have seen
@@ -235,7 +229,8 @@ namespace {
if (N) {
assert(N->getCombinerWorklistIndex() >= 0 &&
"Found a worklist entry without a corresponding map entry!");
- N->setCombinerWorklistIndex(-1);
+ // Set to -2 to indicate that we combined the node.
+ N->setCombinerWorklistIndex(-2);
}
return N;
}
@@ -267,7 +262,8 @@ namespace {
/// Add to the worklist making sure its instance is at the back (next to be
/// processed.)
- void AddToWorklist(SDNode *N, bool IsCandidateForPruning = true) {
+ void AddToWorklist(SDNode *N, bool IsCandidateForPruning = true,
+ bool SkipIfCombinedBefore = false) {
assert(N->getOpcode() != ISD::DELETED_NODE &&
"Deleted Node added to Worklist");
@@ -276,10 +272,13 @@ namespace {
if (N->getOpcode() == ISD::HANDLENODE)
return;
+ if (SkipIfCombinedBefore && N->getCombinerWorklistIndex() == -2)
+ return;
+
if (IsCandidateForPruning)
ConsiderForPruning(N);
- if (N->getCombinerWorklistIndex() == -1) {
+ if (N->getCombinerWorklistIndex() < 0) {
N->setCombinerWorklistIndex(Worklist.size());
Worklist.push_back(N);
}
@@ -287,12 +286,14 @@ namespace {
/// Remove all instances of N from the worklist.
void removeFromWorklist(SDNode *N) {
- CombinedNodes.erase(N);
PruningList.remove(N);
StoreRootCountMap.erase(N);
int WorklistIndex = N->getCombinerWorklistIndex();
- if (WorklistIndex == -1)
+ // If not in the worklist, the index might be -1 or -2 (was combined
+ // before). As the node gets deleted anyway, there's no need to update
+ // the index.
+ if (WorklistIndex < 0)
return; // Not in the worklist.
// Null out the entry rather than erasing it to avoid a linear operation.
@@ -1768,13 +1769,13 @@ void DAGCombiner::Run(CombineLevel AtLevel) {
LLVM_DEBUG(dbgs() << "\nCombining: "; N->dump(&DAG));
// Add any operands of the new node which have not yet been combined to the
- // worklist as well. Because the worklist uniques things already, this
- // won't repeatedly process the same operand.
+ // worklist as well. getNextWorklistEntry flags nodes that have been
+ // combined before. Because the worklist uniques things already, this won't
+ // repeatedly process the same operand.
for (const SDValue &ChildN : N->op_values())
- if (!CombinedNodes.count(ChildN.getNode()))
- AddToWorklist(ChildN.getNode());
+ AddToWorklist(ChildN.getNode(), /*IsCandidateForPruning=*/true,
+ /*SkipIfCombinedBefore=*/true);
- CombinedNodes.insert(N);
SDValue RV = combine(N);
if (!RV.getNode())
``````````
</details>
https://github.com/llvm/llvm-project/pull/94609
More information about the llvm-commits
mailing list