llvm.org GIT mirror llvm / 8d72e72
Merging r322993: ------------------------------------------------------------------------ r322993 | kuhar | 2018-01-19 22:27:24 +0100 (Fri, 19 Jan 2018) | 16 lines [Dominators] Visit affected node candidates found at different root levels Summary: This patch attempts to fix the DomTree incremental insertion bug found here [[ https://bugs.llvm.org/show_bug.cgi?id=35969 | PR35969 ]] . When performing an insertion into a piece of unreachable CFG, we may find the same not at different levels. When this happens, the node can turn out to be affected when we find it starting from a node with a lower level in the tree. The level at which we start visitation affects if we consider a node affected or not. This patch tracks the lowest level at which each node was visited during insertion and allows it to be visited multiple times, if it can cause it to be considered affected. Reviewers: brzycki, davide, dberlin, grosser Reviewed By: brzycki Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D42231 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_60@323110 91177308-0d34-0410-b5e6-96231b3b80d8 Hans Wennborg 1 year, 7 months ago
4 changed file(s) with 172 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
627627 DecreasingLevel>
628628 Bucket; // Queue of tree nodes sorted by level in descending order.
629629 SmallDenseSet Affected;
630 SmallDenseSet, 8> Visited;
630 SmallDenseMap, 8> Visited;
631631 SmallVector AffectedQueue;
632632 SmallVector VisitedNotAffectedQueue;
633633 };
752752
753753 while (!II.Bucket.empty()) {
754754 const TreeNodePtr CurrentNode = II.Bucket.top().second;
755 const unsigned CurrentLevel = CurrentNode->getLevel();
755756 II.Bucket.pop();
756757 DEBUG(dbgs() << "\tAdding to Visited and AffectedQueue: "
757758 << BlockNamePrinter(CurrentNode) << "\n");
758 II.Visited.insert(CurrentNode);
759
760 II.Visited.insert({CurrentNode, CurrentLevel});
759761 II.AffectedQueue.push_back(CurrentNode);
760762
761763 // Discover and collect affected successors of the current node.
762 VisitInsertion(DT, BUI, CurrentNode, CurrentNode->getLevel(), NCD, II);
764 VisitInsertion(DT, BUI, CurrentNode, CurrentLevel, NCD, II);
763765 }
764766
765767 // Finish by updating immediate dominators and levels.
771773 const TreeNodePtr TN, const unsigned RootLevel,
772774 const TreeNodePtr NCD, InsertionInfo &II) {
773775 const unsigned NCDLevel = NCD->getLevel();
774 DEBUG(dbgs() << "Visiting " << BlockNamePrinter(TN) << "\n");
776 DEBUG(dbgs() << "Visiting " << BlockNamePrinter(TN) << ", RootLevel "
777 << RootLevel << "\n");
775778
776779 SmallVector Stack = {TN};
777780 assert(TN->getBlock() && II.Visited.count(TN) && "Preconditions!");
778781
782 SmallPtrSet Processed;
783
779784 do {
780785 TreeNodePtr Next = Stack.pop_back_val();
786 DEBUG(dbgs() << " Next: " << BlockNamePrinter(Next) << "\n");
781787
782788 for (const NodePtr Succ :
783789 ChildrenGetter::Get(Next->getBlock(), BUI)) {
785791 assert(SuccTN && "Unreachable successor found at reachable insertion");
786792 const unsigned SuccLevel = SuccTN->getLevel();
787793
788 DEBUG(dbgs() << "\tSuccessor " << BlockNamePrinter(Succ)
789 << ", level = " << SuccLevel << "\n");
794 DEBUG(dbgs() << "\tSuccessor " << BlockNamePrinter(Succ) << ", level = "
795 << SuccLevel << "\n");
796
797 // Do not process the same node multiple times.
798 if (Processed.count(Next) > 0)
799 continue;
790800
791801 // Succ dominated by subtree From -- not affected.
792802 // (Based on the lemma 2.5 from the second paper.)
793803 if (SuccLevel > RootLevel) {
794804 DEBUG(dbgs() << "\t\tDominated by subtree From\n");
795 if (II.Visited.count(SuccTN) != 0)
796 continue;
805 if (II.Visited.count(SuccTN) != 0) {
806 DEBUG(dbgs() << "\t\t\talready visited at level "
807 << II.Visited[SuccTN] << "\n\t\t\tcurrent level "
808 << RootLevel << ")\n");
809
810 // A node can be necessary to visit again if we see it again at
811 // a lower level than before.
812 if (II.Visited[SuccTN] >= RootLevel)
813 continue;
814 }
797815
798816 DEBUG(dbgs() << "\t\tMarking visited not affected "
799817 << BlockNamePrinter(Succ) << "\n");
800 II.Visited.insert(SuccTN);
818 II.Visited.insert({SuccTN, RootLevel});
801819 II.VisitedNotAffectedQueue.push_back(SuccTN);
802820 Stack.push_back(SuccTN);
803821 } else if ((SuccLevel > NCDLevel + 1) &&
808826 II.Bucket.push({SuccLevel, SuccTN});
809827 }
810828 }
829
830 Processed.insert(Next);
811831 } while (!Stack.empty());
812832 }
813833
0 ; RUN: opt < %s -jump-threading -disable-output -verify-dom-info
1
2 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
3 target triple = "x86_64-unknown-linux-gnu"
4
5 @global = external local_unnamed_addr global i64, align 8
6 @global.1 = external local_unnamed_addr global i64, align 8
7 @global.2 = external local_unnamed_addr global i64, align 8
8
9 ; Function Attrs: norecurse noreturn nounwind uwtable
10 define void @hoge() local_unnamed_addr #0 {
11 bb:
12 br label %bb1
13
14 bb1: ; preds = %bb26, %bb
15 %tmp = load i64, i64* @global, align 8, !tbaa !1
16 %tmp2 = icmp eq i64 %tmp, 0
17 br i1 %tmp2, label %bb27, label %bb3
18
19 bb3: ; preds = %bb1
20 %tmp4 = load i64, i64* @global.1, align 8, !tbaa !1
21 %tmp5 = icmp eq i64 %tmp4, 0
22 br i1 %tmp5, label %bb23, label %bb23
23
24 bb23: ; preds = %bb3, %bb3
25 br label %bb26
26
27 bb26: ; preds = %bb27, %bb23
28 br label %bb1
29
30 bb27: ; preds = %bb1
31 br label %bb26
32 }
33
34 attributes #0 = { norecurse noreturn nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
35
36 !llvm.ident = !{!0}
37
38 !0 = !{!"clang version 7.0.0 "}
39 !1 = !{!2, !2, i64 0}
40 !2 = !{!"long", !3, i64 0}
41 !3 = !{!"omnipotent char", !4, i64 0}
42 !4 = !{!"Simple C/C++ TBAA"}
0 ; RUN: opt < %s -jump-threading -disable-output -verify-dom-info
1 @global = external global i64, align 8
2
3 define void @f() {
4 bb:
5 br label %bb1
6
7 bb1:
8 %tmp = load i64, i64* @global, align 8
9 %tmp2 = icmp eq i64 %tmp, 0
10 br i1 %tmp2, label %bb27, label %bb3
11
12 bb3:
13 %tmp4 = load i64, i64* @global, align 8
14 %tmp5 = icmp eq i64 %tmp4, 0
15 br i1 %tmp5, label %bb6, label %bb7
16
17 bb6:
18 br label %bb7
19
20 bb7:
21 %tmp8 = phi i1 [ true, %bb3 ], [ undef, %bb6 ]
22 %tmp9 = select i1 %tmp8, i64 %tmp4, i64 0
23 br i1 false, label %bb10, label %bb23
24
25 bb10:
26 %tmp11 = load i64, i64* @global, align 8
27 %tmp12 = icmp slt i64 %tmp11, 5
28 br i1 %tmp12, label %bb13, label %bb17
29
30 bb13:
31 br label %bb14
32
33 bb14:
34 br i1 undef, label %bb15, label %bb16
35
36 bb15:
37 unreachable
38
39 bb16:
40 br label %bb10
41
42 bb17:
43 br label %bb18
44
45 bb18:
46 br i1 undef, label %bb22, label %bb13
47
48 bb19:
49 br i1 undef, label %bb20, label %bb21
50
51 bb20:
52 unreachable
53
54 bb21:
55 br label %bb18
56
57 bb22:
58 br label %bb23
59
60 bb23:
61 br i1 undef, label %bb24, label %bb13
62
63 bb24:
64 br i1 undef, label %bb26, label %bb25
65
66 bb25:
67 br label %bb19
68
69 bb26:
70 br label %bb1
71
72 bb27:
73 br label %bb24
74 }
924924 }
925925 }
926926 }
927
928 TEST(DominatorTree, InsertIntoIrreducible) {
929 std::vector Arcs = {
930 {"0", "1"},
931 {"1", "27"}, {"1", "7"},
932 {"10", "18"},
933 {"13", "10"},
934 {"18", "13"}, {"18", "23"},
935 {"23", "13"}, {"23", "24"},
936 {"24", "1"}, {"24", "18"},
937 {"27", "24"}};
938
939 CFGHolder Holder;
940 CFGBuilder B(Holder.F, Arcs, {{Insert, {"7", "23"}}});
941 DominatorTree DT(*Holder.F);
942 EXPECT_TRUE(DT.verify());
943
944 B.applyUpdate();
945 BasicBlock *From = B.getOrAddBlock("7");
946 BasicBlock *To = B.getOrAddBlock("23");
947 DT.insertEdge(From, To);
948
949 EXPECT_TRUE(DT.verify());
950 }
951