llvm.org GIT mirror llvm / 95e74fa
[Dominators] Teach LoopDeletion to use the new incremental API Summary: This patch makes LoopDeletion use the incremental DominatorTree API. We modify LoopDeletion to perform the deletion in 5 steps: 1. Create a new dummy edge from the preheader to the exit, by adding a conditional branch. 2. Inform the DomTree about the new edge. 3. Remove the conditional branch and replace it with an unconditional edge to the exit. This removes the edge to the loop header, making it unreachable. 4. Inform the DomTree about the deleted edge. 5. Remove the unreachable block from the function. Creating the dummy conditional branch is necessary to perform incremental DomTree update. We should consider using the batch updater when it's ready. Reviewers: dberlin, davide, grosser, sanjoy Reviewed By: dberlin, grosser Subscribers: mzolotukhin, llvm-commits Differential Revision: https://reviews.llvm.org/D35391 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@309850 91177308-0d34-0410-b5e6-96231b3b80d8 Jakub Kuderski 2 years ago
4 changed file(s) with 138 addition(s) and 27 deletion(s). Raw diff Collapse all Expand all
480480
481481 /// Inform the dominator tree about a CFG edge deletion and update the tree.
482482 ///
483 /// This function has to be called just after making the update
484 /// on the actual CFG. There cannot be any other updates that the dominator
485 /// tree doesn't know about. The only exception is when the deletion that the
486 /// tree is informed about makes some (dominator) subtree unreachable -- in
487 /// this case, it is fine to perform deletions within this subtree.
483 /// This function has to be called just after making the update on the actual
484 /// CFG. An internal functions checks if the edge doesn't exist in the CFG in
485 /// DEBUG mode. There cannot be any other updates that the
486 /// dominator tree doesn't know about.
487 ///
488 /// However, it is fine to perform multiple CFG deletions that make different
489 /// subtrees forward-unreachable and to inform the DomTree about them all at
490 /// the same time, as the incremental algorithm doesn't walk the tree above
491 /// the NearestCommonDominator of a deleted edge
488492 ///
489493 /// Note that for postdominators it automatically takes care of deleting
490494 /// a reverse edge internally (so there's no need to swap the parameters).
238238
239239 auto *ExitBlock = L->getUniqueExitBlock();
240240 assert(ExitBlock && "Should have a unique exit block!");
241
242241 assert(L->hasDedicatedExits() && "Loop should have dedicated exits!");
243242
244 // Connect the preheader directly to the exit block.
243 auto *OldBr = dyn_cast(Preheader->getTerminator());
244 assert(OldBr && "Preheader must end with a branch");
245 assert(OldBr->isUnconditional() && "Preheader must have a single successor");
246 // Connect the preheader to the exit block. Keep the old edge to the header
247 // around to perform the dominator tree update in two separate steps
248 // -- #1 insertion of the edge preheader -> exit and #2 deletion of the edge
249 // preheader -> header.
250 //
251 //
252 // 0. Preheader 1. Preheader 2. Preheader
253 // | | | |
254 // V | V |
255 // Header <--\ | Header <--\ | Header <--\
256 // | | | | | | | | | | |
257 // | V | | | V | | | V |
258 // | Body --/ | | Body --/ | | Body --/
259 // V V V V V
260 // Exit Exit Exit
261 //
262 // By doing this is two separate steps we can perform the dominator tree
263 // update without using the batch update API.
264 //
245265 // Even when the loop is never executed, we cannot remove the edge from the
246266 // source block to the exit block. Consider the case where the unexecuted loop
247267 // branches back to an outer loop. If we deleted the loop and removed the edge
248268 // coming to this inner loop, this will break the outer loop structure (by
249269 // deleting the backedge of the outer loop). If the outer loop is indeed a
250270 // non-loop, it will be deleted in a future iteration of loop deletion pass.
251 Preheader->getTerminator()->replaceUsesOfWith(L->getHeader(), ExitBlock);
271 IRBuilder<> Builder(OldBr);
272 Builder.CreateCondBr(Builder.getFalse(), L->getHeader(), ExitBlock);
273 // Remove the old branch. The conditional branch becomes a new terminator.
274 OldBr->eraseFromParent();
275
276 // Update the dominator tree by informing it about the new edge from the
277 // preheader to the exit.
278 DT.insertEdge(Preheader, ExitBlock);
252279
253280 // Rewrite phis in the exit block to get their inputs from the Preheader
254281 // instead of the exiting block.
275302 ++BI;
276303 }
277304
278 // Update the dominator tree and remove the instructions and blocks that will
279 // be deleted from the reference counting scheme.
280 SmallVector ChildNodes;
281 for (Loop::block_iterator LI = L->block_begin(), LE = L->block_end();
282 LI != LE; ++LI) {
283 // Move all of the block's children to be children of the Preheader, which
284 // allows us to remove the domtree entry for the block.
285 ChildNodes.insert(ChildNodes.begin(), DT[*LI]->begin(), DT[*LI]->end());
286 for (DomTreeNode *ChildNode : ChildNodes) {
287 DT.changeImmediateDominator(ChildNode, DT[Preheader]);
288 }
289
290 ChildNodes.clear();
291 DT.eraseNode(*LI);
292
293 // Remove the block from the reference counting scheme, so that we can
294 // delete it freely later.
295 (*LI)->dropAllReferences();
296 }
305 // Disconnect the loop body by branching directly to its exit.
306 Builder.SetInsertPoint(Preheader->getTerminator());
307 Builder.CreateBr(ExitBlock);
308 // Remove the old branch.
309 Preheader->getTerminator()->eraseFromParent();
310
311 // Inform the dominator tree about the removed edge.
312 DT.deleteEdge(Preheader, L->getHeader());
313
314 // Remove the block from the reference counting scheme, so that we can
315 // delete it freely later.
316 for (auto *Block : L->blocks())
317 Block->dropAllReferences();
297318
298319 // Erase the instructions and the blocks without having to worry
299320 // about ordering because we already dropped the references.
0 ; RUN: opt < %s -loop-deletion -S
1 ; RUN: opt < %s -loop-deletion -analyze -domtree 2>&1 | FileCheck -check-prefix=DT %s
2 ; RUN: opt < %s -loop-deletion -analyze -verify-dom-info
3
4 ; CHECK: for.body
5 ; CHECK-NOT: for.cond1
6
7 ; Verify only the important parts of the DomTree.
8 ; DT: [1] %entry
9 ; DT: [2] %for.cond
10 ; DT: [3] %lbl63A679E5
11 ; DT: [3] %for.cond9
12 ; DT: [3] %lbl64774A9B
13 ; DT: [3] %for.body
14 ; DT: [4] %for.cond3.loopexit
15
16 define i32 @fn1() {
17 entry:
18 br label %for.cond
19
20 for.cond: ; preds = %entry
21 br i1 undef, label %lbl63A679E5, label %for.body
22
23 for.body: ; preds = %for.cond
24 br label %for.cond1
25
26 for.cond1: ; preds = %for.cond1, %for.body
27 br i1 undef, label %for.cond1, label %for.cond3.loopexit
28
29 for.cond3.loopexit: ; preds = %for.cond1
30 br label %for.cond3
31
32 for.cond3: ; preds = %for.cond9, %for.cond3.loopexit
33 br i1 undef, label %for.body4, label %for.cond17
34
35 for.body4: ; preds = %for.cond3
36 br label %for.cond5
37
38 for.cond5: ; preds = %lbl63A679E5, %for.body4
39 br label %for.cond9
40
41 lbl63A679E5: ; preds = %for.cond
42 br label %for.cond5
43
44 for.cond9: ; preds = %for.end14.split, %for.cond5
45 br i1 undef, label %for.cond3, label %lbl64774A9B
46
47 lbl64774A9B: ; preds = %for.cond17, %for.cond9
48 br label %for.end14.split
49
50 for.end14.split: ; preds = %lbl64774A9B
51 br label %for.cond9
52
53 for.cond17: ; preds = %for.cond3
54 br label %lbl64774A9B
55 }
796796 }
797797 }
798798
799 TEST(DominatorTree, DeletionsInSubtrees) {
800 CFGHolder Holder;
801 std::vector Arcs = {{"0", "1"}, {"1", "2"}, {"1", "3"},
802 {"1", "6"}, {"3", "4"}, {"2", "5"},
803 {"5", "2"}};
804
805 // It is possible to perform multiple deletions and inform the
806 // DominatorTree about them at the same time, if the all of the
807 // deletions happen in different subtrees.
808 std::vector Updates = {{Delete, {"1", "2"}},
809 {Delete, {"1", "3"}}};
810 CFGBuilder B(Holder.F, Arcs, Updates);
811 DominatorTree DT(*Holder.F);
812 EXPECT_TRUE(DT.verify());
813
814 Optional LastUpdate;
815 while ((LastUpdate = B.applyUpdate()))
816 ;
817
818 DT.deleteEdge(B.getOrAddBlock("1"), B.getOrAddBlock("2"));
819 DT.deleteEdge(B.getOrAddBlock("1"), B.getOrAddBlock("3"));
820
821 EXPECT_TRUE(DT.verify());
822 EXPECT_EQ(DT.getNode(B.getOrAddBlock("2")), nullptr);
823 EXPECT_EQ(DT.getNode(B.getOrAddBlock("3")), nullptr);
824 EXPECT_EQ(DT.getNode(B.getOrAddBlock("4")), nullptr);
825 EXPECT_EQ(DT.getNode(B.getOrAddBlock("5")), nullptr);
826 EXPECT_NE(DT.getNode(B.getOrAddBlock("6")), nullptr);
827 }
828
799829 TEST(DominatorTree, InsertDelete) {
800830 std::vector Arcs = {
801831 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"4", "5"}, {"5", "6"}, {"5", "7"},