xref: /llvm-project/llvm/unittests/IR/DominatorTreeBatchUpdatesTest.cpp (revision 6aa050a69041e610587c51032fa477dd3d6da787)
1624463a0SJakub Kuderski //===- llvm/unittests/IR/DominatorTreeBatchUpdatesTest.cpp ----------------===//
2624463a0SJakub Kuderski //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6624463a0SJakub Kuderski //
7624463a0SJakub Kuderski //===----------------------------------------------------------------------===//
8624463a0SJakub Kuderski 
9624463a0SJakub Kuderski #include "CFGBuilder.h"
10624463a0SJakub Kuderski #include "llvm/Analysis/PostDominators.h"
11624463a0SJakub Kuderski #include "llvm/IR/Dominators.h"
12624463a0SJakub Kuderski #include "llvm/Support/GenericDomTreeConstruction.h"
13763ae1d2SJakub Kuderski #include "gtest/gtest.h"
14763ae1d2SJakub Kuderski #include <random>
15624463a0SJakub Kuderski 
16624463a0SJakub Kuderski #define DEBUG_TYPE "batch-update-tests"
17624463a0SJakub Kuderski 
18624463a0SJakub Kuderski using namespace llvm;
19624463a0SJakub Kuderski 
20624463a0SJakub Kuderski namespace {
21624463a0SJakub Kuderski const auto CFGInsert = CFGBuilder::ActionKind::Insert;
22624463a0SJakub Kuderski const auto CFGDelete = CFGBuilder::ActionKind::Delete;
23624463a0SJakub Kuderski 
24624463a0SJakub Kuderski using DomUpdate = DominatorTree::UpdateType;
25624463a0SJakub Kuderski static_assert(
26*6aa050a6SNathan James     std::is_same_v<DomUpdate, PostDominatorTree::UpdateType>,
27624463a0SJakub Kuderski     "Trees differing only in IsPostDom should have the same update types");
28624463a0SJakub Kuderski using DomSNCA = DomTreeBuilder::SemiNCAInfo<DomTreeBuilder::BBDomTree>;
29624463a0SJakub Kuderski using PostDomSNCA = DomTreeBuilder::SemiNCAInfo<DomTreeBuilder::BBPostDomTree>;
30624463a0SJakub Kuderski const auto Insert = DominatorTree::Insert;
31624463a0SJakub Kuderski const auto Delete = DominatorTree::Delete;
32624463a0SJakub Kuderski 
ToDomUpdates(CFGBuilder & B,std::vector<CFGBuilder::Update> & In)33624463a0SJakub Kuderski std::vector<DomUpdate> ToDomUpdates(CFGBuilder &B,
34624463a0SJakub Kuderski                                     std::vector<CFGBuilder::Update> &In) {
35624463a0SJakub Kuderski   std::vector<DomUpdate> Res;
36624463a0SJakub Kuderski   Res.reserve(In.size());
37624463a0SJakub Kuderski 
38624463a0SJakub Kuderski   for (const auto &CFGU : In)
39624463a0SJakub Kuderski     Res.push_back({CFGU.Action == CFGInsert ? Insert : Delete,
40624463a0SJakub Kuderski                    B.getOrAddBlock(CFGU.Edge.From),
41624463a0SJakub Kuderski                    B.getOrAddBlock(CFGU.Edge.To)});
42624463a0SJakub Kuderski   return Res;
43624463a0SJakub Kuderski }
44624463a0SJakub Kuderski }  // namespace
45624463a0SJakub Kuderski 
TEST(DominatorTreeBatchUpdates,LegalizeDomUpdates)46624463a0SJakub Kuderski TEST(DominatorTreeBatchUpdates, LegalizeDomUpdates) {
47624463a0SJakub Kuderski   CFGHolder Holder;
48624463a0SJakub Kuderski   CFGBuilder Builder(Holder.F, {{"A", "B"}}, {});
49624463a0SJakub Kuderski 
50624463a0SJakub Kuderski   BasicBlock *A = Builder.getOrAddBlock("A");
51624463a0SJakub Kuderski   BasicBlock *B = Builder.getOrAddBlock("B");
52624463a0SJakub Kuderski   BasicBlock *C = Builder.getOrAddBlock("C");
53624463a0SJakub Kuderski   BasicBlock *D = Builder.getOrAddBlock("D");
54624463a0SJakub Kuderski 
55624463a0SJakub Kuderski   std::vector<DomUpdate> Updates = {
56624463a0SJakub Kuderski       {Insert, B, C}, {Insert, C, D}, {Delete, B, C}, {Insert, B, C},
57624463a0SJakub Kuderski       {Insert, B, D}, {Delete, C, D}, {Delete, A, B}};
58624463a0SJakub Kuderski   SmallVector<DomUpdate, 4> Legalized;
59148c4454SAlina Sbirlea   cfg::LegalizeUpdates<BasicBlock *>(Updates, Legalized, false);
60d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "Legalized updates:\t");
61148c4454SAlina Sbirlea   LLVM_DEBUG(for (auto &U : Legalized) { U.dump(); dbgs() << ", "; });
62d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "\n");
63624463a0SJakub Kuderski   EXPECT_EQ(Legalized.size(), 3UL);
64763ae1d2SJakub Kuderski   EXPECT_TRUE(llvm::is_contained(Legalized, DomUpdate{Insert, B, C}));
65763ae1d2SJakub Kuderski   EXPECT_TRUE(llvm::is_contained(Legalized, DomUpdate{Insert, B, D}));
66763ae1d2SJakub Kuderski   EXPECT_TRUE(llvm::is_contained(Legalized, DomUpdate{Delete, A, B}));
67624463a0SJakub Kuderski }
68624463a0SJakub Kuderski 
TEST(DominatorTreeBatchUpdates,LegalizePostDomUpdates)69624463a0SJakub Kuderski TEST(DominatorTreeBatchUpdates, LegalizePostDomUpdates) {
70624463a0SJakub Kuderski   CFGHolder Holder;
71624463a0SJakub Kuderski   CFGBuilder Builder(Holder.F, {{"A", "B"}}, {});
72624463a0SJakub Kuderski 
73624463a0SJakub Kuderski   BasicBlock *A = Builder.getOrAddBlock("A");
74624463a0SJakub Kuderski   BasicBlock *B = Builder.getOrAddBlock("B");
75624463a0SJakub Kuderski   BasicBlock *C = Builder.getOrAddBlock("C");
76624463a0SJakub Kuderski   BasicBlock *D = Builder.getOrAddBlock("D");
77624463a0SJakub Kuderski 
78624463a0SJakub Kuderski   std::vector<DomUpdate> Updates = {
79624463a0SJakub Kuderski       {Insert, B, C}, {Insert, C, D}, {Delete, B, C}, {Insert, B, C},
80624463a0SJakub Kuderski       {Insert, B, D}, {Delete, C, D}, {Delete, A, B}};
81624463a0SJakub Kuderski   SmallVector<DomUpdate, 4> Legalized;
82148c4454SAlina Sbirlea   cfg::LegalizeUpdates<BasicBlock *>(Updates, Legalized, true);
83d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "Legalized postdom updates:\t");
84148c4454SAlina Sbirlea   LLVM_DEBUG(for (auto &U : Legalized) { U.dump(); dbgs() << ", "; });
85d34e60caSNicola Zaghen   LLVM_DEBUG(dbgs() << "\n");
86624463a0SJakub Kuderski   EXPECT_EQ(Legalized.size(), 3UL);
87763ae1d2SJakub Kuderski   EXPECT_TRUE(llvm::is_contained(Legalized, DomUpdate{Insert, C, B}));
88763ae1d2SJakub Kuderski   EXPECT_TRUE(llvm::is_contained(Legalized, DomUpdate{Insert, D, B}));
89763ae1d2SJakub Kuderski   EXPECT_TRUE(llvm::is_contained(Legalized, DomUpdate{Delete, B, A}));
90624463a0SJakub Kuderski }
91624463a0SJakub Kuderski 
TEST(DominatorTreeBatchUpdates,SingleInsertion)92624463a0SJakub Kuderski TEST(DominatorTreeBatchUpdates, SingleInsertion) {
93624463a0SJakub Kuderski   CFGHolder Holder;
94624463a0SJakub Kuderski   CFGBuilder Builder(Holder.F, {{"A", "B"}}, {{CFGInsert, {"B", "C"}}});
95624463a0SJakub Kuderski 
96624463a0SJakub Kuderski   DominatorTree DT(*Holder.F);
97624463a0SJakub Kuderski   EXPECT_TRUE(DT.verify());
98ef33edd9SJakub Kuderski   PostDominatorTree PDT(*Holder.F);
990cbc1b0dSJakub Kuderski   EXPECT_TRUE(PDT.verify());
100624463a0SJakub Kuderski 
101624463a0SJakub Kuderski   BasicBlock *B = Builder.getOrAddBlock("B");
102624463a0SJakub Kuderski   BasicBlock *C = Builder.getOrAddBlock("C");
103624463a0SJakub Kuderski   std::vector<DomUpdate> Updates = {{Insert, B, C}};
104624463a0SJakub Kuderski 
105624463a0SJakub Kuderski   ASSERT_TRUE(Builder.applyUpdate());
106624463a0SJakub Kuderski 
107624463a0SJakub Kuderski   DT.applyUpdates(Updates);
108624463a0SJakub Kuderski   EXPECT_TRUE(DT.verify());
109624463a0SJakub Kuderski   PDT.applyUpdates(Updates);
110624463a0SJakub Kuderski   EXPECT_TRUE(PDT.verify());
111624463a0SJakub Kuderski }
112624463a0SJakub Kuderski 
TEST(DominatorTreeBatchUpdates,SingleDeletion)113624463a0SJakub Kuderski TEST(DominatorTreeBatchUpdates, SingleDeletion) {
114624463a0SJakub Kuderski   CFGHolder Holder;
115624463a0SJakub Kuderski   CFGBuilder Builder(Holder.F, {{"A", "B"}, {"B", "C"}},
116624463a0SJakub Kuderski                      {{CFGDelete, {"B", "C"}}});
117624463a0SJakub Kuderski 
118624463a0SJakub Kuderski   DominatorTree DT(*Holder.F);
119624463a0SJakub Kuderski   EXPECT_TRUE(DT.verify());
120ef33edd9SJakub Kuderski   PostDominatorTree PDT(*Holder.F);
1210cbc1b0dSJakub Kuderski   EXPECT_TRUE(PDT.verify());
122624463a0SJakub Kuderski 
123624463a0SJakub Kuderski   BasicBlock *B = Builder.getOrAddBlock("B");
124624463a0SJakub Kuderski   BasicBlock *C = Builder.getOrAddBlock("C");
125624463a0SJakub Kuderski   std::vector<DomUpdate> Updates = {{Delete, B, C}};
126624463a0SJakub Kuderski 
127624463a0SJakub Kuderski   ASSERT_TRUE(Builder.applyUpdate());
128624463a0SJakub Kuderski 
129624463a0SJakub Kuderski   DT.applyUpdates(Updates);
130624463a0SJakub Kuderski   EXPECT_TRUE(DT.verify());
131624463a0SJakub Kuderski   PDT.applyUpdates(Updates);
132624463a0SJakub Kuderski   EXPECT_TRUE(PDT.verify());
133624463a0SJakub Kuderski }
134624463a0SJakub Kuderski 
TEST(DominatorTreeBatchUpdates,FewInsertion)135624463a0SJakub Kuderski TEST(DominatorTreeBatchUpdates, FewInsertion) {
136624463a0SJakub Kuderski   std::vector<CFGBuilder::Update> CFGUpdates = {{CFGInsert, {"B", "C"}},
137624463a0SJakub Kuderski                                                 {CFGInsert, {"C", "B"}},
138624463a0SJakub Kuderski                                                 {CFGInsert, {"C", "D"}},
139624463a0SJakub Kuderski                                                 {CFGInsert, {"D", "E"}}};
140624463a0SJakub Kuderski 
141624463a0SJakub Kuderski   CFGHolder Holder;
142624463a0SJakub Kuderski   CFGBuilder Builder(Holder.F, {{"A", "B"}}, CFGUpdates);
143624463a0SJakub Kuderski 
144624463a0SJakub Kuderski   DominatorTree DT(*Holder.F);
145624463a0SJakub Kuderski   EXPECT_TRUE(DT.verify());
146ef33edd9SJakub Kuderski   PostDominatorTree PDT(*Holder.F);
147624463a0SJakub Kuderski   EXPECT_TRUE(PDT.verify());
148624463a0SJakub Kuderski 
149624463a0SJakub Kuderski   BasicBlock *B = Builder.getOrAddBlock("B");
150624463a0SJakub Kuderski   BasicBlock *C = Builder.getOrAddBlock("C");
151624463a0SJakub Kuderski   BasicBlock *D = Builder.getOrAddBlock("D");
152624463a0SJakub Kuderski   BasicBlock *E = Builder.getOrAddBlock("E");
153624463a0SJakub Kuderski 
154624463a0SJakub Kuderski   std::vector<DomUpdate> Updates = {
155624463a0SJakub Kuderski       {Insert, B, C}, {Insert, C, B}, {Insert, C, D}, {Insert, D, E}};
156624463a0SJakub Kuderski 
157624463a0SJakub Kuderski   while (Builder.applyUpdate())
158624463a0SJakub Kuderski     ;
159624463a0SJakub Kuderski 
160624463a0SJakub Kuderski   DT.applyUpdates(Updates);
161624463a0SJakub Kuderski   EXPECT_TRUE(DT.verify());
162624463a0SJakub Kuderski   PDT.applyUpdates(Updates);
163624463a0SJakub Kuderski   EXPECT_TRUE(PDT.verify());
164624463a0SJakub Kuderski }
165624463a0SJakub Kuderski 
TEST(DominatorTreeBatchUpdates,FewDeletions)166624463a0SJakub Kuderski TEST(DominatorTreeBatchUpdates, FewDeletions) {
167624463a0SJakub Kuderski   std::vector<CFGBuilder::Update> CFGUpdates = {{CFGDelete, {"B", "C"}},
168624463a0SJakub Kuderski                                                 {CFGDelete, {"C", "B"}},
169624463a0SJakub Kuderski                                                 {CFGDelete, {"B", "D"}},
170624463a0SJakub Kuderski                                                 {CFGDelete, {"D", "E"}}};
171624463a0SJakub Kuderski 
172624463a0SJakub Kuderski   CFGHolder Holder;
173624463a0SJakub Kuderski   CFGBuilder Builder(
174624463a0SJakub Kuderski       Holder.F, {{"A", "B"}, {"B", "C"}, {"B", "D"}, {"D", "E"}, {"C", "B"}},
175624463a0SJakub Kuderski       CFGUpdates);
176624463a0SJakub Kuderski 
177624463a0SJakub Kuderski   DominatorTree DT(*Holder.F);
178624463a0SJakub Kuderski   EXPECT_TRUE(DT.verify());
179ef33edd9SJakub Kuderski   PostDominatorTree PDT(*Holder.F);
180624463a0SJakub Kuderski   EXPECT_TRUE(PDT.verify());
181624463a0SJakub Kuderski 
182624463a0SJakub Kuderski   auto Updates = ToDomUpdates(Builder, CFGUpdates);
183624463a0SJakub Kuderski 
184624463a0SJakub Kuderski   while (Builder.applyUpdate())
185624463a0SJakub Kuderski     ;
186624463a0SJakub Kuderski 
187624463a0SJakub Kuderski   DT.applyUpdates(Updates);
188624463a0SJakub Kuderski   EXPECT_TRUE(DT.verify());
189624463a0SJakub Kuderski   PDT.applyUpdates(Updates);
190624463a0SJakub Kuderski   EXPECT_TRUE(PDT.verify());
191624463a0SJakub Kuderski }
192624463a0SJakub Kuderski 
TEST(DominatorTreeBatchUpdates,InsertDelete)193624463a0SJakub Kuderski TEST(DominatorTreeBatchUpdates, InsertDelete) {
194624463a0SJakub Kuderski   std::vector<CFGBuilder::Arc> Arcs = {
195624463a0SJakub Kuderski       {"1", "2"}, {"2", "3"}, {"3", "4"},  {"4", "5"},  {"5", "6"},  {"5", "7"},
196624463a0SJakub Kuderski       {"3", "8"}, {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}};
197624463a0SJakub Kuderski 
198624463a0SJakub Kuderski   std::vector<CFGBuilder::Update> Updates = {
199624463a0SJakub Kuderski       {CFGInsert, {"2", "4"}},  {CFGInsert, {"12", "10"}},
200624463a0SJakub Kuderski       {CFGInsert, {"10", "9"}}, {CFGInsert, {"7", "6"}},
201624463a0SJakub Kuderski       {CFGInsert, {"7", "5"}},  {CFGDelete, {"3", "8"}},
202624463a0SJakub Kuderski       {CFGInsert, {"10", "7"}}, {CFGInsert, {"2", "8"}},
203624463a0SJakub Kuderski       {CFGDelete, {"3", "4"}},  {CFGDelete, {"8", "9"}},
204624463a0SJakub Kuderski       {CFGDelete, {"11", "12"}}};
205624463a0SJakub Kuderski 
206624463a0SJakub Kuderski   CFGHolder Holder;
207624463a0SJakub Kuderski   CFGBuilder B(Holder.F, Arcs, Updates);
208624463a0SJakub Kuderski   DominatorTree DT(*Holder.F);
209624463a0SJakub Kuderski   EXPECT_TRUE(DT.verify());
210ef33edd9SJakub Kuderski   PostDominatorTree PDT(*Holder.F);
211624463a0SJakub Kuderski   EXPECT_TRUE(PDT.verify());
212624463a0SJakub Kuderski 
213624463a0SJakub Kuderski   while (B.applyUpdate())
214624463a0SJakub Kuderski     ;
215624463a0SJakub Kuderski 
216624463a0SJakub Kuderski   auto DomUpdates = ToDomUpdates(B, Updates);
217624463a0SJakub Kuderski   DT.applyUpdates(DomUpdates);
218624463a0SJakub Kuderski   EXPECT_TRUE(DT.verify());
219624463a0SJakub Kuderski   PDT.applyUpdates(DomUpdates);
220624463a0SJakub Kuderski   EXPECT_TRUE(PDT.verify());
221624463a0SJakub Kuderski }
222624463a0SJakub Kuderski 
TEST(DominatorTreeBatchUpdates,InsertDeleteExhaustive)223624463a0SJakub Kuderski TEST(DominatorTreeBatchUpdates, InsertDeleteExhaustive) {
224624463a0SJakub Kuderski   std::vector<CFGBuilder::Arc> Arcs = {
225624463a0SJakub Kuderski       {"1", "2"}, {"2", "3"}, {"3", "4"},  {"4", "5"},  {"5", "6"},  {"5", "7"},
226624463a0SJakub Kuderski       {"3", "8"}, {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}};
227624463a0SJakub Kuderski 
228624463a0SJakub Kuderski   std::vector<CFGBuilder::Update> Updates = {
229624463a0SJakub Kuderski       {CFGInsert, {"2", "4"}},  {CFGInsert, {"12", "10"}},
230624463a0SJakub Kuderski       {CFGInsert, {"10", "9"}}, {CFGInsert, {"7", "6"}},
231624463a0SJakub Kuderski       {CFGInsert, {"7", "5"}},  {CFGDelete, {"3", "8"}},
232624463a0SJakub Kuderski       {CFGInsert, {"10", "7"}}, {CFGInsert, {"2", "8"}},
233624463a0SJakub Kuderski       {CFGDelete, {"3", "4"}},  {CFGDelete, {"8", "9"}},
234624463a0SJakub Kuderski       {CFGDelete, {"11", "12"}}};
235624463a0SJakub Kuderski 
236624463a0SJakub Kuderski   std::mt19937 Generator(0);
237624463a0SJakub Kuderski   for (unsigned i = 0; i < 16; ++i) {
238624463a0SJakub Kuderski     std::shuffle(Updates.begin(), Updates.end(), Generator);
239624463a0SJakub Kuderski     CFGHolder Holder;
240624463a0SJakub Kuderski     CFGBuilder B(Holder.F, Arcs, Updates);
241624463a0SJakub Kuderski     DominatorTree DT(*Holder.F);
242624463a0SJakub Kuderski     EXPECT_TRUE(DT.verify());
243ef33edd9SJakub Kuderski     PostDominatorTree PDT(*Holder.F);
244624463a0SJakub Kuderski     EXPECT_TRUE(PDT.verify());
245624463a0SJakub Kuderski 
246624463a0SJakub Kuderski     while (B.applyUpdate())
247624463a0SJakub Kuderski       ;
248624463a0SJakub Kuderski 
249624463a0SJakub Kuderski     auto DomUpdates = ToDomUpdates(B, Updates);
250624463a0SJakub Kuderski     DT.applyUpdates(DomUpdates);
251624463a0SJakub Kuderski     EXPECT_TRUE(DT.verify());
252624463a0SJakub Kuderski     PDT.applyUpdates(DomUpdates);
253624463a0SJakub Kuderski     EXPECT_TRUE(PDT.verify());
254624463a0SJakub Kuderski   }
255624463a0SJakub Kuderski }
256990eb1fcSDavid Green 
257990eb1fcSDavid Green // These are some odd flowgraphs, usually generated from csmith cases,
258990eb1fcSDavid Green // which are difficult on post dom trees.
TEST(DominatorTreeBatchUpdates,InfiniteLoop)259990eb1fcSDavid Green TEST(DominatorTreeBatchUpdates, InfiniteLoop) {
260990eb1fcSDavid Green   std::vector<CFGBuilder::Arc> Arcs = {
261990eb1fcSDavid Green       {"1", "2"},
262990eb1fcSDavid Green       {"2", "3"},
263990eb1fcSDavid Green       {"3", "6"}, {"3", "5"},
264990eb1fcSDavid Green       {"4", "5"},
265990eb1fcSDavid Green       {"5", "2"},
266990eb1fcSDavid Green       {"6", "3"}, {"6", "4"}};
267990eb1fcSDavid Green 
268990eb1fcSDavid Green   // SplitBlock on 3 -> 5
269990eb1fcSDavid Green   std::vector<CFGBuilder::Update> Updates = {
270990eb1fcSDavid Green       {CFGInsert, {"N", "5"}},  {CFGInsert, {"3", "N"}}, {CFGDelete, {"3", "5"}}};
271990eb1fcSDavid Green 
272990eb1fcSDavid Green   CFGHolder Holder;
273990eb1fcSDavid Green   CFGBuilder B(Holder.F, Arcs, Updates);
274990eb1fcSDavid Green   DominatorTree DT(*Holder.F);
275990eb1fcSDavid Green   EXPECT_TRUE(DT.verify());
276ef33edd9SJakub Kuderski   PostDominatorTree PDT(*Holder.F);
277990eb1fcSDavid Green   EXPECT_TRUE(PDT.verify());
278990eb1fcSDavid Green 
279990eb1fcSDavid Green   while (B.applyUpdate())
280990eb1fcSDavid Green     ;
281990eb1fcSDavid Green 
282990eb1fcSDavid Green   auto DomUpdates = ToDomUpdates(B, Updates);
283990eb1fcSDavid Green   DT.applyUpdates(DomUpdates);
284990eb1fcSDavid Green   EXPECT_TRUE(DT.verify());
285990eb1fcSDavid Green   PDT.applyUpdates(DomUpdates);
286990eb1fcSDavid Green   EXPECT_TRUE(PDT.verify());
287990eb1fcSDavid Green }
288990eb1fcSDavid Green 
TEST(DominatorTreeBatchUpdates,DeadBlocks)289990eb1fcSDavid Green TEST(DominatorTreeBatchUpdates, DeadBlocks) {
290990eb1fcSDavid Green   std::vector<CFGBuilder::Arc> Arcs = {
291990eb1fcSDavid Green       {"1", "2"},
292990eb1fcSDavid Green       {"2", "3"},
293990eb1fcSDavid Green       {"3", "4"}, {"3", "7"},
294990eb1fcSDavid Green       {"4", "4"},
295990eb1fcSDavid Green       {"5", "6"}, {"5", "7"},
296990eb1fcSDavid Green       {"6", "7"},
297990eb1fcSDavid Green       {"7", "2"}, {"7", "8"}};
298990eb1fcSDavid Green 
299990eb1fcSDavid Green   // Remove dead 5 and 7,
300990eb1fcSDavid Green   // plus SplitBlock on 7 -> 8
301990eb1fcSDavid Green   std::vector<CFGBuilder::Update> Updates = {
302990eb1fcSDavid Green       {CFGDelete, {"6", "7"}},  {CFGDelete, {"5", "7"}}, {CFGDelete, {"5", "6"}},
303990eb1fcSDavid Green       {CFGInsert, {"N", "8"}},  {CFGInsert, {"7", "N"}}, {CFGDelete, {"7", "8"}}};
304990eb1fcSDavid Green 
305990eb1fcSDavid Green   CFGHolder Holder;
306990eb1fcSDavid Green   CFGBuilder B(Holder.F, Arcs, Updates);
307990eb1fcSDavid Green   DominatorTree DT(*Holder.F);
308990eb1fcSDavid Green   EXPECT_TRUE(DT.verify());
309ef33edd9SJakub Kuderski   PostDominatorTree PDT(*Holder.F);
310990eb1fcSDavid Green   EXPECT_TRUE(PDT.verify());
311990eb1fcSDavid Green 
312990eb1fcSDavid Green   while (B.applyUpdate())
313990eb1fcSDavid Green     ;
314990eb1fcSDavid Green 
315990eb1fcSDavid Green   auto DomUpdates = ToDomUpdates(B, Updates);
316990eb1fcSDavid Green   DT.applyUpdates(DomUpdates);
317990eb1fcSDavid Green   EXPECT_TRUE(DT.verify());
318990eb1fcSDavid Green   PDT.applyUpdates(DomUpdates);
319990eb1fcSDavid Green   EXPECT_TRUE(PDT.verify());
320990eb1fcSDavid Green }
321990eb1fcSDavid Green 
TEST(DominatorTreeBatchUpdates,InfiniteLoop2)322990eb1fcSDavid Green TEST(DominatorTreeBatchUpdates, InfiniteLoop2) {
323990eb1fcSDavid Green   std::vector<CFGBuilder::Arc> Arcs = {
324990eb1fcSDavid Green       {"1", "2"},
325990eb1fcSDavid Green       {"2", "6"}, {"2", "3"},
326990eb1fcSDavid Green       {"3", "4"},
327990eb1fcSDavid Green       {"4", "5"}, {"4", "6"},
328990eb1fcSDavid Green       {"5", "4"},
329990eb1fcSDavid Green       {"6", "2"}};
330990eb1fcSDavid Green 
331990eb1fcSDavid Green   // SplitBlock on 4 -> 6
332990eb1fcSDavid Green   std::vector<CFGBuilder::Update> Updates = {
333990eb1fcSDavid Green       {CFGInsert, {"N", "6"}},  {CFGInsert, {"4", "N"}}, {CFGDelete, {"4", "6"}}};
334990eb1fcSDavid Green 
335990eb1fcSDavid Green   CFGHolder Holder;
336990eb1fcSDavid Green   CFGBuilder B(Holder.F, Arcs, Updates);
337990eb1fcSDavid Green   DominatorTree DT(*Holder.F);
338990eb1fcSDavid Green   EXPECT_TRUE(DT.verify());
339ef33edd9SJakub Kuderski   PostDominatorTree PDT(*Holder.F);
340990eb1fcSDavid Green   EXPECT_TRUE(PDT.verify());
341990eb1fcSDavid Green 
342990eb1fcSDavid Green   while (B.applyUpdate())
343990eb1fcSDavid Green     ;
344990eb1fcSDavid Green 
345990eb1fcSDavid Green   auto DomUpdates = ToDomUpdates(B, Updates);
346990eb1fcSDavid Green   DT.applyUpdates(DomUpdates);
347990eb1fcSDavid Green   EXPECT_TRUE(DT.verify());
348990eb1fcSDavid Green   PDT.applyUpdates(DomUpdates);
349990eb1fcSDavid Green   EXPECT_TRUE(PDT.verify());
350990eb1fcSDavid Green }
351