llvm.org GIT mirror llvm / 6d979ae
[Dominators] Fix some edge cases for PostDomTree updating These fix some odd cfg cases where batch-updating the post dom tree fails. Usually around infinite loops and roots ending up being different. Differential Revision: https://reviews.llvm.org/D42247 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@323034 91177308-0d34-0410-b5e6-96231b3b80d8 David Green 2 years ago
2 changed file(s) with 111 addition(s) and 16 deletion(s). Raw diff Collapse all Expand all
705705 // algorithm does not really know or use the set of roots and can make a
706706 // different (implicit) decision about which nodes within an infinite loop
707707 // becomes a root.
708 if (DT.isVirtualRoot(TN->getIDom())) {
708 if (TN && !DT.isVirtualRoot(TN->getIDom())) {
709709 DEBUG(dbgs() << "Root " << BlockNamePrinter(R)
710710 << " is not virtual root's child\n"
711711 << "The entire tree needs to be rebuilt\n");
939939 const NodePtr NCDBlock = DT.findNearestCommonDominator(From, To);
940940 const TreeNodePtr NCD = DT.getNode(NCDBlock);
941941
942 // To dominates From -- nothing to do.
943 if (ToTN == NCD) return;
944
945 DT.DFSInfoValid = false;
946
947 const TreeNodePtr ToIDom = ToTN->getIDom();
948 DEBUG(dbgs() << "\tNCD " << BlockNamePrinter(NCD) << ", ToIDom "
949 << BlockNamePrinter(ToIDom) << "\n");
950
951 // To remains reachable after deletion.
952 // (Based on the caption under Figure 4. from the second paper.)
953 if (FromTN != ToIDom || HasProperSupport(DT, BUI, ToTN))
954 DeleteReachable(DT, BUI, FromTN, ToTN);
955 else
956 DeleteUnreachable(DT, BUI, ToTN);
942 // If To dominates From -- nothing to do.
943 if (ToTN != NCD) {
944 DT.DFSInfoValid = false;
945
946 const TreeNodePtr ToIDom = ToTN->getIDom();
947 DEBUG(dbgs() << "\tNCD " << BlockNamePrinter(NCD) << ", ToIDom "
948 << BlockNamePrinter(ToIDom) << "\n");
949
950 // To remains reachable after deletion.
951 // (Based on the caption under Figure 4. from the second paper.)
952 if (FromTN != ToIDom || HasProperSupport(DT, BUI, ToTN))
953 DeleteReachable(DT, BUI, FromTN, ToTN);
954 else
955 DeleteUnreachable(DT, BUI, ToTN);
956 }
957957
958958 if (IsPostDom) UpdateRootsAfterUpdate(DT, BUI);
959959 }
257257 EXPECT_TRUE(PDT.verify());
258258 }
259259 }
260
261 // These are some odd flowgraphs, usually generated from csmith cases,
262 // which are difficult on post dom trees.
263 TEST(DominatorTreeBatchUpdates, InfiniteLoop) {
264 std::vector Arcs = {
265 {"1", "2"},
266 {"2", "3"},
267 {"3", "6"}, {"3", "5"},
268 {"4", "5"},
269 {"5", "2"},
270 {"6", "3"}, {"6", "4"}};
271
272 // SplitBlock on 3 -> 5
273 std::vector Updates = {
274 {CFGInsert, {"N", "5"}}, {CFGInsert, {"3", "N"}}, {CFGDelete, {"3", "5"}}};
275
276 CFGHolder Holder;
277 CFGBuilder B(Holder.F, Arcs, Updates);
278 DominatorTree DT(*Holder.F);
279 EXPECT_TRUE(DT.verify());
280 PostDomTree PDT(*Holder.F);
281 EXPECT_TRUE(PDT.verify());
282
283 while (B.applyUpdate())
284 ;
285
286 auto DomUpdates = ToDomUpdates(B, Updates);
287 DT.applyUpdates(DomUpdates);
288 EXPECT_TRUE(DT.verify());
289 PDT.applyUpdates(DomUpdates);
290 EXPECT_TRUE(PDT.verify());
291 }
292
293 TEST(DominatorTreeBatchUpdates, DeadBlocks) {
294 std::vector Arcs = {
295 {"1", "2"},
296 {"2", "3"},
297 {"3", "4"}, {"3", "7"},
298 {"4", "4"},
299 {"5", "6"}, {"5", "7"},
300 {"6", "7"},
301 {"7", "2"}, {"7", "8"}};
302
303 // Remove dead 5 and 7,
304 // plus SplitBlock on 7 -> 8
305 std::vector Updates = {
306 {CFGDelete, {"6", "7"}}, {CFGDelete, {"5", "7"}}, {CFGDelete, {"5", "6"}},
307 {CFGInsert, {"N", "8"}}, {CFGInsert, {"7", "N"}}, {CFGDelete, {"7", "8"}}};
308
309 CFGHolder Holder;
310 CFGBuilder B(Holder.F, Arcs, Updates);
311 DominatorTree DT(*Holder.F);
312 EXPECT_TRUE(DT.verify());
313 PostDomTree PDT(*Holder.F);
314 EXPECT_TRUE(PDT.verify());
315
316 while (B.applyUpdate())
317 ;
318
319 auto DomUpdates = ToDomUpdates(B, Updates);
320 DT.applyUpdates(DomUpdates);
321 EXPECT_TRUE(DT.verify());
322 PDT.applyUpdates(DomUpdates);
323 EXPECT_TRUE(PDT.verify());
324 }
325
326 TEST(DominatorTreeBatchUpdates, InfiniteLoop2) {
327 std::vector Arcs = {
328 {"1", "2"},
329 {"2", "6"}, {"2", "3"},
330 {"3", "4"},
331 {"4", "5"}, {"4", "6"},
332 {"5", "4"},
333 {"6", "2"}};
334
335 // SplitBlock on 4 -> 6
336 std::vector Updates = {
337 {CFGInsert, {"N", "6"}}, {CFGInsert, {"4", "N"}}, {CFGDelete, {"4", "6"}}};
338
339 CFGHolder Holder;
340 CFGBuilder B(Holder.F, Arcs, Updates);
341 DominatorTree DT(*Holder.F);
342 EXPECT_TRUE(DT.verify());
343 PostDomTree PDT(*Holder.F);
344 EXPECT_TRUE(PDT.verify());
345
346 while (B.applyUpdate())
347 ;
348
349 auto DomUpdates = ToDomUpdates(B, Updates);
350 DT.applyUpdates(DomUpdates);
351 EXPECT_TRUE(DT.verify());
352 PDT.applyUpdates(DomUpdates);
353 EXPECT_TRUE(PDT.verify());
354 }