blob: 2adc09af2c5cec930df25daaf108f3313fdc9a14 [file] [log] [blame]
NAKAMURA Takumiafda71e2013-01-23 08:30:10 +00001//===- llvm/unittests/IR/DominatorTreeTest.cpp - Constants unit tests -----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
Diego Novilloee592422013-12-02 14:08:27 +000010#include "llvm/Analysis/PostDominators.h"
Chandler Carruth9aca9182014-01-07 12:34:26 +000011#include "llvm/AsmParser/Parser.h"
Daniel Berlin8f8174c2015-04-14 19:49:26 +000012#include "llvm/IR/Constants.h"
Adam Nemet7fa6dee2017-05-27 04:05:50 +000013#include "llvm/IR/Dominators.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000014#include "llvm/IR/Instructions.h"
15#include "llvm/IR/LLVMContext.h"
Adam Nemet7fa6dee2017-05-27 04:05:50 +000016#include "llvm/IR/Module.h"
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000017#include "llvm/Support/SourceMgr.h"
Jakub Kuderski13e9ef12017-07-14 21:17:33 +000018#include "CFGBuilder.h"
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000019#include "gtest/gtest.h"
20
21using namespace llvm;
22
Jakub Kuderskib292c222017-07-14 18:26:09 +000023struct PostDomTree : PostDomTreeBase<BasicBlock> {
24 PostDomTree(Function &F) { recalculate(F); }
25};
26
Adam Nemet147ede92017-05-27 04:05:52 +000027/// Build the dominator tree for the function and run the Test.
Jakub Kuderskib292c222017-07-14 18:26:09 +000028static void runWithDomTree(
29 Module &M, StringRef FuncName,
30 function_ref<void(Function &F, DominatorTree *DT, PostDomTree *PDT)> Test) {
Adam Nemet147ede92017-05-27 04:05:52 +000031 auto *F = M.getFunction(FuncName);
32 ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
33 // Compute the dominator tree for the function.
34 DominatorTree DT(*F);
Jakub Kuderskib292c222017-07-14 18:26:09 +000035 PostDomTree PDT(*F);
Adam Nemet147ede92017-05-27 04:05:52 +000036 Test(*F, &DT, &PDT);
37}
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000038
Adam Nemet147ede92017-05-27 04:05:52 +000039static std::unique_ptr<Module> makeLLVMModule(LLVMContext &Context,
40 StringRef ModuleStr) {
41 SMDiagnostic Err;
42 std::unique_ptr<Module> M = parseAssemblyString(ModuleStr, Err, Context);
43 assert(M && "Bad assembly?");
44 return M;
45}
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000046
Adam Nemet147ede92017-05-27 04:05:52 +000047TEST(DominatorTree, Unreachable) {
48 StringRef ModuleString =
Adam Nemet7fa6dee2017-05-27 04:05:50 +000049 "declare i32 @g()\n"
50 "define void @f(i32 %x) personality i32 ()* @g {\n"
51 "bb0:\n"
52 " %y1 = add i32 %x, 1\n"
53 " %y2 = add i32 %x, 1\n"
54 " %y3 = invoke i32 @g() to label %bb1 unwind label %bb2\n"
55 "bb1:\n"
56 " %y4 = add i32 %x, 1\n"
57 " br label %bb4\n"
58 "bb2:\n"
59 " %y5 = landingpad i32\n"
60 " cleanup\n"
61 " br label %bb4\n"
62 "bb3:\n"
63 " %y6 = add i32 %x, 1\n"
64 " %y7 = add i32 %x, 1\n"
65 " ret void\n"
66 "bb4:\n"
67 " %y8 = phi i32 [0, %bb2], [%y4, %bb1]\n"
68 " %y9 = phi i32 [0, %bb2], [%y4, %bb1]\n"
69 " ret void\n"
70 "}\n";
Rafael Espindolaa53c46a2012-03-30 16:46:21 +000071
Adam Nemet147ede92017-05-27 04:05:52 +000072 // Parse the module.
Adam Nemet7fa6dee2017-05-27 04:05:50 +000073 LLVMContext Context;
Adam Nemet147ede92017-05-27 04:05:52 +000074 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
Adam Nemet7fa6dee2017-05-27 04:05:50 +000075
Adam Nemet147ede92017-05-27 04:05:52 +000076 runWithDomTree(
Jakub Kuderskib292c222017-07-14 18:26:09 +000077 *M, "f", [&](Function &F, DominatorTree *DT, PostDomTree *PDT) {
Adam Nemet147ede92017-05-27 04:05:52 +000078 Function::iterator FI = F.begin();
79
80 BasicBlock *BB0 = &*FI++;
81 BasicBlock::iterator BBI = BB0->begin();
82 Instruction *Y1 = &*BBI++;
83 Instruction *Y2 = &*BBI++;
84 Instruction *Y3 = &*BBI++;
85
86 BasicBlock *BB1 = &*FI++;
87 BBI = BB1->begin();
88 Instruction *Y4 = &*BBI++;
89
90 BasicBlock *BB2 = &*FI++;
91 BBI = BB2->begin();
92 Instruction *Y5 = &*BBI++;
93
94 BasicBlock *BB3 = &*FI++;
95 BBI = BB3->begin();
96 Instruction *Y6 = &*BBI++;
97 Instruction *Y7 = &*BBI++;
98
99 BasicBlock *BB4 = &*FI++;
100 BBI = BB4->begin();
101 Instruction *Y8 = &*BBI++;
102 Instruction *Y9 = &*BBI++;
103
104 // Reachability
105 EXPECT_TRUE(DT->isReachableFromEntry(BB0));
106 EXPECT_TRUE(DT->isReachableFromEntry(BB1));
107 EXPECT_TRUE(DT->isReachableFromEntry(BB2));
108 EXPECT_FALSE(DT->isReachableFromEntry(BB3));
109 EXPECT_TRUE(DT->isReachableFromEntry(BB4));
110
111 // BB dominance
112 EXPECT_TRUE(DT->dominates(BB0, BB0));
113 EXPECT_TRUE(DT->dominates(BB0, BB1));
114 EXPECT_TRUE(DT->dominates(BB0, BB2));
115 EXPECT_TRUE(DT->dominates(BB0, BB3));
116 EXPECT_TRUE(DT->dominates(BB0, BB4));
117
118 EXPECT_FALSE(DT->dominates(BB1, BB0));
119 EXPECT_TRUE(DT->dominates(BB1, BB1));
120 EXPECT_FALSE(DT->dominates(BB1, BB2));
121 EXPECT_TRUE(DT->dominates(BB1, BB3));
122 EXPECT_FALSE(DT->dominates(BB1, BB4));
123
124 EXPECT_FALSE(DT->dominates(BB2, BB0));
125 EXPECT_FALSE(DT->dominates(BB2, BB1));
126 EXPECT_TRUE(DT->dominates(BB2, BB2));
127 EXPECT_TRUE(DT->dominates(BB2, BB3));
128 EXPECT_FALSE(DT->dominates(BB2, BB4));
129
130 EXPECT_FALSE(DT->dominates(BB3, BB0));
131 EXPECT_FALSE(DT->dominates(BB3, BB1));
132 EXPECT_FALSE(DT->dominates(BB3, BB2));
133 EXPECT_TRUE(DT->dominates(BB3, BB3));
134 EXPECT_FALSE(DT->dominates(BB3, BB4));
135
136 // BB proper dominance
137 EXPECT_FALSE(DT->properlyDominates(BB0, BB0));
138 EXPECT_TRUE(DT->properlyDominates(BB0, BB1));
139 EXPECT_TRUE(DT->properlyDominates(BB0, BB2));
140 EXPECT_TRUE(DT->properlyDominates(BB0, BB3));
141
142 EXPECT_FALSE(DT->properlyDominates(BB1, BB0));
143 EXPECT_FALSE(DT->properlyDominates(BB1, BB1));
144 EXPECT_FALSE(DT->properlyDominates(BB1, BB2));
145 EXPECT_TRUE(DT->properlyDominates(BB1, BB3));
146
147 EXPECT_FALSE(DT->properlyDominates(BB2, BB0));
148 EXPECT_FALSE(DT->properlyDominates(BB2, BB1));
149 EXPECT_FALSE(DT->properlyDominates(BB2, BB2));
150 EXPECT_TRUE(DT->properlyDominates(BB2, BB3));
151
152 EXPECT_FALSE(DT->properlyDominates(BB3, BB0));
153 EXPECT_FALSE(DT->properlyDominates(BB3, BB1));
154 EXPECT_FALSE(DT->properlyDominates(BB3, BB2));
155 EXPECT_FALSE(DT->properlyDominates(BB3, BB3));
156
157 // Instruction dominance in the same reachable BB
158 EXPECT_FALSE(DT->dominates(Y1, Y1));
159 EXPECT_TRUE(DT->dominates(Y1, Y2));
160 EXPECT_FALSE(DT->dominates(Y2, Y1));
161 EXPECT_FALSE(DT->dominates(Y2, Y2));
162
163 // Instruction dominance in the same unreachable BB
164 EXPECT_TRUE(DT->dominates(Y6, Y6));
165 EXPECT_TRUE(DT->dominates(Y6, Y7));
166 EXPECT_TRUE(DT->dominates(Y7, Y6));
167 EXPECT_TRUE(DT->dominates(Y7, Y7));
168
169 // Invoke
170 EXPECT_TRUE(DT->dominates(Y3, Y4));
171 EXPECT_FALSE(DT->dominates(Y3, Y5));
172
173 // Phi
174 EXPECT_TRUE(DT->dominates(Y2, Y9));
175 EXPECT_FALSE(DT->dominates(Y3, Y9));
176 EXPECT_FALSE(DT->dominates(Y8, Y9));
177
178 // Anything dominates unreachable
179 EXPECT_TRUE(DT->dominates(Y1, Y6));
180 EXPECT_TRUE(DT->dominates(Y3, Y6));
181
182 // Unreachable doesn't dominate reachable
183 EXPECT_FALSE(DT->dominates(Y6, Y1));
184
185 // Instruction, BB dominance
186 EXPECT_FALSE(DT->dominates(Y1, BB0));
187 EXPECT_TRUE(DT->dominates(Y1, BB1));
188 EXPECT_TRUE(DT->dominates(Y1, BB2));
189 EXPECT_TRUE(DT->dominates(Y1, BB3));
190 EXPECT_TRUE(DT->dominates(Y1, BB4));
191
192 EXPECT_FALSE(DT->dominates(Y3, BB0));
193 EXPECT_TRUE(DT->dominates(Y3, BB1));
194 EXPECT_FALSE(DT->dominates(Y3, BB2));
195 EXPECT_TRUE(DT->dominates(Y3, BB3));
196 EXPECT_FALSE(DT->dominates(Y3, BB4));
197
198 EXPECT_TRUE(DT->dominates(Y6, BB3));
199
200 // Post dominance.
201 EXPECT_TRUE(PDT->dominates(BB0, BB0));
202 EXPECT_FALSE(PDT->dominates(BB1, BB0));
203 EXPECT_FALSE(PDT->dominates(BB2, BB0));
204 EXPECT_FALSE(PDT->dominates(BB3, BB0));
205 EXPECT_TRUE(PDT->dominates(BB4, BB1));
206
207 // Dominance descendants.
208 SmallVector<BasicBlock *, 8> DominatedBBs, PostDominatedBBs;
209
210 DT->getDescendants(BB0, DominatedBBs);
211 PDT->getDescendants(BB0, PostDominatedBBs);
212 EXPECT_EQ(DominatedBBs.size(), 4UL);
213 EXPECT_EQ(PostDominatedBBs.size(), 1UL);
214
215 // BB3 is unreachable. It should have no dominators nor postdominators.
216 DominatedBBs.clear();
217 PostDominatedBBs.clear();
218 DT->getDescendants(BB3, DominatedBBs);
219 DT->getDescendants(BB3, PostDominatedBBs);
220 EXPECT_EQ(DominatedBBs.size(), 0UL);
221 EXPECT_EQ(PostDominatedBBs.size(), 0UL);
222
223 // Check DFS Numbers before
Jakub Kuderski837755c2017-06-30 01:28:21 +0000224 DT->updateDFSNumbers();
Adam Nemet147ede92017-05-27 04:05:52 +0000225 EXPECT_EQ(DT->getNode(BB0)->getDFSNumIn(), 0UL);
226 EXPECT_EQ(DT->getNode(BB0)->getDFSNumOut(), 7UL);
227 EXPECT_EQ(DT->getNode(BB1)->getDFSNumIn(), 1UL);
228 EXPECT_EQ(DT->getNode(BB1)->getDFSNumOut(), 2UL);
229 EXPECT_EQ(DT->getNode(BB2)->getDFSNumIn(), 5UL);
230 EXPECT_EQ(DT->getNode(BB2)->getDFSNumOut(), 6UL);
231 EXPECT_EQ(DT->getNode(BB4)->getDFSNumIn(), 3UL);
232 EXPECT_EQ(DT->getNode(BB4)->getDFSNumOut(), 4UL);
233
Jakub Kuderski604a22b2017-07-01 00:23:01 +0000234 // Check levels before
235 EXPECT_EQ(DT->getNode(BB0)->getLevel(), 0U);
236 EXPECT_EQ(DT->getNode(BB1)->getLevel(), 1U);
237 EXPECT_EQ(DT->getNode(BB2)->getLevel(), 1U);
238 EXPECT_EQ(DT->getNode(BB4)->getLevel(), 1U);
239
Adam Nemet147ede92017-05-27 04:05:52 +0000240 // Reattach block 3 to block 1 and recalculate
241 BB1->getTerminator()->eraseFromParent();
242 BranchInst::Create(BB4, BB3, ConstantInt::getTrue(F.getContext()), BB1);
243 DT->recalculate(F);
244
245 // Check DFS Numbers after
Jakub Kuderski837755c2017-06-30 01:28:21 +0000246 DT->updateDFSNumbers();
Adam Nemet147ede92017-05-27 04:05:52 +0000247 EXPECT_EQ(DT->getNode(BB0)->getDFSNumIn(), 0UL);
248 EXPECT_EQ(DT->getNode(BB0)->getDFSNumOut(), 9UL);
249 EXPECT_EQ(DT->getNode(BB1)->getDFSNumIn(), 1UL);
250 EXPECT_EQ(DT->getNode(BB1)->getDFSNumOut(), 4UL);
251 EXPECT_EQ(DT->getNode(BB2)->getDFSNumIn(), 7UL);
252 EXPECT_EQ(DT->getNode(BB2)->getDFSNumOut(), 8UL);
253 EXPECT_EQ(DT->getNode(BB3)->getDFSNumIn(), 2UL);
254 EXPECT_EQ(DT->getNode(BB3)->getDFSNumOut(), 3UL);
255 EXPECT_EQ(DT->getNode(BB4)->getDFSNumIn(), 5UL);
256 EXPECT_EQ(DT->getNode(BB4)->getDFSNumOut(), 6UL);
257
Jakub Kuderski604a22b2017-07-01 00:23:01 +0000258 // Check levels after
259 EXPECT_EQ(DT->getNode(BB0)->getLevel(), 0U);
260 EXPECT_EQ(DT->getNode(BB1)->getLevel(), 1U);
261 EXPECT_EQ(DT->getNode(BB2)->getLevel(), 1U);
262 EXPECT_EQ(DT->getNode(BB3)->getLevel(), 2U);
263 EXPECT_EQ(DT->getNode(BB4)->getLevel(), 1U);
264
Adam Nemet147ede92017-05-27 04:05:52 +0000265 // Change root node
266 DT->verifyDomTree();
267 BasicBlock *NewEntry =
268 BasicBlock::Create(F.getContext(), "new_entry", &F, BB0);
269 BranchInst::Create(BB0, NewEntry);
270 EXPECT_EQ(F.begin()->getName(), NewEntry->getName());
271 EXPECT_TRUE(&F.getEntryBlock() == NewEntry);
272 DT->setNewRoot(NewEntry);
273 DT->verifyDomTree();
274 });
275}
Adam Nemet4ef096b2017-06-05 16:27:09 +0000276
277TEST(DominatorTree, NonUniqueEdges) {
278 StringRef ModuleString =
279 "define i32 @f(i32 %i, i32 *%p) {\n"
280 "bb0:\n"
281 " store i32 %i, i32 *%p\n"
282 " switch i32 %i, label %bb2 [\n"
283 " i32 0, label %bb1\n"
284 " i32 1, label %bb1\n"
285 " ]\n"
286 " bb1:\n"
287 " ret i32 1\n"
288 " bb2:\n"
289 " ret i32 4\n"
290 "}\n";
291
292 // Parse the module.
293 LLVMContext Context;
294 std::unique_ptr<Module> M = makeLLVMModule(Context, ModuleString);
295
296 runWithDomTree(
Jakub Kuderskib292c222017-07-14 18:26:09 +0000297 *M, "f", [&](Function &F, DominatorTree *DT, PostDomTree *PDT) {
Adam Nemet4ef096b2017-06-05 16:27:09 +0000298 Function::iterator FI = F.begin();
299
300 BasicBlock *BB0 = &*FI++;
301 BasicBlock *BB1 = &*FI++;
302 BasicBlock *BB2 = &*FI++;
303
304 const TerminatorInst *TI = BB0->getTerminator();
305 assert(TI->getNumSuccessors() == 3 && "Switch has three successors");
306
307 BasicBlockEdge Edge_BB0_BB2(BB0, TI->getSuccessor(0));
308 assert(Edge_BB0_BB2.getEnd() == BB2 &&
309 "Default label is the 1st successor");
310
311 BasicBlockEdge Edge_BB0_BB1_a(BB0, TI->getSuccessor(1));
312 assert(Edge_BB0_BB1_a.getEnd() == BB1 && "BB1 is the 2nd successor");
313
314 BasicBlockEdge Edge_BB0_BB1_b(BB0, TI->getSuccessor(2));
315 assert(Edge_BB0_BB1_b.getEnd() == BB1 && "BB1 is the 3rd successor");
316
317 EXPECT_TRUE(DT->dominates(Edge_BB0_BB2, BB2));
318 EXPECT_FALSE(DT->dominates(Edge_BB0_BB2, BB1));
319
320 EXPECT_FALSE(DT->dominates(Edge_BB0_BB1_a, BB1));
321 EXPECT_FALSE(DT->dominates(Edge_BB0_BB1_b, BB1));
322
323 EXPECT_FALSE(DT->dominates(Edge_BB0_BB1_a, BB2));
324 EXPECT_FALSE(DT->dominates(Edge_BB0_BB1_b, BB2));
325 });
326}
Jakub Kuderski13e9ef12017-07-14 21:17:33 +0000327
328namespace {
329const auto Insert = CFGBuilder::ActionKind::Insert;
330
331bool CompUpdates(const CFGBuilder::Update &A, const CFGBuilder::Update &B) {
332 return std::tie(A.Action, A.Edge.From, A.Edge.To) <
333 std::tie(B.Action, B.Edge.From, B.Edge.To);
334};
335} // namespace
336
337TEST(DominatorTree, InsertReachable) {
338 CFGHolder Holder;
339 std::vector<CFGBuilder::Arc> Arcs = {
340 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"4", "5"}, {"5", "6"}, {"5", "7"},
341 {"3", "8"}, {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}};
342
343 std::vector<CFGBuilder::Update> Updates = {{Insert, {"12", "10"}},
344 {Insert, {"10", "9"}},
345 {Insert, {"7", "6"}},
346 {Insert, {"7", "5"}}};
347 CFGBuilder B(Holder.F, Arcs, Updates);
348 DominatorTree DT(*Holder.F);
349 EXPECT_TRUE(DT.verify());
350 PostDomTree PDT(*Holder.F);
351 EXPECT_TRUE(PDT.verify());
352
353 Optional<CFGBuilder::Update> LastUpdate;
354 while ((LastUpdate = B.applyUpdate())) {
355 EXPECT_EQ(LastUpdate->Action, Insert);
356 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
357 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
358 DT.insertEdge(From, To);
359 EXPECT_TRUE(DT.verify());
360 PDT.insertEdge(From, To);
361 EXPECT_TRUE(PDT.verify());
362 }
363}
364
365TEST(DominatorTree, InsertUnreachable) {
366 CFGHolder Holder;
367 std::vector<CFGBuilder::Arc> Arcs = {{"1", "2"}, {"2", "3"}, {"3", "4"},
368 {"5", "6"}, {"5", "7"}, {"3", "8"},
369 {"9", "10"}, {"11", "12"}};
370
371 std::vector<CFGBuilder::Update> Updates = {{Insert, {"4", "5"}},
372 {Insert, {"8", "9"}},
373 {Insert, {"10", "12"}},
374 {Insert, {"10", "11"}}};
375 CFGBuilder B(Holder.F, Arcs, Updates);
376 DominatorTree DT(*Holder.F);
377 EXPECT_TRUE(DT.verify());
378 PostDomTree PDT(*Holder.F);
379 EXPECT_TRUE(PDT.verify());
380
381 Optional<CFGBuilder::Update> LastUpdate;
382 while ((LastUpdate = B.applyUpdate())) {
383 EXPECT_EQ(LastUpdate->Action, Insert);
384 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
385 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
386 DT.insertEdge(From, To);
387 EXPECT_TRUE(DT.verify());
388 PDT.insertEdge(From, To);
389 EXPECT_TRUE(PDT.verify());
390 }
391}
392
393TEST(DominatorTree, InsertMixed) {
394 CFGHolder Holder;
395 std::vector<CFGBuilder::Arc> Arcs = {
396 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"5", "6"}, {"5", "7"},
397 {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}, {"7", "3"}};
398
399 std::vector<CFGBuilder::Update> Updates = {
400 {Insert, {"4", "5"}}, {Insert, {"2", "5"}}, {Insert, {"10", "9"}},
401 {Insert, {"12", "10"}}, {Insert, {"12", "10"}}, {Insert, {"7", "8"}},
402 {Insert, {"7", "5"}}};
403 CFGBuilder B(Holder.F, Arcs, Updates);
404 DominatorTree DT(*Holder.F);
405 EXPECT_TRUE(DT.verify());
406 PostDomTree PDT(*Holder.F);
407 EXPECT_TRUE(PDT.verify());
408
409 Optional<CFGBuilder::Update> LastUpdate;
410 while ((LastUpdate = B.applyUpdate())) {
411 EXPECT_EQ(LastUpdate->Action, Insert);
412 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
413 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
414 DT.insertEdge(From, To);
415 EXPECT_TRUE(DT.verify());
416 PDT.insertEdge(From, To);
417 EXPECT_TRUE(PDT.verify());
418 }
419}
420
421TEST(DominatorTree, InsertPermut) {
422 std::vector<CFGBuilder::Arc> Arcs = {
423 {"1", "2"}, {"2", "3"}, {"3", "4"}, {"5", "6"}, {"5", "7"},
424 {"8", "9"}, {"9", "10"}, {"8", "11"}, {"11", "12"}, {"7", "3"}};
425
426 std::vector<CFGBuilder::Update> Updates = {{Insert, {"4", "5"}},
427 {Insert, {"2", "5"}},
428 {Insert, {"10", "9"}},
429 {Insert, {"12", "10"}}};
430
431 while (std::next_permutation(Updates.begin(), Updates.end(), CompUpdates)) {
432 CFGHolder Holder;
433 CFGBuilder B(Holder.F, Arcs, Updates);
434 DominatorTree DT(*Holder.F);
435 EXPECT_TRUE(DT.verify());
436 PostDomTree PDT(*Holder.F);
437 EXPECT_TRUE(PDT.verify());
438
439 Optional<CFGBuilder::Update> LastUpdate;
440 while ((LastUpdate = B.applyUpdate())) {
441 EXPECT_EQ(LastUpdate->Action, Insert);
442 BasicBlock *From = B.getOrAddBlock(LastUpdate->Edge.From);
443 BasicBlock *To = B.getOrAddBlock(LastUpdate->Edge.To);
444 DT.insertEdge(From, To);
445 EXPECT_TRUE(DT.verify());
446 PDT.insertEdge(From, To);
447 EXPECT_TRUE(PDT.verify());
448 }
449 }
450}