llvm.org GIT mirror llvm / bc2f48c
[DomTreeUpdater] Ignore updates when both DT and PDT are nullptrs Summary: Previously, when both DT and PDT are nullptrs and the UpdateStrategy is Lazy, DomTreeUpdater still pends updates inside. After this patch, DomTreeUpdater will ignore all updates from(`applyUpdates()/insertEdge*()/deleteEdge*()`) in this case. (call `delBB()` still pends BasicBlock deletion until a flush event according to the doc). The behavior of DomTreeUpdater previously documented won't change after the patch. Reviewers: dmgreen, davide, kuhar, brzycki, grosser Reviewed By: kuhar Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D48974 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336968 91177308-0d34-0410-b5e6-96231b3b80d8 Chijun Sima 1 year, 3 months ago
3 changed file(s) with 58 addition(s) and 40 deletion(s). Raw diff Collapse all Expand all
7575 bool hasPendingUpdates() const;
7676
7777 /// Returns true if there are DominatorTree updates queued.
78 /// Returns false under Eager UpdateStrategy.
78 /// Returns false under Eager UpdateStrategy or DT is nullptr.
7979 bool hasPendingDomTreeUpdates() const;
8080
8181 /// Returns true if there are PostDominatorTree updates queued.
82 /// Returns false under Eager UpdateStrategy.
82 /// Returns false under Eager UpdateStrategy or PDT is nullptr.
8383 bool hasPendingPostDomTreeUpdates() const;
8484
8585 /// Apply updates on all available trees. Under Eager UpdateStrategy with
8686 /// ForceRemoveDuplicates enabled or under Lazy UpdateStrategy, it will
87 /// discard duplicated updates and self-dominance updates. The Eager
88 /// Strategy applies the updates immediately while the Lazy Strategy
89 /// queues the updates. It is required for the state of
90 /// the LLVM IR to be updated *before* applying the Updates because the
91 /// internal update routine will analyze the current state of the relationship
92 /// between a pair of (From, To) BasicBlocks to determine whether a single
93 /// update needs to be discarded.
87 /// discard duplicated updates and self-dominance updates. If both DT and PDT
88 /// are nullptrs, this function discards all updates. The Eager Strategy
89 /// applies the updates immediately while the Lazy Strategy queues the
90 /// updates. It is required for the state of the LLVM IR to be updated
91 /// *before* applying the Updates because the internal update routine will
92 /// analyze the current state of the relationship between a pair of (From, To)
93 /// BasicBlocks to determine whether a single update needs to be discarded.
9494 void applyUpdates(ArrayRef Updates,
9595 bool ForceRemoveDuplicates = false);
9696
97 /// Notify all available trees on an edge insertion. Under either Strategy,
97 /// Notify all available trees on an edge insertion. If both DT and PDT are
98 /// nullptrs, this function discards the update. Under either Strategy,
9899 /// self-dominance update will be removed. The Eager Strategy applies
99100 /// the update immediately while the Lazy Strategy queues the update.
100101 /// It is recommended to only use this method when you have exactly one
105106 void insertEdge(BasicBlock *From, BasicBlock *To);
106107
107108 /// Notify all available trees on an edge insertion.
108 /// Under either Strategy, these updates will be discard silently in the
109 /// following sequence
109 /// Under either Strategy, the following updates will be discard silently
110110 /// 1. Invalid - Inserting an edge that does not exist in the CFG.
111111 /// 2. Self-dominance update.
112 /// 3. Both DT and PDT are nullptrs.
112113 /// The Eager Strategy applies the update immediately while the Lazy Strategy
113114 /// queues the update. It is recommended to only use this method when you have
114115 /// exactly one insertion (and no deletions) and want to discard an invalid
115 /// update. Returns true if the update is valid.
116 bool insertEdgeRelaxed(BasicBlock *From, BasicBlock *To);
117
118 /// Notify all available trees on an edge deletion. Under either Strategy,
116 /// update.
117 void insertEdgeRelaxed(BasicBlock *From, BasicBlock *To);
118
119 /// Notify all available trees on an edge deletion. If both DT and PDT are
120 /// nullptrs, this function discards the update. Under either Strategy,
119121 /// self-dominance update will be removed. The Eager Strategy applies
120122 /// the update immediately while the Lazy Strategy queues the update.
121123 /// It is recommended to only use this method when you have exactly one
126128 void deleteEdge(BasicBlock *From, BasicBlock *To);
127129
128130 /// Notify all available trees on an edge deletion.
129 /// Under either Strategy, these updates will be discard silently in the
130 /// following sequence:
131 /// Under either Strategy, the following updates will be discard silently
131132 /// 1. Invalid - Deleting an edge that still exists in the CFG.
132133 /// 2. Self-dominance update.
134 /// 3. Both DT and PDT are nullptrs.
133135 /// The Eager Strategy applies the update immediately while the Lazy Strategy
134136 /// queues the update. It is recommended to only use this method when you have
135137 /// exactly one deletion (and no insertions) and want to discard an invalid
136 /// update. Returns true if the update is valid.
137 bool deleteEdgeRelaxed(BasicBlock *From, BasicBlock *To);
138 /// update.
139 void deleteEdgeRelaxed(BasicBlock *From, BasicBlock *To);
138140
139141 /// Delete DelBB. DelBB will be removed from its Parent and
140142 /// erased from available trees if it exists and finally get deleted.
141143 /// Under Eager UpdateStrategy, DelBB will be processed immediately.
142144 /// Under Lazy UpdateStrategy, DelBB will be queued until a flush event and
143 /// all available trees are up-to-date.
145 /// all available trees are up-to-date. When both DT and PDT are nullptrs,
146 /// DelBB will be queued until flush() is called.
144147 void deleteBB(BasicBlock *DelBB);
145148
146149 /// Delete DelBB. DelBB will be removed from its Parent and
5555
5656 bool DomTreeUpdater::applyLazyUpdate(DominatorTree::UpdateKind Kind,
5757 BasicBlock *From, BasicBlock *To) {
58 assert(DT ||
59 PDT && "Call applyLazyUpdate() when both DT and PDT are nullptrs.");
5860 assert(Strategy == DomTreeUpdater::UpdateStrategy::Lazy &&
5961 "Call applyLazyUpdate() with Eager strategy error");
6062 // Analyze pending updates to determine if the update is unnecessary.
259261
260262 void DomTreeUpdater::applyUpdates(ArrayRef Updates,
261263 bool ForceRemoveDuplicates) {
264 if (!DT && !PDT)
265 return;
266
262267 if (Strategy == UpdateStrategy::Lazy || ForceRemoveDuplicates) {
263268 SmallVector Seen;
264269 for (const auto U : Updates)
309314 "Inserted edge does not appear in the CFG");
310315 #endif
311316
317 if (!DT && !PDT)
318 return;
319
312320 // Won't affect DomTree and PostDomTree; discard update.
313321 if (From == To)
314322 return;
324332 applyLazyUpdate(DominatorTree::Insert, From, To);
325333 }
326334
327 bool DomTreeUpdater::insertEdgeRelaxed(BasicBlock *From, BasicBlock *To) {
335 void DomTreeUpdater::insertEdgeRelaxed(BasicBlock *From, BasicBlock *To) {
336 if (From == To)
337 return;
338
339 if (!DT && !PDT)
340 return;
341
328342 if (!isUpdateValid({DominatorTree::Insert, From, To}))
329 return false;
330
331 if (From == To)
332 return true;
343 return;
333344
334345 if (Strategy == UpdateStrategy::Eager) {
335346 if (DT)
336347 DT->insertEdge(From, To);
337348 if (PDT)
338349 PDT->insertEdge(From, To);
339 return true;
350 return;
340351 }
341352
342353 applyLazyUpdate(DominatorTree::Insert, From, To);
343 return true;
344354 }
345355
346356 void DomTreeUpdater::deleteEdge(BasicBlock *From, BasicBlock *To) {
350360 "Deleted edge still exists in the CFG!");
351361 #endif
352362
363 if (!DT && !PDT)
364 return;
365
353366 // Won't affect DomTree and PostDomTree; discard update.
354367 if (From == To)
355368 return;
365378 applyLazyUpdate(DominatorTree::Delete, From, To);
366379 }
367380
368 bool DomTreeUpdater::deleteEdgeRelaxed(BasicBlock *From, BasicBlock *To) {
381 void DomTreeUpdater::deleteEdgeRelaxed(BasicBlock *From, BasicBlock *To) {
382 if (From == To)
383 return;
384
385 if (!DT && !PDT)
386 return;
387
369388 if (!isUpdateValid({DominatorTree::Delete, From, To}))
370 return false;
371
372 if (From == To)
373 return true;
389 return;
374390
375391 if (Strategy == UpdateStrategy::Eager) {
376392 if (DT)
377393 DT->deleteEdge(From, To);
378394 if (PDT)
379395 PDT->deleteEdge(From, To);
380 return true;
396 return;
381397 }
382398
383399 applyLazyUpdate(DominatorTree::Delete, From, To);
384 return true;
385400 }
386401
387402 void DomTreeUpdater::dropOutOfDateUpdates() {
7171 SwitchInst *SI = dyn_cast(BB0->getTerminator());
7272 ASSERT_NE(SI, nullptr) << "Couldn't get SwitchInst.";
7373
74 ASSERT_FALSE(DTU.insertEdgeRelaxed(BB0, BB0));
75 ASSERT_TRUE(DTU.deleteEdgeRelaxed(BB0, BB0));
74 DTU.insertEdgeRelaxed(BB0, BB0);
75 DTU.deleteEdgeRelaxed(BB0, BB0);
7676
7777 // Delete edge bb0 -> bb3 and push the update twice to verify duplicate
7878 // entries are discarded.
105105 ASSERT_FALSE(DTU.hasPendingUpdates());
106106
107107 // Invalid Insert: no edge bb1 -> bb2 after change to bb0.
108 ASSERT_FALSE(DTU.insertEdgeRelaxed(BB1, BB2));
108 DTU.insertEdgeRelaxed(BB1, BB2);
109109 // Invalid Delete: edge exists bb0 -> bb1 after change to bb0.
110 ASSERT_FALSE(DTU.deleteEdgeRelaxed(BB0, BB1));
110 DTU.deleteEdgeRelaxed(BB0, BB1);
111111
112112 // DTU working with Eager UpdateStrategy does not need to flush.
113113 ASSERT_TRUE(DT.verify());
182182 EXPECT_EQ(F->begin()->getName(), NewEntry->getName());
183183 EXPECT_TRUE(&F->getEntryBlock() == NewEntry);
184184
185 ASSERT_TRUE(DTU.insertEdgeRelaxed(NewEntry, BB0));
185 DTU.insertEdgeRelaxed(NewEntry, BB0);
186186
187187 // Changing the Entry BB requires a full recalculation of DomTree.
188188 DTU.recalculate(*F);