@@ -180,12 +180,6 @@ namespace {
180
180
/// in the worklist, this is different from the tail of the worklist.
181
181
SmallSetVector<SDNode *, 32> PruningList;
182
182
183
- /// Set of nodes which have been combined (at least once).
184
- ///
185
- /// This is used to allow us to reliably add any operands of a DAG node
186
- /// which have not yet been combined to the worklist.
187
- SmallPtrSet<SDNode *, 32> CombinedNodes;
188
-
189
183
/// Map from candidate StoreNode to the pair of RootNode and count.
190
184
/// The count is used to track how many times we have seen the StoreNode
191
185
/// with the same RootNode bail out in dependence check. If we have seen
@@ -235,7 +229,8 @@ namespace {
235
229
if (N) {
236
230
assert(N->getCombinerWorklistIndex() >= 0 &&
237
231
"Found a worklist entry without a corresponding map entry!");
238
- N->setCombinerWorklistIndex(-1);
232
+ // Set to -2 to indicate that we combined the node.
233
+ N->setCombinerWorklistIndex(-2);
239
234
}
240
235
return N;
241
236
}
@@ -267,7 +262,8 @@ namespace {
267
262
268
263
/// Add to the worklist making sure its instance is at the back (next to be
269
264
/// processed.)
270
- void AddToWorklist(SDNode *N, bool IsCandidateForPruning = true) {
265
+ void AddToWorklist(SDNode *N, bool IsCandidateForPruning = true,
266
+ bool SkipIfCombinedBefore = false) {
271
267
assert(N->getOpcode() != ISD::DELETED_NODE &&
272
268
"Deleted Node added to Worklist");
273
269
@@ -276,23 +272,28 @@ namespace {
276
272
if (N->getOpcode() == ISD::HANDLENODE)
277
273
return;
278
274
275
+ if (SkipIfCombinedBefore && N->getCombinerWorklistIndex() == -2)
276
+ return;
277
+
279
278
if (IsCandidateForPruning)
280
279
ConsiderForPruning(N);
281
280
282
- if (N->getCombinerWorklistIndex() == -1 ) {
281
+ if (N->getCombinerWorklistIndex() < 0 ) {
283
282
N->setCombinerWorklistIndex(Worklist.size());
284
283
Worklist.push_back(N);
285
284
}
286
285
}
287
286
288
287
/// Remove all instances of N from the worklist.
289
288
void removeFromWorklist(SDNode *N) {
290
- CombinedNodes.erase(N);
291
289
PruningList.remove(N);
292
290
StoreRootCountMap.erase(N);
293
291
294
292
int WorklistIndex = N->getCombinerWorklistIndex();
295
- if (WorklistIndex == -1)
293
+ // If not in the worklist, the index might be -1 or -2 (was combined
294
+ // before). As the node gets deleted anyway, there's no need to update
295
+ // the index.
296
+ if (WorklistIndex < 0)
296
297
return; // Not in the worklist.
297
298
298
299
// Null out the entry rather than erasing it to avoid a linear operation.
@@ -1768,13 +1769,13 @@ void DAGCombiner::Run(CombineLevel AtLevel) {
1768
1769
LLVM_DEBUG(dbgs() << "\nCombining: "; N->dump(&DAG));
1769
1770
1770
1771
// Add any operands of the new node which have not yet been combined to the
1771
- // worklist as well. Because the worklist uniques things already, this
1772
- // won't repeatedly process the same operand.
1772
+ // worklist as well. getNextWorklistEntry flags nodes that have been
1773
+ // combined before. Because the worklist uniques things already, this won't
1774
+ // repeatedly process the same operand.
1773
1775
for (const SDValue &ChildN : N->op_values())
1774
- if (!CombinedNodes.count( ChildN.getNode()))
1775
- AddToWorklist(ChildN.getNode() );
1776
+ AddToWorklist( ChildN.getNode(), /*IsCandidateForPruning=*/true,
1777
+ /*SkipIfCombinedBefore=*/true );
1776
1778
1777
- CombinedNodes.insert(N);
1778
1779
SDValue RV = combine(N);
1779
1780
1780
1781
if (!RV.getNode())
0 commit comments