/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/include/llvm/Support/GenericDomTreeConstruction.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- GenericDomTreeConstruction.h - Dominator Calculation ------*- C++ -*-==// |
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 | | /// \file |
10 | | /// |
11 | | /// Generic dominator tree construction - This file provides routines to |
12 | | /// construct immediate dominator information for a flow-graph based on the |
13 | | /// Semi-NCA algorithm described in this dissertation: |
14 | | /// |
15 | | /// Linear-Time Algorithms for Dominators and Related Problems |
16 | | /// Loukas Georgiadis, Princeton University, November 2005, pp. 21-23: |
17 | | /// ftp://ftp.cs.princeton.edu/reports/2005/737.pdf |
18 | | /// |
19 | | /// This implements the O(n*log(n)) versions of EVAL and LINK, because it turns |
20 | | /// out that the theoretically slower O(n*log(n)) implementation is actually |
21 | | /// faster than the almost-linear O(n*alpha(n)) version, even for large CFGs. |
22 | | /// |
23 | | /// The file uses the Depth Based Search algorithm to perform incremental |
24 | | /// updates (insertion and deletions). The implemented algorithm is based on |
25 | | /// this publication: |
26 | | /// |
27 | | /// An Experimental Study of Dynamic Dominators |
28 | | /// Loukas Georgiadis, et al., April 12 2016, pp. 5-7, 9-10: |
29 | | /// https://arxiv.org/pdf/1604.02711.pdf |
30 | | /// |
31 | | //===----------------------------------------------------------------------===// |
32 | | |
33 | | #ifndef LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H |
34 | | #define LLVM_SUPPORT_GENERICDOMTREECONSTRUCTION_H |
35 | | |
36 | | #include <queue> |
37 | | #include "llvm/ADT/ArrayRef.h" |
38 | | #include "llvm/ADT/DenseSet.h" |
39 | | #include "llvm/ADT/DepthFirstIterator.h" |
40 | | #include "llvm/ADT/PointerIntPair.h" |
41 | | #include "llvm/ADT/SmallPtrSet.h" |
42 | | #include "llvm/Support/Debug.h" |
43 | | #include "llvm/Support/GenericDomTree.h" |
44 | | |
45 | | #define DEBUG_TYPE "dom-tree-builder" |
46 | | |
47 | | namespace llvm { |
48 | | namespace DomTreeBuilder { |
49 | | |
50 | | template <typename DomTreeT> |
51 | | struct SemiNCAInfo { |
52 | | using NodePtr = typename DomTreeT::NodePtr; |
53 | | using NodeT = typename DomTreeT::NodeType; |
54 | | using TreeNodePtr = DomTreeNodeBase<NodeT> *; |
55 | | using RootsT = decltype(DomTreeT::Roots); |
56 | | static constexpr bool IsPostDom = DomTreeT::IsPostDominator; |
57 | | |
58 | | // Information record used by Semi-NCA during tree construction. |
59 | | struct InfoRec { |
60 | | unsigned DFSNum = 0; |
61 | | unsigned Parent = 0; |
62 | | unsigned Semi = 0; |
63 | | NodePtr Label = nullptr; |
64 | | NodePtr IDom = nullptr; |
65 | | SmallVector<NodePtr, 2> ReverseChildren; |
66 | | }; |
67 | | |
68 | | // Number to node mapping is 1-based. Initialize the mapping to start with |
69 | | // a dummy element. |
70 | | std::vector<NodePtr> NumToNode = {nullptr}; |
71 | | DenseMap<NodePtr, InfoRec> NodeToInfo; |
72 | | |
73 | | using UpdateT = typename DomTreeT::UpdateType; |
74 | | struct BatchUpdateInfo { |
75 | | SmallVector<UpdateT, 4> Updates; |
76 | | using NodePtrAndKind = PointerIntPair<NodePtr, 1, UpdateKind>; |
77 | | |
78 | | // In order to be able to walk a CFG that is out of sync with the CFG |
79 | | // DominatorTree last knew about, use the list of updates to reconstruct |
80 | | // previous CFG versions of the current CFG. For each node, we store a set |
81 | | // of its virtually added/deleted future successors and predecessors. |
82 | | // Note that these children are from the future relative to what the |
83 | | // DominatorTree knows about -- using them to gets us some snapshot of the |
84 | | // CFG from the past (relative to the state of the CFG). |
85 | | DenseMap<NodePtr, SmallDenseSet<NodePtrAndKind, 4>> FutureSuccessors; |
86 | | DenseMap<NodePtr, SmallDenseSet<NodePtrAndKind, 4>> FuturePredecessors; |
87 | | // Remembers if the whole tree was recalculated at some point during the |
88 | | // current batch update. |
89 | | bool IsRecalculated = false; |
90 | | }; |
91 | | |
92 | | BatchUpdateInfo *BatchUpdates; |
93 | | using BatchUpdatePtr = BatchUpdateInfo *; |
94 | | |
95 | | // If BUI is a nullptr, then there's no batch update in progress. |
96 | 21.5M | SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {} llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::SemiNCAInfo(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*) Line | Count | Source | 96 | 3.66M | SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {} |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::SemiNCAInfo(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*) Line | Count | Source | 96 | 3.56M | SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {} |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::SemiNCAInfo(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*) Line | Count | Source | 96 | 13.1M | SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {} |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::SemiNCAInfo(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*) Line | Count | Source | 96 | 1.16M | SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {} |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::SemiNCAInfo(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::BatchUpdateInfo*) Line | Count | Source | 96 | 5 | SemiNCAInfo(BatchUpdatePtr BUI) : BatchUpdates(BUI) {} |
|
97 | | |
98 | 277k | void clear() { |
99 | 277k | NumToNode = {nullptr}; // Restore to initial state with a dummy start node. |
100 | 277k | NodeToInfo.clear(); |
101 | 277k | // Don't reset the pointer to BatchUpdateInfo here -- if there's an update |
102 | 277k | // in progress, we need this information to continue it. |
103 | 277k | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::clear() llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::clear() Line | Count | Source | 98 | 1.10k | void clear() { | 99 | 1.10k | NumToNode = {nullptr}; // Restore to initial state with a dummy start node. | 100 | 1.10k | NodeToInfo.clear(); | 101 | 1.10k | // Don't reset the pointer to BatchUpdateInfo here -- if there's an update | 102 | 1.10k | // in progress, we need this information to continue it. | 103 | 1.10k | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::clear() Line | Count | Source | 98 | 4.49k | void clear() { | 99 | 4.49k | NumToNode = {nullptr}; // Restore to initial state with a dummy start node. | 100 | 4.49k | NodeToInfo.clear(); | 101 | 4.49k | // Don't reset the pointer to BatchUpdateInfo here -- if there's an update | 102 | 4.49k | // in progress, we need this information to continue it. | 103 | 4.49k | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::clear() Line | Count | Source | 98 | 271k | void clear() { | 99 | 271k | NumToNode = {nullptr}; // Restore to initial state with a dummy start node. | 100 | 271k | NodeToInfo.clear(); | 101 | 271k | // Don't reset the pointer to BatchUpdateInfo here -- if there's an update | 102 | 271k | // in progress, we need this information to continue it. | 103 | 271k | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::clear() |
104 | | |
105 | | template <bool Inverse> |
106 | | struct ChildrenGetter { |
107 | | using ResultTy = SmallVector<NodePtr, 8>; |
108 | | |
109 | 163M | static ResultTy Get(NodePtr N, std::integral_constant<bool, false>) { |
110 | 163M | auto RChildren = reverse(children<NodePtr>(N)); |
111 | 163M | return ResultTy(RChildren.begin(), RChildren.end()); |
112 | 163M | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ChildrenGetter<false>::Get(llvm::BasicBlock*, std::__1::integral_constant<bool, false>) Line | Count | Source | 109 | 4.01M | static ResultTy Get(NodePtr N, std::integral_constant<bool, false>) { | 110 | 4.01M | auto RChildren = reverse(children<NodePtr>(N)); | 111 | 4.01M | return ResultTy(RChildren.begin(), RChildren.end()); | 112 | 4.01M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ChildrenGetter<false>::Get(llvm::MachineBasicBlock*, std::__1::integral_constant<bool, false>) Line | Count | Source | 109 | 12.5M | static ResultTy Get(NodePtr N, std::integral_constant<bool, false>) { | 110 | 12.5M | auto RChildren = reverse(children<NodePtr>(N)); | 111 | 12.5M | return ResultTy(RChildren.begin(), RChildren.end()); | 112 | 12.5M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ChildrenGetter<false>::Get(llvm::MachineBasicBlock*, std::__1::integral_constant<bool, false>) Line | Count | Source | 109 | 23.8M | static ResultTy Get(NodePtr N, std::integral_constant<bool, false>) { | 110 | 23.8M | auto RChildren = reverse(children<NodePtr>(N)); | 111 | 23.8M | return ResultTy(RChildren.begin(), RChildren.end()); | 112 | 23.8M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ChildrenGetter<false>::Get(llvm::BasicBlock*, std::__1::integral_constant<bool, false>) Line | Count | Source | 109 | 122M | static ResultTy Get(NodePtr N, std::integral_constant<bool, false>) { | 110 | 122M | auto RChildren = reverse(children<NodePtr>(N)); | 111 | 122M | return ResultTy(RChildren.begin(), RChildren.end()); | 112 | 122M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::ChildrenGetter<false>::Get(clang::CFGBlock*, std::__1::integral_constant<bool, false>) Line | Count | Source | 109 | 52 | static ResultTy Get(NodePtr N, std::integral_constant<bool, false>) { | 110 | 52 | auto RChildren = reverse(children<NodePtr>(N)); | 111 | 52 | return ResultTy(RChildren.begin(), RChildren.end()); | 112 | 52 | } |
|
113 | | |
114 | 33.7M | static ResultTy Get(NodePtr N, std::integral_constant<bool, true>) { |
115 | 33.7M | auto IChildren = inverse_children<NodePtr>(N); |
116 | 33.7M | return ResultTy(IChildren.begin(), IChildren.end()); |
117 | 33.7M | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ChildrenGetter<true>::Get(llvm::MachineBasicBlock*, std::__1::integral_constant<bool, true>) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ChildrenGetter<true>::Get(llvm::MachineBasicBlock*, std::__1::integral_constant<bool, true>) Line | Count | Source | 114 | 25.1M | static ResultTy Get(NodePtr N, std::integral_constant<bool, true>) { | 115 | 25.1M | auto IChildren = inverse_children<NodePtr>(N); | 116 | 25.1M | return ResultTy(IChildren.begin(), IChildren.end()); | 117 | 25.1M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ChildrenGetter<true>::Get(llvm::BasicBlock*, std::__1::integral_constant<bool, true>) Line | Count | Source | 114 | 8.05M | static ResultTy Get(NodePtr N, std::integral_constant<bool, true>) { | 115 | 8.05M | auto IChildren = inverse_children<NodePtr>(N); | 116 | 8.05M | return ResultTy(IChildren.begin(), IChildren.end()); | 117 | 8.05M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ChildrenGetter<true>::Get(llvm::BasicBlock*, std::__1::integral_constant<bool, true>) Line | Count | Source | 114 | 590k | static ResultTy Get(NodePtr N, std::integral_constant<bool, true>) { | 115 | 590k | auto IChildren = inverse_children<NodePtr>(N); | 116 | 590k | return ResultTy(IChildren.begin(), IChildren.end()); | 117 | 590k | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::ChildrenGetter<true>::Get(clang::CFGBlock*, std::__1::integral_constant<bool, true>) |
118 | | |
119 | | using Tag = std::integral_constant<bool, Inverse>; |
120 | | |
121 | | // The function below is the core part of the batch updater. It allows the |
122 | | // Depth Based Search algorithm to perform incremental updates in lockstep |
123 | | // with updates to the CFG. We emulated lockstep CFG updates by getting its |
124 | | // next snapshots by reverse-applying future updates. |
125 | 196M | static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) { |
126 | 196M | ResultTy Res = Get(N, Tag()); |
127 | 196M | // If there's no batch update in progress, simply return node's children. |
128 | 196M | if (!BUI196M ) return Res176M ; |
129 | 196M | |
130 | 196M | // CFG children are actually its *most current* children, and we have to |
131 | 196M | // reverse-apply the future updates to get the node's children at the |
132 | 196M | // point in time the update was performed. |
133 | 20.4M | auto &FutureChildren = (Inverse != IsPostDom) ? 20.4M BUI->FuturePredecessors527k |
134 | 19.9M | : BUI->FutureSuccessors; |
135 | 20.4M | auto FCIt = FutureChildren.find(N); |
136 | 20.4M | if (FCIt == FutureChildren.end()20.4M ) return Res19.1M ; |
137 | 20.4M | |
138 | 1.29M | for (auto ChildAndKind : FCIt->second) 1.29M { |
139 | 1.68M | const NodePtr Child = ChildAndKind.getPointer(); |
140 | 1.68M | const UpdateKind UK = ChildAndKind.getInt(); |
141 | 1.68M | |
142 | 1.68M | // Reverse-apply the future update. |
143 | 1.68M | if (UK == UpdateKind::Insert1.68M ) { |
144 | 790k | // If there's an insertion in the future, it means that the edge must |
145 | 790k | // exist in the current CFG, but was not present in it before. |
146 | 790k | assert(llvm::find(Res, Child) != Res.end() |
147 | 790k | && "Expected child not found in the CFG"); |
148 | 790k | Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end()); |
149 | 790k | DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> " |
150 | 790k | << BlockNamePrinter(Child) << "\n"); |
151 | 1.68M | } else { |
152 | 892k | // If there's an deletion in the future, it means that the edge cannot |
153 | 892k | // exist in the current CFG, but existed in it before. |
154 | 892k | assert(llvm::find(Res, Child) == Res.end() && |
155 | 892k | "Unexpected child found in the CFG"); |
156 | 892k | DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N) |
157 | 892k | << " -> " << BlockNamePrinter(Child) << "\n"); |
158 | 892k | Res.push_back(Child); |
159 | 892k | } |
160 | 1.68M | } |
161 | 1.29M | |
162 | 1.29M | return Res; |
163 | 196M | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ChildrenGetter<true>::Get(llvm::MachineBasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*) Line | Count | Source | 125 | 25.1M | static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) { | 126 | 25.1M | ResultTy Res = Get(N, Tag()); | 127 | 25.1M | // If there's no batch update in progress, simply return node's children. | 128 | 25.1M | if (!BUI25.1M ) return Res25.1M ; | 129 | 25.1M | | 130 | 25.1M | // CFG children are actually its *most current* children, and we have to | 131 | 25.1M | // reverse-apply the future updates to get the node's children at the | 132 | 25.1M | // point in time the update was performed. | 133 | 12 | auto &FutureChildren = (Inverse != IsPostDom) ? 12 BUI->FuturePredecessors0 | 134 | 12 | : BUI->FutureSuccessors; | 135 | 12 | auto FCIt = FutureChildren.find(N); | 136 | 12 | if (FCIt == FutureChildren.end()12 ) return Res0 ; | 137 | 12 | | 138 | 12 | for (auto ChildAndKind : FCIt->second) 12 { | 139 | 0 | const NodePtr Child = ChildAndKind.getPointer(); | 140 | 0 | const UpdateKind UK = ChildAndKind.getInt(); | 141 | 0 |
| 142 | 0 | // Reverse-apply the future update. | 143 | 0 | if (UK == UpdateKind::Insert0 ) { | 144 | 0 | // If there's an insertion in the future, it means that the edge must | 145 | 0 | // exist in the current CFG, but was not present in it before. | 146 | 0 | assert(llvm::find(Res, Child) != Res.end() | 147 | 0 | && "Expected child not found in the CFG"); | 148 | 0 | Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end()); | 149 | 0 | DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> " | 150 | 0 | << BlockNamePrinter(Child) << "\n"); | 151 | 0 | } else { | 152 | 0 | // If there's an deletion in the future, it means that the edge cannot | 153 | 0 | // exist in the current CFG, but existed in it before. | 154 | 0 | assert(llvm::find(Res, Child) == Res.end() && | 155 | 0 | "Unexpected child found in the CFG"); | 156 | 0 | DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N) | 157 | 0 | << " -> " << BlockNamePrinter(Child) << "\n"); | 158 | 0 | Res.push_back(Child); | 159 | 0 | } | 160 | 0 | } | 161 | 12 | | 162 | 12 | return Res; | 163 | 25.1M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ChildrenGetter<false>::Get(llvm::MachineBasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*) Line | Count | Source | 125 | 23.8M | static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) { | 126 | 23.8M | ResultTy Res = Get(N, Tag()); | 127 | 23.8M | // If there's no batch update in progress, simply return node's children. | 128 | 23.8M | if (!BUI23.8M ) return Res23.8M ; | 129 | 23.8M | | 130 | 23.8M | // CFG children are actually its *most current* children, and we have to | 131 | 23.8M | // reverse-apply the future updates to get the node's children at the | 132 | 23.8M | // point in time the update was performed. | 133 | 2 | auto &FutureChildren = (Inverse != IsPostDom) ? 2 BUI->FuturePredecessors0 | 134 | 2 | : BUI->FutureSuccessors; | 135 | 2 | auto FCIt = FutureChildren.find(N); | 136 | 2 | if (FCIt == FutureChildren.end()2 ) return Res0 ; | 137 | 2 | | 138 | 2 | for (auto ChildAndKind : FCIt->second) 2 { | 139 | 0 | const NodePtr Child = ChildAndKind.getPointer(); | 140 | 0 | const UpdateKind UK = ChildAndKind.getInt(); | 141 | 0 |
| 142 | 0 | // Reverse-apply the future update. | 143 | 0 | if (UK == UpdateKind::Insert0 ) { | 144 | 0 | // If there's an insertion in the future, it means that the edge must | 145 | 0 | // exist in the current CFG, but was not present in it before. | 146 | 0 | assert(llvm::find(Res, Child) != Res.end() | 147 | 0 | && "Expected child not found in the CFG"); | 148 | 0 | Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end()); | 149 | 0 | DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> " | 150 | 0 | << BlockNamePrinter(Child) << "\n"); | 151 | 0 | } else { | 152 | 0 | // If there's an deletion in the future, it means that the edge cannot | 153 | 0 | // exist in the current CFG, but existed in it before. | 154 | 0 | assert(llvm::find(Res, Child) == Res.end() && | 155 | 0 | "Unexpected child found in the CFG"); | 156 | 0 | DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N) | 157 | 0 | << " -> " << BlockNamePrinter(Child) << "\n"); | 158 | 0 | Res.push_back(Child); | 159 | 0 | } | 160 | 0 | } | 161 | 2 | | 162 | 2 | return Res; | 163 | 23.8M | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::ChildrenGetter<true>::Get(clang::CFGBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::BatchUpdateInfo*) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::ChildrenGetter<false>::Get(clang::CFGBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::BatchUpdateInfo*) Line | Count | Source | 125 | 52 | static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) { | 126 | 52 | ResultTy Res = Get(N, Tag()); | 127 | 52 | // If there's no batch update in progress, simply return node's children. | 128 | 52 | if (!BUI52 ) return Res52 ; | 129 | 52 | | 130 | 52 | // CFG children are actually its *most current* children, and we have to | 131 | 52 | // reverse-apply the future updates to get the node's children at the | 132 | 52 | // point in time the update was performed. | 133 | 0 | auto &FutureChildren = (Inverse != IsPostDom) ? 0 BUI->FuturePredecessors0 | 134 | 0 | : BUI->FutureSuccessors; | 135 | 0 | auto FCIt = FutureChildren.find(N); | 136 | 0 | if (FCIt == FutureChildren.end()0 ) return Res0 ; | 137 | 0 |
| 138 | 0 | for (auto ChildAndKind : FCIt->second) 0 { | 139 | 0 | const NodePtr Child = ChildAndKind.getPointer(); | 140 | 0 | const UpdateKind UK = ChildAndKind.getInt(); | 141 | 0 |
| 142 | 0 | // Reverse-apply the future update. | 143 | 0 | if (UK == UpdateKind::Insert0 ) { | 144 | 0 | // If there's an insertion in the future, it means that the edge must | 145 | 0 | // exist in the current CFG, but was not present in it before. | 146 | 0 | assert(llvm::find(Res, Child) != Res.end() | 147 | 0 | && "Expected child not found in the CFG"); | 148 | 0 | Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end()); | 149 | 0 | DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> " | 150 | 0 | << BlockNamePrinter(Child) << "\n"); | 151 | 0 | } else { | 152 | 0 | // If there's an deletion in the future, it means that the edge cannot | 153 | 0 | // exist in the current CFG, but existed in it before. | 154 | 0 | assert(llvm::find(Res, Child) == Res.end() && | 155 | 0 | "Unexpected child found in the CFG"); | 156 | 0 | DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N) | 157 | 0 | << " -> " << BlockNamePrinter(Child) << "\n"); | 158 | 0 | Res.push_back(Child); | 159 | 0 | } | 160 | 0 | } | 161 | 0 |
| 162 | 0 | return Res; | 163 | 52 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ChildrenGetter<true>::Get(llvm::BasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*) Line | Count | Source | 125 | 590k | static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) { | 126 | 590k | ResultTy Res = Get(N, Tag()); | 127 | 590k | // If there's no batch update in progress, simply return node's children. | 128 | 590k | if (!BUI590k ) return Res63.6k ; | 129 | 590k | | 130 | 590k | // CFG children are actually its *most current* children, and we have to | 131 | 590k | // reverse-apply the future updates to get the node's children at the | 132 | 590k | // point in time the update was performed. | 133 | 527k | auto &FutureChildren = (Inverse != IsPostDom) ? 527k BUI->FuturePredecessors527k | 134 | 0 | : BUI->FutureSuccessors; | 135 | 527k | auto FCIt = FutureChildren.find(N); | 136 | 527k | if (FCIt == FutureChildren.end()527k ) return Res491k ; | 137 | 527k | | 138 | 35.9k | for (auto ChildAndKind : FCIt->second) 35.9k { | 139 | 81.4k | const NodePtr Child = ChildAndKind.getPointer(); | 140 | 81.4k | const UpdateKind UK = ChildAndKind.getInt(); | 141 | 81.4k | | 142 | 81.4k | // Reverse-apply the future update. | 143 | 81.4k | if (UK == UpdateKind::Insert81.4k ) { | 144 | 28 | // If there's an insertion in the future, it means that the edge must | 145 | 28 | // exist in the current CFG, but was not present in it before. | 146 | 28 | assert(llvm::find(Res, Child) != Res.end() | 147 | 28 | && "Expected child not found in the CFG"); | 148 | 28 | Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end()); | 149 | 28 | DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> " | 150 | 28 | << BlockNamePrinter(Child) << "\n"); | 151 | 81.4k | } else { | 152 | 81.4k | // If there's an deletion in the future, it means that the edge cannot | 153 | 81.4k | // exist in the current CFG, but existed in it before. | 154 | 81.4k | assert(llvm::find(Res, Child) == Res.end() && | 155 | 81.4k | "Unexpected child found in the CFG"); | 156 | 81.4k | DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N) | 157 | 81.4k | << " -> " << BlockNamePrinter(Child) << "\n"); | 158 | 81.4k | Res.push_back(Child); | 159 | 81.4k | } | 160 | 81.4k | } | 161 | 35.9k | | 162 | 35.9k | return Res; | 163 | 590k | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ChildrenGetter<true>::Get(llvm::BasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*) Line | Count | Source | 125 | 8.05M | static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) { | 126 | 8.05M | ResultTy Res = Get(N, Tag()); | 127 | 8.05M | // If there's no batch update in progress, simply return node's children. | 128 | 8.05M | if (!BUI8.05M ) return Res8.05M ; | 129 | 8.05M | | 130 | 8.05M | // CFG children are actually its *most current* children, and we have to | 131 | 8.05M | // reverse-apply the future updates to get the node's children at the | 132 | 8.05M | // point in time the update was performed. | 133 | 513 | auto &FutureChildren = (Inverse != IsPostDom) ? 513 BUI->FuturePredecessors0 | 134 | 513 | : BUI->FutureSuccessors; | 135 | 513 | auto FCIt = FutureChildren.find(N); | 136 | 513 | if (FCIt == FutureChildren.end()513 ) return Res443 ; | 137 | 513 | | 138 | 70 | for (auto ChildAndKind : FCIt->second) 70 { | 139 | 77 | const NodePtr Child = ChildAndKind.getPointer(); | 140 | 77 | const UpdateKind UK = ChildAndKind.getInt(); | 141 | 77 | | 142 | 77 | // Reverse-apply the future update. | 143 | 77 | if (UK == UpdateKind::Insert77 ) { | 144 | 49 | // If there's an insertion in the future, it means that the edge must | 145 | 49 | // exist in the current CFG, but was not present in it before. | 146 | 49 | assert(llvm::find(Res, Child) != Res.end() | 147 | 49 | && "Expected child not found in the CFG"); | 148 | 49 | Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end()); | 149 | 49 | DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> " | 150 | 49 | << BlockNamePrinter(Child) << "\n"); | 151 | 77 | } else { | 152 | 28 | // If there's an deletion in the future, it means that the edge cannot | 153 | 28 | // exist in the current CFG, but existed in it before. | 154 | 28 | assert(llvm::find(Res, Child) == Res.end() && | 155 | 28 | "Unexpected child found in the CFG"); | 156 | 28 | DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N) | 157 | 28 | << " -> " << BlockNamePrinter(Child) << "\n"); | 158 | 28 | Res.push_back(Child); | 159 | 28 | } | 160 | 77 | } | 161 | 70 | | 162 | 70 | return Res; | 163 | 8.05M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ChildrenGetter<false>::Get(llvm::BasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*) Line | Count | Source | 125 | 4.01M | static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) { | 126 | 4.01M | ResultTy Res = Get(N, Tag()); | 127 | 4.01M | // If there's no batch update in progress, simply return node's children. | 128 | 4.01M | if (!BUI4.01M ) return Res4.01M ; | 129 | 4.01M | | 130 | 4.01M | // CFG children are actually its *most current* children, and we have to | 131 | 4.01M | // reverse-apply the future updates to get the node's children at the | 132 | 4.01M | // point in time the update was performed. | 133 | 281 | auto &FutureChildren = (Inverse != IsPostDom) ? 281 BUI->FuturePredecessors280 | 134 | 1 | : BUI->FutureSuccessors; | 135 | 281 | auto FCIt = FutureChildren.find(N); | 136 | 281 | if (FCIt == FutureChildren.end()281 ) return Res208 ; | 137 | 281 | | 138 | 73 | for (auto ChildAndKind : FCIt->second) 73 { | 139 | 107 | const NodePtr Child = ChildAndKind.getPointer(); | 140 | 107 | const UpdateKind UK = ChildAndKind.getInt(); | 141 | 107 | | 142 | 107 | // Reverse-apply the future update. | 143 | 107 | if (UK == UpdateKind::Insert107 ) { | 144 | 79 | // If there's an insertion in the future, it means that the edge must | 145 | 79 | // exist in the current CFG, but was not present in it before. | 146 | 79 | assert(llvm::find(Res, Child) != Res.end() | 147 | 79 | && "Expected child not found in the CFG"); | 148 | 79 | Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end()); | 149 | 79 | DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> " | 150 | 79 | << BlockNamePrinter(Child) << "\n"); | 151 | 107 | } else { | 152 | 28 | // If there's an deletion in the future, it means that the edge cannot | 153 | 28 | // exist in the current CFG, but existed in it before. | 154 | 28 | assert(llvm::find(Res, Child) == Res.end() && | 155 | 28 | "Unexpected child found in the CFG"); | 156 | 28 | DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N) | 157 | 28 | << " -> " << BlockNamePrinter(Child) << "\n"); | 158 | 28 | Res.push_back(Child); | 159 | 28 | } | 160 | 107 | } | 161 | 73 | | 162 | 73 | return Res; | 163 | 4.01M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ChildrenGetter<false>::Get(llvm::BasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*) Line | Count | Source | 125 | 122M | static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) { | 126 | 122M | ResultTy Res = Get(N, Tag()); | 127 | 122M | // If there's no batch update in progress, simply return node's children. | 128 | 122M | if (!BUI122M ) return Res102M ; | 129 | 122M | | 130 | 122M | // CFG children are actually its *most current* children, and we have to | 131 | 122M | // reverse-apply the future updates to get the node's children at the | 132 | 122M | // point in time the update was performed. | 133 | 19.9M | auto &FutureChildren = (Inverse != IsPostDom) ? 19.9M BUI->FuturePredecessors0 | 134 | 19.9M | : BUI->FutureSuccessors; | 135 | 19.9M | auto FCIt = FutureChildren.find(N); | 136 | 19.9M | if (FCIt == FutureChildren.end()19.9M ) return Res18.6M ; | 137 | 19.9M | | 138 | 1.26M | for (auto ChildAndKind : FCIt->second) 1.26M { | 139 | 1.60M | const NodePtr Child = ChildAndKind.getPointer(); | 140 | 1.60M | const UpdateKind UK = ChildAndKind.getInt(); | 141 | 1.60M | | 142 | 1.60M | // Reverse-apply the future update. | 143 | 1.60M | if (UK == UpdateKind::Insert1.60M ) { | 144 | 790k | // If there's an insertion in the future, it means that the edge must | 145 | 790k | // exist in the current CFG, but was not present in it before. | 146 | 790k | assert(llvm::find(Res, Child) != Res.end() | 147 | 790k | && "Expected child not found in the CFG"); | 148 | 790k | Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end()); | 149 | 790k | DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> " | 150 | 790k | << BlockNamePrinter(Child) << "\n"); | 151 | 1.60M | } else { | 152 | 810k | // If there's an deletion in the future, it means that the edge cannot | 153 | 810k | // exist in the current CFG, but existed in it before. | 154 | 810k | assert(llvm::find(Res, Child) == Res.end() && | 155 | 810k | "Unexpected child found in the CFG"); | 156 | 810k | DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N) | 157 | 810k | << " -> " << BlockNamePrinter(Child) << "\n"); | 158 | 810k | Res.push_back(Child); | 159 | 810k | } | 160 | 1.60M | } | 161 | 1.26M | | 162 | 1.26M | return Res; | 163 | 122M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ChildrenGetter<false>::Get(llvm::MachineBasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*) Line | Count | Source | 125 | 12.5M | static ResultTy Get(NodePtr N, BatchUpdatePtr BUI) { | 126 | 12.5M | ResultTy Res = Get(N, Tag()); | 127 | 12.5M | // If there's no batch update in progress, simply return node's children. | 128 | 12.5M | if (!BUI12.5M ) return Res12.5M ; | 129 | 12.5M | | 130 | 12.5M | // CFG children are actually its *most current* children, and we have to | 131 | 12.5M | // reverse-apply the future updates to get the node's children at the | 132 | 12.5M | // point in time the update was performed. | 133 | 18.4E | auto &FutureChildren = (Inverse != IsPostDom) ? 18.4E BUI->FuturePredecessors0 | 134 | 18.4E | : BUI->FutureSuccessors; | 135 | 18.4E | auto FCIt = FutureChildren.find(N); | 136 | 18.4E | if (FCIt == FutureChildren.end()18.4E ) return Res0 ; | 137 | 18.4E | | 138 | 18.4E | for (auto ChildAndKind : FCIt->second) 18.4E { | 139 | 0 | const NodePtr Child = ChildAndKind.getPointer(); | 140 | 0 | const UpdateKind UK = ChildAndKind.getInt(); | 141 | 0 |
| 142 | 0 | // Reverse-apply the future update. | 143 | 0 | if (UK == UpdateKind::Insert0 ) { | 144 | 0 | // If there's an insertion in the future, it means that the edge must | 145 | 0 | // exist in the current CFG, but was not present in it before. | 146 | 0 | assert(llvm::find(Res, Child) != Res.end() | 147 | 0 | && "Expected child not found in the CFG"); | 148 | 0 | Res.erase(std::remove(Res.begin(), Res.end(), Child), Res.end()); | 149 | 0 | DEBUG(dbgs() << "\tHiding edge " << BlockNamePrinter(N) << " -> " | 150 | 0 | << BlockNamePrinter(Child) << "\n"); | 151 | 0 | } else { | 152 | 0 | // If there's an deletion in the future, it means that the edge cannot | 153 | 0 | // exist in the current CFG, but existed in it before. | 154 | 0 | assert(llvm::find(Res, Child) == Res.end() && | 155 | 0 | "Unexpected child found in the CFG"); | 156 | 0 | DEBUG(dbgs() << "\tShowing virtual edge " << BlockNamePrinter(N) | 157 | 0 | << " -> " << BlockNamePrinter(Child) << "\n"); | 158 | 0 | Res.push_back(Child); | 159 | 0 | } | 160 | 0 | } | 161 | 18.4E | | 162 | 18.4E | return Res; | 163 | 12.5M | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ChildrenGetter<true>::Get(llvm::MachineBasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*) |
164 | | }; |
165 | | |
166 | 126M | NodePtr getIDom(NodePtr BB) const { |
167 | 126M | auto InfoIt = NodeToInfo.find(BB); |
168 | 126M | if (InfoIt == NodeToInfo.end()126M ) return nullptr0 ; |
169 | 126M | |
170 | 126M | return InfoIt->second.IDom; |
171 | 126M | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::getIDom(llvm::MachineBasicBlock*) const Line | Count | Source | 166 | 20.1M | NodePtr getIDom(NodePtr BB) const { | 167 | 20.1M | auto InfoIt = NodeToInfo.find(BB); | 168 | 20.1M | if (InfoIt == NodeToInfo.end()20.1M ) return nullptr0 ; | 169 | 20.1M | | 170 | 20.1M | return InfoIt->second.IDom; | 171 | 20.1M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::getIDom(llvm::BasicBlock*) const Line | Count | Source | 166 | 89.7M | NodePtr getIDom(NodePtr BB) const { | 167 | 89.7M | auto InfoIt = NodeToInfo.find(BB); | 168 | 89.7M | if (InfoIt == NodeToInfo.end()89.7M ) return nullptr0 ; | 169 | 89.7M | | 170 | 89.7M | return InfoIt->second.IDom; | 171 | 89.7M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::getIDom(llvm::MachineBasicBlock*) const Line | Count | Source | 166 | 12.5M | NodePtr getIDom(NodePtr BB) const { | 167 | 12.5M | auto InfoIt = NodeToInfo.find(BB); | 168 | 12.5M | if (InfoIt == NodeToInfo.end()12.5M ) return nullptr0 ; | 169 | 12.5M | | 170 | 12.5M | return InfoIt->second.IDom; | 171 | 12.5M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::getIDom(llvm::BasicBlock*) const Line | Count | Source | 166 | 4.00M | NodePtr getIDom(NodePtr BB) const { | 167 | 4.00M | auto InfoIt = NodeToInfo.find(BB); | 168 | 4.00M | if (InfoIt == NodeToInfo.end()4.00M ) return nullptr0 ; | 169 | 4.00M | | 170 | 4.00M | return InfoIt->second.IDom; | 171 | 4.00M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::getIDom(clang::CFGBlock*) const Line | Count | Source | 166 | 47 | NodePtr getIDom(NodePtr BB) const { | 167 | 47 | auto InfoIt = NodeToInfo.find(BB); | 168 | 47 | if (InfoIt == NodeToInfo.end()47 ) return nullptr0 ; | 169 | 47 | | 170 | 47 | return InfoIt->second.IDom; | 171 | 47 | } |
|
172 | | |
173 | 126M | TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) { |
174 | 126M | if (TreeNodePtr Node126M = DT.getNode(BB)) return Node126M ; |
175 | 126M | |
176 | 126M | // Haven't calculated this node yet? Get or calculate the node for the |
177 | 126M | // immediate dominator. |
178 | 18.4E | NodePtr IDom = getIDom(BB); |
179 | 18.4E | |
180 | 18.4E | assert(IDom || DT.DomTreeNodes[nullptr]); |
181 | 18.4E | TreeNodePtr IDomNode = getNodeForBlock(IDom, DT); |
182 | 18.4E | |
183 | 18.4E | // Add a new tree node for this NodeT, and link it as a child of |
184 | 18.4E | // IDomNode |
185 | 18.4E | return (DT.DomTreeNodes[BB] = IDomNode->addChild( |
186 | 18.4E | llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))) |
187 | 18.4E | .get(); |
188 | 126M | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::getNodeForBlock(llvm::MachineBasicBlock*, llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&) Line | Count | Source | 173 | 20.1M | TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) { | 174 | 20.1M | if (TreeNodePtr Node20.1M = DT.getNode(BB)) return Node20.1M ; | 175 | 20.1M | | 176 | 20.1M | // Haven't calculated this node yet? Get or calculate the node for the | 177 | 20.1M | // immediate dominator. | 178 | 0 | NodePtr IDom = getIDom(BB); | 179 | 0 |
| 180 | 0 | assert(IDom || DT.DomTreeNodes[nullptr]); | 181 | 0 | TreeNodePtr IDomNode = getNodeForBlock(IDom, DT); | 182 | 0 |
| 183 | 0 | // Add a new tree node for this NodeT, and link it as a child of | 184 | 0 | // IDomNode | 185 | 0 | return (DT.DomTreeNodes[BB] = IDomNode->addChild( | 186 | 0 | llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))) | 187 | 0 | .get(); | 188 | 20.1M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::getNodeForBlock(llvm::BasicBlock*, llvm::DominatorTreeBase<llvm::BasicBlock, false>&) Line | Count | Source | 173 | 89.7M | TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) { | 174 | 89.7M | if (TreeNodePtr Node89.7M = DT.getNode(BB)) return Node89.7M ; | 175 | 89.7M | | 176 | 89.7M | // Haven't calculated this node yet? Get or calculate the node for the | 177 | 89.7M | // immediate dominator. | 178 | 1 | NodePtr IDom = getIDom(BB); | 179 | 1 | | 180 | 1 | assert(IDom || DT.DomTreeNodes[nullptr]); | 181 | 1 | TreeNodePtr IDomNode = getNodeForBlock(IDom, DT); | 182 | 1 | | 183 | 1 | // Add a new tree node for this NodeT, and link it as a child of | 184 | 1 | // IDomNode | 185 | 1 | return (DT.DomTreeNodes[BB] = IDomNode->addChild( | 186 | 1 | llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))) | 187 | 1 | .get(); | 188 | 89.7M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::getNodeForBlock(llvm::BasicBlock*, llvm::DominatorTreeBase<llvm::BasicBlock, true>&) Line | Count | Source | 173 | 4.00M | TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) { | 174 | 4.00M | if (TreeNodePtr Node4.00M = DT.getNode(BB)) return Node4.00M ; | 175 | 4.00M | | 176 | 4.00M | // Haven't calculated this node yet? Get or calculate the node for the | 177 | 4.00M | // immediate dominator. | 178 | 18.4E | NodePtr IDom = getIDom(BB); | 179 | 18.4E | | 180 | 18.4E | assert(IDom || DT.DomTreeNodes[nullptr]); | 181 | 18.4E | TreeNodePtr IDomNode = getNodeForBlock(IDom, DT); | 182 | 18.4E | | 183 | 18.4E | // Add a new tree node for this NodeT, and link it as a child of | 184 | 18.4E | // IDomNode | 185 | 18.4E | return (DT.DomTreeNodes[BB] = IDomNode->addChild( | 186 | 18.4E | llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))) | 187 | 18.4E | .get(); | 188 | 4.00M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::getNodeForBlock(clang::CFGBlock*, llvm::DominatorTreeBase<clang::CFGBlock, false>&) Line | Count | Source | 173 | 47 | TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) { | 174 | 47 | if (TreeNodePtr Node47 = DT.getNode(BB)) return Node47 ; | 175 | 47 | | 176 | 47 | // Haven't calculated this node yet? Get or calculate the node for the | 177 | 47 | // immediate dominator. | 178 | 0 | NodePtr IDom = getIDom(BB); | 179 | 0 |
| 180 | 0 | assert(IDom || DT.DomTreeNodes[nullptr]); | 181 | 0 | TreeNodePtr IDomNode = getNodeForBlock(IDom, DT); | 182 | 0 |
| 183 | 0 | // Add a new tree node for this NodeT, and link it as a child of | 184 | 0 | // IDomNode | 185 | 0 | return (DT.DomTreeNodes[BB] = IDomNode->addChild( | 186 | 0 | llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))) | 187 | 0 | .get(); | 188 | 47 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::getNodeForBlock(llvm::MachineBasicBlock*, llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&) Line | Count | Source | 173 | 12.5M | TreeNodePtr getNodeForBlock(NodePtr BB, DomTreeT &DT) { | 174 | 12.5M | if (TreeNodePtr Node12.5M = DT.getNode(BB)) return Node12.5M ; | 175 | 12.5M | | 176 | 12.5M | // Haven't calculated this node yet? Get or calculate the node for the | 177 | 12.5M | // immediate dominator. | 178 | 0 | NodePtr IDom = getIDom(BB); | 179 | 0 |
| 180 | 0 | assert(IDom || DT.DomTreeNodes[nullptr]); | 181 | 0 | TreeNodePtr IDomNode = getNodeForBlock(IDom, DT); | 182 | 0 |
| 183 | 0 | // Add a new tree node for this NodeT, and link it as a child of | 184 | 0 | // IDomNode | 185 | 0 | return (DT.DomTreeNodes[BB] = IDomNode->addChild( | 186 | 0 | llvm::make_unique<DomTreeNodeBase<NodeT>>(BB, IDomNode))) | 187 | 0 | .get(); | 188 | 12.5M | } |
|
189 | | |
190 | 152M | static bool AlwaysDescend(NodePtr, NodePtr) { return true; } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::AlwaysDescend(llvm::BasicBlock*, llvm::BasicBlock*) Line | Count | Source | 190 | 7.13M | static bool AlwaysDescend(NodePtr, NodePtr) { return true; } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::AlwaysDescend(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) Line | Count | Source | 190 | 22.3M | static bool AlwaysDescend(NodePtr, NodePtr) { return true; } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::AlwaysDescend(llvm::BasicBlock*, llvm::BasicBlock*) Line | Count | Source | 190 | 98.5M | static bool AlwaysDescend(NodePtr, NodePtr) { return true; } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::AlwaysDescend(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) Line | Count | Source | 190 | 24.5M | static bool AlwaysDescend(NodePtr, NodePtr) { return true; } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::AlwaysDescend(clang::CFGBlock*, clang::CFGBlock*) Line | Count | Source | 190 | 48 | static bool AlwaysDescend(NodePtr, NodePtr) { return true; } |
|
191 | | |
192 | | struct BlockNamePrinter { |
193 | | NodePtr N; |
194 | | |
195 | 0 | BlockNamePrinter(NodePtr Block) : N(Block) {} Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BlockNamePrinter::BlockNamePrinter(llvm::BasicBlock*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BlockNamePrinter::BlockNamePrinter(llvm::BasicBlock*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BlockNamePrinter::BlockNamePrinter(llvm::MachineBasicBlock*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BlockNamePrinter::BlockNamePrinter(llvm::MachineBasicBlock*) |
196 | 0 | BlockNamePrinter(TreeNodePtr TN) : N(TN ? TN->getBlock() : nullptr) {} Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BlockNamePrinter::BlockNamePrinter(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BlockNamePrinter::BlockNamePrinter(llvm::DomTreeNodeBase<llvm::BasicBlock>*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BlockNamePrinter::BlockNamePrinter(llvm::DomTreeNodeBase<llvm::BasicBlock>*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BlockNamePrinter::BlockNamePrinter(llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) |
197 | | |
198 | 0 | friend raw_ostream &operator<<(raw_ostream &O, const BlockNamePrinter &BP) { |
199 | 0 | if (!BP.N) |
200 | 0 | O << "nullptr"; |
201 | 0 | else |
202 | 0 | BP.N->printAsOperand(O, false); |
203 | 0 |
|
204 | 0 | return O; |
205 | 0 | } Unexecuted instantiation: llvm::DomTreeBuilder::operator<<(llvm::raw_ostream&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BlockNamePrinter const&) Unexecuted instantiation: llvm::DomTreeBuilder::operator<<(llvm::raw_ostream&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BlockNamePrinter const&) Unexecuted instantiation: llvm::DomTreeBuilder::operator<<(llvm::raw_ostream&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BlockNamePrinter const&) Unexecuted instantiation: llvm::DomTreeBuilder::operator<<(llvm::raw_ostream&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BlockNamePrinter const&) |
206 | | }; |
207 | | |
208 | | // Custom DFS implementation which can skip nodes based on a provided |
209 | | // predicate. It also collects ReverseChildren so that we don't have to spend |
210 | | // time getting predecessors in SemiNCA. |
211 | | // |
212 | | // If IsReverse is set to true, the DFS walk will be performed backwards |
213 | | // relative to IsPostDom -- using reverse edges for dominators and forward |
214 | | // edges for postdominators. |
215 | | template <bool IsReverse = false, typename DescendCondition> |
216 | | unsigned runDFS(NodePtr V, unsigned LastNum, DescendCondition Condition, |
217 | 23.2M | unsigned AttachToNum) { |
218 | 23.2M | assert(V); |
219 | 23.2M | SmallVector<NodePtr, 64> WorkList = {V}; |
220 | 23.2M | if (NodeToInfo.count(V) != 023.2M ) NodeToInfo[V].Parent = AttachToNum0 ; |
221 | 23.2M | |
222 | 218M | while (!WorkList.empty()218M ) { |
223 | 195M | const NodePtr BB = WorkList.pop_back_val(); |
224 | 195M | auto &BBInfo = NodeToInfo[BB]; |
225 | 195M | |
226 | 195M | // Visited nodes always have positive DFS numbers. |
227 | 195M | if (BBInfo.DFSNum != 0195M ) continue18.6M ; |
228 | 177M | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; |
229 | 177M | BBInfo.Label = BB; |
230 | 177M | NumToNode.push_back(BB); |
231 | 177M | |
232 | 177M | constexpr bool Direction = IsReverse != IsPostDom; // XOR. |
233 | 177M | for (const NodePtr Succ : |
234 | 241M | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { |
235 | 241M | const auto SIT = NodeToInfo.find(Succ); |
236 | 241M | // Don't visit nodes more than once but remember to collect |
237 | 241M | // ReverseChildren. |
238 | 241M | if (SIT != NodeToInfo.end() && 241M SIT->second.DFSNum != 085.8M ) { |
239 | 67.1M | if (Succ != BB67.1M ) SIT->second.ReverseChildren.push_back(BB)54.4M ; |
240 | 67.1M | continue; |
241 | 67.1M | } |
242 | 241M | |
243 | 174M | if (174M !Condition(BB, Succ)174M ) continue1.94M ; |
244 | 174M | |
245 | 174M | // It's fine to add Succ to the map, because we know that it will be |
246 | 174M | // visited later. |
247 | 172M | auto &SuccInfo = NodeToInfo[Succ]; |
248 | 172M | WorkList.push_back(Succ); |
249 | 172M | SuccInfo.Parent = LastNum; |
250 | 172M | SuccInfo.ReverseChildren.push_back(BB); |
251 | 172M | } |
252 | 195M | } |
253 | 23.2M | |
254 | 23.2M | return LastNum; |
255 | 23.2M | } unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) Line | Count | Source | 217 | 5.02k | unsigned AttachToNum) { | 218 | 5.02k | assert(V); | 219 | 5.02k | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 5.02k | if (NodeToInfo.count(V) != 05.02k ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 5.02k | | 222 | 20.0k | while (!WorkList.empty()20.0k ) { | 223 | 15.0k | const NodePtr BB = WorkList.pop_back_val(); | 224 | 15.0k | auto &BBInfo = NodeToInfo[BB]; | 225 | 15.0k | | 226 | 15.0k | // Visited nodes always have positive DFS numbers. | 227 | 15.0k | if (BBInfo.DFSNum != 015.0k ) continue431 ; | 228 | 14.6k | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 14.6k | BBInfo.Label = BB; | 230 | 14.6k | NumToNode.push_back(BB); | 231 | 14.6k | | 232 | 14.6k | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 14.6k | for (const NodePtr Succ : | 234 | 15.1k | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 15.1k | const auto SIT = NodeToInfo.find(Succ); | 236 | 15.1k | // Don't visit nodes more than once but remember to collect | 237 | 15.1k | // ReverseChildren. | 238 | 15.1k | if (SIT != NodeToInfo.end() && 15.1k SIT->second.DFSNum != 03.21k ) { | 239 | 2.78k | if (Succ != BB2.78k ) SIT->second.ReverseChildren.push_back(BB)2.78k ; | 240 | 2.78k | continue; | 241 | 2.78k | } | 242 | 15.1k | | 243 | 12.4k | if (12.4k !Condition(BB, Succ)12.4k ) continue2.39k ; | 244 | 12.4k | | 245 | 12.4k | // It's fine to add Succ to the map, because we know that it will be | 246 | 12.4k | // visited later. | 247 | 10.0k | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 10.0k | WorkList.push_back(Succ); | 249 | 10.0k | SuccInfo.Parent = LastNum; | 250 | 10.0k | SuccInfo.ReverseChildren.push_back(BB); | 251 | 10.0k | } | 252 | 15.0k | } | 253 | 5.02k | | 254 | 5.02k | return LastNum; | 255 | 5.02k | } |
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) Line | Count | Source | 217 | 5.91k | unsigned AttachToNum) { | 218 | 5.91k | assert(V); | 219 | 5.91k | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 5.91k | if (NodeToInfo.count(V) != 05.91k ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 5.91k | | 222 | 26.3k | while (!WorkList.empty()26.3k ) { | 223 | 20.3k | const NodePtr BB = WorkList.pop_back_val(); | 224 | 20.3k | auto &BBInfo = NodeToInfo[BB]; | 225 | 20.3k | | 226 | 20.3k | // Visited nodes always have positive DFS numbers. | 227 | 20.3k | if (BBInfo.DFSNum != 020.3k ) continue786 ; | 228 | 19.6k | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 19.6k | BBInfo.Label = BB; | 230 | 19.6k | NumToNode.push_back(BB); | 231 | 19.6k | | 232 | 19.6k | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 19.6k | for (const NodePtr Succ : | 234 | 20.9k | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 20.9k | const auto SIT = NodeToInfo.find(Succ); | 236 | 20.9k | // Don't visit nodes more than once but remember to collect | 237 | 20.9k | // ReverseChildren. | 238 | 20.9k | if (SIT != NodeToInfo.end() && 20.9k SIT->second.DFSNum != 05.06k ) { | 239 | 4.27k | if (Succ != BB4.27k ) SIT->second.ReverseChildren.push_back(BB)4.27k ; | 240 | 4.27k | continue; | 241 | 4.27k | } | 242 | 20.9k | | 243 | 16.7k | if (16.7k !Condition(BB, Succ)16.7k ) continue2.23k ; | 244 | 16.7k | | 245 | 16.7k | // It's fine to add Succ to the map, because we know that it will be | 246 | 16.7k | // visited later. | 247 | 14.4k | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 14.4k | WorkList.push_back(Succ); | 249 | 14.4k | SuccInfo.Parent = LastNum; | 250 | 14.4k | SuccInfo.ReverseChildren.push_back(BB); | 251 | 14.4k | } | 252 | 20.3k | } | 253 | 5.91k | | 254 | 5.91k | return LastNum; | 255 | 5.91k | } |
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::runDFS<true, bool (*)(clang::CFGBlock*, clang::CFGBlock*)>(clang::CFGBlock*, unsigned int, bool (*)(clang::CFGBlock*, clang::CFGBlock*), unsigned int) unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::runDFS<false, bool (*)(clang::CFGBlock*, clang::CFGBlock*)>(clang::CFGBlock*, unsigned int, bool (*)(clang::CFGBlock*, clang::CFGBlock*), unsigned int) Line | Count | Source | 217 | 5 | unsigned AttachToNum) { | 218 | 5 | assert(V); | 219 | 5 | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 5 | if (NodeToInfo.count(V) != 05 ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 5 | | 222 | 58 | while (!WorkList.empty()58 ) { | 223 | 53 | const NodePtr BB = WorkList.pop_back_val(); | 224 | 53 | auto &BBInfo = NodeToInfo[BB]; | 225 | 53 | | 226 | 53 | // Visited nodes always have positive DFS numbers. | 227 | 53 | if (BBInfo.DFSNum != 053 ) continue1 ; | 228 | 52 | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 52 | BBInfo.Label = BB; | 230 | 52 | NumToNode.push_back(BB); | 231 | 52 | | 232 | 52 | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 52 | for (const NodePtr Succ : | 234 | 61 | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 61 | const auto SIT = NodeToInfo.find(Succ); | 236 | 61 | // Don't visit nodes more than once but remember to collect | 237 | 61 | // ReverseChildren. | 238 | 61 | if (SIT != NodeToInfo.end() && 61 SIT->second.DFSNum != 014 ) { | 239 | 13 | if (Succ != BB13 ) SIT->second.ReverseChildren.push_back(BB)13 ; | 240 | 13 | continue; | 241 | 13 | } | 242 | 61 | | 243 | 48 | if (48 !Condition(BB, Succ)48 ) continue0 ; | 244 | 48 | | 245 | 48 | // It's fine to add Succ to the map, because we know that it will be | 246 | 48 | // visited later. | 247 | 48 | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 48 | WorkList.push_back(Succ); | 249 | 48 | SuccInfo.Parent = LastNum; | 250 | 48 | SuccInfo.ReverseChildren.push_back(BB); | 251 | 48 | } | 252 | 53 | } | 253 | 5 | | 254 | 5 | return LastNum; | 255 | 5 | } |
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) Line | Count | Source | 217 | 2.24k | unsigned AttachToNum) { | 218 | 2.24k | assert(V); | 219 | 2.24k | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 2.24k | if (NodeToInfo.count(V) != 02.24k ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 2.24k | | 222 | 17.7k | while (!WorkList.empty()17.7k ) { | 223 | 15.5k | const NodePtr BB = WorkList.pop_back_val(); | 224 | 15.5k | auto &BBInfo = NodeToInfo[BB]; | 225 | 15.5k | | 226 | 15.5k | // Visited nodes always have positive DFS numbers. | 227 | 15.5k | if (BBInfo.DFSNum != 015.5k ) continue340 ; | 228 | 15.1k | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 15.1k | BBInfo.Label = BB; | 230 | 15.1k | NumToNode.push_back(BB); | 231 | 15.1k | | 232 | 15.1k | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 15.1k | for (const NodePtr Succ : | 234 | 16.9k | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 16.9k | const auto SIT = NodeToInfo.find(Succ); | 236 | 16.9k | // Don't visit nodes more than once but remember to collect | 237 | 16.9k | // ReverseChildren. | 238 | 16.9k | if (SIT != NodeToInfo.end() && 16.9k SIT->second.DFSNum != 01.52k ) { | 239 | 1.18k | if (Succ != BB1.18k ) SIT->second.ReverseChildren.push_back(BB)1.18k ; | 240 | 1.18k | continue; | 241 | 1.18k | } | 242 | 16.9k | | 243 | 15.7k | if (15.7k !Condition(BB, Succ)15.7k ) continue2.49k ; | 244 | 15.7k | | 245 | 15.7k | // It's fine to add Succ to the map, because we know that it will be | 246 | 15.7k | // visited later. | 247 | 13.2k | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 13.2k | WorkList.push_back(Succ); | 249 | 13.2k | SuccInfo.Parent = LastNum; | 250 | 13.2k | SuccInfo.ReverseChildren.push_back(BB); | 251 | 13.2k | } | 252 | 15.5k | } | 253 | 2.24k | | 254 | 2.24k | return LastNum; | 255 | 2.24k | } |
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda0'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda0'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<true, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<false, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) Line | Count | Source | 217 | 3.66M | unsigned AttachToNum) { | 218 | 3.66M | assert(V); | 219 | 3.66M | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 3.66M | if (NodeToInfo.count(V) != 03.66M ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 3.66M | | 222 | 29.6M | while (!WorkList.empty()29.6M ) { | 223 | 26.0M | const NodePtr BB = WorkList.pop_back_val(); | 224 | 26.0M | auto &BBInfo = NodeToInfo[BB]; | 225 | 26.0M | | 226 | 26.0M | // Visited nodes always have positive DFS numbers. | 227 | 26.0M | if (BBInfo.DFSNum != 026.0M ) continue2.19M ; | 228 | 23.8M | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 23.8M | BBInfo.Label = BB; | 230 | 23.8M | NumToNode.push_back(BB); | 231 | 23.8M | | 232 | 23.8M | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 23.8M | for (const NodePtr Succ : | 234 | 30.5M | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 30.5M | const auto SIT = NodeToInfo.find(Succ); | 236 | 30.5M | // Don't visit nodes more than once but remember to collect | 237 | 30.5M | // ReverseChildren. | 238 | 30.5M | if (SIT != NodeToInfo.end() && 30.5M SIT->second.DFSNum != 010.3M ) { | 239 | 8.17M | if (Succ != BB8.17M ) SIT->second.ReverseChildren.push_back(BB)7.01M ; | 240 | 8.17M | continue; | 241 | 8.17M | } | 242 | 30.5M | | 243 | 22.3M | if (22.3M !Condition(BB, Succ)22.3M ) continue0 ; | 244 | 22.3M | | 245 | 22.3M | // It's fine to add Succ to the map, because we know that it will be | 246 | 22.3M | // visited later. | 247 | 22.3M | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 22.3M | WorkList.push_back(Succ); | 249 | 22.3M | SuccInfo.Parent = LastNum; | 250 | 22.3M | SuccInfo.ReverseChildren.push_back(BB); | 251 | 22.3M | } | 252 | 26.0M | } | 253 | 3.66M | | 254 | 3.66M | return LastNum; | 255 | 3.66M | } |
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<true, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda0'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda0'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) Line | Count | Source | 217 | 1.56k | unsigned AttachToNum) { | 218 | 1.56k | assert(V); | 219 | 1.56k | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 1.56k | if (NodeToInfo.count(V) != 01.56k ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 1.56k | | 222 | 8.74k | while (!WorkList.empty()8.74k ) { | 223 | 7.18k | const NodePtr BB = WorkList.pop_back_val(); | 224 | 7.18k | auto &BBInfo = NodeToInfo[BB]; | 225 | 7.18k | | 226 | 7.18k | // Visited nodes always have positive DFS numbers. | 227 | 7.18k | if (BBInfo.DFSNum != 07.18k ) continue141 ; | 228 | 7.03k | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 7.03k | BBInfo.Label = BB; | 230 | 7.03k | NumToNode.push_back(BB); | 231 | 7.03k | | 232 | 7.03k | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 7.03k | for (const NodePtr Succ : | 234 | 7.67k | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 7.67k | const auto SIT = NodeToInfo.find(Succ); | 236 | 7.67k | // Don't visit nodes more than once but remember to collect | 237 | 7.67k | // ReverseChildren. | 238 | 7.67k | if (SIT != NodeToInfo.end() && 7.67k SIT->second.DFSNum != 0554 ) { | 239 | 413 | if (Succ != BB413 ) SIT->second.ReverseChildren.push_back(BB)413 ; | 240 | 413 | continue; | 241 | 413 | } | 242 | 7.67k | | 243 | 7.25k | if (7.25k !Condition(BB, Succ)7.25k ) continue1.64k ; | 244 | 7.25k | | 245 | 7.25k | // It's fine to add Succ to the map, because we know that it will be | 246 | 7.25k | // visited later. | 247 | 5.61k | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 5.61k | WorkList.push_back(Succ); | 249 | 5.61k | SuccInfo.Parent = LastNum; | 250 | 5.61k | SuccInfo.ReverseChildren.push_back(BB); | 251 | 5.61k | } | 252 | 7.18k | } | 253 | 1.56k | | 254 | 1.56k | return LastNum; | 255 | 1.56k | } |
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) Line | Count | Source | 217 | 125 | unsigned AttachToNum) { | 218 | 125 | assert(V); | 219 | 125 | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 125 | if (NodeToInfo.count(V) != 0125 ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 125 | | 222 | 568 | while (!WorkList.empty()568 ) { | 223 | 443 | const NodePtr BB = WorkList.pop_back_val(); | 224 | 443 | auto &BBInfo = NodeToInfo[BB]; | 225 | 443 | | 226 | 443 | // Visited nodes always have positive DFS numbers. | 227 | 443 | if (BBInfo.DFSNum != 0443 ) continue7 ; | 228 | 436 | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 436 | BBInfo.Label = BB; | 230 | 436 | NumToNode.push_back(BB); | 231 | 436 | | 232 | 436 | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 436 | for (const NodePtr Succ : | 234 | 442 | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 442 | const auto SIT = NodeToInfo.find(Succ); | 236 | 442 | // Don't visit nodes more than once but remember to collect | 237 | 442 | // ReverseChildren. | 238 | 442 | if (SIT != NodeToInfo.end() && 442 SIT->second.DFSNum != 026 ) { | 239 | 19 | if (Succ != BB19 ) SIT->second.ReverseChildren.push_back(BB)17 ; | 240 | 19 | continue; | 241 | 19 | } | 242 | 442 | | 243 | 423 | if (423 !Condition(BB, Succ)423 ) continue105 ; | 244 | 423 | | 245 | 423 | // It's fine to add Succ to the map, because we know that it will be | 246 | 423 | // visited later. | 247 | 318 | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 318 | WorkList.push_back(Succ); | 249 | 318 | SuccInfo.Parent = LastNum; | 250 | 318 | SuccInfo.ReverseChildren.push_back(BB); | 251 | 318 | } | 252 | 443 | } | 253 | 125 | | 254 | 125 | return LastNum; | 255 | 125 | } |
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda0'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda0'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) Line | Count | Source | 217 | 267k | unsigned AttachToNum) { | 218 | 267k | assert(V); | 219 | 267k | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 267k | if (NodeToInfo.count(V) != 0267k ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 267k | | 222 | 8.91M | while (!WorkList.empty()8.91M ) { | 223 | 8.65M | const NodePtr BB = WorkList.pop_back_val(); | 224 | 8.65M | auto &BBInfo = NodeToInfo[BB]; | 225 | 8.65M | | 226 | 8.65M | // Visited nodes always have positive DFS numbers. | 227 | 8.65M | if (BBInfo.DFSNum != 08.65M ) continue961k ; | 228 | 7.68M | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 7.68M | BBInfo.Label = BB; | 230 | 7.68M | NumToNode.push_back(BB); | 231 | 7.68M | | 232 | 7.68M | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 7.68M | for (const NodePtr Succ : | 234 | 11.8M | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 11.8M | const auto SIT = NodeToInfo.find(Succ); | 236 | 11.8M | // Don't visit nodes more than once but remember to collect | 237 | 11.8M | // ReverseChildren. | 238 | 11.8M | if (SIT != NodeToInfo.end() && 11.8M SIT->second.DFSNum != 03.86M ) { | 239 | 2.90M | if (Succ != BB2.90M ) SIT->second.ReverseChildren.push_back(BB)2.44M ; | 240 | 2.90M | continue; | 241 | 2.90M | } | 242 | 11.8M | | 243 | 8.91M | if (8.91M !Condition(BB, Succ)8.91M ) continue528k ; | 244 | 8.91M | | 245 | 8.91M | // It's fine to add Succ to the map, because we know that it will be | 246 | 8.91M | // visited later. | 247 | 8.38M | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 8.38M | WorkList.push_back(Succ); | 249 | 8.38M | SuccInfo.Parent = LastNum; | 250 | 8.38M | SuccInfo.ReverseChildren.push_back(BB); | 251 | 8.38M | } | 252 | 8.65M | } | 253 | 267k | | 254 | 267k | return LastNum; | 255 | 267k | } |
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<false, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) Line | Count | Source | 217 | 4.96M | unsigned AttachToNum) { | 218 | 4.96M | assert(V); | 219 | 4.96M | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 4.96M | if (NodeToInfo.count(V) != 04.96M ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 4.96M | | 222 | 34.4M | while (!WorkList.empty()34.4M ) { | 223 | 29.4M | const NodePtr BB = WorkList.pop_back_val(); | 224 | 29.4M | auto &BBInfo = NodeToInfo[BB]; | 225 | 29.4M | | 226 | 29.4M | // Visited nodes always have positive DFS numbers. | 227 | 29.4M | if (BBInfo.DFSNum != 029.4M ) continue4.37M ; | 228 | 25.1M | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 25.1M | BBInfo.Label = BB; | 230 | 25.1M | NumToNode.push_back(BB); | 231 | 25.1M | | 232 | 25.1M | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 25.1M | for (const NodePtr Succ : | 234 | 32.4M | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 32.4M | const auto SIT = NodeToInfo.find(Succ); | 236 | 32.4M | // Don't visit nodes more than once but remember to collect | 237 | 32.4M | // ReverseChildren. | 238 | 32.4M | if (SIT != NodeToInfo.end() && 32.4M SIT->second.DFSNum != 012.3M ) { | 239 | 7.92M | if (Succ != BB7.92M ) SIT->second.ReverseChildren.push_back(BB)6.73M ; | 240 | 7.92M | continue; | 241 | 7.92M | } | 242 | 32.4M | | 243 | 24.5M | if (24.5M !Condition(BB, Succ)24.5M ) continue0 ; | 244 | 24.5M | | 245 | 24.5M | // It's fine to add Succ to the map, because we know that it will be | 246 | 24.5M | // visited later. | 247 | 24.5M | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 24.5M | WorkList.push_back(Succ); | 249 | 24.5M | SuccInfo.Parent = LastNum; | 250 | 24.5M | SuccInfo.ReverseChildren.push_back(BB); | 251 | 24.5M | } | 252 | 29.4M | } | 253 | 4.96M | | 254 | 4.96M | return LastNum; | 255 | 4.96M | } |
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<true, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) Line | Count | Source | 217 | 2.21k | unsigned AttachToNum) { | 218 | 2.21k | assert(V); | 219 | 2.21k | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 2.21k | if (NodeToInfo.count(V) != 02.21k ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 2.21k | | 222 | 8.73k | while (!WorkList.empty()8.73k ) { | 223 | 6.52k | const NodePtr BB = WorkList.pop_back_val(); | 224 | 6.52k | auto &BBInfo = NodeToInfo[BB]; | 225 | 6.52k | | 226 | 6.52k | // Visited nodes always have positive DFS numbers. | 227 | 6.52k | if (BBInfo.DFSNum != 06.52k ) continue1.02k ; | 228 | 5.50k | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 5.50k | BBInfo.Label = BB; | 230 | 5.50k | NumToNode.push_back(BB); | 231 | 5.50k | | 232 | 5.50k | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 5.50k | for (const NodePtr Succ : | 234 | 8.66k | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 8.66k | const auto SIT = NodeToInfo.find(Succ); | 236 | 8.66k | // Don't visit nodes more than once but remember to collect | 237 | 8.66k | // ReverseChildren. | 238 | 8.66k | if (SIT != NodeToInfo.end() && 8.66k SIT->second.DFSNum != 05.36k ) { | 239 | 4.34k | if (Succ != BB4.34k ) SIT->second.ReverseChildren.push_back(BB)2.25k ; | 240 | 4.34k | continue; | 241 | 4.34k | } | 242 | 8.66k | | 243 | 4.31k | if (4.31k !Condition(BB, Succ)4.31k ) continue0 ; | 244 | 4.31k | | 245 | 4.31k | // It's fine to add Succ to the map, because we know that it will be | 246 | 4.31k | // visited later. | 247 | 4.31k | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 4.31k | WorkList.push_back(Succ); | 249 | 4.31k | SuccInfo.Parent = LastNum; | 250 | 4.31k | SuccInfo.ReverseChildren.push_back(BB); | 251 | 4.31k | } | 252 | 6.52k | } | 253 | 2.21k | | 254 | 2.21k | return LastNum; | 255 | 2.21k | } |
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda0'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::MachineBasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda0'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*), unsigned int) unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<false, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) Line | Count | Source | 217 | 12.2M | unsigned AttachToNum) { | 218 | 12.2M | assert(V); | 219 | 12.2M | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 12.2M | if (NodeToInfo.count(V) != 012.2M ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 12.2M | | 222 | 122M | while (!WorkList.empty()122M ) { | 223 | 110M | const NodePtr BB = WorkList.pop_back_val(); | 224 | 110M | auto &BBInfo = NodeToInfo[BB]; | 225 | 110M | | 226 | 110M | // Visited nodes always have positive DFS numbers. | 227 | 110M | if (BBInfo.DFSNum != 0110M ) continue9.44M ; | 228 | 101M | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 101M | BBInfo.Label = BB; | 230 | 101M | NumToNode.push_back(BB); | 231 | 101M | | 232 | 101M | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 101M | for (const NodePtr Succ : | 234 | 139M | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 139M | const auto SIT = NodeToInfo.find(Succ); | 236 | 139M | // Don't visit nodes more than once but remember to collect | 237 | 139M | // ReverseChildren. | 238 | 139M | if (SIT != NodeToInfo.end() && 139M SIT->second.DFSNum != 050.2M ) { | 239 | 40.8M | if (Succ != BB40.8M ) SIT->second.ReverseChildren.push_back(BB)31.6M ; | 240 | 40.8M | continue; | 241 | 40.8M | } | 242 | 139M | | 243 | 98.5M | if (98.5M !Condition(BB, Succ)98.5M ) continue0 ; | 244 | 98.5M | | 245 | 98.5M | // It's fine to add Succ to the map, because we know that it will be | 246 | 98.5M | // visited later. | 247 | 98.5M | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 98.5M | WorkList.push_back(Succ); | 249 | 98.5M | SuccInfo.Parent = LastNum; | 250 | 98.5M | SuccInfo.ReverseChildren.push_back(BB); | 251 | 98.5M | } | 252 | 110M | } | 253 | 12.2M | | 254 | 12.2M | return LastNum; | 255 | 12.2M | } |
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) Line | Count | Source | 217 | 411k | unsigned AttachToNum) { | 218 | 411k | assert(V); | 219 | 411k | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 411k | if (NodeToInfo.count(V) != 0411k ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 411k | | 222 | 1.40M | while (!WorkList.empty()1.40M ) { | 223 | 990k | const NodePtr BB = WorkList.pop_back_val(); | 224 | 990k | auto &BBInfo = NodeToInfo[BB]; | 225 | 990k | | 226 | 990k | // Visited nodes always have positive DFS numbers. | 227 | 990k | if (BBInfo.DFSNum != 0990k ) continue46.4k ; | 228 | 944k | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 944k | BBInfo.Label = BB; | 230 | 944k | NumToNode.push_back(BB); | 231 | 944k | | 232 | 944k | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 944k | for (const NodePtr Succ : | 234 | 1.21M | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 1.21M | const auto SIT = NodeToInfo.find(Succ); | 236 | 1.21M | // Don't visit nodes more than once but remember to collect | 237 | 1.21M | // ReverseChildren. | 238 | 1.21M | if (SIT != NodeToInfo.end() && 1.21M SIT->second.DFSNum != 0222k ) { | 239 | 175k | if (Succ != BB175k ) SIT->second.ReverseChildren.push_back(BB)133k ; | 240 | 175k | continue; | 241 | 175k | } | 242 | 1.21M | | 243 | 1.04M | if (1.04M !Condition(BB, Succ)1.04M ) continue464k ; | 244 | 1.04M | | 245 | 1.04M | // It's fine to add Succ to the map, because we know that it will be | 246 | 1.04M | // visited later. | 247 | 579k | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 579k | WorkList.push_back(Succ); | 249 | 579k | SuccInfo.Parent = LastNum; | 250 | 579k | SuccInfo.ReverseChildren.push_back(BB); | 251 | 579k | } | 252 | 990k | } | 253 | 411k | | 254 | 411k | return LastNum; | 255 | 411k | } |
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) Line | Count | Source | 217 | 308k | unsigned AttachToNum) { | 218 | 308k | assert(V); | 219 | 308k | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 308k | if (NodeToInfo.count(V) != 0308k ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 308k | | 222 | 10.9M | while (!WorkList.empty()10.9M ) { | 223 | 10.6M | const NodePtr BB = WorkList.pop_back_val(); | 224 | 10.6M | auto &BBInfo = NodeToInfo[BB]; | 225 | 10.6M | | 226 | 10.6M | // Visited nodes always have positive DFS numbers. | 227 | 10.6M | if (BBInfo.DFSNum != 010.6M ) continue1.18M ; | 228 | 9.42M | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 9.42M | BBInfo.Label = BB; | 230 | 9.42M | NumToNode.push_back(BB); | 231 | 9.42M | | 232 | 9.42M | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 9.42M | for (const NodePtr Succ : | 234 | 14.6M | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 14.6M | const auto SIT = NodeToInfo.find(Succ); | 236 | 14.6M | // Don't visit nodes more than once but remember to collect | 237 | 14.6M | // ReverseChildren. | 238 | 14.6M | if (SIT != NodeToInfo.end() && 14.6M SIT->second.DFSNum != 04.71M ) { | 239 | 3.53M | if (Succ != BB3.53M ) SIT->second.ReverseChildren.push_back(BB)3.23M ; | 240 | 3.53M | continue; | 241 | 3.53M | } | 242 | 14.6M | | 243 | 11.1M | if (11.1M !Condition(BB, Succ)11.1M ) continue830k ; | 244 | 11.1M | | 245 | 11.1M | // It's fine to add Succ to the map, because we know that it will be | 246 | 11.1M | // visited later. | 247 | 10.2M | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 10.2M | WorkList.push_back(Succ); | 249 | 10.2M | SuccInfo.Parent = LastNum; | 250 | 10.2M | SuccInfo.ReverseChildren.push_back(BB); | 251 | 10.2M | } | 252 | 10.6M | } | 253 | 308k | | 254 | 308k | return LastNum; | 255 | 308k | } |
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<false, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) Line | Count | Source | 217 | 1.23M | unsigned AttachToNum) { | 218 | 1.23M | assert(V); | 219 | 1.23M | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 1.23M | if (NodeToInfo.count(V) != 01.23M ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 1.23M | | 222 | 9.60M | while (!WorkList.empty()9.60M ) { | 223 | 8.37M | const NodePtr BB = WorkList.pop_back_val(); | 224 | 8.37M | auto &BBInfo = NodeToInfo[BB]; | 225 | 8.37M | | 226 | 8.37M | // Visited nodes always have positive DFS numbers. | 227 | 8.37M | if (BBInfo.DFSNum != 08.37M ) continue350k ; | 228 | 8.02M | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 8.02M | BBInfo.Label = BB; | 230 | 8.02M | NumToNode.push_back(BB); | 231 | 8.02M | | 232 | 8.02M | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 8.02M | for (const NodePtr Succ : | 234 | 10.6M | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 10.6M | const auto SIT = NodeToInfo.find(Succ); | 236 | 10.6M | // Don't visit nodes more than once but remember to collect | 237 | 10.6M | // ReverseChildren. | 238 | 10.6M | if (SIT != NodeToInfo.end() && 10.6M SIT->second.DFSNum != 03.85M ) { | 239 | 3.50M | if (Succ != BB3.50M ) SIT->second.ReverseChildren.push_back(BB)3.15M ; | 240 | 3.50M | continue; | 241 | 3.50M | } | 242 | 10.6M | | 243 | 7.13M | if (7.13M !Condition(BB, Succ)7.13M ) continue0 ; | 244 | 7.13M | | 245 | 7.13M | // It's fine to add Succ to the map, because we know that it will be | 246 | 7.13M | // visited later. | 247 | 7.13M | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 7.13M | WorkList.push_back(Succ); | 249 | 7.13M | SuccInfo.Parent = LastNum; | 250 | 7.13M | SuccInfo.ReverseChildren.push_back(BB); | 251 | 7.13M | } | 252 | 8.37M | } | 253 | 1.23M | | 254 | 1.23M | return LastNum; | 255 | 1.23M | } |
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<true, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) Line | Count | Source | 217 | 692 | unsigned AttachToNum) { | 218 | 692 | assert(V); | 219 | 692 | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 692 | if (NodeToInfo.count(V) != 0692 ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 692 | | 222 | 2.35k | while (!WorkList.empty()2.35k ) { | 223 | 1.66k | const NodePtr BB = WorkList.pop_back_val(); | 224 | 1.66k | auto &BBInfo = NodeToInfo[BB]; | 225 | 1.66k | | 226 | 1.66k | // Visited nodes always have positive DFS numbers. | 227 | 1.66k | if (BBInfo.DFSNum != 01.66k ) continue52 ; | 228 | 1.61k | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 1.61k | BBInfo.Label = BB; | 230 | 1.61k | NumToNode.push_back(BB); | 231 | 1.61k | | 232 | 1.61k | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 1.61k | for (const NodePtr Succ : | 234 | 1.81k | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 1.81k | const auto SIT = NodeToInfo.find(Succ); | 236 | 1.81k | // Don't visit nodes more than once but remember to collect | 237 | 1.81k | // ReverseChildren. | 238 | 1.81k | if (SIT != NodeToInfo.end() && 1.81k SIT->second.DFSNum != 0892 ) { | 239 | 840 | if (Succ != BB840 ) SIT->second.ReverseChildren.push_back(BB)470 ; | 240 | 840 | continue; | 241 | 840 | } | 242 | 1.81k | | 243 | 974 | if (974 !Condition(BB, Succ)974 ) continue0 ; | 244 | 974 | | 245 | 974 | // It's fine to add Succ to the map, because we know that it will be | 246 | 974 | // visited later. | 247 | 974 | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 974 | WorkList.push_back(Succ); | 249 | 974 | SuccInfo.Parent = LastNum; | 250 | 974 | SuccInfo.ReverseChildren.push_back(BB); | 251 | 974 | } | 252 | 1.66k | } | 253 | 692 | | 254 | 692 | return LastNum; | 255 | 692 | } |
unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) Line | Count | Source | 217 | 206k | unsigned AttachToNum) { | 218 | 206k | assert(V); | 219 | 206k | SmallVector<NodePtr, 64> WorkList = {V}; | 220 | 206k | if (NodeToInfo.count(V) != 0206k ) NodeToInfo[V].Parent = AttachToNum0 ; | 221 | 206k | | 222 | 892k | while (!WorkList.empty()892k ) { | 223 | 685k | const NodePtr BB = WorkList.pop_back_val(); | 224 | 685k | auto &BBInfo = NodeToInfo[BB]; | 225 | 685k | | 226 | 685k | // Visited nodes always have positive DFS numbers. | 227 | 685k | if (BBInfo.DFSNum != 0685k ) continue47.2k ; | 228 | 638k | BBInfo.DFSNum = BBInfo.Semi = ++LastNum; | 229 | 638k | BBInfo.Label = BB; | 230 | 638k | NumToNode.push_back(BB); | 231 | 638k | | 232 | 638k | constexpr bool Direction = IsReverse != IsPostDom; // XOR. | 233 | 638k | for (const NodePtr Succ : | 234 | 733k | ChildrenGetter<Direction>::Get(BB, BatchUpdates)) { | 235 | 733k | const auto SIT = NodeToInfo.find(Succ); | 236 | 733k | // Don't visit nodes more than once but remember to collect | 237 | 733k | // ReverseChildren. | 238 | 733k | if (SIT != NodeToInfo.end() && 733k SIT->second.DFSNum != 0185k ) { | 239 | 138k | if (Succ != BB138k ) SIT->second.ReverseChildren.push_back(BB)125k ; | 240 | 138k | continue; | 241 | 138k | } | 242 | 733k | | 243 | 594k | if (594k !Condition(BB, Succ)594k ) continue115k ; | 244 | 594k | | 245 | 594k | // It's fine to add Succ to the map, because we know that it will be | 246 | 594k | // visited later. | 247 | 479k | auto &SuccInfo = NodeToInfo[Succ]; | 248 | 479k | WorkList.push_back(Succ); | 249 | 479k | SuccInfo.Parent = LastNum; | 250 | 479k | SuccInfo.ReverseChildren.push_back(BB); | 251 | 479k | } | 252 | 685k | } | 253 | 206k | | 254 | 206k | return LastNum; | 255 | 206k | } |
Unexecuted instantiation: unsigned int llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runDFS<false, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::BasicBlock*, unsigned int, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*), unsigned int) |
256 | | |
257 | 205M | NodePtr eval(NodePtr VIn, unsigned LastLinked) { |
258 | 205M | auto &VInInfo = NodeToInfo[VIn]; |
259 | 205M | if (VInInfo.DFSNum < LastLinked) |
260 | 155M | return VIn; |
261 | 205M | |
262 | 49.2M | SmallVector<NodePtr, 32> Work; |
263 | 49.2M | SmallPtrSet<NodePtr, 32> Visited; |
264 | 49.2M | |
265 | 49.2M | if (VInInfo.Parent >= LastLinked) |
266 | 31.6M | Work.push_back(VIn); |
267 | 49.2M | |
268 | 253M | while (!Work.empty()253M ) { |
269 | 204M | NodePtr V = Work.back(); |
270 | 204M | auto &VInfo = NodeToInfo[V]; |
271 | 204M | NodePtr VAncestor = NumToNode[VInfo.Parent]; |
272 | 204M | |
273 | 204M | // Process Ancestor first |
274 | 204M | if (Visited.insert(VAncestor).second && 204M VInfo.Parent >= LastLinked117M ) { |
275 | 86.2M | Work.push_back(VAncestor); |
276 | 86.2M | continue; |
277 | 86.2M | } |
278 | 117M | Work.pop_back(); |
279 | 117M | |
280 | 117M | // Update VInfo based on Ancestor info |
281 | 117M | if (VInfo.Parent < LastLinked) |
282 | 31.6M | continue; |
283 | 117M | |
284 | 86.2M | auto &VAInfo = NodeToInfo[VAncestor]; |
285 | 86.2M | NodePtr VAncestorLabel = VAInfo.Label; |
286 | 86.2M | NodePtr VLabel = VInfo.Label; |
287 | 86.2M | if (NodeToInfo[VAncestorLabel].Semi < NodeToInfo[VLabel].Semi) |
288 | 81.9M | VInfo.Label = VAncestorLabel; |
289 | 204M | VInfo.Parent = VAInfo.Parent; |
290 | 204M | } |
291 | 49.2M | |
292 | 49.2M | return VInInfo.Label; |
293 | 205M | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::eval(clang::CFGBlock*, unsigned int) Line | Count | Source | 257 | 61 | NodePtr eval(NodePtr VIn, unsigned LastLinked) { | 258 | 61 | auto &VInInfo = NodeToInfo[VIn]; | 259 | 61 | if (VInInfo.DFSNum < LastLinked) | 260 | 48 | return VIn; | 261 | 61 | | 262 | 13 | SmallVector<NodePtr, 32> Work; | 263 | 13 | SmallPtrSet<NodePtr, 32> Visited; | 264 | 13 | | 265 | 13 | if (VInInfo.Parent >= LastLinked) | 266 | 7 | Work.push_back(VIn); | 267 | 13 | | 268 | 40 | while (!Work.empty()40 ) { | 269 | 27 | NodePtr V = Work.back(); | 270 | 27 | auto &VInfo = NodeToInfo[V]; | 271 | 27 | NodePtr VAncestor = NumToNode[VInfo.Parent]; | 272 | 27 | | 273 | 27 | // Process Ancestor first | 274 | 27 | if (Visited.insert(VAncestor).second && 27 VInfo.Parent >= LastLinked17 ) { | 275 | 10 | Work.push_back(VAncestor); | 276 | 10 | continue; | 277 | 10 | } | 278 | 17 | Work.pop_back(); | 279 | 17 | | 280 | 17 | // Update VInfo based on Ancestor info | 281 | 17 | if (VInfo.Parent < LastLinked) | 282 | 7 | continue; | 283 | 17 | | 284 | 10 | auto &VAInfo = NodeToInfo[VAncestor]; | 285 | 10 | NodePtr VAncestorLabel = VAInfo.Label; | 286 | 10 | NodePtr VLabel = VInfo.Label; | 287 | 10 | if (NodeToInfo[VAncestorLabel].Semi < NodeToInfo[VLabel].Semi) | 288 | 10 | VInfo.Label = VAncestorLabel; | 289 | 27 | VInfo.Parent = VAInfo.Parent; | 290 | 27 | } | 291 | 13 | | 292 | 13 | return VInInfo.Label; | 293 | 61 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::eval(llvm::MachineBasicBlock*, unsigned int) Line | Count | Source | 257 | 15.6M | NodePtr eval(NodePtr VIn, unsigned LastLinked) { | 258 | 15.6M | auto &VInInfo = NodeToInfo[VIn]; | 259 | 15.6M | if (VInInfo.DFSNum < LastLinked) | 260 | 12.2M | return VIn; | 261 | 15.6M | | 262 | 3.36M | SmallVector<NodePtr, 32> Work; | 263 | 3.36M | SmallPtrSet<NodePtr, 32> Visited; | 264 | 3.36M | | 265 | 3.36M | if (VInInfo.Parent >= LastLinked) | 266 | 1.36M | Work.push_back(VIn); | 267 | 3.36M | | 268 | 13.8M | while (!Work.empty()13.8M ) { | 269 | 10.5M | NodePtr V = Work.back(); | 270 | 10.5M | auto &VInfo = NodeToInfo[V]; | 271 | 10.5M | NodePtr VAncestor = NumToNode[VInfo.Parent]; | 272 | 10.5M | | 273 | 10.5M | // Process Ancestor first | 274 | 10.5M | if (Visited.insert(VAncestor).second && 10.5M VInfo.Parent >= LastLinked5.93M ) { | 275 | 4.56M | Work.push_back(VAncestor); | 276 | 4.56M | continue; | 277 | 4.56M | } | 278 | 5.93M | Work.pop_back(); | 279 | 5.93M | | 280 | 5.93M | // Update VInfo based on Ancestor info | 281 | 5.93M | if (VInfo.Parent < LastLinked) | 282 | 1.36M | continue; | 283 | 5.93M | | 284 | 4.56M | auto &VAInfo = NodeToInfo[VAncestor]; | 285 | 4.56M | NodePtr VAncestorLabel = VAInfo.Label; | 286 | 4.56M | NodePtr VLabel = VInfo.Label; | 287 | 4.56M | if (NodeToInfo[VAncestorLabel].Semi < NodeToInfo[VLabel].Semi) | 288 | 3.04M | VInfo.Label = VAncestorLabel; | 289 | 10.5M | VInfo.Parent = VAInfo.Parent; | 290 | 10.5M | } | 291 | 3.36M | | 292 | 3.36M | return VInInfo.Label; | 293 | 15.6M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::eval(llvm::BasicBlock*, unsigned int) Line | Count | Source | 257 | 155M | NodePtr eval(NodePtr VIn, unsigned LastLinked) { | 258 | 155M | auto &VInInfo = NodeToInfo[VIn]; | 259 | 155M | if (VInInfo.DFSNum < LastLinked) | 260 | 117M | return VIn; | 261 | 155M | | 262 | 37.3M | SmallVector<NodePtr, 32> Work; | 263 | 37.3M | SmallPtrSet<NodePtr, 32> Visited; | 264 | 37.3M | | 265 | 37.3M | if (VInInfo.Parent >= LastLinked) | 266 | 25.1M | Work.push_back(VIn); | 267 | 37.3M | | 268 | 200M | while (!Work.empty()200M ) { | 269 | 163M | NodePtr V = Work.back(); | 270 | 163M | auto &VInfo = NodeToInfo[V]; | 271 | 163M | NodePtr VAncestor = NumToNode[VInfo.Parent]; | 272 | 163M | | 273 | 163M | // Process Ancestor first | 274 | 163M | if (Visited.insert(VAncestor).second && 163M VInfo.Parent >= LastLinked94.3M ) { | 275 | 69.1M | Work.push_back(VAncestor); | 276 | 69.1M | continue; | 277 | 69.1M | } | 278 | 94.3M | Work.pop_back(); | 279 | 94.3M | | 280 | 94.3M | // Update VInfo based on Ancestor info | 281 | 94.3M | if (VInfo.Parent < LastLinked) | 282 | 25.1M | continue; | 283 | 94.3M | | 284 | 69.1M | auto &VAInfo = NodeToInfo[VAncestor]; | 285 | 69.1M | NodePtr VAncestorLabel = VAInfo.Label; | 286 | 69.1M | NodePtr VLabel = VInfo.Label; | 287 | 69.1M | if (NodeToInfo[VAncestorLabel].Semi < NodeToInfo[VLabel].Semi) | 288 | 67.2M | VInfo.Label = VAncestorLabel; | 289 | 163M | VInfo.Parent = VAInfo.Parent; | 290 | 163M | } | 291 | 37.3M | | 292 | 37.3M | return VInInfo.Label; | 293 | 155M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::eval(llvm::BasicBlock*, unsigned int) Line | Count | Source | 257 | 5.14M | NodePtr eval(NodePtr VIn, unsigned LastLinked) { | 258 | 5.14M | auto &VInInfo = NodeToInfo[VIn]; | 259 | 5.14M | if (VInInfo.DFSNum < LastLinked) | 260 | 3.56M | return VIn; | 261 | 5.14M | | 262 | 1.57M | SmallVector<NodePtr, 32> Work; | 263 | 1.57M | SmallPtrSet<NodePtr, 32> Visited; | 264 | 1.57M | | 265 | 1.57M | if (VInInfo.Parent >= LastLinked) | 266 | 729k | Work.push_back(VIn); | 267 | 1.57M | | 268 | 5.40M | while (!Work.empty()5.40M ) { | 269 | 3.82M | NodePtr V = Work.back(); | 270 | 3.82M | auto &VInfo = NodeToInfo[V]; | 271 | 3.82M | NodePtr VAncestor = NumToNode[VInfo.Parent]; | 272 | 3.82M | | 273 | 3.82M | // Process Ancestor first | 274 | 3.82M | if (Visited.insert(VAncestor).second && 3.82M VInfo.Parent >= LastLinked2.27M ) { | 275 | 1.54M | Work.push_back(VAncestor); | 276 | 1.54M | continue; | 277 | 1.54M | } | 278 | 2.27M | Work.pop_back(); | 279 | 2.27M | | 280 | 2.27M | // Update VInfo based on Ancestor info | 281 | 2.27M | if (VInfo.Parent < LastLinked) | 282 | 729k | continue; | 283 | 2.27M | | 284 | 1.54M | auto &VAInfo = NodeToInfo[VAncestor]; | 285 | 1.54M | NodePtr VAncestorLabel = VAInfo.Label; | 286 | 1.54M | NodePtr VLabel = VInfo.Label; | 287 | 1.54M | if (NodeToInfo[VAncestorLabel].Semi < NodeToInfo[VLabel].Semi) | 288 | 1.00M | VInfo.Label = VAncestorLabel; | 289 | 3.82M | VInfo.Parent = VAInfo.Parent; | 290 | 3.82M | } | 291 | 1.57M | | 292 | 1.57M | return VInInfo.Label; | 293 | 5.14M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::eval(llvm::MachineBasicBlock*, unsigned int) Line | Count | Source | 257 | 29.3M | NodePtr eval(NodePtr VIn, unsigned LastLinked) { | 258 | 29.3M | auto &VInInfo = NodeToInfo[VIn]; | 259 | 29.3M | if (VInInfo.DFSNum < LastLinked) | 260 | 22.3M | return VIn; | 261 | 29.3M | | 262 | 7.01M | SmallVector<NodePtr, 32> Work; | 263 | 7.01M | SmallPtrSet<NodePtr, 32> Visited; | 264 | 7.01M | | 265 | 7.01M | if (VInInfo.Parent >= LastLinked) | 266 | 4.34M | Work.push_back(VIn); | 267 | 7.01M | | 268 | 33.3M | while (!Work.empty()33.3M ) { | 269 | 26.3M | NodePtr V = Work.back(); | 270 | 26.3M | auto &VInfo = NodeToInfo[V]; | 271 | 26.3M | NodePtr VAncestor = NumToNode[VInfo.Parent]; | 272 | 26.3M | | 273 | 26.3M | // Process Ancestor first | 274 | 26.3M | if (Visited.insert(VAncestor).second && 26.3M VInfo.Parent >= LastLinked15.3M ) { | 275 | 10.9M | Work.push_back(VAncestor); | 276 | 10.9M | continue; | 277 | 10.9M | } | 278 | 15.3M | Work.pop_back(); | 279 | 15.3M | | 280 | 15.3M | // Update VInfo based on Ancestor info | 281 | 15.3M | if (VInfo.Parent < LastLinked) | 282 | 4.34M | continue; | 283 | 15.3M | | 284 | 10.9M | auto &VAInfo = NodeToInfo[VAncestor]; | 285 | 10.9M | NodePtr VAncestorLabel = VAInfo.Label; | 286 | 10.9M | NodePtr VLabel = VInfo.Label; | 287 | 10.9M | if (NodeToInfo[VAncestorLabel].Semi < NodeToInfo[VLabel].Semi) | 288 | 10.6M | VInfo.Label = VAncestorLabel; | 289 | 26.3M | VInfo.Parent = VAInfo.Parent; | 290 | 26.3M | } | 291 | 7.01M | | 292 | 7.01M | return VInInfo.Label; | 293 | 29.3M | } |
|
294 | | |
295 | | // This function requires DFS to be run before calling it. |
296 | 19.0M | void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) { |
297 | 19.0M | const unsigned NextDFSNum(NumToNode.size()); |
298 | 19.0M | // Initialize IDoms to spanning tree parents. |
299 | 180M | for (unsigned i = 1; i < NextDFSNum180M ; ++i161M ) { |
300 | 161M | const NodePtr V = NumToNode[i]; |
301 | 161M | auto &VInfo = NodeToInfo[V]; |
302 | 161M | VInfo.IDom = NumToNode[VInfo.Parent]; |
303 | 161M | } |
304 | 19.0M | |
305 | 19.0M | // Step #1: Calculate the semidominators of all vertices. |
306 | 161M | for (unsigned i = NextDFSNum - 1; i >= 2161M ; --i142M ) { |
307 | 142M | NodePtr W = NumToNode[i]; |
308 | 142M | auto &WInfo = NodeToInfo[W]; |
309 | 142M | |
310 | 142M | // Initialize the semi dominator to point to the parent node. |
311 | 142M | WInfo.Semi = WInfo.Parent; |
312 | 205M | for (const auto &N : WInfo.ReverseChildren) { |
313 | 205M | if (NodeToInfo.count(N) == 0) // Skip unreachable predecessors. |
314 | 0 | continue; |
315 | 205M | |
316 | 205M | const TreeNodePtr TN = DT.getNode(N); |
317 | 205M | // Skip predecessors whose level is above the subtree we are processing. |
318 | 205M | if (TN && 205M TN->getLevel() < MinLevel24.2M ) |
319 | 0 | continue; |
320 | 205M | |
321 | 205M | unsigned SemiU = NodeToInfo[eval(N, i + 1)].Semi; |
322 | 205M | if (SemiU < WInfo.Semi205M ) WInfo.Semi = SemiU23.9M ; |
323 | 205M | } |
324 | 142M | } |
325 | 19.0M | |
326 | 19.0M | // Step #2: Explicitly define the immediate dominator of each vertex. |
327 | 19.0M | // IDom[i] = NCA(SDom[i], SpanningTreeParent(i)). |
328 | 19.0M | // Note that the parents were stored in IDoms and later got invalidated |
329 | 19.0M | // during path compression in Eval. |
330 | 161M | for (unsigned i = 2; i < NextDFSNum161M ; ++i142M ) { |
331 | 142M | const NodePtr W = NumToNode[i]; |
332 | 142M | auto &WInfo = NodeToInfo[W]; |
333 | 142M | const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum; |
334 | 142M | NodePtr WIDomCandidate = WInfo.IDom; |
335 | 189M | while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum) |
336 | 46.4M | WIDomCandidate = NodeToInfo[WIDomCandidate].IDom; |
337 | 142M | |
338 | 142M | WInfo.IDom = WIDomCandidate; |
339 | 142M | } |
340 | 19.0M | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::runSemiNCA(llvm::DominatorTreeBase<clang::CFGBlock, false>&, unsigned int) Line | Count | Source | 296 | 5 | void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) { | 297 | 5 | const unsigned NextDFSNum(NumToNode.size()); | 298 | 5 | // Initialize IDoms to spanning tree parents. | 299 | 57 | for (unsigned i = 1; i < NextDFSNum57 ; ++i52 ) { | 300 | 52 | const NodePtr V = NumToNode[i]; | 301 | 52 | auto &VInfo = NodeToInfo[V]; | 302 | 52 | VInfo.IDom = NumToNode[VInfo.Parent]; | 303 | 52 | } | 304 | 5 | | 305 | 5 | // Step #1: Calculate the semidominators of all vertices. | 306 | 52 | for (unsigned i = NextDFSNum - 1; i >= 252 ; --i47 ) { | 307 | 47 | NodePtr W = NumToNode[i]; | 308 | 47 | auto &WInfo = NodeToInfo[W]; | 309 | 47 | | 310 | 47 | // Initialize the semi dominator to point to the parent node. | 311 | 47 | WInfo.Semi = WInfo.Parent; | 312 | 61 | for (const auto &N : WInfo.ReverseChildren) { | 313 | 61 | if (NodeToInfo.count(N) == 0) // Skip unreachable predecessors. | 314 | 0 | continue; | 315 | 61 | | 316 | 61 | const TreeNodePtr TN = DT.getNode(N); | 317 | 61 | // Skip predecessors whose level is above the subtree we are processing. | 318 | 61 | if (TN && 61 TN->getLevel() < MinLevel0 ) | 319 | 0 | continue; | 320 | 61 | | 321 | 61 | unsigned SemiU = NodeToInfo[eval(N, i + 1)].Semi; | 322 | 61 | if (SemiU < WInfo.Semi61 ) WInfo.Semi = SemiU7 ; | 323 | 61 | } | 324 | 47 | } | 325 | 5 | | 326 | 5 | // Step #2: Explicitly define the immediate dominator of each vertex. | 327 | 5 | // IDom[i] = NCA(SDom[i], SpanningTreeParent(i)). | 328 | 5 | // Note that the parents were stored in IDoms and later got invalidated | 329 | 5 | // during path compression in Eval. | 330 | 52 | for (unsigned i = 2; i < NextDFSNum52 ; ++i47 ) { | 331 | 47 | const NodePtr W = NumToNode[i]; | 332 | 47 | auto &WInfo = NodeToInfo[W]; | 333 | 47 | const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum; | 334 | 47 | NodePtr WIDomCandidate = WInfo.IDom; | 335 | 56 | while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum) | 336 | 9 | WIDomCandidate = NodeToInfo[WIDomCandidate].IDom; | 337 | 47 | | 338 | 47 | WInfo.IDom = WIDomCandidate; | 339 | 47 | } | 340 | 5 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::runSemiNCA(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, unsigned int) Line | Count | Source | 296 | 582k | void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) { | 297 | 582k | const unsigned NextDFSNum(NumToNode.size()); | 298 | 582k | // Initialize IDoms to spanning tree parents. | 299 | 5.16M | for (unsigned i = 1; i < NextDFSNum5.16M ; ++i4.58M ) { | 300 | 4.58M | const NodePtr V = NumToNode[i]; | 301 | 4.58M | auto &VInfo = NodeToInfo[V]; | 302 | 4.58M | VInfo.IDom = NumToNode[VInfo.Parent]; | 303 | 4.58M | } | 304 | 582k | | 305 | 582k | // Step #1: Calculate the semidominators of all vertices. | 306 | 4.58M | for (unsigned i = NextDFSNum - 1; i >= 24.58M ; --i4.00M ) { | 307 | 4.00M | NodePtr W = NumToNode[i]; | 308 | 4.00M | auto &WInfo = NodeToInfo[W]; | 309 | 4.00M | | 310 | 4.00M | // Initialize the semi dominator to point to the parent node. | 311 | 4.00M | WInfo.Semi = WInfo.Parent; | 312 | 5.14M | for (const auto &N : WInfo.ReverseChildren) { | 313 | 5.14M | if (NodeToInfo.count(N) == 0) // Skip unreachable predecessors. | 314 | 0 | continue; | 315 | 5.14M | | 316 | 5.14M | const TreeNodePtr TN = DT.getNode(N); | 317 | 5.14M | // Skip predecessors whose level is above the subtree we are processing. | 318 | 5.14M | if (TN && 5.14M TN->getLevel() < MinLevel325 ) | 319 | 0 | continue; | 320 | 5.14M | | 321 | 5.14M | unsigned SemiU = NodeToInfo[eval(N, i + 1)].Semi; | 322 | 5.14M | if (SemiU < WInfo.Semi5.14M ) WInfo.Semi = SemiU954k ; | 323 | 5.14M | } | 324 | 4.00M | } | 325 | 582k | | 326 | 582k | // Step #2: Explicitly define the immediate dominator of each vertex. | 327 | 582k | // IDom[i] = NCA(SDom[i], SpanningTreeParent(i)). | 328 | 582k | // Note that the parents were stored in IDoms and later got invalidated | 329 | 582k | // during path compression in Eval. | 330 | 4.58M | for (unsigned i = 2; i < NextDFSNum4.58M ; ++i4.00M ) { | 331 | 4.00M | const NodePtr W = NumToNode[i]; | 332 | 4.00M | auto &WInfo = NodeToInfo[W]; | 333 | 4.00M | const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum; | 334 | 4.00M | NodePtr WIDomCandidate = WInfo.IDom; | 335 | 5.25M | while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum) | 336 | 1.25M | WIDomCandidate = NodeToInfo[WIDomCandidate].IDom; | 337 | 4.00M | | 338 | 4.00M | WInfo.IDom = WIDomCandidate; | 339 | 4.00M | } | 340 | 582k | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::runSemiNCA(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, unsigned int) Line | Count | Source | 296 | 12.9M | void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) { | 297 | 12.9M | const unsigned NextDFSNum(NumToNode.size()); | 298 | 12.9M | // Initialize IDoms to spanning tree parents. | 299 | 132M | for (unsigned i = 1; i < NextDFSNum132M ; ++i119M ) { | 300 | 119M | const NodePtr V = NumToNode[i]; | 301 | 119M | auto &VInfo = NodeToInfo[V]; | 302 | 119M | VInfo.IDom = NumToNode[VInfo.Parent]; | 303 | 119M | } | 304 | 12.9M | | 305 | 12.9M | // Step #1: Calculate the semidominators of all vertices. | 306 | 119M | for (unsigned i = NextDFSNum - 1; i >= 2119M ; --i106M ) { | 307 | 106M | NodePtr W = NumToNode[i]; | 308 | 106M | auto &WInfo = NodeToInfo[W]; | 309 | 106M | | 310 | 106M | // Initialize the semi dominator to point to the parent node. | 311 | 106M | WInfo.Semi = WInfo.Parent; | 312 | 155M | for (const auto &N : WInfo.ReverseChildren) { | 313 | 155M | if (NodeToInfo.count(N) == 0) // Skip unreachable predecessors. | 314 | 0 | continue; | 315 | 155M | | 316 | 155M | const TreeNodePtr TN = DT.getNode(N); | 317 | 155M | // Skip predecessors whose level is above the subtree we are processing. | 318 | 155M | if (TN && 155M TN->getLevel() < MinLevel24.2M ) | 319 | 0 | continue; | 320 | 155M | | 321 | 155M | unsigned SemiU = NodeToInfo[eval(N, i + 1)].Semi; | 322 | 155M | if (SemiU < WInfo.Semi155M ) WInfo.Semi = SemiU14.6M ; | 323 | 155M | } | 324 | 106M | } | 325 | 12.9M | | 326 | 12.9M | // Step #2: Explicitly define the immediate dominator of each vertex. | 327 | 12.9M | // IDom[i] = NCA(SDom[i], SpanningTreeParent(i)). | 328 | 12.9M | // Note that the parents were stored in IDoms and later got invalidated | 329 | 12.9M | // during path compression in Eval. | 330 | 119M | for (unsigned i = 2; i < NextDFSNum119M ; ++i106M ) { | 331 | 106M | const NodePtr W = NumToNode[i]; | 332 | 106M | auto &WInfo = NodeToInfo[W]; | 333 | 106M | const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum; | 334 | 106M | NodePtr WIDomCandidate = WInfo.IDom; | 335 | 137M | while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum) | 336 | 31.8M | WIDomCandidate = NodeToInfo[WIDomCandidate].IDom; | 337 | 106M | | 338 | 106M | WInfo.IDom = WIDomCandidate; | 339 | 106M | } | 340 | 12.9M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::runSemiNCA(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, unsigned int) Line | Count | Source | 296 | 1.77M | void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) { | 297 | 1.77M | const unsigned NextDFSNum(NumToNode.size()); | 298 | 1.77M | // Initialize IDoms to spanning tree parents. | 299 | 16.1M | for (unsigned i = 1; i < NextDFSNum16.1M ; ++i14.3M ) { | 300 | 14.3M | const NodePtr V = NumToNode[i]; | 301 | 14.3M | auto &VInfo = NodeToInfo[V]; | 302 | 14.3M | VInfo.IDom = NumToNode[VInfo.Parent]; | 303 | 14.3M | } | 304 | 1.77M | | 305 | 1.77M | // Step #1: Calculate the semidominators of all vertices. | 306 | 14.3M | for (unsigned i = NextDFSNum - 1; i >= 214.3M ; --i12.5M ) { | 307 | 12.5M | NodePtr W = NumToNode[i]; | 308 | 12.5M | auto &WInfo = NodeToInfo[W]; | 309 | 12.5M | | 310 | 12.5M | // Initialize the semi dominator to point to the parent node. | 311 | 12.5M | WInfo.Semi = WInfo.Parent; | 312 | 15.6M | for (const auto &N : WInfo.ReverseChildren) { | 313 | 15.6M | if (NodeToInfo.count(N) == 0) // Skip unreachable predecessors. | 314 | 0 | continue; | 315 | 15.6M | | 316 | 15.6M | const TreeNodePtr TN = DT.getNode(N); | 317 | 15.6M | // Skip predecessors whose level is above the subtree we are processing. | 318 | 15.6M | if (TN && 15.6M TN->getLevel() < MinLevel0 ) | 319 | 0 | continue; | 320 | 15.6M | | 321 | 15.6M | unsigned SemiU = NodeToInfo[eval(N, i + 1)].Semi; | 322 | 15.6M | if (SemiU < WInfo.Semi15.6M ) WInfo.Semi = SemiU4.99M ; | 323 | 15.6M | } | 324 | 12.5M | } | 325 | 1.77M | | 326 | 1.77M | // Step #2: Explicitly define the immediate dominator of each vertex. | 327 | 1.77M | // IDom[i] = NCA(SDom[i], SpanningTreeParent(i)). | 328 | 1.77M | // Note that the parents were stored in IDoms and later got invalidated | 329 | 1.77M | // during path compression in Eval. | 330 | 14.3M | for (unsigned i = 2; i < NextDFSNum14.3M ; ++i12.5M ) { | 331 | 12.5M | const NodePtr W = NumToNode[i]; | 332 | 12.5M | auto &WInfo = NodeToInfo[W]; | 333 | 12.5M | const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum; | 334 | 12.5M | NodePtr WIDomCandidate = WInfo.IDom; | 335 | 19.6M | while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum) | 336 | 7.07M | WIDomCandidate = NodeToInfo[WIDomCandidate].IDom; | 337 | 12.5M | | 338 | 12.5M | WInfo.IDom = WIDomCandidate; | 339 | 12.5M | } | 340 | 1.77M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::runSemiNCA(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, unsigned int) Line | Count | Source | 296 | 3.66M | void runSemiNCA(DomTreeT &DT, const unsigned MinLevel = 0) { | 297 | 3.66M | const unsigned NextDFSNum(NumToNode.size()); | 298 | 3.66M | // Initialize IDoms to spanning tree parents. | 299 | 27.4M | for (unsigned i = 1; i < NextDFSNum27.4M ; ++i23.8M ) { | 300 | 23.8M | const NodePtr V = NumToNode[i]; | 301 | 23.8M | auto &VInfo = NodeToInfo[V]; | 302 | 23.8M | VInfo.IDom = NumToNode[VInfo.Parent]; | 303 | 23.8M | } | 304 | 3.66M | | 305 | 3.66M | // Step #1: Calculate the semidominators of all vertices. | 306 | 23.8M | for (unsigned i = NextDFSNum - 1; i >= 223.8M ; --i20.1M ) { | 307 | 20.1M | NodePtr W = NumToNode[i]; | 308 | 20.1M | auto &WInfo = NodeToInfo[W]; | 309 | 20.1M | | 310 | 20.1M | // Initialize the semi dominator to point to the parent node. | 311 | 20.1M | WInfo.Semi = WInfo.Parent; | 312 | 29.3M | for (const auto &N : WInfo.ReverseChildren) { | 313 | 29.3M | if (NodeToInfo.count(N) == 0) // Skip unreachable predecessors. | 314 | 0 | continue; | 315 | 29.3M | | 316 | 29.3M | const TreeNodePtr TN = DT.getNode(N); | 317 | 29.3M | // Skip predecessors whose level is above the subtree we are processing. | 318 | 29.3M | if (TN && 29.3M TN->getLevel() < MinLevel0 ) | 319 | 0 | continue; | 320 | 29.3M | | 321 | 29.3M | unsigned SemiU = NodeToInfo[eval(N, i + 1)].Semi; | 322 | 29.3M | if (SemiU < WInfo.Semi29.3M ) WInfo.Semi = SemiU3.34M ; | 323 | 29.3M | } | 324 | 20.1M | } | 325 | 3.66M | | 326 | 3.66M | // Step #2: Explicitly define the immediate dominator of each vertex. | 327 | 3.66M | // IDom[i] = NCA(SDom[i], SpanningTreeParent(i)). | 328 | 3.66M | // Note that the parents were stored in IDoms and later got invalidated | 329 | 3.66M | // during path compression in Eval. | 330 | 23.8M | for (unsigned i = 2; i < NextDFSNum23.8M ; ++i20.1M ) { | 331 | 20.1M | const NodePtr W = NumToNode[i]; | 332 | 20.1M | auto &WInfo = NodeToInfo[W]; | 333 | 20.1M | const unsigned SDomNum = NodeToInfo[NumToNode[WInfo.Semi]].DFSNum; | 334 | 20.1M | NodePtr WIDomCandidate = WInfo.IDom; | 335 | 26.5M | while (NodeToInfo[WIDomCandidate].DFSNum > SDomNum) | 336 | 6.35M | WIDomCandidate = NodeToInfo[WIDomCandidate].IDom; | 337 | 20.1M | | 338 | 20.1M | WInfo.IDom = WIDomCandidate; | 339 | 20.1M | } | 340 | 3.66M | } |
|
341 | | |
342 | | // PostDominatorTree always has a virtual root that represents a virtual CFG |
343 | | // node that serves as a single exit from the function. All the other exits |
344 | | // (CFG nodes with terminators and nodes in infinite loops are logically |
345 | | // connected to this virtual CFG exit node). |
346 | | // This functions maps a nullptr CFG node to the virtual root tree node. |
347 | 4.72M | void addVirtualRoot() { |
348 | 4.72M | assert(IsPostDom && "Only postdominators have a virtual root"); |
349 | 4.72M | assert(NumToNode.size() == 1 && "SNCAInfo must be freshly constructed"); |
350 | 4.72M | |
351 | 4.72M | auto &BBInfo = NodeToInfo[nullptr]; |
352 | 4.72M | BBInfo.DFSNum = BBInfo.Semi = 1; |
353 | 4.72M | BBInfo.Label = nullptr; |
354 | 4.72M | |
355 | 4.72M | NumToNode.push_back(nullptr); // NumToNode[1] = nullptr; |
356 | 4.72M | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::addVirtualRoot() llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::addVirtualRoot() Line | Count | Source | 347 | 1.16M | void addVirtualRoot() { | 348 | 1.16M | assert(IsPostDom && "Only postdominators have a virtual root"); | 349 | 1.16M | assert(NumToNode.size() == 1 && "SNCAInfo must be freshly constructed"); | 350 | 1.16M | | 351 | 1.16M | auto &BBInfo = NodeToInfo[nullptr]; | 352 | 1.16M | BBInfo.DFSNum = BBInfo.Semi = 1; | 353 | 1.16M | BBInfo.Label = nullptr; | 354 | 1.16M | | 355 | 1.16M | NumToNode.push_back(nullptr); // NumToNode[1] = nullptr; | 356 | 1.16M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::addVirtualRoot() Line | Count | Source | 347 | 3.55M | void addVirtualRoot() { | 348 | 3.55M | assert(IsPostDom && "Only postdominators have a virtual root"); | 349 | 3.55M | assert(NumToNode.size() == 1 && "SNCAInfo must be freshly constructed"); | 350 | 3.55M | | 351 | 3.55M | auto &BBInfo = NodeToInfo[nullptr]; | 352 | 3.55M | BBInfo.DFSNum = BBInfo.Semi = 1; | 353 | 3.55M | BBInfo.Label = nullptr; | 354 | 3.55M | | 355 | 3.55M | NumToNode.push_back(nullptr); // NumToNode[1] = nullptr; | 356 | 3.55M | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::addVirtualRoot() Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::addVirtualRoot() |
357 | | |
358 | | // For postdominators, nodes with no forward successors are trivial roots that |
359 | | // are always selected as tree roots. Roots with forward successors correspond |
360 | | // to CFG nodes within infinite loops. |
361 | 16.5M | static bool HasForwardSuccessors(const NodePtr N, BatchUpdatePtr BUI) { |
362 | 16.5M | assert(N && "N must be a valid node"); |
363 | 16.5M | return !ChildrenGetter<false>::Get(N, BUI).empty(); |
364 | 16.5M | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::HasForwardSuccessors(clang::CFGBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::BatchUpdateInfo*) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::HasForwardSuccessors(llvm::BasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*) Line | Count | Source | 361 | 4.01M | static bool HasForwardSuccessors(const NodePtr N, BatchUpdatePtr BUI) { | 362 | 4.01M | assert(N && "N must be a valid node"); | 363 | 4.01M | return !ChildrenGetter<false>::Get(N, BUI).empty(); | 364 | 4.01M | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::HasForwardSuccessors(llvm::BasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::HasForwardSuccessors(llvm::MachineBasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*) Line | Count | Source | 361 | 12.5M | static bool HasForwardSuccessors(const NodePtr N, BatchUpdatePtr BUI) { | 362 | 12.5M | assert(N && "N must be a valid node"); | 363 | 12.5M | return !ChildrenGetter<false>::Get(N, BUI).empty(); | 364 | 12.5M | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::HasForwardSuccessors(llvm::MachineBasicBlock*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*) |
365 | | |
366 | 15.8M | static NodePtr GetEntryNode(const DomTreeT &DT) { |
367 | 15.8M | assert(DT.Parent && "Parent not set"); |
368 | 15.8M | return GraphTraits<typename DomTreeT::ParentPtr>::getEntryNode(DT.Parent); |
369 | 15.8M | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::GetEntryNode(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&) Line | Count | Source | 366 | 12.2M | static NodePtr GetEntryNode(const DomTreeT &DT) { | 367 | 12.2M | assert(DT.Parent && "Parent not set"); | 368 | 12.2M | return GraphTraits<typename DomTreeT::ParentPtr>::getEntryNode(DT.Parent); | 369 | 12.2M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::GetEntryNode(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&) Line | Count | Source | 366 | 3.66M | static NodePtr GetEntryNode(const DomTreeT &DT) { | 367 | 3.66M | assert(DT.Parent && "Parent not set"); | 368 | 3.66M | return GraphTraits<typename DomTreeT::ParentPtr>::getEntryNode(DT.Parent); | 369 | 3.66M | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::GetEntryNode(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::GetEntryNode(llvm::DominatorTreeBase<clang::CFGBlock, false> const&) Line | Count | Source | 366 | 5 | static NodePtr GetEntryNode(const DomTreeT &DT) { | 367 | 5 | assert(DT.Parent && "Parent not set"); | 368 | 5 | return GraphTraits<typename DomTreeT::ParentPtr>::getEntryNode(DT.Parent); | 369 | 5 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::GetEntryNode(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&) |
370 | | |
371 | | // Finds all roots without relaying on the set of roots already stored in the |
372 | | // tree. |
373 | | // We define roots to be some non-redundant set of the CFG nodes |
374 | 18.2M | static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) { |
375 | 18.2M | assert(DT.Parent && "Parent pointer is not set"); |
376 | 18.2M | RootsT Roots; |
377 | 18.2M | |
378 | 18.2M | // For dominators, function entry CFG node is always a tree root node. |
379 | 18.2M | if (!IsPostDom18.2M ) { |
380 | 15.8M | Roots.push_back(GetEntryNode(DT)); |
381 | 15.8M | return Roots; |
382 | 15.8M | } |
383 | 18.2M | |
384 | 2.36M | SemiNCAInfo SNCA(BUI); |
385 | 2.36M | |
386 | 2.36M | // PostDominatorTree always has a virtual root. |
387 | 2.36M | SNCA.addVirtualRoot(); |
388 | 2.36M | unsigned Num = 1; |
389 | 2.36M | |
390 | 2.36M | DEBUG(dbgs() << "\t\tLooking for trivial roots\n"); |
391 | 2.36M | |
392 | 2.36M | // Step #1: Find all the trivial roots that are going to will definitely |
393 | 2.36M | // remain tree roots. |
394 | 2.36M | unsigned Total = 0; |
395 | 2.36M | // It may happen that there are some new nodes in the CFG that are result of |
396 | 2.36M | // the ongoing batch update, but we cannot really pretend that they don't |
397 | 2.36M | // exist -- we won't see any outgoing or incoming edges to them, so it's |
398 | 2.36M | // fine to discover them here, as they would end up appearing in the CFG at |
399 | 2.36M | // some point anyway. |
400 | 16.5M | for (const NodePtr N : nodes(DT.Parent)) { |
401 | 16.5M | ++Total; |
402 | 16.5M | // If it has no *successors*, it is definitely a root. |
403 | 16.5M | if (!HasForwardSuccessors(N, BUI)16.5M ) { |
404 | 3.09M | Roots.push_back(N); |
405 | 3.09M | // Run DFS not to walk this part of CFG later. |
406 | 3.09M | Num = SNCA.runDFS(N, Num, AlwaysDescend, 1); |
407 | 3.09M | DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N) |
408 | 3.09M | << "\n"); |
409 | 3.09M | DEBUG(dbgs() << "Last visited node: " |
410 | 3.09M | << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n"); |
411 | 3.09M | } |
412 | 16.5M | } |
413 | 2.36M | |
414 | 2.36M | DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n"); |
415 | 2.36M | |
416 | 2.36M | // Step #2: Find all non-trivial root candidates. Those are CFG nodes that |
417 | 2.36M | // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG |
418 | 2.36M | // nodes in infinite loops). |
419 | 2.36M | bool HasNonTrivialRoots = false; |
420 | 2.36M | // Accounting for the virtual exit, see if we had any reverse-unreachable |
421 | 2.36M | // nodes. |
422 | 2.36M | if (Total + 1 != Num2.36M ) { |
423 | 1.32k | HasNonTrivialRoots = true; |
424 | 1.32k | // Make another DFS pass over all other nodes to find the |
425 | 1.32k | // reverse-unreachable blocks, and find the furthest paths we'll be able |
426 | 1.32k | // to make. |
427 | 1.32k | // Note that this looks N^2, but it's really 2N worst case, if every node |
428 | 1.32k | // is unreachable. This is because we are still going to only visit each |
429 | 1.32k | // unreachable node once, we may just visit it in two directions, |
430 | 1.32k | // depending on how lucky we get. |
431 | 1.32k | SmallPtrSet<NodePtr, 4> ConnectToExitBlock; |
432 | 12.6k | for (const NodePtr I : nodes(DT.Parent)) { |
433 | 12.6k | if (SNCA.NodeToInfo.count(I) == 012.6k ) { |
434 | 1.45k | DEBUG(dbgs() << "\t\t\tVisiting node " << BlockNamePrinter(I) |
435 | 1.45k | << "\n"); |
436 | 1.45k | // Find the furthest away we can get by following successors, then |
437 | 1.45k | // follow them in reverse. This gives us some reasonable answer about |
438 | 1.45k | // the post-dom tree inside any infinite loop. In particular, it |
439 | 1.45k | // guarantees we get to the farthest away point along *some* |
440 | 1.45k | // path. This also matches the GCC's behavior. |
441 | 1.45k | // If we really wanted a totally complete picture of dominance inside |
442 | 1.45k | // this infinite loop, we could do it with SCC-like algorithms to find |
443 | 1.45k | // the lowest and highest points in the infinite loop. In theory, it |
444 | 1.45k | // would be nice to give the canonical backedge for the loop, but it's |
445 | 1.45k | // expensive and does not always lead to a minimal set of roots. |
446 | 1.45k | DEBUG(dbgs() << "\t\t\tRunning forward DFS\n"); |
447 | 1.45k | |
448 | 1.45k | const unsigned NewNum = SNCA.runDFS<true>(I, Num, AlwaysDescend, Num); |
449 | 1.45k | const NodePtr FurthestAway = SNCA.NumToNode[NewNum]; |
450 | 1.45k | DEBUG(dbgs() << "\t\t\tFound a new furthest away node " |
451 | 1.45k | << "(non-trivial root): " |
452 | 1.45k | << BlockNamePrinter(FurthestAway) << "\n"); |
453 | 1.45k | ConnectToExitBlock.insert(FurthestAway); |
454 | 1.45k | Roots.push_back(FurthestAway); |
455 | 1.45k | DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: " |
456 | 1.45k | << NewNum << "\n\t\t\tRemoving DFS info\n"); |
457 | 5.78k | for (unsigned i = NewNum; i > Num5.78k ; --i4.33k ) { |
458 | 4.33k | const NodePtr N = SNCA.NumToNode[i]; |
459 | 4.33k | DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for " |
460 | 4.33k | << BlockNamePrinter(N) << "\n"); |
461 | 4.33k | SNCA.NodeToInfo.erase(N); |
462 | 4.33k | SNCA.NumToNode.pop_back(); |
463 | 4.33k | } |
464 | 1.45k | const unsigned PrevNum = Num; |
465 | 1.45k | DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n"); |
466 | 1.45k | Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1); |
467 | 5.59k | for (unsigned i = PrevNum + 1; i <= Num5.59k ; ++i4.14k ) |
468 | 1.45k | DEBUG(dbgs() << "\t\t\t\tfound node " |
469 | 1.45k | << BlockNamePrinter(SNCA.NumToNode[i]) << "\n"); |
470 | 1.45k | } |
471 | 12.6k | } |
472 | 1.32k | } |
473 | 2.36M | |
474 | 2.36M | DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n"); |
475 | 2.36M | DEBUG(dbgs() << "Discovered CFG nodes:\n"); |
476 | 2.36M | DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs() |
477 | 2.36M | << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n"); |
478 | 2.36M | |
479 | 2.36M | assert((Total + 1 == Num) && "Everything should have been visited"); |
480 | 2.36M | |
481 | 2.36M | // Step #3: If we found some non-trivial roots, make them non-redundant. |
482 | 2.36M | if (HasNonTrivialRoots2.36M ) RemoveRedundantRoots(DT, BUI, Roots)1.32k ; |
483 | 2.36M | |
484 | 2.36M | DEBUG(dbgs() << "Found roots: "); |
485 | 2.36M | DEBUG(for (auto *Root : Roots) dbgs() << BlockNamePrinter(Root) << " "); |
486 | 2.36M | DEBUG(dbgs() << "\n"); |
487 | 2.36M | |
488 | 2.36M | return Roots; |
489 | 18.2M | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::FindRoots(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*) Line | Count | Source | 374 | 3.66M | static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) { | 375 | 3.66M | assert(DT.Parent && "Parent pointer is not set"); | 376 | 3.66M | RootsT Roots; | 377 | 3.66M | | 378 | 3.66M | // For dominators, function entry CFG node is always a tree root node. | 379 | 3.66M | if (!IsPostDom3.66M ) { | 380 | 3.66M | Roots.push_back(GetEntryNode(DT)); | 381 | 3.66M | return Roots; | 382 | 3.66M | } | 383 | 3.66M | | 384 | 0 | SemiNCAInfo SNCA(BUI); | 385 | 0 |
| 386 | 0 | // PostDominatorTree always has a virtual root. | 387 | 0 | SNCA.addVirtualRoot(); | 388 | 0 | unsigned Num = 1; | 389 | 0 |
| 390 | 0 | DEBUG(dbgs() << "\t\tLooking for trivial roots\n"); | 391 | 0 |
| 392 | 0 | // Step #1: Find all the trivial roots that are going to will definitely | 393 | 0 | // remain tree roots. | 394 | 0 | unsigned Total = 0; | 395 | 0 | // It may happen that there are some new nodes in the CFG that are result of | 396 | 0 | // the ongoing batch update, but we cannot really pretend that they don't | 397 | 0 | // exist -- we won't see any outgoing or incoming edges to them, so it's | 398 | 0 | // fine to discover them here, as they would end up appearing in the CFG at | 399 | 0 | // some point anyway. | 400 | 0 | for (const NodePtr N : nodes(DT.Parent)) { | 401 | 0 | ++Total; | 402 | 0 | // If it has no *successors*, it is definitely a root. | 403 | 0 | if (!HasForwardSuccessors(N, BUI)0 ) { | 404 | 0 | Roots.push_back(N); | 405 | 0 | // Run DFS not to walk this part of CFG later. | 406 | 0 | Num = SNCA.runDFS(N, Num, AlwaysDescend, 1); | 407 | 0 | DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N) | 408 | 0 | << "\n"); | 409 | 0 | DEBUG(dbgs() << "Last visited node: " | 410 | 0 | << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n"); | 411 | 0 | } | 412 | 0 | } | 413 | 0 |
| 414 | 0 | DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n"); | 415 | 0 |
| 416 | 0 | // Step #2: Find all non-trivial root candidates. Those are CFG nodes that | 417 | 0 | // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG | 418 | 0 | // nodes in infinite loops). | 419 | 0 | bool HasNonTrivialRoots = false; | 420 | 0 | // Accounting for the virtual exit, see if we had any reverse-unreachable | 421 | 0 | // nodes. | 422 | 0 | if (Total + 1 != Num0 ) { | 423 | 0 | HasNonTrivialRoots = true; | 424 | 0 | // Make another DFS pass over all other nodes to find the | 425 | 0 | // reverse-unreachable blocks, and find the furthest paths we'll be able | 426 | 0 | // to make. | 427 | 0 | // Note that this looks N^2, but it's really 2N worst case, if every node | 428 | 0 | // is unreachable. This is because we are still going to only visit each | 429 | 0 | // unreachable node once, we may just visit it in two directions, | 430 | 0 | // depending on how lucky we get. | 431 | 0 | SmallPtrSet<NodePtr, 4> ConnectToExitBlock; | 432 | 0 | for (const NodePtr I : nodes(DT.Parent)) { | 433 | 0 | if (SNCA.NodeToInfo.count(I) == 00 ) { | 434 | 0 | DEBUG(dbgs() << "\t\t\tVisiting node " << BlockNamePrinter(I) | 435 | 0 | << "\n"); | 436 | 0 | // Find the furthest away we can get by following successors, then | 437 | 0 | // follow them in reverse. This gives us some reasonable answer about | 438 | 0 | // the post-dom tree inside any infinite loop. In particular, it | 439 | 0 | // guarantees we get to the farthest away point along *some* | 440 | 0 | // path. This also matches the GCC's behavior. | 441 | 0 | // If we really wanted a totally complete picture of dominance inside | 442 | 0 | // this infinite loop, we could do it with SCC-like algorithms to find | 443 | 0 | // the lowest and highest points in the infinite loop. In theory, it | 444 | 0 | // would be nice to give the canonical backedge for the loop, but it's | 445 | 0 | // expensive and does not always lead to a minimal set of roots. | 446 | 0 | DEBUG(dbgs() << "\t\t\tRunning forward DFS\n"); | 447 | 0 |
| 448 | 0 | const unsigned NewNum = SNCA.runDFS<true>(I, Num, AlwaysDescend, Num); | 449 | 0 | const NodePtr FurthestAway = SNCA.NumToNode[NewNum]; | 450 | 0 | DEBUG(dbgs() << "\t\t\tFound a new furthest away node " | 451 | 0 | << "(non-trivial root): " | 452 | 0 | << BlockNamePrinter(FurthestAway) << "\n"); | 453 | 0 | ConnectToExitBlock.insert(FurthestAway); | 454 | 0 | Roots.push_back(FurthestAway); | 455 | 0 | DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: " | 456 | 0 | << NewNum << "\n\t\t\tRemoving DFS info\n"); | 457 | 0 | for (unsigned i = NewNum; i > Num0 ; --i0 ) { | 458 | 0 | const NodePtr N = SNCA.NumToNode[i]; | 459 | 0 | DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for " | 460 | 0 | << BlockNamePrinter(N) << "\n"); | 461 | 0 | SNCA.NodeToInfo.erase(N); | 462 | 0 | SNCA.NumToNode.pop_back(); | 463 | 0 | } | 464 | 0 | const unsigned PrevNum = Num; | 465 | 0 | DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n"); | 466 | 0 | Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1); | 467 | 0 | for (unsigned i = PrevNum + 1; i <= Num0 ; ++i0 ) | 468 | 0 | DEBUG(dbgs() << "\t\t\t\tfound node " | 469 | 0 | << BlockNamePrinter(SNCA.NumToNode[i]) << "\n"); | 470 | 0 | } | 471 | 0 | } | 472 | 0 | } | 473 | 0 |
| 474 | 0 | DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n"); | 475 | 0 | DEBUG(dbgs() << "Discovered CFG nodes:\n"); | 476 | 0 | DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs() | 477 | 0 | << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n"); | 478 | 0 |
| 479 | 0 | assert((Total + 1 == Num) && "Everything should have been visited"); | 480 | 0 |
| 481 | 0 | // Step #3: If we found some non-trivial roots, make them non-redundant. | 482 | 0 | if (HasNonTrivialRoots0 ) RemoveRedundantRoots(DT, BUI, Roots)0 ; | 483 | 0 |
| 484 | 0 | DEBUG(dbgs() << "Found roots: "); | 485 | 0 | DEBUG(for (auto *Root : Roots) dbgs() << BlockNamePrinter(Root) << " "); | 486 | 0 | DEBUG(dbgs() << "\n"); | 487 | 0 |
| 488 | 0 | return Roots; | 489 | 3.66M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::FindRoots(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*) Line | Count | Source | 374 | 1.77M | static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) { | 375 | 1.77M | assert(DT.Parent && "Parent pointer is not set"); | 376 | 1.77M | RootsT Roots; | 377 | 1.77M | | 378 | 1.77M | // For dominators, function entry CFG node is always a tree root node. | 379 | 1.77M | if (!IsPostDom1.77M ) { | 380 | 0 | Roots.push_back(GetEntryNode(DT)); | 381 | 0 | return Roots; | 382 | 0 | } | 383 | 1.77M | | 384 | 1.77M | SemiNCAInfo SNCA(BUI); | 385 | 1.77M | | 386 | 1.77M | // PostDominatorTree always has a virtual root. | 387 | 1.77M | SNCA.addVirtualRoot(); | 388 | 1.77M | unsigned Num = 1; | 389 | 1.77M | | 390 | 1.77M | DEBUG(dbgs() << "\t\tLooking for trivial roots\n"); | 391 | 1.77M | | 392 | 1.77M | // Step #1: Find all the trivial roots that are going to will definitely | 393 | 1.77M | // remain tree roots. | 394 | 1.77M | unsigned Total = 0; | 395 | 1.77M | // It may happen that there are some new nodes in the CFG that are result of | 396 | 1.77M | // the ongoing batch update, but we cannot really pretend that they don't | 397 | 1.77M | // exist -- we won't see any outgoing or incoming edges to them, so it's | 398 | 1.77M | // fine to discover them here, as they would end up appearing in the CFG at | 399 | 1.77M | // some point anyway. | 400 | 12.5M | for (const NodePtr N : nodes(DT.Parent)) { | 401 | 12.5M | ++Total; | 402 | 12.5M | // If it has no *successors*, it is definitely a root. | 403 | 12.5M | if (!HasForwardSuccessors(N, BUI)12.5M ) { | 404 | 2.48M | Roots.push_back(N); | 405 | 2.48M | // Run DFS not to walk this part of CFG later. | 406 | 2.48M | Num = SNCA.runDFS(N, Num, AlwaysDescend, 1); | 407 | 2.48M | DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N) | 408 | 2.48M | << "\n"); | 409 | 2.48M | DEBUG(dbgs() << "Last visited node: " | 410 | 2.48M | << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n"); | 411 | 2.48M | } | 412 | 12.5M | } | 413 | 1.77M | | 414 | 1.77M | DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n"); | 415 | 1.77M | | 416 | 1.77M | // Step #2: Find all non-trivial root candidates. Those are CFG nodes that | 417 | 1.77M | // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG | 418 | 1.77M | // nodes in infinite loops). | 419 | 1.77M | bool HasNonTrivialRoots = false; | 420 | 1.77M | // Accounting for the virtual exit, see if we had any reverse-unreachable | 421 | 1.77M | // nodes. | 422 | 1.77M | if (Total + 1 != Num1.77M ) { | 423 | 1.01k | HasNonTrivialRoots = true; | 424 | 1.01k | // Make another DFS pass over all other nodes to find the | 425 | 1.01k | // reverse-unreachable blocks, and find the furthest paths we'll be able | 426 | 1.01k | // to make. | 427 | 1.01k | // Note that this looks N^2, but it's really 2N worst case, if every node | 428 | 1.01k | // is unreachable. This is because we are still going to only visit each | 429 | 1.01k | // unreachable node once, we may just visit it in two directions, | 430 | 1.01k | // depending on how lucky we get. | 431 | 1.01k | SmallPtrSet<NodePtr, 4> ConnectToExitBlock; | 432 | 9.11k | for (const NodePtr I : nodes(DT.Parent)) { | 433 | 9.11k | if (SNCA.NodeToInfo.count(I) == 09.11k ) { | 434 | 1.10k | DEBUG(dbgs() << "\t\t\tVisiting node " << BlockNamePrinter(I) | 435 | 1.10k | << "\n"); | 436 | 1.10k | // Find the furthest away we can get by following successors, then | 437 | 1.10k | // follow them in reverse. This gives us some reasonable answer about | 438 | 1.10k | // the post-dom tree inside any infinite loop. In particular, it | 439 | 1.10k | // guarantees we get to the farthest away point along *some* | 440 | 1.10k | // path. This also matches the GCC's behavior. | 441 | 1.10k | // If we really wanted a totally complete picture of dominance inside | 442 | 1.10k | // this infinite loop, we could do it with SCC-like algorithms to find | 443 | 1.10k | // the lowest and highest points in the infinite loop. In theory, it | 444 | 1.10k | // would be nice to give the canonical backedge for the loop, but it's | 445 | 1.10k | // expensive and does not always lead to a minimal set of roots. | 446 | 1.10k | DEBUG(dbgs() << "\t\t\tRunning forward DFS\n"); | 447 | 1.10k | | 448 | 1.10k | const unsigned NewNum = SNCA.runDFS<true>(I, Num, AlwaysDescend, Num); | 449 | 1.10k | const NodePtr FurthestAway = SNCA.NumToNode[NewNum]; | 450 | 1.10k | DEBUG(dbgs() << "\t\t\tFound a new furthest away node " | 451 | 1.10k | << "(non-trivial root): " | 452 | 1.10k | << BlockNamePrinter(FurthestAway) << "\n"); | 453 | 1.10k | ConnectToExitBlock.insert(FurthestAway); | 454 | 1.10k | Roots.push_back(FurthestAway); | 455 | 1.10k | DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: " | 456 | 1.10k | << NewNum << "\n\t\t\tRemoving DFS info\n"); | 457 | 4.48k | for (unsigned i = NewNum; i > Num4.48k ; --i3.38k ) { | 458 | 3.38k | const NodePtr N = SNCA.NumToNode[i]; | 459 | 3.38k | DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for " | 460 | 3.38k | << BlockNamePrinter(N) << "\n"); | 461 | 3.38k | SNCA.NodeToInfo.erase(N); | 462 | 3.38k | SNCA.NumToNode.pop_back(); | 463 | 3.38k | } | 464 | 1.10k | const unsigned PrevNum = Num; | 465 | 1.10k | DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n"); | 466 | 1.10k | Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1); | 467 | 4.33k | for (unsigned i = PrevNum + 1; i <= Num4.33k ; ++i3.22k ) | 468 | 1.10k | DEBUG(dbgs() << "\t\t\t\tfound node " | 469 | 1.10k | << BlockNamePrinter(SNCA.NumToNode[i]) << "\n"); | 470 | 1.10k | } | 471 | 9.11k | } | 472 | 1.01k | } | 473 | 1.77M | | 474 | 1.77M | DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n"); | 475 | 1.77M | DEBUG(dbgs() << "Discovered CFG nodes:\n"); | 476 | 1.77M | DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs() | 477 | 1.77M | << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n"); | 478 | 1.77M | | 479 | 1.77M | assert((Total + 1 == Num) && "Everything should have been visited"); | 480 | 1.77M | | 481 | 1.77M | // Step #3: If we found some non-trivial roots, make them non-redundant. | 482 | 1.77M | if (HasNonTrivialRoots1.77M ) RemoveRedundantRoots(DT, BUI, Roots)1.01k ; | 483 | 1.77M | | 484 | 1.77M | DEBUG(dbgs() << "Found roots: "); | 485 | 1.77M | DEBUG(for (auto *Root : Roots) dbgs() << BlockNamePrinter(Root) << " "); | 486 | 1.77M | DEBUG(dbgs() << "\n"); | 487 | 1.77M | | 488 | 1.77M | return Roots; | 489 | 1.77M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::FindRoots(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*) Line | Count | Source | 374 | 582k | static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) { | 375 | 582k | assert(DT.Parent && "Parent pointer is not set"); | 376 | 582k | RootsT Roots; | 377 | 582k | | 378 | 582k | // For dominators, function entry CFG node is always a tree root node. | 379 | 582k | if (!IsPostDom582k ) { | 380 | 0 | Roots.push_back(GetEntryNode(DT)); | 381 | 0 | return Roots; | 382 | 0 | } | 383 | 582k | | 384 | 582k | SemiNCAInfo SNCA(BUI); | 385 | 582k | | 386 | 582k | // PostDominatorTree always has a virtual root. | 387 | 582k | SNCA.addVirtualRoot(); | 388 | 582k | unsigned Num = 1; | 389 | 582k | | 390 | 582k | DEBUG(dbgs() << "\t\tLooking for trivial roots\n"); | 391 | 582k | | 392 | 582k | // Step #1: Find all the trivial roots that are going to will definitely | 393 | 582k | // remain tree roots. | 394 | 582k | unsigned Total = 0; | 395 | 582k | // It may happen that there are some new nodes in the CFG that are result of | 396 | 582k | // the ongoing batch update, but we cannot really pretend that they don't | 397 | 582k | // exist -- we won't see any outgoing or incoming edges to them, so it's | 398 | 582k | // fine to discover them here, as they would end up appearing in the CFG at | 399 | 582k | // some point anyway. | 400 | 4.00M | for (const NodePtr N : nodes(DT.Parent)) { | 401 | 4.00M | ++Total; | 402 | 4.00M | // If it has no *successors*, it is definitely a root. | 403 | 4.00M | if (!HasForwardSuccessors(N, BUI)4.00M ) { | 404 | 615k | Roots.push_back(N); | 405 | 615k | // Run DFS not to walk this part of CFG later. | 406 | 615k | Num = SNCA.runDFS(N, Num, AlwaysDescend, 1); | 407 | 615k | DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N) | 408 | 615k | << "\n"); | 409 | 615k | DEBUG(dbgs() << "Last visited node: " | 410 | 615k | << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n"); | 411 | 615k | } | 412 | 4.00M | } | 413 | 582k | | 414 | 582k | DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n"); | 415 | 582k | | 416 | 582k | // Step #2: Find all non-trivial root candidates. Those are CFG nodes that | 417 | 582k | // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG | 418 | 582k | // nodes in infinite loops). | 419 | 582k | bool HasNonTrivialRoots = false; | 420 | 582k | // Accounting for the virtual exit, see if we had any reverse-unreachable | 421 | 582k | // nodes. | 422 | 582k | if (Total + 1 != Num582k ) { | 423 | 311 | HasNonTrivialRoots = true; | 424 | 311 | // Make another DFS pass over all other nodes to find the | 425 | 311 | // reverse-unreachable blocks, and find the furthest paths we'll be able | 426 | 311 | // to make. | 427 | 311 | // Note that this looks N^2, but it's really 2N worst case, if every node | 428 | 311 | // is unreachable. This is because we are still going to only visit each | 429 | 311 | // unreachable node once, we may just visit it in two directions, | 430 | 311 | // depending on how lucky we get. | 431 | 311 | SmallPtrSet<NodePtr, 4> ConnectToExitBlock; | 432 | 3.58k | for (const NodePtr I : nodes(DT.Parent)) { | 433 | 3.58k | if (SNCA.NodeToInfo.count(I) == 03.58k ) { | 434 | 346 | DEBUG(dbgs() << "\t\t\tVisiting node " << BlockNamePrinter(I) | 435 | 346 | << "\n"); | 436 | 346 | // Find the furthest away we can get by following successors, then | 437 | 346 | // follow them in reverse. This gives us some reasonable answer about | 438 | 346 | // the post-dom tree inside any infinite loop. In particular, it | 439 | 346 | // guarantees we get to the farthest away point along *some* | 440 | 346 | // path. This also matches the GCC's behavior. | 441 | 346 | // If we really wanted a totally complete picture of dominance inside | 442 | 346 | // this infinite loop, we could do it with SCC-like algorithms to find | 443 | 346 | // the lowest and highest points in the infinite loop. In theory, it | 444 | 346 | // would be nice to give the canonical backedge for the loop, but it's | 445 | 346 | // expensive and does not always lead to a minimal set of roots. | 446 | 346 | DEBUG(dbgs() << "\t\t\tRunning forward DFS\n"); | 447 | 346 | | 448 | 346 | const unsigned NewNum = SNCA.runDFS<true>(I, Num, AlwaysDescend, Num); | 449 | 346 | const NodePtr FurthestAway = SNCA.NumToNode[NewNum]; | 450 | 346 | DEBUG(dbgs() << "\t\t\tFound a new furthest away node " | 451 | 346 | << "(non-trivial root): " | 452 | 346 | << BlockNamePrinter(FurthestAway) << "\n"); | 453 | 346 | ConnectToExitBlock.insert(FurthestAway); | 454 | 346 | Roots.push_back(FurthestAway); | 455 | 346 | DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: " | 456 | 346 | << NewNum << "\n\t\t\tRemoving DFS info\n"); | 457 | 1.30k | for (unsigned i = NewNum; i > Num1.30k ; --i955 ) { | 458 | 955 | const NodePtr N = SNCA.NumToNode[i]; | 459 | 955 | DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for " | 460 | 955 | << BlockNamePrinter(N) << "\n"); | 461 | 955 | SNCA.NodeToInfo.erase(N); | 462 | 955 | SNCA.NumToNode.pop_back(); | 463 | 955 | } | 464 | 346 | const unsigned PrevNum = Num; | 465 | 346 | DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n"); | 466 | 346 | Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1); | 467 | 1.26k | for (unsigned i = PrevNum + 1; i <= Num1.26k ; ++i918 ) | 468 | 346 | DEBUG(dbgs() << "\t\t\t\tfound node " | 469 | 346 | << BlockNamePrinter(SNCA.NumToNode[i]) << "\n"); | 470 | 346 | } | 471 | 3.58k | } | 472 | 311 | } | 473 | 582k | | 474 | 582k | DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n"); | 475 | 582k | DEBUG(dbgs() << "Discovered CFG nodes:\n"); | 476 | 582k | DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs() | 477 | 582k | << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n"); | 478 | 582k | | 479 | 582k | assert((Total + 1 == Num) && "Everything should have been visited"); | 480 | 582k | | 481 | 582k | // Step #3: If we found some non-trivial roots, make them non-redundant. | 482 | 582k | if (HasNonTrivialRoots582k ) RemoveRedundantRoots(DT, BUI, Roots)311 ; | 483 | 582k | | 484 | 582k | DEBUG(dbgs() << "Found roots: "); | 485 | 582k | DEBUG(for (auto *Root : Roots) dbgs() << BlockNamePrinter(Root) << " "); | 486 | 582k | DEBUG(dbgs() << "\n"); | 487 | 582k | | 488 | 582k | return Roots; | 489 | 582k | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::FindRoots(llvm::DominatorTreeBase<clang::CFGBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::BatchUpdateInfo*) Line | Count | Source | 374 | 5 | static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) { | 375 | 5 | assert(DT.Parent && "Parent pointer is not set"); | 376 | 5 | RootsT Roots; | 377 | 5 | | 378 | 5 | // For dominators, function entry CFG node is always a tree root node. | 379 | 5 | if (!IsPostDom5 ) { | 380 | 5 | Roots.push_back(GetEntryNode(DT)); | 381 | 5 | return Roots; | 382 | 5 | } | 383 | 5 | | 384 | 0 | SemiNCAInfo SNCA(BUI); | 385 | 0 |
| 386 | 0 | // PostDominatorTree always has a virtual root. | 387 | 0 | SNCA.addVirtualRoot(); | 388 | 0 | unsigned Num = 1; | 389 | 0 |
| 390 | 0 | DEBUG(dbgs() << "\t\tLooking for trivial roots\n"); | 391 | 0 |
| 392 | 0 | // Step #1: Find all the trivial roots that are going to will definitely | 393 | 0 | // remain tree roots. | 394 | 0 | unsigned Total = 0; | 395 | 0 | // It may happen that there are some new nodes in the CFG that are result of | 396 | 0 | // the ongoing batch update, but we cannot really pretend that they don't | 397 | 0 | // exist -- we won't see any outgoing or incoming edges to them, so it's | 398 | 0 | // fine to discover them here, as they would end up appearing in the CFG at | 399 | 0 | // some point anyway. | 400 | 0 | for (const NodePtr N : nodes(DT.Parent)) { | 401 | 0 | ++Total; | 402 | 0 | // If it has no *successors*, it is definitely a root. | 403 | 0 | if (!HasForwardSuccessors(N, BUI)0 ) { | 404 | 0 | Roots.push_back(N); | 405 | 0 | // Run DFS not to walk this part of CFG later. | 406 | 0 | Num = SNCA.runDFS(N, Num, AlwaysDescend, 1); | 407 | 0 | DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N) | 408 | 0 | << "\n"); | 409 | 0 | DEBUG(dbgs() << "Last visited node: " | 410 | 0 | << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n"); | 411 | 0 | } | 412 | 0 | } | 413 | 0 |
| 414 | 0 | DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n"); | 415 | 0 |
| 416 | 0 | // Step #2: Find all non-trivial root candidates. Those are CFG nodes that | 417 | 0 | // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG | 418 | 0 | // nodes in infinite loops). | 419 | 0 | bool HasNonTrivialRoots = false; | 420 | 0 | // Accounting for the virtual exit, see if we had any reverse-unreachable | 421 | 0 | // nodes. | 422 | 0 | if (Total + 1 != Num0 ) { | 423 | 0 | HasNonTrivialRoots = true; | 424 | 0 | // Make another DFS pass over all other nodes to find the | 425 | 0 | // reverse-unreachable blocks, and find the furthest paths we'll be able | 426 | 0 | // to make. | 427 | 0 | // Note that this looks N^2, but it's really 2N worst case, if every node | 428 | 0 | // is unreachable. This is because we are still going to only visit each | 429 | 0 | // unreachable node once, we may just visit it in two directions, | 430 | 0 | // depending on how lucky we get. | 431 | 0 | SmallPtrSet<NodePtr, 4> ConnectToExitBlock; | 432 | 0 | for (const NodePtr I : nodes(DT.Parent)) { | 433 | 0 | if (SNCA.NodeToInfo.count(I) == 00 ) { | 434 | 0 | DEBUG(dbgs() << "\t\t\tVisiting node " << BlockNamePrinter(I) | 435 | 0 | << "\n"); | 436 | 0 | // Find the furthest away we can get by following successors, then | 437 | 0 | // follow them in reverse. This gives us some reasonable answer about | 438 | 0 | // the post-dom tree inside any infinite loop. In particular, it | 439 | 0 | // guarantees we get to the farthest away point along *some* | 440 | 0 | // path. This also matches the GCC's behavior. | 441 | 0 | // If we really wanted a totally complete picture of dominance inside | 442 | 0 | // this infinite loop, we could do it with SCC-like algorithms to find | 443 | 0 | // the lowest and highest points in the infinite loop. In theory, it | 444 | 0 | // would be nice to give the canonical backedge for the loop, but it's | 445 | 0 | // expensive and does not always lead to a minimal set of roots. | 446 | 0 | DEBUG(dbgs() << "\t\t\tRunning forward DFS\n"); | 447 | 0 |
| 448 | 0 | const unsigned NewNum = SNCA.runDFS<true>(I, Num, AlwaysDescend, Num); | 449 | 0 | const NodePtr FurthestAway = SNCA.NumToNode[NewNum]; | 450 | 0 | DEBUG(dbgs() << "\t\t\tFound a new furthest away node " | 451 | 0 | << "(non-trivial root): " | 452 | 0 | << BlockNamePrinter(FurthestAway) << "\n"); | 453 | 0 | ConnectToExitBlock.insert(FurthestAway); | 454 | 0 | Roots.push_back(FurthestAway); | 455 | 0 | DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: " | 456 | 0 | << NewNum << "\n\t\t\tRemoving DFS info\n"); | 457 | 0 | for (unsigned i = NewNum; i > Num0 ; --i0 ) { | 458 | 0 | const NodePtr N = SNCA.NumToNode[i]; | 459 | 0 | DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for " | 460 | 0 | << BlockNamePrinter(N) << "\n"); | 461 | 0 | SNCA.NodeToInfo.erase(N); | 462 | 0 | SNCA.NumToNode.pop_back(); | 463 | 0 | } | 464 | 0 | const unsigned PrevNum = Num; | 465 | 0 | DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n"); | 466 | 0 | Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1); | 467 | 0 | for (unsigned i = PrevNum + 1; i <= Num0 ; ++i0 ) | 468 | 0 | DEBUG(dbgs() << "\t\t\t\tfound node " | 469 | 0 | << BlockNamePrinter(SNCA.NumToNode[i]) << "\n"); | 470 | 0 | } | 471 | 0 | } | 472 | 0 | } | 473 | 0 |
| 474 | 0 | DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n"); | 475 | 0 | DEBUG(dbgs() << "Discovered CFG nodes:\n"); | 476 | 0 | DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs() | 477 | 0 | << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n"); | 478 | 0 |
| 479 | 0 | assert((Total + 1 == Num) && "Everything should have been visited"); | 480 | 0 |
| 481 | 0 | // Step #3: If we found some non-trivial roots, make them non-redundant. | 482 | 0 | if (HasNonTrivialRoots0 ) RemoveRedundantRoots(DT, BUI, Roots)0 ; | 483 | 0 |
| 484 | 0 | DEBUG(dbgs() << "Found roots: "); | 485 | 0 | DEBUG(for (auto *Root : Roots) dbgs() << BlockNamePrinter(Root) << " "); | 486 | 0 | DEBUG(dbgs() << "\n"); | 487 | 0 |
| 488 | 0 | return Roots; | 489 | 5 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::FindRoots(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*) Line | Count | Source | 374 | 12.1M | static RootsT FindRoots(const DomTreeT &DT, BatchUpdatePtr BUI) { | 375 | 12.1M | assert(DT.Parent && "Parent pointer is not set"); | 376 | 12.1M | RootsT Roots; | 377 | 12.1M | | 378 | 12.1M | // For dominators, function entry CFG node is always a tree root node. | 379 | 12.1M | if (!IsPostDom12.1M ) { | 380 | 12.1M | Roots.push_back(GetEntryNode(DT)); | 381 | 12.1M | return Roots; | 382 | 12.1M | } | 383 | 12.1M | | 384 | 0 | SemiNCAInfo SNCA(BUI); | 385 | 0 |
| 386 | 0 | // PostDominatorTree always has a virtual root. | 387 | 0 | SNCA.addVirtualRoot(); | 388 | 0 | unsigned Num = 1; | 389 | 0 |
| 390 | 0 | DEBUG(dbgs() << "\t\tLooking for trivial roots\n"); | 391 | 0 |
| 392 | 0 | // Step #1: Find all the trivial roots that are going to will definitely | 393 | 0 | // remain tree roots. | 394 | 0 | unsigned Total = 0; | 395 | 0 | // It may happen that there are some new nodes in the CFG that are result of | 396 | 0 | // the ongoing batch update, but we cannot really pretend that they don't | 397 | 0 | // exist -- we won't see any outgoing or incoming edges to them, so it's | 398 | 0 | // fine to discover them here, as they would end up appearing in the CFG at | 399 | 0 | // some point anyway. | 400 | 0 | for (const NodePtr N : nodes(DT.Parent)) { | 401 | 0 | ++Total; | 402 | 0 | // If it has no *successors*, it is definitely a root. | 403 | 0 | if (!HasForwardSuccessors(N, BUI)0 ) { | 404 | 0 | Roots.push_back(N); | 405 | 0 | // Run DFS not to walk this part of CFG later. | 406 | 0 | Num = SNCA.runDFS(N, Num, AlwaysDescend, 1); | 407 | 0 | DEBUG(dbgs() << "Found a new trivial root: " << BlockNamePrinter(N) | 408 | 0 | << "\n"); | 409 | 0 | DEBUG(dbgs() << "Last visited node: " | 410 | 0 | << BlockNamePrinter(SNCA.NumToNode[Num]) << "\n"); | 411 | 0 | } | 412 | 0 | } | 413 | 0 |
| 414 | 0 | DEBUG(dbgs() << "\t\tLooking for non-trivial roots\n"); | 415 | 0 |
| 416 | 0 | // Step #2: Find all non-trivial root candidates. Those are CFG nodes that | 417 | 0 | // are reverse-unreachable were not visited by previous DFS walks (i.e. CFG | 418 | 0 | // nodes in infinite loops). | 419 | 0 | bool HasNonTrivialRoots = false; | 420 | 0 | // Accounting for the virtual exit, see if we had any reverse-unreachable | 421 | 0 | // nodes. | 422 | 0 | if (Total + 1 != Num0 ) { | 423 | 0 | HasNonTrivialRoots = true; | 424 | 0 | // Make another DFS pass over all other nodes to find the | 425 | 0 | // reverse-unreachable blocks, and find the furthest paths we'll be able | 426 | 0 | // to make. | 427 | 0 | // Note that this looks N^2, but it's really 2N worst case, if every node | 428 | 0 | // is unreachable. This is because we are still going to only visit each | 429 | 0 | // unreachable node once, we may just visit it in two directions, | 430 | 0 | // depending on how lucky we get. | 431 | 0 | SmallPtrSet<NodePtr, 4> ConnectToExitBlock; | 432 | 0 | for (const NodePtr I : nodes(DT.Parent)) { | 433 | 0 | if (SNCA.NodeToInfo.count(I) == 00 ) { | 434 | 0 | DEBUG(dbgs() << "\t\t\tVisiting node " << BlockNamePrinter(I) | 435 | 0 | << "\n"); | 436 | 0 | // Find the furthest away we can get by following successors, then | 437 | 0 | // follow them in reverse. This gives us some reasonable answer about | 438 | 0 | // the post-dom tree inside any infinite loop. In particular, it | 439 | 0 | // guarantees we get to the farthest away point along *some* | 440 | 0 | // path. This also matches the GCC's behavior. | 441 | 0 | // If we really wanted a totally complete picture of dominance inside | 442 | 0 | // this infinite loop, we could do it with SCC-like algorithms to find | 443 | 0 | // the lowest and highest points in the infinite loop. In theory, it | 444 | 0 | // would be nice to give the canonical backedge for the loop, but it's | 445 | 0 | // expensive and does not always lead to a minimal set of roots. | 446 | 0 | DEBUG(dbgs() << "\t\t\tRunning forward DFS\n"); | 447 | 0 |
| 448 | 0 | const unsigned NewNum = SNCA.runDFS<true>(I, Num, AlwaysDescend, Num); | 449 | 0 | const NodePtr FurthestAway = SNCA.NumToNode[NewNum]; | 450 | 0 | DEBUG(dbgs() << "\t\t\tFound a new furthest away node " | 451 | 0 | << "(non-trivial root): " | 452 | 0 | << BlockNamePrinter(FurthestAway) << "\n"); | 453 | 0 | ConnectToExitBlock.insert(FurthestAway); | 454 | 0 | Roots.push_back(FurthestAway); | 455 | 0 | DEBUG(dbgs() << "\t\t\tPrev DFSNum: " << Num << ", new DFSNum: " | 456 | 0 | << NewNum << "\n\t\t\tRemoving DFS info\n"); | 457 | 0 | for (unsigned i = NewNum; i > Num0 ; --i0 ) { | 458 | 0 | const NodePtr N = SNCA.NumToNode[i]; | 459 | 0 | DEBUG(dbgs() << "\t\t\t\tRemoving DFS info for " | 460 | 0 | << BlockNamePrinter(N) << "\n"); | 461 | 0 | SNCA.NodeToInfo.erase(N); | 462 | 0 | SNCA.NumToNode.pop_back(); | 463 | 0 | } | 464 | 0 | const unsigned PrevNum = Num; | 465 | 0 | DEBUG(dbgs() << "\t\t\tRunning reverse DFS\n"); | 466 | 0 | Num = SNCA.runDFS(FurthestAway, Num, AlwaysDescend, 1); | 467 | 0 | for (unsigned i = PrevNum + 1; i <= Num0 ; ++i0 ) | 468 | 0 | DEBUG(dbgs() << "\t\t\t\tfound node " | 469 | 0 | << BlockNamePrinter(SNCA.NumToNode[i]) << "\n"); | 470 | 0 | } | 471 | 0 | } | 472 | 0 | } | 473 | 0 |
| 474 | 0 | DEBUG(dbgs() << "Total: " << Total << ", Num: " << Num << "\n"); | 475 | 0 | DEBUG(dbgs() << "Discovered CFG nodes:\n"); | 476 | 0 | DEBUG(for (size_t i = 0; i <= Num; ++i) dbgs() | 477 | 0 | << i << ": " << BlockNamePrinter(SNCA.NumToNode[i]) << "\n"); | 478 | 0 |
| 479 | 0 | assert((Total + 1 == Num) && "Everything should have been visited"); | 480 | 0 |
| 481 | 0 | // Step #3: If we found some non-trivial roots, make them non-redundant. | 482 | 0 | if (HasNonTrivialRoots0 ) RemoveRedundantRoots(DT, BUI, Roots)0 ; | 483 | 0 |
| 484 | 0 | DEBUG(dbgs() << "Found roots: "); | 485 | 0 | DEBUG(for (auto *Root : Roots) dbgs() << BlockNamePrinter(Root) << " "); | 486 | 0 | DEBUG(dbgs() << "\n"); | 487 | 0 |
| 488 | 0 | return Roots; | 489 | 12.1M | } |
|
490 | | |
491 | | // This function only makes sense for postdominators. |
492 | | // We define roots to be some set of CFG nodes where (reverse) DFS walks have |
493 | | // to start in order to visit all the CFG nodes (including the |
494 | | // reverse-unreachable ones). |
495 | | // When the search for non-trivial roots is done it may happen that some of |
496 | | // the non-trivial roots are reverse-reachable from other non-trivial roots, |
497 | | // which makes them redundant. This function removes them from the set of |
498 | | // input roots. |
499 | | static void RemoveRedundantRoots(const DomTreeT &DT, BatchUpdatePtr BUI, |
500 | 1.32k | RootsT &Roots) { |
501 | 1.32k | assert(IsPostDom && "This function is for postdominators only"); |
502 | 1.32k | DEBUG(dbgs() << "Removing redundant roots\n"); |
503 | 1.32k | |
504 | 1.32k | SemiNCAInfo SNCA(BUI); |
505 | 1.32k | |
506 | 3.84k | for (unsigned i = 0; i < Roots.size()3.84k ; ++i2.52k ) { |
507 | 2.52k | auto &Root = Roots[i]; |
508 | 2.52k | // Trivial roots are always non-redundant. |
509 | 2.52k | if (!HasForwardSuccessors(Root, BUI)2.52k ) continue1.07k ; |
510 | 1.45k | DEBUG1.45k (dbgs() << "\tChecking if " << BlockNamePrinter(Root) |
511 | 1.45k | << " remains a root\n"); |
512 | 1.45k | SNCA.clear(); |
513 | 1.45k | // Do a forward walk looking for the other roots. |
514 | 1.45k | const unsigned Num = SNCA.runDFS<true>(Root, 0, AlwaysDescend, 0); |
515 | 1.45k | // Skip the start node and begin from the second one (note that DFS uses |
516 | 1.45k | // 1-based indexing). |
517 | 2.64k | for (unsigned x = 2; x <= Num2.64k ; ++x1.19k ) { |
518 | 1.26k | const NodePtr N = SNCA.NumToNode[x]; |
519 | 1.26k | // If we wound another root in a (forward) DFS walk, remove the current |
520 | 1.26k | // root from the set of roots, as it is reverse-reachable from the other |
521 | 1.26k | // one. |
522 | 1.26k | if (llvm::find(Roots, N) != Roots.end()1.26k ) { |
523 | 71 | DEBUG(dbgs() << "\tForward DFS walk found another root " |
524 | 71 | << BlockNamePrinter(N) << "\n\tRemoving root " |
525 | 71 | << BlockNamePrinter(Root) << "\n"); |
526 | 71 | std::swap(Root, Roots.back()); |
527 | 71 | Roots.pop_back(); |
528 | 71 | |
529 | 71 | // Root at the back takes the current root's place. |
530 | 71 | // Start the next loop iteration with the same index. |
531 | 71 | --i; |
532 | 71 | break; |
533 | 71 | } |
534 | 1.26k | } |
535 | 2.52k | } |
536 | 1.32k | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::RemoveRedundantRoots(llvm::DominatorTreeBase<clang::CFGBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::BatchUpdateInfo*, llvm::SmallVector<clang::CFGBlock*, 1u>&) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::RemoveRedundantRoots(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::SmallVector<llvm::BasicBlock*, 4u>&) Line | Count | Source | 500 | 311 | RootsT &Roots) { | 501 | 311 | assert(IsPostDom && "This function is for postdominators only"); | 502 | 311 | DEBUG(dbgs() << "Removing redundant roots\n"); | 503 | 311 | | 504 | 311 | SemiNCAInfo SNCA(BUI); | 505 | 311 | | 506 | 1.02k | for (unsigned i = 0; i < Roots.size()1.02k ; ++i714 ) { | 507 | 714 | auto &Root = Roots[i]; | 508 | 714 | // Trivial roots are always non-redundant. | 509 | 714 | if (!HasForwardSuccessors(Root, BUI)714 ) continue368 ; | 510 | 346 | DEBUG346 (dbgs() << "\tChecking if " << BlockNamePrinter(Root) | 511 | 346 | << " remains a root\n"); | 512 | 346 | SNCA.clear(); | 513 | 346 | // Do a forward walk looking for the other roots. | 514 | 346 | const unsigned Num = SNCA.runDFS<true>(Root, 0, AlwaysDescend, 0); | 515 | 346 | // Skip the start node and begin from the second one (note that DFS uses | 516 | 346 | // 1-based indexing). | 517 | 601 | for (unsigned x = 2; x <= Num601 ; ++x255 ) { | 518 | 285 | const NodePtr N = SNCA.NumToNode[x]; | 519 | 285 | // If we wound another root in a (forward) DFS walk, remove the current | 520 | 285 | // root from the set of roots, as it is reverse-reachable from the other | 521 | 285 | // one. | 522 | 285 | if (llvm::find(Roots, N) != Roots.end()285 ) { | 523 | 30 | DEBUG(dbgs() << "\tForward DFS walk found another root " | 524 | 30 | << BlockNamePrinter(N) << "\n\tRemoving root " | 525 | 30 | << BlockNamePrinter(Root) << "\n"); | 526 | 30 | std::swap(Root, Roots.back()); | 527 | 30 | Roots.pop_back(); | 528 | 30 | | 529 | 30 | // Root at the back takes the current root's place. | 530 | 30 | // Start the next loop iteration with the same index. | 531 | 30 | --i; | 532 | 30 | break; | 533 | 30 | } | 534 | 285 | } | 535 | 714 | } | 536 | 311 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::RemoveRedundantRoots(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::SmallVector<llvm::MachineBasicBlock*, 4u>&) Line | Count | Source | 500 | 1.01k | RootsT &Roots) { | 501 | 1.01k | assert(IsPostDom && "This function is for postdominators only"); | 502 | 1.01k | DEBUG(dbgs() << "Removing redundant roots\n"); | 503 | 1.01k | | 504 | 1.01k | SemiNCAInfo SNCA(BUI); | 505 | 1.01k | | 506 | 2.82k | for (unsigned i = 0; i < Roots.size()2.82k ; ++i1.80k ) { | 507 | 1.80k | auto &Root = Roots[i]; | 508 | 1.80k | // Trivial roots are always non-redundant. | 509 | 1.80k | if (!HasForwardSuccessors(Root, BUI)1.80k ) continue702 ; | 510 | 1.10k | DEBUG1.10k (dbgs() << "\tChecking if " << BlockNamePrinter(Root) | 511 | 1.10k | << " remains a root\n"); | 512 | 1.10k | SNCA.clear(); | 513 | 1.10k | // Do a forward walk looking for the other roots. | 514 | 1.10k | const unsigned Num = SNCA.runDFS<true>(Root, 0, AlwaysDescend, 0); | 515 | 1.10k | // Skip the start node and begin from the second one (note that DFS uses | 516 | 1.10k | // 1-based indexing). | 517 | 2.04k | for (unsigned x = 2; x <= Num2.04k ; ++x939 ) { | 518 | 980 | const NodePtr N = SNCA.NumToNode[x]; | 519 | 980 | // If we wound another root in a (forward) DFS walk, remove the current | 520 | 980 | // root from the set of roots, as it is reverse-reachable from the other | 521 | 980 | // one. | 522 | 980 | if (llvm::find(Roots, N) != Roots.end()980 ) { | 523 | 41 | DEBUG(dbgs() << "\tForward DFS walk found another root " | 524 | 41 | << BlockNamePrinter(N) << "\n\tRemoving root " | 525 | 41 | << BlockNamePrinter(Root) << "\n"); | 526 | 41 | std::swap(Root, Roots.back()); | 527 | 41 | Roots.pop_back(); | 528 | 41 | | 529 | 41 | // Root at the back takes the current root's place. | 530 | 41 | // Start the next loop iteration with the same index. | 531 | 41 | --i; | 532 | 41 | break; | 533 | 41 | } | 534 | 980 | } | 535 | 1.80k | } | 536 | 1.01k | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::RemoveRedundantRoots(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::SmallVector<llvm::MachineBasicBlock*, 1u>&) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::RemoveRedundantRoots(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::SmallVector<llvm::BasicBlock*, 1u>&) |
537 | | |
538 | | template <typename DescendCondition> |
539 | 18.2M | void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) { |
540 | 18.2M | if (!IsPostDom18.2M ) { |
541 | 15.8M | assert(DT.Roots.size() == 1 && "Dominators should have a singe root"); |
542 | 15.8M | runDFS(DT.Roots[0], 0, DC, 0); |
543 | 15.8M | return; |
544 | 15.8M | } |
545 | 18.2M | |
546 | 2.36M | addVirtualRoot(); |
547 | 2.36M | unsigned Num = 1; |
548 | 3.10M | for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0); |
549 | 18.2M | } void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)) Line | Count | Source | 539 | 1.56k | void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) { | 540 | 1.56k | if (!IsPostDom1.56k ) { | 541 | 1.56k | assert(DT.Roots.size() == 1 && "Dominators should have a singe root"); | 542 | 1.56k | runDFS(DT.Roots[0], 0, DC, 0); | 543 | 1.56k | return; | 544 | 1.56k | } | 545 | 1.56k | | 546 | 0 | addVirtualRoot(); | 547 | 0 | unsigned Num = 1; | 548 | 0 | for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0); | 549 | 1.56k | } |
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::doFullDFSWalk<bool (*)(clang::CFGBlock*, clang::CFGBlock*)>(llvm::DominatorTreeBase<clang::CFGBlock, false> const&, bool (*)(clang::CFGBlock*, clang::CFGBlock*)) Line | Count | Source | 539 | 5 | void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) { | 540 | 5 | if (!IsPostDom5 ) { | 541 | 5 | assert(DT.Roots.size() == 1 && "Dominators should have a singe root"); | 542 | 5 | runDFS(DT.Roots[0], 0, DC, 0); | 543 | 5 | return; | 544 | 5 | } | 545 | 5 | | 546 | 0 | addVirtualRoot(); | 547 | 0 | unsigned Num = 1; | 548 | 0 | for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0); | 549 | 5 | } |
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)) Line | Count | Source | 539 | 1.95k | void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) { | 540 | 1.95k | if (!IsPostDom1.95k ) { | 541 | 0 | assert(DT.Roots.size() == 1 && "Dominators should have a singe root"); | 542 | 0 | runDFS(DT.Roots[0], 0, DC, 0); | 543 | 0 | return; | 544 | 0 | } | 545 | 1.95k | | 546 | 1.95k | addVirtualRoot(); | 547 | 1.95k | unsigned Num = 1; | 548 | 5.91k | for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0); | 549 | 1.95k | } |
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)) Line | Count | Source | 539 | 1.62k | void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) { | 540 | 1.62k | if (!IsPostDom1.62k ) { | 541 | 0 | assert(DT.Roots.size() == 1 && "Dominators should have a singe root"); | 542 | 0 | runDFS(DT.Roots[0], 0, DC, 0); | 543 | 0 | return; | 544 | 0 | } | 545 | 1.62k | | 546 | 1.62k | addVirtualRoot(); | 547 | 1.62k | unsigned Num = 1; | 548 | 5.02k | for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0); | 549 | 1.62k | } |
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)) Line | Count | Source | 539 | 2.24k | void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) { | 540 | 2.24k | if (!IsPostDom2.24k ) { | 541 | 2.24k | assert(DT.Roots.size() == 1 && "Dominators should have a singe root"); | 542 | 2.24k | runDFS(DT.Roots[0], 0, DC, 0); | 543 | 2.24k | return; | 544 | 2.24k | } | 545 | 2.24k | | 546 | 0 | addVirtualRoot(); | 547 | 0 | unsigned Num = 1; | 548 | 0 | for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0); | 549 | 2.24k | } |
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::doFullDFSWalk<bool (*)(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*)) Line | Count | Source | 539 | 582k | void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) { | 540 | 582k | if (!IsPostDom582k ) { | 541 | 0 | assert(DT.Roots.size() == 1 && "Dominators should have a singe root"); | 542 | 0 | runDFS(DT.Roots[0], 0, DC, 0); | 543 | 0 | return; | 544 | 0 | } | 545 | 582k | | 546 | 582k | addVirtualRoot(); | 547 | 582k | unsigned Num = 1; | 548 | 616k | for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0); | 549 | 582k | } |
void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::doFullDFSWalk<bool (*)(llvm::BasicBlock*, llvm::BasicBlock*)>(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&, bool (*)(llvm::BasicBlock*, llvm::BasicBlock*)) Line | Count | Source | 539 | 12.2M | void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) { | 540 | 12.2M | if (!IsPostDom12.2M ) { | 541 | 12.2M | assert(DT.Roots.size() == 1 && "Dominators should have a singe root"); | 542 | 12.2M | runDFS(DT.Roots[0], 0, DC, 0); | 543 | 12.2M | return; | 544 | 12.2M | } | 545 | 12.2M | | 546 | 0 | addVirtualRoot(); | 547 | 0 | unsigned Num = 1; | 548 | 0 | for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0); | 549 | 12.2M | } |
Unexecuted instantiation: void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)) Unexecuted instantiation: void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)) void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::doFullDFSWalk<bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)) Line | Count | Source | 539 | 1.77M | void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) { | 540 | 1.77M | if (!IsPostDom1.77M ) { | 541 | 0 | assert(DT.Roots.size() == 1 && "Dominators should have a singe root"); | 542 | 0 | runDFS(DT.Roots[0], 0, DC, 0); | 543 | 0 | return; | 544 | 0 | } | 545 | 1.77M | | 546 | 1.77M | addVirtualRoot(); | 547 | 1.77M | unsigned Num = 1; | 548 | 2.48M | for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0); | 549 | 1.77M | } |
Unexecuted instantiation: void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)) Unexecuted instantiation: void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::doFullDFSWalk<llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)) void llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::doFullDFSWalk<bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)>(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&, bool (*)(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)) Line | Count | Source | 539 | 3.66M | void doFullDFSWalk(const DomTreeT &DT, DescendCondition DC) { | 540 | 3.66M | if (!IsPostDom3.66M ) { | 541 | 3.66M | assert(DT.Roots.size() == 1 && "Dominators should have a singe root"); | 542 | 3.66M | runDFS(DT.Roots[0], 0, DC, 0); | 543 | 3.66M | return; | 544 | 3.66M | } | 545 | 3.66M | | 546 | 0 | addVirtualRoot(); | 547 | 0 | unsigned Num = 1; | 548 | 0 | for (const NodePtr Root : DT.Roots) Num = runDFS(Root, Num, DC, 0); | 549 | 3.66M | } |
|
550 | | |
551 | 18.2M | static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) { |
552 | 18.2M | auto *Parent = DT.Parent; |
553 | 18.2M | DT.reset(); |
554 | 18.2M | DT.Parent = Parent; |
555 | 18.2M | SemiNCAInfo SNCA(nullptr); // Since we are rebuilding the whole tree, |
556 | 18.2M | // there's no point doing it incrementally. |
557 | 18.2M | |
558 | 18.2M | // Step #0: Number blocks in depth-first order and initialize variables used |
559 | 18.2M | // in later stages of the algorithm. |
560 | 18.2M | DT.Roots = FindRoots(DT, nullptr); |
561 | 18.2M | SNCA.doFullDFSWalk(DT, AlwaysDescend); |
562 | 18.2M | |
563 | 18.2M | SNCA.runSemiNCA(DT); |
564 | 18.2M | if (BUI18.2M ) { |
565 | 185k | BUI->IsRecalculated = true; |
566 | 185k | DEBUG(dbgs() << "DomTree recalculated, skipping future batch updates\n"); |
567 | 185k | } |
568 | 18.2M | |
569 | 18.2M | if (DT.Roots.empty()18.2M ) return0 ; |
570 | 18.2M | |
571 | 18.2M | // Add a node for the root. If the tree is a PostDominatorTree it will be |
572 | 18.2M | // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates |
573 | 18.2M | // all real exits (including multiple exit blocks, infinite loops). |
574 | 18.2M | NodePtr Root = IsPostDom ? 18.2M nullptr2.36M : DT.Roots[0]15.8M ; |
575 | 18.2M | |
576 | 18.2M | DT.RootNode = (DT.DomTreeNodes[Root] = |
577 | 18.2M | llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr)) |
578 | 18.2M | .get(); |
579 | 18.2M | SNCA.attachNewSubtree(DT, DT.RootNode); |
580 | 18.2M | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::CalculateFromScratch(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*) Line | Count | Source | 551 | 1.77M | static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) { | 552 | 1.77M | auto *Parent = DT.Parent; | 553 | 1.77M | DT.reset(); | 554 | 1.77M | DT.Parent = Parent; | 555 | 1.77M | SemiNCAInfo SNCA(nullptr); // Since we are rebuilding the whole tree, | 556 | 1.77M | // there's no point doing it incrementally. | 557 | 1.77M | | 558 | 1.77M | // Step #0: Number blocks in depth-first order and initialize variables used | 559 | 1.77M | // in later stages of the algorithm. | 560 | 1.77M | DT.Roots = FindRoots(DT, nullptr); | 561 | 1.77M | SNCA.doFullDFSWalk(DT, AlwaysDescend); | 562 | 1.77M | | 563 | 1.77M | SNCA.runSemiNCA(DT); | 564 | 1.77M | if (BUI1.77M ) { | 565 | 0 | BUI->IsRecalculated = true; | 566 | 0 | DEBUG(dbgs() << "DomTree recalculated, skipping future batch updates\n"); | 567 | 0 | } | 568 | 1.77M | | 569 | 1.77M | if (DT.Roots.empty()1.77M ) return0 ; | 570 | 1.77M | | 571 | 1.77M | // Add a node for the root. If the tree is a PostDominatorTree it will be | 572 | 1.77M | // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates | 573 | 1.77M | // all real exits (including multiple exit blocks, infinite loops). | 574 | 18.4E | NodePtr Root = IsPostDom ? 1.77M nullptr1.77M : DT.Roots[0]18.4E ; | 575 | 1.77M | | 576 | 1.77M | DT.RootNode = (DT.DomTreeNodes[Root] = | 577 | 1.77M | llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr)) | 578 | 1.77M | .get(); | 579 | 1.77M | SNCA.attachNewSubtree(DT, DT.RootNode); | 580 | 1.77M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::CalculateFromScratch(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*) Line | Count | Source | 551 | 12.1M | static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) { | 552 | 12.1M | auto *Parent = DT.Parent; | 553 | 12.1M | DT.reset(); | 554 | 12.1M | DT.Parent = Parent; | 555 | 12.1M | SemiNCAInfo SNCA(nullptr); // Since we are rebuilding the whole tree, | 556 | 12.1M | // there's no point doing it incrementally. | 557 | 12.1M | | 558 | 12.1M | // Step #0: Number blocks in depth-first order and initialize variables used | 559 | 12.1M | // in later stages of the algorithm. | 560 | 12.1M | DT.Roots = FindRoots(DT, nullptr); | 561 | 12.1M | SNCA.doFullDFSWalk(DT, AlwaysDescend); | 562 | 12.1M | | 563 | 12.1M | SNCA.runSemiNCA(DT); | 564 | 12.1M | if (BUI12.1M ) { | 565 | 185k | BUI->IsRecalculated = true; | 566 | 185k | DEBUG(dbgs() << "DomTree recalculated, skipping future batch updates\n"); | 567 | 185k | } | 568 | 12.1M | | 569 | 12.1M | if (DT.Roots.empty()12.1M ) return0 ; | 570 | 12.1M | | 571 | 12.1M | // Add a node for the root. If the tree is a PostDominatorTree it will be | 572 | 12.1M | // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates | 573 | 12.1M | // all real exits (including multiple exit blocks, infinite loops). | 574 | 12.1M | NodePtr Root = IsPostDom ? 12.1M nullptr0 : DT.Roots[0]12.1M ; | 575 | 12.1M | | 576 | 12.1M | DT.RootNode = (DT.DomTreeNodes[Root] = | 577 | 12.1M | llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr)) | 578 | 12.1M | .get(); | 579 | 12.1M | SNCA.attachNewSubtree(DT, DT.RootNode); | 580 | 12.1M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::CalculateFromScratch(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*) Line | Count | Source | 551 | 3.66M | static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) { | 552 | 3.66M | auto *Parent = DT.Parent; | 553 | 3.66M | DT.reset(); | 554 | 3.66M | DT.Parent = Parent; | 555 | 3.66M | SemiNCAInfo SNCA(nullptr); // Since we are rebuilding the whole tree, | 556 | 3.66M | // there's no point doing it incrementally. | 557 | 3.66M | | 558 | 3.66M | // Step #0: Number blocks in depth-first order and initialize variables used | 559 | 3.66M | // in later stages of the algorithm. | 560 | 3.66M | DT.Roots = FindRoots(DT, nullptr); | 561 | 3.66M | SNCA.doFullDFSWalk(DT, AlwaysDescend); | 562 | 3.66M | | 563 | 3.66M | SNCA.runSemiNCA(DT); | 564 | 3.66M | if (BUI3.66M ) { | 565 | 0 | BUI->IsRecalculated = true; | 566 | 0 | DEBUG(dbgs() << "DomTree recalculated, skipping future batch updates\n"); | 567 | 0 | } | 568 | 3.66M | | 569 | 3.66M | if (DT.Roots.empty()3.66M ) return0 ; | 570 | 3.66M | | 571 | 3.66M | // Add a node for the root. If the tree is a PostDominatorTree it will be | 572 | 3.66M | // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates | 573 | 3.66M | // all real exits (including multiple exit blocks, infinite loops). | 574 | 3.66M | NodePtr Root = IsPostDom ? 3.66M nullptr0 : DT.Roots[0]3.66M ; | 575 | 3.66M | | 576 | 3.66M | DT.RootNode = (DT.DomTreeNodes[Root] = | 577 | 3.66M | llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr)) | 578 | 3.66M | .get(); | 579 | 3.66M | SNCA.attachNewSubtree(DT, DT.RootNode); | 580 | 3.66M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::CalculateFromScratch(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*) Line | Count | Source | 551 | 581k | static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) { | 552 | 581k | auto *Parent = DT.Parent; | 553 | 581k | DT.reset(); | 554 | 581k | DT.Parent = Parent; | 555 | 581k | SemiNCAInfo SNCA(nullptr); // Since we are rebuilding the whole tree, | 556 | 581k | // there's no point doing it incrementally. | 557 | 581k | | 558 | 581k | // Step #0: Number blocks in depth-first order and initialize variables used | 559 | 581k | // in later stages of the algorithm. | 560 | 581k | DT.Roots = FindRoots(DT, nullptr); | 561 | 581k | SNCA.doFullDFSWalk(DT, AlwaysDescend); | 562 | 581k | | 563 | 581k | SNCA.runSemiNCA(DT); | 564 | 581k | if (BUI581k ) { | 565 | 26 | BUI->IsRecalculated = true; | 566 | 26 | DEBUG(dbgs() << "DomTree recalculated, skipping future batch updates\n"); | 567 | 26 | } | 568 | 581k | | 569 | 581k | if (DT.Roots.empty()581k ) return0 ; | 570 | 581k | | 571 | 581k | // Add a node for the root. If the tree is a PostDominatorTree it will be | 572 | 581k | // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates | 573 | 581k | // all real exits (including multiple exit blocks, infinite loops). | 574 | 18.4E | NodePtr Root = IsPostDom ? 581k nullptr581k : DT.Roots[0]18.4E ; | 575 | 581k | | 576 | 581k | DT.RootNode = (DT.DomTreeNodes[Root] = | 577 | 581k | llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr)) | 578 | 581k | .get(); | 579 | 581k | SNCA.attachNewSubtree(DT, DT.RootNode); | 580 | 581k | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::CalculateFromScratch(llvm::DominatorTreeBase<clang::CFGBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::BatchUpdateInfo*) Line | Count | Source | 551 | 5 | static void CalculateFromScratch(DomTreeT &DT, BatchUpdatePtr BUI) { | 552 | 5 | auto *Parent = DT.Parent; | 553 | 5 | DT.reset(); | 554 | 5 | DT.Parent = Parent; | 555 | 5 | SemiNCAInfo SNCA(nullptr); // Since we are rebuilding the whole tree, | 556 | 5 | // there's no point doing it incrementally. | 557 | 5 | | 558 | 5 | // Step #0: Number blocks in depth-first order and initialize variables used | 559 | 5 | // in later stages of the algorithm. | 560 | 5 | DT.Roots = FindRoots(DT, nullptr); | 561 | 5 | SNCA.doFullDFSWalk(DT, AlwaysDescend); | 562 | 5 | | 563 | 5 | SNCA.runSemiNCA(DT); | 564 | 5 | if (BUI5 ) { | 565 | 0 | BUI->IsRecalculated = true; | 566 | 0 | DEBUG(dbgs() << "DomTree recalculated, skipping future batch updates\n"); | 567 | 0 | } | 568 | 5 | | 569 | 5 | if (DT.Roots.empty()5 ) return0 ; | 570 | 5 | | 571 | 5 | // Add a node for the root. If the tree is a PostDominatorTree it will be | 572 | 5 | // the virtual exit (denoted by (BasicBlock *) nullptr) which postdominates | 573 | 5 | // all real exits (including multiple exit blocks, infinite loops). | 574 | 5 | NodePtr Root = IsPostDom ? 5 nullptr0 : DT.Roots[0]5 ; | 575 | 5 | | 576 | 5 | DT.RootNode = (DT.DomTreeNodes[Root] = | 577 | 5 | llvm::make_unique<DomTreeNodeBase<NodeT>>(Root, nullptr)) | 578 | 5 | .get(); | 579 | 5 | SNCA.attachNewSubtree(DT, DT.RootNode); | 580 | 5 | } |
|
581 | | |
582 | 18.4M | void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) { |
583 | 18.4M | // Attach the first unreachable block to AttachTo. |
584 | 18.4M | NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock(); |
585 | 18.4M | // Loop over all of the discovered blocks in the function... |
586 | 163M | for (size_t i = 1, e = NumToNode.size(); i != e163M ; ++i144M ) { |
587 | 144M | NodePtr W = NumToNode[i]; |
588 | 144M | DEBUG(dbgs() << "\tdiscovered a new reachable node " |
589 | 144M | << BlockNamePrinter(W) << "\n"); |
590 | 144M | |
591 | 144M | // Don't replace this with 'count', the insertion side effect is important |
592 | 144M | if (DT.DomTreeNodes[W]144M ) continue18.2M ; // Haven't calculated this node yet? |
593 | 144M | |
594 | 126M | NodePtr ImmDom = getIDom(W); |
595 | 126M | |
596 | 126M | // Get or calculate the node for the immediate dominator. |
597 | 126M | TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT); |
598 | 126M | |
599 | 126M | // Add a new tree node for this BasicBlock, and link it as a child of |
600 | 126M | // IDomNode. |
601 | 126M | DT.DomTreeNodes[W] = IDomNode->addChild( |
602 | 126M | llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode)); |
603 | 126M | } |
604 | 18.4M | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::attachNewSubtree(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) Line | Count | Source | 582 | 1.77M | void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) { | 583 | 1.77M | // Attach the first unreachable block to AttachTo. | 584 | 1.77M | NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock(); | 585 | 1.77M | // Loop over all of the discovered blocks in the function... | 586 | 16.1M | for (size_t i = 1, e = NumToNode.size(); i != e16.1M ; ++i14.3M ) { | 587 | 14.3M | NodePtr W = NumToNode[i]; | 588 | 14.3M | DEBUG(dbgs() << "\tdiscovered a new reachable node " | 589 | 14.3M | << BlockNamePrinter(W) << "\n"); | 590 | 14.3M | | 591 | 14.3M | // Don't replace this with 'count', the insertion side effect is important | 592 | 14.3M | if (DT.DomTreeNodes[W]14.3M ) continue1.77M ; // Haven't calculated this node yet? | 593 | 14.3M | | 594 | 12.5M | NodePtr ImmDom = getIDom(W); | 595 | 12.5M | | 596 | 12.5M | // Get or calculate the node for the immediate dominator. | 597 | 12.5M | TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT); | 598 | 12.5M | | 599 | 12.5M | // Add a new tree node for this BasicBlock, and link it as a child of | 600 | 12.5M | // IDomNode. | 601 | 12.5M | DT.DomTreeNodes[W] = IDomNode->addChild( | 602 | 12.5M | llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode)); | 603 | 12.5M | } | 604 | 1.77M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::attachNewSubtree(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeNodeBase<llvm::BasicBlock>*) Line | Count | Source | 582 | 12.4M | void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) { | 583 | 12.4M | // Attach the first unreachable block to AttachTo. | 584 | 12.4M | NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock(); | 585 | 12.4M | // Loop over all of the discovered blocks in the function... | 586 | 114M | for (size_t i = 1, e = NumToNode.size(); i != e114M ; ++i101M ) { | 587 | 101M | NodePtr W = NumToNode[i]; | 588 | 101M | DEBUG(dbgs() << "\tdiscovered a new reachable node " | 589 | 101M | << BlockNamePrinter(W) << "\n"); | 590 | 101M | | 591 | 101M | // Don't replace this with 'count', the insertion side effect is important | 592 | 101M | if (DT.DomTreeNodes[W]101M ) continue12.1M ; // Haven't calculated this node yet? | 593 | 101M | | 594 | 89.7M | NodePtr ImmDom = getIDom(W); | 595 | 89.7M | | 596 | 89.7M | // Get or calculate the node for the immediate dominator. | 597 | 89.7M | TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT); | 598 | 89.7M | | 599 | 89.7M | // Add a new tree node for this BasicBlock, and link it as a child of | 600 | 89.7M | // IDomNode. | 601 | 89.7M | DT.DomTreeNodes[W] = IDomNode->addChild( | 602 | 89.7M | llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode)); | 603 | 89.7M | } | 604 | 12.4M | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<clang::CFGBlock, false> >::attachNewSubtree(llvm::DominatorTreeBase<clang::CFGBlock, false>&, llvm::DomTreeNodeBase<clang::CFGBlock>*) Line | Count | Source | 582 | 5 | void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) { | 583 | 5 | // Attach the first unreachable block to AttachTo. | 584 | 5 | NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock(); | 585 | 5 | // Loop over all of the discovered blocks in the function... | 586 | 57 | for (size_t i = 1, e = NumToNode.size(); i != e57 ; ++i52 ) { | 587 | 52 | NodePtr W = NumToNode[i]; | 588 | 52 | DEBUG(dbgs() << "\tdiscovered a new reachable node " | 589 | 52 | << BlockNamePrinter(W) << "\n"); | 590 | 52 | | 591 | 52 | // Don't replace this with 'count', the insertion side effect is important | 592 | 52 | if (DT.DomTreeNodes[W]52 ) continue5 ; // Haven't calculated this node yet? | 593 | 52 | | 594 | 47 | NodePtr ImmDom = getIDom(W); | 595 | 47 | | 596 | 47 | // Get or calculate the node for the immediate dominator. | 597 | 47 | TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT); | 598 | 47 | | 599 | 47 | // Add a new tree node for this BasicBlock, and link it as a child of | 600 | 47 | // IDomNode. | 601 | 47 | DT.DomTreeNodes[W] = IDomNode->addChild( | 602 | 47 | llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode)); | 603 | 47 | } | 604 | 5 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::attachNewSubtree(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeNodeBase<llvm::BasicBlock>*) Line | Count | Source | 582 | 581k | void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) { | 583 | 581k | // Attach the first unreachable block to AttachTo. | 584 | 581k | NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock(); | 585 | 581k | // Loop over all of the discovered blocks in the function... | 586 | 5.16M | for (size_t i = 1, e = NumToNode.size(); i != e5.16M ; ++i4.58M ) { | 587 | 4.58M | NodePtr W = NumToNode[i]; | 588 | 4.58M | DEBUG(dbgs() << "\tdiscovered a new reachable node " | 589 | 4.58M | << BlockNamePrinter(W) << "\n"); | 590 | 4.58M | | 591 | 4.58M | // Don't replace this with 'count', the insertion side effect is important | 592 | 4.58M | if (DT.DomTreeNodes[W]4.58M ) continue581k ; // Haven't calculated this node yet? | 593 | 4.58M | | 594 | 4.00M | NodePtr ImmDom = getIDom(W); | 595 | 4.00M | | 596 | 4.00M | // Get or calculate the node for the immediate dominator. | 597 | 4.00M | TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT); | 598 | 4.00M | | 599 | 4.00M | // Add a new tree node for this BasicBlock, and link it as a child of | 600 | 4.00M | // IDomNode. | 601 | 4.00M | DT.DomTreeNodes[W] = IDomNode->addChild( | 602 | 4.00M | llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode)); | 603 | 4.00M | } | 604 | 581k | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::attachNewSubtree(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) Line | Count | Source | 582 | 3.66M | void attachNewSubtree(DomTreeT& DT, const TreeNodePtr AttachTo) { | 583 | 3.66M | // Attach the first unreachable block to AttachTo. | 584 | 3.66M | NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock(); | 585 | 3.66M | // Loop over all of the discovered blocks in the function... | 586 | 27.4M | for (size_t i = 1, e = NumToNode.size(); i != e27.4M ; ++i23.8M ) { | 587 | 23.8M | NodePtr W = NumToNode[i]; | 588 | 23.8M | DEBUG(dbgs() << "\tdiscovered a new reachable node " | 589 | 23.8M | << BlockNamePrinter(W) << "\n"); | 590 | 23.8M | | 591 | 23.8M | // Don't replace this with 'count', the insertion side effect is important | 592 | 23.8M | if (DT.DomTreeNodes[W]23.8M ) continue3.66M ; // Haven't calculated this node yet? | 593 | 23.8M | | 594 | 20.1M | NodePtr ImmDom = getIDom(W); | 595 | 20.1M | | 596 | 20.1M | // Get or calculate the node for the immediate dominator. | 597 | 20.1M | TreeNodePtr IDomNode = getNodeForBlock(ImmDom, DT); | 598 | 20.1M | | 599 | 20.1M | // Add a new tree node for this BasicBlock, and link it as a child of | 600 | 20.1M | // IDomNode. | 601 | 20.1M | DT.DomTreeNodes[W] = IDomNode->addChild( | 602 | 20.1M | llvm::make_unique<DomTreeNodeBase<NodeT>>(W, IDomNode)); | 603 | 20.1M | } | 604 | 3.66M | } |
|
605 | | |
606 | 575k | void reattachExistingSubtree(DomTreeT &DT, const TreeNodePtr AttachTo) { |
607 | 575k | NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock(); |
608 | 17.6M | for (size_t i = 1, e = NumToNode.size(); i != e17.6M ; ++i17.1M ) { |
609 | 17.1M | const NodePtr N = NumToNode[i]; |
610 | 17.1M | const TreeNodePtr TN = DT.getNode(N); |
611 | 17.1M | assert(TN); |
612 | 17.1M | const TreeNodePtr NewIDom = DT.getNode(NodeToInfo[N].IDom); |
613 | 17.1M | TN->setIDom(NewIDom); |
614 | 17.1M | } |
615 | 575k | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::reattachExistingSubtree(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeNodeBase<llvm::BasicBlock>*) Line | Count | Source | 606 | 575k | void reattachExistingSubtree(DomTreeT &DT, const TreeNodePtr AttachTo) { | 607 | 575k | NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock(); | 608 | 17.6M | for (size_t i = 1, e = NumToNode.size(); i != e17.6M ; ++i17.1M ) { | 609 | 17.1M | const NodePtr N = NumToNode[i]; | 610 | 17.1M | const TreeNodePtr TN = DT.getNode(N); | 611 | 17.1M | assert(TN); | 612 | 17.1M | const TreeNodePtr NewIDom = DT.getNode(NodeToInfo[N].IDom); | 613 | 17.1M | TN->setIDom(NewIDom); | 614 | 17.1M | } | 615 | 575k | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::reattachExistingSubtree(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::reattachExistingSubtree(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::reattachExistingSubtree(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeNodeBase<llvm::BasicBlock>*) Line | Count | Source | 606 | 125 | void reattachExistingSubtree(DomTreeT &DT, const TreeNodePtr AttachTo) { | 607 | 125 | NodeToInfo[NumToNode[1]].IDom = AttachTo->getBlock(); | 608 | 561 | for (size_t i = 1, e = NumToNode.size(); i != e561 ; ++i436 ) { | 609 | 436 | const NodePtr N = NumToNode[i]; | 610 | 436 | const TreeNodePtr TN = DT.getNode(N); | 611 | 436 | assert(TN); | 612 | 436 | const TreeNodePtr NewIDom = DT.getNode(NodeToInfo[N].IDom); | 613 | 436 | TN->setIDom(NewIDom); | 614 | 436 | } | 615 | 125 | } |
|
616 | | |
617 | | // Helper struct used during edge insertions. |
618 | | struct InsertionInfo { |
619 | | using BucketElementTy = std::pair<unsigned, TreeNodePtr>; |
620 | | struct DecreasingLevel { |
621 | | bool operator()(const BucketElementTy &First, |
622 | 4.50k | const BucketElementTy &Second) const { |
623 | 4.50k | return First.first > Second.first; |
624 | 4.50k | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::InsertionInfo::DecreasingLevel::operator()(std::__1::pair<unsigned int, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> const&, std::__1::pair<unsigned int, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> const&) const Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::InsertionInfo::DecreasingLevel::operator()(std::__1::pair<unsigned int, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> const&, std::__1::pair<unsigned int, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> const&) const llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::InsertionInfo::DecreasingLevel::operator()(std::__1::pair<unsigned int, llvm::DomTreeNodeBase<llvm::BasicBlock>*> const&, std::__1::pair<unsigned int, llvm::DomTreeNodeBase<llvm::BasicBlock>*> const&) const Line | Count | Source | 622 | 1 | const BucketElementTy &Second) const { | 623 | 1 | return First.first > Second.first; | 624 | 1 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::InsertionInfo::DecreasingLevel::operator()(std::__1::pair<unsigned int, llvm::DomTreeNodeBase<llvm::BasicBlock>*> const&, std::__1::pair<unsigned int, llvm::DomTreeNodeBase<llvm::BasicBlock>*> const&) const Line | Count | Source | 622 | 4.50k | const BucketElementTy &Second) const { | 623 | 4.50k | return First.first > Second.first; | 624 | 4.50k | } |
|
625 | | }; |
626 | | |
627 | | std::priority_queue<BucketElementTy, SmallVector<BucketElementTy, 8>, |
628 | | DecreasingLevel> |
629 | | Bucket; // Queue of tree nodes sorted by level in descending order. |
630 | | SmallDenseSet<TreeNodePtr, 8> Affected; |
631 | | SmallDenseSet<TreeNodePtr, 8> Visited; |
632 | | SmallVector<TreeNodePtr, 8> AffectedQueue; |
633 | | SmallVector<TreeNodePtr, 8> VisitedNotAffectedQueue; |
634 | | }; |
635 | | |
636 | | static void InsertEdge(DomTreeT &DT, const BatchUpdatePtr BUI, |
637 | 819k | const NodePtr From, const NodePtr To) { |
638 | 819k | assert((From || IsPostDom) && |
639 | 819k | "From has to be a valid CFG node or a virtual root"); |
640 | 819k | assert(To && "Cannot be a nullptr"); |
641 | 819k | DEBUG(dbgs() << "Inserting edge " << BlockNamePrinter(From) << " -> " |
642 | 819k | << BlockNamePrinter(To) << "\n"); |
643 | 819k | TreeNodePtr FromTN = DT.getNode(From); |
644 | 819k | |
645 | 819k | if (!FromTN819k ) { |
646 | 43.5k | // Ignore edges from unreachable nodes for (forward) dominators. |
647 | 43.5k | if (!IsPostDom43.5k ) return43.5k ; |
648 | 43.5k | |
649 | 43.5k | // The unreachable node becomes a new root -- a tree node for it. |
650 | 3 | TreeNodePtr VirtualRoot = DT.getNode(nullptr); |
651 | 3 | FromTN = |
652 | 3 | (DT.DomTreeNodes[From] = VirtualRoot->addChild( |
653 | 3 | llvm::make_unique<DomTreeNodeBase<NodeT>>(From, VirtualRoot))) |
654 | 3 | .get(); |
655 | 3 | DT.Roots.push_back(From); |
656 | 3 | } |
657 | 819k | |
658 | 775k | DT.DFSInfoValid = false; |
659 | 775k | |
660 | 775k | const TreeNodePtr ToTN = DT.getNode(To); |
661 | 775k | if (!ToTN) |
662 | 206k | InsertUnreachable(DT, BUI, FromTN, To); |
663 | 775k | else |
664 | 569k | InsertReachable(DT, BUI, FromTN, ToTN); |
665 | 819k | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::InsertEdge(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::InsertEdge(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::BasicBlock*) Line | Count | Source | 637 | 154 | const NodePtr From, const NodePtr To) { | 638 | 154 | assert((From || IsPostDom) && | 639 | 154 | "From has to be a valid CFG node or a virtual root"); | 640 | 154 | assert(To && "Cannot be a nullptr"); | 641 | 154 | DEBUG(dbgs() << "Inserting edge " << BlockNamePrinter(From) << " -> " | 642 | 154 | << BlockNamePrinter(To) << "\n"); | 643 | 154 | TreeNodePtr FromTN = DT.getNode(From); | 644 | 154 | | 645 | 154 | if (!FromTN154 ) { | 646 | 3 | // Ignore edges from unreachable nodes for (forward) dominators. | 647 | 3 | if (!IsPostDom3 ) return0 ; | 648 | 3 | | 649 | 3 | // The unreachable node becomes a new root -- a tree node for it. | 650 | 3 | TreeNodePtr VirtualRoot = DT.getNode(nullptr); | 651 | 3 | FromTN = | 652 | 3 | (DT.DomTreeNodes[From] = VirtualRoot->addChild( | 653 | 3 | llvm::make_unique<DomTreeNodeBase<NodeT>>(From, VirtualRoot))) | 654 | 3 | .get(); | 655 | 3 | DT.Roots.push_back(From); | 656 | 3 | } | 657 | 154 | | 658 | 154 | DT.DFSInfoValid = false; | 659 | 154 | | 660 | 154 | const TreeNodePtr ToTN = DT.getNode(To); | 661 | 154 | if (!ToTN) | 662 | 0 | InsertUnreachable(DT, BUI, FromTN, To); | 663 | 154 | else | 664 | 154 | InsertReachable(DT, BUI, FromTN, ToTN); | 665 | 154 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::InsertEdge(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::BasicBlock*) Line | Count | Source | 637 | 819k | const NodePtr From, const NodePtr To) { | 638 | 819k | assert((From || IsPostDom) && | 639 | 819k | "From has to be a valid CFG node or a virtual root"); | 640 | 819k | assert(To && "Cannot be a nullptr"); | 641 | 819k | DEBUG(dbgs() << "Inserting edge " << BlockNamePrinter(From) << " -> " | 642 | 819k | << BlockNamePrinter(To) << "\n"); | 643 | 819k | TreeNodePtr FromTN = DT.getNode(From); | 644 | 819k | | 645 | 819k | if (!FromTN819k ) { | 646 | 43.5k | // Ignore edges from unreachable nodes for (forward) dominators. | 647 | 43.5k | if (!IsPostDom43.5k ) return43.5k ; | 648 | 43.5k | | 649 | 43.5k | // The unreachable node becomes a new root -- a tree node for it. | 650 | 0 | TreeNodePtr VirtualRoot = DT.getNode(nullptr); | 651 | 0 | FromTN = | 652 | 0 | (DT.DomTreeNodes[From] = VirtualRoot->addChild( | 653 | 0 | llvm::make_unique<DomTreeNodeBase<NodeT>>(From, VirtualRoot))) | 654 | 0 | .get(); | 655 | 0 | DT.Roots.push_back(From); | 656 | 0 | } | 657 | 819k | | 658 | 775k | DT.DFSInfoValid = false; | 659 | 775k | | 660 | 775k | const TreeNodePtr ToTN = DT.getNode(To); | 661 | 775k | if (!ToTN) | 662 | 206k | InsertUnreachable(DT, BUI, FromTN, To); | 663 | 775k | else | 664 | 569k | InsertReachable(DT, BUI, FromTN, ToTN); | 665 | 819k | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::InsertEdge(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) |
666 | | |
667 | | // Determines if some existing root becomes reverse-reachable after the |
668 | | // insertion. Rebuilds the whole tree if that situation happens. |
669 | | static bool UpdateRootsBeforeInsertion(DomTreeT &DT, const BatchUpdatePtr BUI, |
670 | | const TreeNodePtr From, |
671 | 201 | const TreeNodePtr To) { |
672 | 201 | assert(IsPostDom && "This function is only for postdominators"); |
673 | 201 | // Destination node is not attached to the virtual root, so it cannot be a |
674 | 201 | // root. |
675 | 201 | if (!DT.isVirtualRoot(To->getIDom())201 ) return false103 ; |
676 | 201 | |
677 | 98 | auto RIt = llvm::find(DT.Roots, To->getBlock()); |
678 | 98 | if (RIt == DT.Roots.end()) |
679 | 15 | return false; // To is not a root, nothing to update. |
680 | 98 | |
681 | 83 | DEBUG83 (dbgs() << "\t\tAfter the insertion, " << BlockNamePrinter(To) |
682 | 83 | << " is no longer a root\n\t\tRebuilding the tree!!!\n"); |
683 | 83 | |
684 | 83 | CalculateFromScratch(DT, BUI); |
685 | 83 | return true; |
686 | 201 | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::UpdateRootsBeforeInsertion(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::UpdateRootsBeforeInsertion(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::UpdateRootsBeforeInsertion(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) Line | Count | Source | 671 | 201 | const TreeNodePtr To) { | 672 | 201 | assert(IsPostDom && "This function is only for postdominators"); | 673 | 201 | // Destination node is not attached to the virtual root, so it cannot be a | 674 | 201 | // root. | 675 | 201 | if (!DT.isVirtualRoot(To->getIDom())201 ) return false103 ; | 676 | 201 | | 677 | 98 | auto RIt = llvm::find(DT.Roots, To->getBlock()); | 678 | 98 | if (RIt == DT.Roots.end()) | 679 | 15 | return false; // To is not a root, nothing to update. | 680 | 98 | | 681 | 83 | DEBUG83 (dbgs() << "\t\tAfter the insertion, " << BlockNamePrinter(To) | 682 | 83 | << " is no longer a root\n\t\tRebuilding the tree!!!\n"); | 683 | 83 | | 684 | 83 | CalculateFromScratch(DT, BUI); | 685 | 83 | return true; | 686 | 201 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::UpdateRootsBeforeInsertion(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) |
687 | | |
688 | | // Updates the set of roots after insertion or deletion. This ensures that |
689 | | // roots are the same when after a series of updates and when the tree would |
690 | | // be built from scratch. |
691 | 293 | static void UpdateRootsAfterUpdate(DomTreeT &DT, const BatchUpdatePtr BUI) { |
692 | 293 | assert(IsPostDom && "This function is only for postdominators"); |
693 | 293 | |
694 | 293 | // The tree has only trivial roots -- nothing to update. |
695 | 293 | if (std::none_of(DT.Roots.begin(), DT.Roots.end(), [BUI](const NodePtr N) 293 { |
696 | 686 | return HasForwardSuccessors(N, BUI); |
697 | 686 | })) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::UpdateRootsAfterUpdate(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*)::'lambda'(llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*) const llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::UpdateRootsAfterUpdate(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*)::'lambda'(llvm::BasicBlock*)::operator()(llvm::BasicBlock*) const Line | Count | Source | 695 | 686 | if (std::none_of(DT.Roots.begin(), DT.Roots.end(), [BUI](const NodePtr N) { | 696 | 686 | return HasForwardSuccessors(N, BUI); | 697 | 686 | })) |
|
698 | 257 | return; |
699 | 293 | |
700 | 293 | // Recalculate the set of roots. |
701 | 36 | DT.Roots = FindRoots(DT, BUI); |
702 | 36 | for (const NodePtr R : DT.Roots) { |
703 | 36 | const TreeNodePtr TN = DT.getNode(R); |
704 | 36 | // A CFG node was selected as a tree root, but the corresponding tree node |
705 | 36 | // is not connected to the virtual root. This is because the incremental |
706 | 36 | // algorithm does not really know or use the set of roots and can make a |
707 | 36 | // different (implicit) decision about which nodes within an infinite loop |
708 | 36 | // becomes a root. |
709 | 36 | if (DT.isVirtualRoot(TN->getIDom())36 ) { |
710 | 36 | DEBUG(dbgs() << "Root " << BlockNamePrinter(R) |
711 | 36 | << " is not virtual root's child\n" |
712 | 36 | << "The entire tree needs to be rebuilt\n"); |
713 | 36 | // It should be possible to rotate the subtree instead of recalculating |
714 | 36 | // the whole tree, but this situation happens extremely rarely in |
715 | 36 | // practice. |
716 | 36 | CalculateFromScratch(DT, BUI); |
717 | 36 | return; |
718 | 36 | } |
719 | 36 | } |
720 | 293 | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::UpdateRootsAfterUpdate(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*) Line | Count | Source | 691 | 293 | static void UpdateRootsAfterUpdate(DomTreeT &DT, const BatchUpdatePtr BUI) { | 692 | 293 | assert(IsPostDom && "This function is only for postdominators"); | 693 | 293 | | 694 | 293 | // The tree has only trivial roots -- nothing to update. | 695 | 293 | if (std::none_of(DT.Roots.begin(), DT.Roots.end(), [BUI](const NodePtr N) { | 696 | 293 | return HasForwardSuccessors(N, BUI); | 697 | 293 | })) | 698 | 257 | return; | 699 | 293 | | 700 | 293 | // Recalculate the set of roots. | 701 | 36 | DT.Roots = FindRoots(DT, BUI); | 702 | 36 | for (const NodePtr R : DT.Roots) { | 703 | 36 | const TreeNodePtr TN = DT.getNode(R); | 704 | 36 | // A CFG node was selected as a tree root, but the corresponding tree node | 705 | 36 | // is not connected to the virtual root. This is because the incremental | 706 | 36 | // algorithm does not really know or use the set of roots and can make a | 707 | 36 | // different (implicit) decision about which nodes within an infinite loop | 708 | 36 | // becomes a root. | 709 | 36 | if (DT.isVirtualRoot(TN->getIDom())36 ) { | 710 | 36 | DEBUG(dbgs() << "Root " << BlockNamePrinter(R) | 711 | 36 | << " is not virtual root's child\n" | 712 | 36 | << "The entire tree needs to be rebuilt\n"); | 713 | 36 | // It should be possible to rotate the subtree instead of recalculating | 714 | 36 | // the whole tree, but this situation happens extremely rarely in | 715 | 36 | // practice. | 716 | 36 | CalculateFromScratch(DT, BUI); | 717 | 36 | return; | 718 | 36 | } | 719 | 36 | } | 720 | 293 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::UpdateRootsAfterUpdate(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::UpdateRootsAfterUpdate(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::UpdateRootsAfterUpdate(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*) |
721 | | |
722 | | // Handles insertion to a node already in the dominator tree. |
723 | | static void InsertReachable(DomTreeT &DT, const BatchUpdatePtr BUI, |
724 | 684k | const TreeNodePtr From, const TreeNodePtr To) { |
725 | 684k | DEBUG(dbgs() << "\tReachable " << BlockNamePrinter(From->getBlock()) |
726 | 684k | << " -> " << BlockNamePrinter(To->getBlock()) << "\n"); |
727 | 684k | if (IsPostDom && 684k UpdateRootsBeforeInsertion(DT, BUI, From, To)201 ) return83 ; |
728 | 684k | // DT.findNCD expects both pointers to be valid. When From is a virtual |
729 | 684k | // root, then its CFG block pointer is a nullptr, so we have to 'compute' |
730 | 684k | // the NCD manually. |
731 | 684k | const NodePtr NCDBlock = |
732 | 684k | (From->getBlock() && To->getBlock()) |
733 | 684k | ? DT.findNearestCommonDominator(From->getBlock(), To->getBlock()) |
734 | 47 | : nullptr; |
735 | 684k | assert(NCDBlock || DT.isPostDominator()); |
736 | 684k | const TreeNodePtr NCD = DT.getNode(NCDBlock); |
737 | 684k | assert(NCD); |
738 | 684k | |
739 | 684k | DEBUG(dbgs() << "\t\tNCA == " << BlockNamePrinter(NCD) << "\n"); |
740 | 684k | const TreeNodePtr ToIDom = To->getIDom(); |
741 | 684k | |
742 | 684k | // Nothing affected -- NCA property holds. |
743 | 684k | // (Based on the lemma 2.5 from the second paper.) |
744 | 684k | if (NCD == To || 684k NCD == ToIDom677k ) return413k ; |
745 | 684k | |
746 | 684k | // Identify and collect affected nodes. |
747 | 271k | InsertionInfo II; |
748 | 271k | DEBUG(dbgs() << "Marking " << BlockNamePrinter(To) << " as affected\n"); |
749 | 271k | II.Affected.insert(To); |
750 | 271k | const unsigned ToLevel = To->getLevel(); |
751 | 271k | DEBUG(dbgs() << "Putting " << BlockNamePrinter(To) << " into a Bucket\n"); |
752 | 271k | II.Bucket.push({ToLevel, To}); |
753 | 271k | |
754 | 569k | while (!II.Bucket.empty()569k ) { |
755 | 297k | const TreeNodePtr CurrentNode = II.Bucket.top().second; |
756 | 297k | II.Bucket.pop(); |
757 | 297k | DEBUG(dbgs() << "\tAdding to Visited and AffectedQueue: " |
758 | 297k | << BlockNamePrinter(CurrentNode) << "\n"); |
759 | 297k | II.Visited.insert(CurrentNode); |
760 | 297k | II.AffectedQueue.push_back(CurrentNode); |
761 | 297k | |
762 | 297k | // Discover and collect affected successors of the current node. |
763 | 297k | VisitInsertion(DT, BUI, CurrentNode, CurrentNode->getLevel(), NCD, II); |
764 | 297k | } |
765 | 684k | |
766 | 684k | // Finish by updating immediate dominators and levels. |
767 | 684k | UpdateInsertion(DT, BUI, NCD, II); |
768 | 684k | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::InsertReachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) Line | Count | Source | 724 | 684k | const TreeNodePtr From, const TreeNodePtr To) { | 725 | 684k | DEBUG(dbgs() << "\tReachable " << BlockNamePrinter(From->getBlock()) | 726 | 684k | << " -> " << BlockNamePrinter(To->getBlock()) << "\n"); | 727 | 684k | if (IsPostDom && 684k UpdateRootsBeforeInsertion(DT, BUI, From, To)0 ) return0 ; | 728 | 684k | // DT.findNCD expects both pointers to be valid. When From is a virtual | 729 | 684k | // root, then its CFG block pointer is a nullptr, so we have to 'compute' | 730 | 684k | // the NCD manually. | 731 | 684k | const NodePtr NCDBlock = | 732 | 684k | (From->getBlock() && To->getBlock()) | 733 | 684k | ? DT.findNearestCommonDominator(From->getBlock(), To->getBlock()) | 734 | 0 | : nullptr; | 735 | 684k | assert(NCDBlock || DT.isPostDominator()); | 736 | 684k | const TreeNodePtr NCD = DT.getNode(NCDBlock); | 737 | 684k | assert(NCD); | 738 | 684k | | 739 | 684k | DEBUG(dbgs() << "\t\tNCA == " << BlockNamePrinter(NCD) << "\n"); | 740 | 684k | const TreeNodePtr ToIDom = To->getIDom(); | 741 | 684k | | 742 | 684k | // Nothing affected -- NCA property holds. | 743 | 684k | // (Based on the lemma 2.5 from the second paper.) | 744 | 684k | if (NCD == To || 684k NCD == ToIDom677k ) return413k ; | 745 | 684k | | 746 | 684k | // Identify and collect affected nodes. | 747 | 271k | InsertionInfo II; | 748 | 271k | DEBUG(dbgs() << "Marking " << BlockNamePrinter(To) << " as affected\n"); | 749 | 271k | II.Affected.insert(To); | 750 | 271k | const unsigned ToLevel = To->getLevel(); | 751 | 271k | DEBUG(dbgs() << "Putting " << BlockNamePrinter(To) << " into a Bucket\n"); | 752 | 271k | II.Bucket.push({ToLevel, To}); | 753 | 271k | | 754 | 568k | while (!II.Bucket.empty()568k ) { | 755 | 297k | const TreeNodePtr CurrentNode = II.Bucket.top().second; | 756 | 297k | II.Bucket.pop(); | 757 | 297k | DEBUG(dbgs() << "\tAdding to Visited and AffectedQueue: " | 758 | 297k | << BlockNamePrinter(CurrentNode) << "\n"); | 759 | 297k | II.Visited.insert(CurrentNode); | 760 | 297k | II.AffectedQueue.push_back(CurrentNode); | 761 | 297k | | 762 | 297k | // Discover and collect affected successors of the current node. | 763 | 297k | VisitInsertion(DT, BUI, CurrentNode, CurrentNode->getLevel(), NCD, II); | 764 | 297k | } | 765 | 684k | | 766 | 684k | // Finish by updating immediate dominators and levels. | 767 | 684k | UpdateInsertion(DT, BUI, NCD, II); | 768 | 684k | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::InsertReachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) Line | Count | Source | 724 | 201 | const TreeNodePtr From, const TreeNodePtr To) { | 725 | 201 | DEBUG(dbgs() << "\tReachable " << BlockNamePrinter(From->getBlock()) | 726 | 201 | << " -> " << BlockNamePrinter(To->getBlock()) << "\n"); | 727 | 201 | if (IsPostDom && 201 UpdateRootsBeforeInsertion(DT, BUI, From, To)201 ) return83 ; | 728 | 201 | // DT.findNCD expects both pointers to be valid. When From is a virtual | 729 | 201 | // root, then its CFG block pointer is a nullptr, so we have to 'compute' | 730 | 201 | // the NCD manually. | 731 | 118 | const NodePtr NCDBlock = | 732 | 71 | (From->getBlock() && To->getBlock()) | 733 | 71 | ? DT.findNearestCommonDominator(From->getBlock(), To->getBlock()) | 734 | 47 | : nullptr; | 735 | 118 | assert(NCDBlock || DT.isPostDominator()); | 736 | 118 | const TreeNodePtr NCD = DT.getNode(NCDBlock); | 737 | 118 | assert(NCD); | 738 | 118 | | 739 | 118 | DEBUG(dbgs() << "\t\tNCA == " << BlockNamePrinter(NCD) << "\n"); | 740 | 118 | const TreeNodePtr ToIDom = To->getIDom(); | 741 | 118 | | 742 | 118 | // Nothing affected -- NCA property holds. | 743 | 118 | // (Based on the lemma 2.5 from the second paper.) | 744 | 118 | if (NCD == To || 118 NCD == ToIDom109 ) return36 ; | 745 | 118 | | 746 | 118 | // Identify and collect affected nodes. | 747 | 82 | InsertionInfo II; | 748 | 82 | DEBUG(dbgs() << "Marking " << BlockNamePrinter(To) << " as affected\n"); | 749 | 82 | II.Affected.insert(To); | 750 | 82 | const unsigned ToLevel = To->getLevel(); | 751 | 82 | DEBUG(dbgs() << "Putting " << BlockNamePrinter(To) << " into a Bucket\n"); | 752 | 82 | II.Bucket.push({ToLevel, To}); | 753 | 82 | | 754 | 176 | while (!II.Bucket.empty()176 ) { | 755 | 94 | const TreeNodePtr CurrentNode = II.Bucket.top().second; | 756 | 94 | II.Bucket.pop(); | 757 | 94 | DEBUG(dbgs() << "\tAdding to Visited and AffectedQueue: " | 758 | 94 | << BlockNamePrinter(CurrentNode) << "\n"); | 759 | 94 | II.Visited.insert(CurrentNode); | 760 | 94 | II.AffectedQueue.push_back(CurrentNode); | 761 | 94 | | 762 | 94 | // Discover and collect affected successors of the current node. | 763 | 94 | VisitInsertion(DT, BUI, CurrentNode, CurrentNode->getLevel(), NCD, II); | 764 | 94 | } | 765 | 201 | | 766 | 201 | // Finish by updating immediate dominators and levels. | 767 | 201 | UpdateInsertion(DT, BUI, NCD, II); | 768 | 201 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::InsertReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::InsertReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) |
769 | | |
770 | | // Visits an affected node and collect its affected successors. |
771 | | static void VisitInsertion(DomTreeT &DT, const BatchUpdatePtr BUI, |
772 | | const TreeNodePtr TN, const unsigned RootLevel, |
773 | 297k | const TreeNodePtr NCD, InsertionInfo &II) { |
774 | 297k | const unsigned NCDLevel = NCD->getLevel(); |
775 | 297k | DEBUG(dbgs() << "Visiting " << BlockNamePrinter(TN) << "\n"); |
776 | 297k | |
777 | 297k | SmallVector<TreeNodePtr, 8> Stack = {TN}; |
778 | 297k | assert(TN->getBlock() && II.Visited.count(TN) && "Preconditions!"); |
779 | 297k | |
780 | 2.75M | do { |
781 | 2.75M | TreeNodePtr Next = Stack.pop_back_val(); |
782 | 2.75M | |
783 | 2.75M | for (const NodePtr Succ : |
784 | 4.07M | ChildrenGetter<IsPostDom>::Get(Next->getBlock(), BUI)) { |
785 | 4.07M | const TreeNodePtr SuccTN = DT.getNode(Succ); |
786 | 4.07M | assert(SuccTN && "Unreachable successor found at reachable insertion"); |
787 | 4.07M | const unsigned SuccLevel = SuccTN->getLevel(); |
788 | 4.07M | |
789 | 4.07M | DEBUG(dbgs() << "\tSuccessor " << BlockNamePrinter(Succ) |
790 | 4.07M | << ", level = " << SuccLevel << "\n"); |
791 | 4.07M | |
792 | 4.07M | // Succ dominated by subtree From -- not affected. |
793 | 4.07M | // (Based on the lemma 2.5 from the second paper.) |
794 | 4.07M | if (SuccLevel > RootLevel4.07M ) { |
795 | 3.65M | DEBUG(dbgs() << "\t\tDominated by subtree From\n"); |
796 | 3.65M | if (II.Visited.count(SuccTN) != 0) |
797 | 1.19M | continue; |
798 | 3.65M | |
799 | 2.45M | DEBUG2.45M (dbgs() << "\t\tMarking visited not affected " |
800 | 2.45M | << BlockNamePrinter(Succ) << "\n"); |
801 | 2.45M | II.Visited.insert(SuccTN); |
802 | 2.45M | II.VisitedNotAffectedQueue.push_back(SuccTN); |
803 | 2.45M | Stack.push_back(SuccTN); |
804 | 4.07M | } else if (419k (SuccLevel > NCDLevel + 1) && |
805 | 419k | II.Affected.count(SuccTN) == 038.3k ) { |
806 | 26.7k | DEBUG(dbgs() << "\t\tMarking affected and adding " |
807 | 419k | << BlockNamePrinter(Succ) << " to a Bucket\n"); |
808 | 419k | II.Affected.insert(SuccTN); |
809 | 419k | II.Bucket.push({SuccLevel, SuccTN}); |
810 | 419k | } |
811 | 4.07M | } |
812 | 2.75M | } while (!Stack.empty()); |
813 | 297k | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::VisitInsertion(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, unsigned int, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::InsertionInfo&) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::VisitInsertion(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, unsigned int, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::InsertionInfo&) Line | Count | Source | 773 | 297k | const TreeNodePtr NCD, InsertionInfo &II) { | 774 | 297k | const unsigned NCDLevel = NCD->getLevel(); | 775 | 297k | DEBUG(dbgs() << "Visiting " << BlockNamePrinter(TN) << "\n"); | 776 | 297k | | 777 | 297k | SmallVector<TreeNodePtr, 8> Stack = {TN}; | 778 | 297k | assert(TN->getBlock() && II.Visited.count(TN) && "Preconditions!"); | 779 | 297k | | 780 | 2.75M | do { | 781 | 2.75M | TreeNodePtr Next = Stack.pop_back_val(); | 782 | 2.75M | | 783 | 2.75M | for (const NodePtr Succ : | 784 | 4.07M | ChildrenGetter<IsPostDom>::Get(Next->getBlock(), BUI)) { | 785 | 4.07M | const TreeNodePtr SuccTN = DT.getNode(Succ); | 786 | 4.07M | assert(SuccTN && "Unreachable successor found at reachable insertion"); | 787 | 4.07M | const unsigned SuccLevel = SuccTN->getLevel(); | 788 | 4.07M | | 789 | 4.07M | DEBUG(dbgs() << "\tSuccessor " << BlockNamePrinter(Succ) | 790 | 4.07M | << ", level = " << SuccLevel << "\n"); | 791 | 4.07M | | 792 | 4.07M | // Succ dominated by subtree From -- not affected. | 793 | 4.07M | // (Based on the lemma 2.5 from the second paper.) | 794 | 4.07M | if (SuccLevel > RootLevel4.07M ) { | 795 | 3.65M | DEBUG(dbgs() << "\t\tDominated by subtree From\n"); | 796 | 3.65M | if (II.Visited.count(SuccTN) != 0) | 797 | 1.19M | continue; | 798 | 3.65M | | 799 | 2.45M | DEBUG2.45M (dbgs() << "\t\tMarking visited not affected " | 800 | 2.45M | << BlockNamePrinter(Succ) << "\n"); | 801 | 2.45M | II.Visited.insert(SuccTN); | 802 | 2.45M | II.VisitedNotAffectedQueue.push_back(SuccTN); | 803 | 2.45M | Stack.push_back(SuccTN); | 804 | 4.07M | } else if (419k (SuccLevel > NCDLevel + 1) && | 805 | 419k | II.Affected.count(SuccTN) == 038.3k ) { | 806 | 26.7k | DEBUG(dbgs() << "\t\tMarking affected and adding " | 807 | 419k | << BlockNamePrinter(Succ) << " to a Bucket\n"); | 808 | 419k | II.Affected.insert(SuccTN); | 809 | 419k | II.Bucket.push({SuccLevel, SuccTN}); | 810 | 419k | } | 811 | 4.07M | } | 812 | 2.75M | } while (!Stack.empty()); | 813 | 297k | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::VisitInsertion(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, unsigned int, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::InsertionInfo&) Line | Count | Source | 773 | 94 | const TreeNodePtr NCD, InsertionInfo &II) { | 774 | 94 | const unsigned NCDLevel = NCD->getLevel(); | 775 | 94 | DEBUG(dbgs() << "Visiting " << BlockNamePrinter(TN) << "\n"); | 776 | 94 | | 777 | 94 | SmallVector<TreeNodePtr, 8> Stack = {TN}; | 778 | 94 | assert(TN->getBlock() && II.Visited.count(TN) && "Preconditions!"); | 779 | 94 | | 780 | 185 | do { | 781 | 185 | TreeNodePtr Next = Stack.pop_back_val(); | 782 | 185 | | 783 | 185 | for (const NodePtr Succ : | 784 | 156 | ChildrenGetter<IsPostDom>::Get(Next->getBlock(), BUI)) { | 785 | 156 | const TreeNodePtr SuccTN = DT.getNode(Succ); | 786 | 156 | assert(SuccTN && "Unreachable successor found at reachable insertion"); | 787 | 156 | const unsigned SuccLevel = SuccTN->getLevel(); | 788 | 156 | | 789 | 156 | DEBUG(dbgs() << "\tSuccessor " << BlockNamePrinter(Succ) | 790 | 156 | << ", level = " << SuccLevel << "\n"); | 791 | 156 | | 792 | 156 | // Succ dominated by subtree From -- not affected. | 793 | 156 | // (Based on the lemma 2.5 from the second paper.) | 794 | 156 | if (SuccLevel > RootLevel156 ) { | 795 | 100 | DEBUG(dbgs() << "\t\tDominated by subtree From\n"); | 796 | 100 | if (II.Visited.count(SuccTN) != 0) | 797 | 9 | continue; | 798 | 100 | | 799 | 91 | DEBUG91 (dbgs() << "\t\tMarking visited not affected " | 800 | 91 | << BlockNamePrinter(Succ) << "\n"); | 801 | 91 | II.Visited.insert(SuccTN); | 802 | 91 | II.VisitedNotAffectedQueue.push_back(SuccTN); | 803 | 91 | Stack.push_back(SuccTN); | 804 | 156 | } else if (56 (SuccLevel > NCDLevel + 1) && | 805 | 56 | II.Affected.count(SuccTN) == 014 ) { | 806 | 12 | DEBUG(dbgs() << "\t\tMarking affected and adding " | 807 | 56 | << BlockNamePrinter(Succ) << " to a Bucket\n"); | 808 | 56 | II.Affected.insert(SuccTN); | 809 | 56 | II.Bucket.push({SuccLevel, SuccTN}); | 810 | 56 | } | 811 | 156 | } | 812 | 185 | } while (!Stack.empty()); | 813 | 94 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::VisitInsertion(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, unsigned int, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::InsertionInfo&) |
814 | | |
815 | | // Updates immediate dominators and levels after insertion. |
816 | | static void UpdateInsertion(DomTreeT &DT, const BatchUpdatePtr BUI, |
817 | 271k | const TreeNodePtr NCD, InsertionInfo &II) { |
818 | 271k | DEBUG(dbgs() << "Updating NCD = " << BlockNamePrinter(NCD) << "\n"); |
819 | 271k | |
820 | 297k | for (const TreeNodePtr TN : II.AffectedQueue) { |
821 | 297k | DEBUG(dbgs() << "\tIDom(" << BlockNamePrinter(TN) |
822 | 297k | << ") = " << BlockNamePrinter(NCD) << "\n"); |
823 | 297k | TN->setIDom(NCD); |
824 | 297k | } |
825 | 271k | |
826 | 271k | UpdateLevelsAfterInsertion(II); |
827 | 271k | if (IsPostDom271k ) UpdateRootsAfterUpdate(DT, BUI)82 ; |
828 | 271k | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::UpdateInsertion(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::InsertionInfo&) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::UpdateInsertion(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::InsertionInfo&) Line | Count | Source | 817 | 82 | const TreeNodePtr NCD, InsertionInfo &II) { | 818 | 82 | DEBUG(dbgs() << "Updating NCD = " << BlockNamePrinter(NCD) << "\n"); | 819 | 82 | | 820 | 94 | for (const TreeNodePtr TN : II.AffectedQueue) { | 821 | 94 | DEBUG(dbgs() << "\tIDom(" << BlockNamePrinter(TN) | 822 | 94 | << ") = " << BlockNamePrinter(NCD) << "\n"); | 823 | 94 | TN->setIDom(NCD); | 824 | 94 | } | 825 | 82 | | 826 | 82 | UpdateLevelsAfterInsertion(II); | 827 | 82 | if (IsPostDom82 ) UpdateRootsAfterUpdate(DT, BUI)82 ; | 828 | 82 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::UpdateInsertion(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::InsertionInfo&) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::UpdateInsertion(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::InsertionInfo&) Line | Count | Source | 817 | 271k | const TreeNodePtr NCD, InsertionInfo &II) { | 818 | 271k | DEBUG(dbgs() << "Updating NCD = " << BlockNamePrinter(NCD) << "\n"); | 819 | 271k | | 820 | 297k | for (const TreeNodePtr TN : II.AffectedQueue) { | 821 | 297k | DEBUG(dbgs() << "\tIDom(" << BlockNamePrinter(TN) | 822 | 297k | << ") = " << BlockNamePrinter(NCD) << "\n"); | 823 | 297k | TN->setIDom(NCD); | 824 | 297k | } | 825 | 271k | | 826 | 271k | UpdateLevelsAfterInsertion(II); | 827 | 271k | if (IsPostDom271k ) UpdateRootsAfterUpdate(DT, BUI)0 ; | 828 | 271k | } |
|
829 | | |
830 | 271k | static void UpdateLevelsAfterInsertion(InsertionInfo &II) { |
831 | 271k | DEBUG(dbgs() << "Updating levels for visited but not affected nodes\n"); |
832 | 271k | |
833 | 2.45M | for (const TreeNodePtr TN : II.VisitedNotAffectedQueue) { |
834 | 2.45M | DEBUG(dbgs() << "\tlevel(" << BlockNamePrinter(TN) << ") = (" |
835 | 2.45M | << BlockNamePrinter(TN->getIDom()) << ") " |
836 | 2.45M | << TN->getIDom()->getLevel() << " + 1\n"); |
837 | 2.45M | TN->UpdateLevel(); |
838 | 2.45M | } |
839 | 271k | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::UpdateLevelsAfterInsertion(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::InsertionInfo&) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::UpdateLevelsAfterInsertion(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::InsertionInfo&) Line | Count | Source | 830 | 271k | static void UpdateLevelsAfterInsertion(InsertionInfo &II) { | 831 | 271k | DEBUG(dbgs() << "Updating levels for visited but not affected nodes\n"); | 832 | 271k | | 833 | 2.45M | for (const TreeNodePtr TN : II.VisitedNotAffectedQueue) { | 834 | 2.45M | DEBUG(dbgs() << "\tlevel(" << BlockNamePrinter(TN) << ") = (" | 835 | 2.45M | << BlockNamePrinter(TN->getIDom()) << ") " | 836 | 2.45M | << TN->getIDom()->getLevel() << " + 1\n"); | 837 | 2.45M | TN->UpdateLevel(); | 838 | 2.45M | } | 839 | 271k | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::UpdateLevelsAfterInsertion(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::InsertionInfo&) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::UpdateLevelsAfterInsertion(llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::InsertionInfo&) Line | Count | Source | 830 | 82 | static void UpdateLevelsAfterInsertion(InsertionInfo &II) { | 831 | 82 | DEBUG(dbgs() << "Updating levels for visited but not affected nodes\n"); | 832 | 82 | | 833 | 91 | for (const TreeNodePtr TN : II.VisitedNotAffectedQueue) { | 834 | 91 | DEBUG(dbgs() << "\tlevel(" << BlockNamePrinter(TN) << ") = (" | 835 | 91 | << BlockNamePrinter(TN->getIDom()) << ") " | 836 | 91 | << TN->getIDom()->getLevel() << " + 1\n"); | 837 | 91 | TN->UpdateLevel(); | 838 | 91 | } | 839 | 82 | } |
|
840 | | |
841 | | // Handles insertion to previously unreachable nodes. |
842 | | static void InsertUnreachable(DomTreeT &DT, const BatchUpdatePtr BUI, |
843 | 206k | const TreeNodePtr From, const NodePtr To) { |
844 | 206k | DEBUG(dbgs() << "Inserting " << BlockNamePrinter(From) |
845 | 206k | << " -> (unreachable) " << BlockNamePrinter(To) << "\n"); |
846 | 206k | |
847 | 206k | // Collect discovered edges to already reachable nodes. |
848 | 206k | SmallVector<std::pair<NodePtr, TreeNodePtr>, 8> DiscoveredEdgesToReachable; |
849 | 206k | // Discover and connect nodes that became reachable with the insertion. |
850 | 206k | ComputeUnreachableDominators(DT, BUI, To, From, DiscoveredEdgesToReachable); |
851 | 206k | |
852 | 206k | DEBUG(dbgs() << "Inserted " << BlockNamePrinter(From) |
853 | 206k | << " -> (prev unreachable) " << BlockNamePrinter(To) << "\n"); |
854 | 206k | |
855 | 206k | // Used the discovered edges and inset discovered connecting (incoming) |
856 | 206k | // edges. |
857 | 115k | for (const auto &Edge : DiscoveredEdgesToReachable) { |
858 | 115k | DEBUG(dbgs() << "\tInserting discovered connecting edge " |
859 | 115k | << BlockNamePrinter(Edge.first) << " -> " |
860 | 115k | << BlockNamePrinter(Edge.second) << "\n"); |
861 | 115k | InsertReachable(DT, BUI, DT.getNode(Edge.first), Edge.second); |
862 | 115k | } |
863 | 206k | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::InsertUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::BasicBlock*) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::InsertUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::BasicBlock*) Line | Count | Source | 843 | 206k | const TreeNodePtr From, const NodePtr To) { | 844 | 206k | DEBUG(dbgs() << "Inserting " << BlockNamePrinter(From) | 845 | 206k | << " -> (unreachable) " << BlockNamePrinter(To) << "\n"); | 846 | 206k | | 847 | 206k | // Collect discovered edges to already reachable nodes. | 848 | 206k | SmallVector<std::pair<NodePtr, TreeNodePtr>, 8> DiscoveredEdgesToReachable; | 849 | 206k | // Discover and connect nodes that became reachable with the insertion. | 850 | 206k | ComputeUnreachableDominators(DT, BUI, To, From, DiscoveredEdgesToReachable); | 851 | 206k | | 852 | 206k | DEBUG(dbgs() << "Inserted " << BlockNamePrinter(From) | 853 | 206k | << " -> (prev unreachable) " << BlockNamePrinter(To) << "\n"); | 854 | 206k | | 855 | 206k | // Used the discovered edges and inset discovered connecting (incoming) | 856 | 206k | // edges. | 857 | 115k | for (const auto &Edge : DiscoveredEdgesToReachable) { | 858 | 115k | DEBUG(dbgs() << "\tInserting discovered connecting edge " | 859 | 115k | << BlockNamePrinter(Edge.first) << " -> " | 860 | 115k | << BlockNamePrinter(Edge.second) << "\n"); | 861 | 115k | InsertReachable(DT, BUI, DT.getNode(Edge.first), Edge.second); | 862 | 115k | } | 863 | 206k | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::InsertUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::MachineBasicBlock*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::InsertUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::MachineBasicBlock*) |
864 | | |
865 | | // Connects nodes that become reachable with an insertion. |
866 | | static void ComputeUnreachableDominators( |
867 | | DomTreeT &DT, const BatchUpdatePtr BUI, const NodePtr Root, |
868 | | const TreeNodePtr Incoming, |
869 | | SmallVectorImpl<std::pair<NodePtr, TreeNodePtr>> |
870 | 206k | &DiscoveredConnectingEdges) { |
871 | 206k | assert(!DT.getNode(Root) && "Root must not be reachable"); |
872 | 206k | |
873 | 206k | // Visit only previously unreachable nodes. |
874 | 206k | auto UnreachableDescender = [&DT, &DiscoveredConnectingEdges](NodePtr From, |
875 | 594k | NodePtr To) { |
876 | 594k | const TreeNodePtr ToTN = DT.getNode(To); |
877 | 594k | if (!ToTN594k ) return true479k ; |
878 | 594k | |
879 | 115k | DiscoveredConnectingEdges.push_back({From, ToTN}); |
880 | 115k | return false; |
881 | 594k | }; Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const Line | Count | Source | 875 | 594k | NodePtr To) { | 876 | 594k | const TreeNodePtr ToTN = DT.getNode(To); | 877 | 594k | if (!ToTN594k ) return true479k ; | 878 | 594k | | 879 | 115k | DiscoveredConnectingEdges.push_back({From, ToTN}); | 880 | 115k | return false; | 881 | 594k | }; |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const |
882 | 206k | |
883 | 206k | SemiNCAInfo SNCA(BUI); |
884 | 206k | SNCA.runDFS(Root, 0, UnreachableDescender, 0); |
885 | 206k | SNCA.runSemiNCA(DT); |
886 | 206k | SNCA.attachNewSubtree(DT, Incoming); |
887 | 206k | |
888 | 206k | DEBUG(dbgs() << "After adding unreachable nodes\n"); |
889 | 206k | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&) Line | Count | Source | 870 | 206k | &DiscoveredConnectingEdges) { | 871 | 206k | assert(!DT.getNode(Root) && "Root must not be reachable"); | 872 | 206k | | 873 | 206k | // Visit only previously unreachable nodes. | 874 | 206k | auto UnreachableDescender = [&DT, &DiscoveredConnectingEdges](NodePtr From, | 875 | 206k | NodePtr To) { | 876 | 206k | const TreeNodePtr ToTN = DT.getNode(To); | 877 | 206k | if (!ToTN) return true; | 878 | 206k | | 879 | 206k | DiscoveredConnectingEdges.push_back({From, ToTN}); | 880 | 206k | return false; | 881 | 206k | }; | 882 | 206k | | 883 | 206k | SemiNCAInfo SNCA(BUI); | 884 | 206k | SNCA.runDFS(Root, 0, UnreachableDescender, 0); | 885 | 206k | SNCA.runSemiNCA(DT); | 886 | 206k | SNCA.attachNewSubtree(DT, Incoming); | 887 | 206k | | 888 | 206k | DEBUG(dbgs() << "After adding unreachable nodes\n"); | 889 | 206k | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::BasicBlock*, llvm::DomTreeNodeBase<llvm::BasicBlock>*> >&) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ComputeUnreachableDominators(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::SmallVectorImpl<std::__1::pair<llvm::MachineBasicBlock*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*> >&) |
890 | | |
891 | | static void DeleteEdge(DomTreeT &DT, const BatchUpdatePtr BUI, |
892 | 1.02M | const NodePtr From, const NodePtr To) { |
893 | 1.02M | assert(From && To && "Cannot disconnect nullptrs"); |
894 | 1.02M | DEBUG(dbgs() << "Deleting edge " << BlockNamePrinter(From) << " -> " |
895 | 1.02M | << BlockNamePrinter(To) << "\n"); |
896 | 1.02M | |
897 | | #ifndef NDEBUG |
898 | | // Ensure that the edge was in fact deleted from the CFG before informing |
899 | | // the DomTree about it. |
900 | | // The check is O(N), so run it only in debug configuration. |
901 | | auto IsSuccessor = [BUI](const NodePtr SuccCandidate, const NodePtr Of) { |
902 | | auto Successors = ChildrenGetter<IsPostDom>::Get(Of, BUI); |
903 | | return llvm::find(Successors, SuccCandidate) != Successors.end(); |
904 | | }; |
905 | | (void)IsSuccessor; |
906 | | assert(!IsSuccessor(To, From) && "Deleted edge still exists in the CFG!"); |
907 | | #endif |
908 | | |
909 | 1.02M | const TreeNodePtr FromTN = DT.getNode(From); |
910 | 1.02M | // Deletion in an unreachable subtree -- nothing to do. |
911 | 1.02M | if (!FromTN1.02M ) return246k ; |
912 | 1.02M | |
913 | 777k | const TreeNodePtr ToTN = DT.getNode(To); |
914 | 777k | if (!ToTN777k ) { |
915 | 0 | DEBUG(dbgs() << "\tTo (" << BlockNamePrinter(To) |
916 | 0 | << ") already unreachable -- there is no edge to delete\n"); |
917 | 0 | return; |
918 | 0 | } |
919 | 777k | |
920 | 777k | const NodePtr NCDBlock = DT.findNearestCommonDominator(From, To); |
921 | 777k | const TreeNodePtr NCD = DT.getNode(NCDBlock); |
922 | 777k | |
923 | 777k | // To dominates From -- nothing to do. |
924 | 777k | if (ToTN == NCD777k ) return2.61k ; |
925 | 777k | |
926 | 774k | DT.DFSInfoValid = false; |
927 | 774k | |
928 | 774k | const TreeNodePtr ToIDom = ToTN->getIDom(); |
929 | 774k | DEBUG(dbgs() << "\tNCD " << BlockNamePrinter(NCD) << ", ToIDom " |
930 | 774k | << BlockNamePrinter(ToIDom) << "\n"); |
931 | 774k | |
932 | 774k | // To remains reachable after deletion. |
933 | 774k | // (Based on the caption under Figure 4. from the second paper.) |
934 | 774k | if (FromTN != ToIDom || 774k HasProperSupport(DT, BUI, ToTN)590k ) |
935 | 362k | DeleteReachable(DT, BUI, FromTN, ToTN); |
936 | 774k | else |
937 | 411k | DeleteUnreachable(DT, BUI, ToTN); |
938 | 774k | |
939 | 774k | if (IsPostDom774k ) UpdateRootsAfterUpdate(DT, BUI)211 ; |
940 | 1.02M | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteEdge(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::BasicBlock*) Line | Count | Source | 892 | 218 | const NodePtr From, const NodePtr To) { | 893 | 218 | assert(From && To && "Cannot disconnect nullptrs"); | 894 | 218 | DEBUG(dbgs() << "Deleting edge " << BlockNamePrinter(From) << " -> " | 895 | 218 | << BlockNamePrinter(To) << "\n"); | 896 | 218 | | 897 | | #ifndef NDEBUG | 898 | | // Ensure that the edge was in fact deleted from the CFG before informing | 899 | | // the DomTree about it. | 900 | | // The check is O(N), so run it only in debug configuration. | 901 | | auto IsSuccessor = [BUI](const NodePtr SuccCandidate, const NodePtr Of) { | 902 | | auto Successors = ChildrenGetter<IsPostDom>::Get(Of, BUI); | 903 | | return llvm::find(Successors, SuccCandidate) != Successors.end(); | 904 | | }; | 905 | | (void)IsSuccessor; | 906 | | assert(!IsSuccessor(To, From) && "Deleted edge still exists in the CFG!"); | 907 | | #endif | 908 | | | 909 | 218 | const TreeNodePtr FromTN = DT.getNode(From); | 910 | 218 | // Deletion in an unreachable subtree -- nothing to do. | 911 | 218 | if (!FromTN218 ) return0 ; | 912 | 218 | | 913 | 218 | const TreeNodePtr ToTN = DT.getNode(To); | 914 | 218 | if (!ToTN218 ) { | 915 | 0 | DEBUG(dbgs() << "\tTo (" << BlockNamePrinter(To) | 916 | 0 | << ") already unreachable -- there is no edge to delete\n"); | 917 | 0 | return; | 918 | 0 | } | 919 | 218 | | 920 | 218 | const NodePtr NCDBlock = DT.findNearestCommonDominator(From, To); | 921 | 218 | const TreeNodePtr NCD = DT.getNode(NCDBlock); | 922 | 218 | | 923 | 218 | // To dominates From -- nothing to do. | 924 | 218 | if (ToTN == NCD218 ) return7 ; | 925 | 218 | | 926 | 211 | DT.DFSInfoValid = false; | 927 | 211 | | 928 | 211 | const TreeNodePtr ToIDom = ToTN->getIDom(); | 929 | 211 | DEBUG(dbgs() << "\tNCD " << BlockNamePrinter(NCD) << ", ToIDom " | 930 | 211 | << BlockNamePrinter(ToIDom) << "\n"); | 931 | 211 | | 932 | 211 | // To remains reachable after deletion. | 933 | 211 | // (Based on the caption under Figure 4. from the second paper.) | 934 | 211 | if (FromTN != ToIDom || 211 HasProperSupport(DT, BUI, ToTN)48 ) | 935 | 164 | DeleteReachable(DT, BUI, FromTN, ToTN); | 936 | 211 | else | 937 | 47 | DeleteUnreachable(DT, BUI, ToTN); | 938 | 211 | | 939 | 211 | if (IsPostDom211 ) UpdateRootsAfterUpdate(DT, BUI)211 ; | 940 | 218 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteEdge(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::BasicBlock*, llvm::BasicBlock*) Line | Count | Source | 892 | 1.02M | const NodePtr From, const NodePtr To) { | 893 | 1.02M | assert(From && To && "Cannot disconnect nullptrs"); | 894 | 1.02M | DEBUG(dbgs() << "Deleting edge " << BlockNamePrinter(From) << " -> " | 895 | 1.02M | << BlockNamePrinter(To) << "\n"); | 896 | 1.02M | | 897 | | #ifndef NDEBUG | 898 | | // Ensure that the edge was in fact deleted from the CFG before informing | 899 | | // the DomTree about it. | 900 | | // The check is O(N), so run it only in debug configuration. | 901 | | auto IsSuccessor = [BUI](const NodePtr SuccCandidate, const NodePtr Of) { | 902 | | auto Successors = ChildrenGetter<IsPostDom>::Get(Of, BUI); | 903 | | return llvm::find(Successors, SuccCandidate) != Successors.end(); | 904 | | }; | 905 | | (void)IsSuccessor; | 906 | | assert(!IsSuccessor(To, From) && "Deleted edge still exists in the CFG!"); | 907 | | #endif | 908 | | | 909 | 1.02M | const TreeNodePtr FromTN = DT.getNode(From); | 910 | 1.02M | // Deletion in an unreachable subtree -- nothing to do. | 911 | 1.02M | if (!FromTN1.02M ) return246k ; | 912 | 1.02M | | 913 | 777k | const TreeNodePtr ToTN = DT.getNode(To); | 914 | 777k | if (!ToTN777k ) { | 915 | 0 | DEBUG(dbgs() << "\tTo (" << BlockNamePrinter(To) | 916 | 0 | << ") already unreachable -- there is no edge to delete\n"); | 917 | 0 | return; | 918 | 0 | } | 919 | 777k | | 920 | 777k | const NodePtr NCDBlock = DT.findNearestCommonDominator(From, To); | 921 | 777k | const TreeNodePtr NCD = DT.getNode(NCDBlock); | 922 | 777k | | 923 | 777k | // To dominates From -- nothing to do. | 924 | 777k | if (ToTN == NCD777k ) return2.60k ; | 925 | 777k | | 926 | 774k | DT.DFSInfoValid = false; | 927 | 774k | | 928 | 774k | const TreeNodePtr ToIDom = ToTN->getIDom(); | 929 | 774k | DEBUG(dbgs() << "\tNCD " << BlockNamePrinter(NCD) << ", ToIDom " | 930 | 774k | << BlockNamePrinter(ToIDom) << "\n"); | 931 | 774k | | 932 | 774k | // To remains reachable after deletion. | 933 | 774k | // (Based on the caption under Figure 4. from the second paper.) | 934 | 774k | if (FromTN != ToIDom || 774k HasProperSupport(DT, BUI, ToTN)590k ) | 935 | 362k | DeleteReachable(DT, BUI, FromTN, ToTN); | 936 | 774k | else | 937 | 411k | DeleteUnreachable(DT, BUI, ToTN); | 938 | 774k | | 939 | 774k | if (IsPostDom774k ) UpdateRootsAfterUpdate(DT, BUI)0 ; | 940 | 1.02M | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteEdge(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteEdge(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) |
941 | | |
942 | | // Handles deletions that leave destination nodes reachable. |
943 | | static void DeleteReachable(DomTreeT &DT, const BatchUpdatePtr BUI, |
944 | | const TreeNodePtr FromTN, |
945 | 362k | const TreeNodePtr ToTN) { |
946 | 362k | DEBUG(dbgs() << "Deleting reachable " << BlockNamePrinter(FromTN) << " -> " |
947 | 362k | << BlockNamePrinter(ToTN) << "\n"); |
948 | 362k | DEBUG(dbgs() << "\tRebuilding subtree\n"); |
949 | 362k | |
950 | 362k | // Find the top of the subtree that needs to be rebuilt. |
951 | 362k | // (Based on the lemma 2.6 from the second paper.) |
952 | 362k | const NodePtr ToIDom = |
953 | 362k | DT.findNearestCommonDominator(FromTN->getBlock(), ToTN->getBlock()); |
954 | 362k | assert(ToIDom || DT.isPostDominator()); |
955 | 362k | const TreeNodePtr ToIDomTN = DT.getNode(ToIDom); |
956 | 362k | assert(ToIDomTN); |
957 | 362k | const TreeNodePtr PrevIDomSubTree = ToIDomTN->getIDom(); |
958 | 362k | // Top of the subtree to rebuild is the root node. Rebuild the tree from |
959 | 362k | // scratch. |
960 | 362k | if (!PrevIDomSubTree362k ) { |
961 | 54.1k | DEBUG(dbgs() << "The entire tree needs to be rebuilt\n"); |
962 | 54.1k | CalculateFromScratch(DT, BUI); |
963 | 54.1k | return; |
964 | 54.1k | } |
965 | 362k | |
966 | 362k | // Only visit nodes in the subtree starting at To. |
967 | 308k | const unsigned Level = ToIDomTN->getLevel(); |
968 | 11.1M | auto DescendBelow = [Level, &DT](NodePtr, NodePtr To) { |
969 | 11.1M | return DT.getNode(To)->getLevel() > Level; |
970 | 11.1M | }; Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const Line | Count | Source | 968 | 11.1M | auto DescendBelow = [Level, &DT](NodePtr, NodePtr To) { | 969 | 11.1M | return DT.getNode(To)->getLevel() > Level; | 970 | 11.1M | }; |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const Line | Count | Source | 968 | 423 | auto DescendBelow = [Level, &DT](NodePtr, NodePtr To) { | 969 | 423 | return DT.getNode(To)->getLevel() > Level; | 970 | 423 | }; |
|
971 | 308k | |
972 | 308k | DEBUG(dbgs() << "\tTop of subtree: " << BlockNamePrinter(ToIDomTN) << "\n"); |
973 | 308k | |
974 | 308k | SemiNCAInfo SNCA(BUI); |
975 | 308k | SNCA.runDFS(ToIDom, 0, DescendBelow, 0); |
976 | 308k | DEBUG(dbgs() << "\tRunning Semi-NCA\n"); |
977 | 362k | SNCA.runSemiNCA(DT, Level); |
978 | 362k | SNCA.reattachExistingSubtree(DT, PrevIDomSubTree); |
979 | 362k | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) Line | Count | Source | 945 | 362k | const TreeNodePtr ToTN) { | 946 | 362k | DEBUG(dbgs() << "Deleting reachable " << BlockNamePrinter(FromTN) << " -> " | 947 | 362k | << BlockNamePrinter(ToTN) << "\n"); | 948 | 362k | DEBUG(dbgs() << "\tRebuilding subtree\n"); | 949 | 362k | | 950 | 362k | // Find the top of the subtree that needs to be rebuilt. | 951 | 362k | // (Based on the lemma 2.6 from the second paper.) | 952 | 362k | const NodePtr ToIDom = | 953 | 362k | DT.findNearestCommonDominator(FromTN->getBlock(), ToTN->getBlock()); | 954 | 362k | assert(ToIDom || DT.isPostDominator()); | 955 | 362k | const TreeNodePtr ToIDomTN = DT.getNode(ToIDom); | 956 | 362k | assert(ToIDomTN); | 957 | 362k | const TreeNodePtr PrevIDomSubTree = ToIDomTN->getIDom(); | 958 | 362k | // Top of the subtree to rebuild is the root node. Rebuild the tree from | 959 | 362k | // scratch. | 960 | 362k | if (!PrevIDomSubTree362k ) { | 961 | 54.0k | DEBUG(dbgs() << "The entire tree needs to be rebuilt\n"); | 962 | 54.0k | CalculateFromScratch(DT, BUI); | 963 | 54.0k | return; | 964 | 54.0k | } | 965 | 362k | | 966 | 362k | // Only visit nodes in the subtree starting at To. | 967 | 308k | const unsigned Level = ToIDomTN->getLevel(); | 968 | 308k | auto DescendBelow = [Level, &DT](NodePtr, NodePtr To) { | 969 | 308k | return DT.getNode(To)->getLevel() > Level; | 970 | 308k | }; | 971 | 308k | | 972 | 308k | DEBUG(dbgs() << "\tTop of subtree: " << BlockNamePrinter(ToIDomTN) << "\n"); | 973 | 308k | | 974 | 308k | SemiNCAInfo SNCA(BUI); | 975 | 308k | SNCA.runDFS(ToIDom, 0, DescendBelow, 0); | 976 | 308k | DEBUG(dbgs() << "\tRunning Semi-NCA\n"); | 977 | 362k | SNCA.runSemiNCA(DT, Level); | 978 | 362k | SNCA.reattachExistingSubtree(DT, PrevIDomSubTree); | 979 | 362k | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteReachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) Line | Count | Source | 945 | 164 | const TreeNodePtr ToTN) { | 946 | 164 | DEBUG(dbgs() << "Deleting reachable " << BlockNamePrinter(FromTN) << " -> " | 947 | 164 | << BlockNamePrinter(ToTN) << "\n"); | 948 | 164 | DEBUG(dbgs() << "\tRebuilding subtree\n"); | 949 | 164 | | 950 | 164 | // Find the top of the subtree that needs to be rebuilt. | 951 | 164 | // (Based on the lemma 2.6 from the second paper.) | 952 | 164 | const NodePtr ToIDom = | 953 | 164 | DT.findNearestCommonDominator(FromTN->getBlock(), ToTN->getBlock()); | 954 | 164 | assert(ToIDom || DT.isPostDominator()); | 955 | 164 | const TreeNodePtr ToIDomTN = DT.getNode(ToIDom); | 956 | 164 | assert(ToIDomTN); | 957 | 164 | const TreeNodePtr PrevIDomSubTree = ToIDomTN->getIDom(); | 958 | 164 | // Top of the subtree to rebuild is the root node. Rebuild the tree from | 959 | 164 | // scratch. | 960 | 164 | if (!PrevIDomSubTree164 ) { | 961 | 39 | DEBUG(dbgs() << "The entire tree needs to be rebuilt\n"); | 962 | 39 | CalculateFromScratch(DT, BUI); | 963 | 39 | return; | 964 | 39 | } | 965 | 164 | | 966 | 164 | // Only visit nodes in the subtree starting at To. | 967 | 125 | const unsigned Level = ToIDomTN->getLevel(); | 968 | 125 | auto DescendBelow = [Level, &DT](NodePtr, NodePtr To) { | 969 | 125 | return DT.getNode(To)->getLevel() > Level; | 970 | 125 | }; | 971 | 125 | | 972 | 125 | DEBUG(dbgs() << "\tTop of subtree: " << BlockNamePrinter(ToIDomTN) << "\n"); | 973 | 125 | | 974 | 125 | SemiNCAInfo SNCA(BUI); | 975 | 125 | SNCA.runDFS(ToIDom, 0, DescendBelow, 0); | 976 | 125 | DEBUG(dbgs() << "\tRunning Semi-NCA\n"); | 977 | 164 | SNCA.runSemiNCA(DT, Level); | 978 | 164 | SNCA.reattachExistingSubtree(DT, PrevIDomSubTree); | 979 | 164 | } |
|
980 | | |
981 | | // Checks if a node has proper support, as defined on the page 3 and later |
982 | | // explained on the page 7 of the second paper. |
983 | | static bool HasProperSupport(DomTreeT &DT, const BatchUpdatePtr BUI, |
984 | 590k | const TreeNodePtr TN) { |
985 | 590k | DEBUG(dbgs() << "IsReachableFromIDom " << BlockNamePrinter(TN) << "\n"); |
986 | 590k | for (const NodePtr Pred : |
987 | 210k | ChildrenGetter<!IsPostDom>::Get(TN->getBlock(), BUI)) { |
988 | 210k | DEBUG(dbgs() << "\tPred " << BlockNamePrinter(Pred) << "\n"); |
989 | 210k | if (!DT.getNode(Pred)210k ) continue32 ; |
990 | 210k | |
991 | 210k | const NodePtr Support = |
992 | 210k | DT.findNearestCommonDominator(TN->getBlock(), Pred); |
993 | 210k | DEBUG(dbgs() << "\tSupport " << BlockNamePrinter(Support) << "\n"); |
994 | 210k | if (Support != TN->getBlock()210k ) { |
995 | 179k | DEBUG(dbgs() << "\t" << BlockNamePrinter(TN) |
996 | 179k | << " is reachable from support " |
997 | 179k | << BlockNamePrinter(Support) << "\n"); |
998 | 179k | return true; |
999 | 179k | } |
1000 | 210k | } |
1001 | 590k | |
1002 | 411k | return false; |
1003 | 590k | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::HasProperSupport(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::HasProperSupport(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) Line | Count | Source | 984 | 48 | const TreeNodePtr TN) { | 985 | 48 | DEBUG(dbgs() << "IsReachableFromIDom " << BlockNamePrinter(TN) << "\n"); | 986 | 48 | for (const NodePtr Pred : | 987 | 3 | ChildrenGetter<!IsPostDom>::Get(TN->getBlock(), BUI)) { | 988 | 3 | DEBUG(dbgs() << "\tPred " << BlockNamePrinter(Pred) << "\n"); | 989 | 3 | if (!DT.getNode(Pred)3 ) continue0 ; | 990 | 3 | | 991 | 3 | const NodePtr Support = | 992 | 3 | DT.findNearestCommonDominator(TN->getBlock(), Pred); | 993 | 3 | DEBUG(dbgs() << "\tSupport " << BlockNamePrinter(Support) << "\n"); | 994 | 3 | if (Support != TN->getBlock()3 ) { | 995 | 1 | DEBUG(dbgs() << "\t" << BlockNamePrinter(TN) | 996 | 1 | << " is reachable from support " | 997 | 1 | << BlockNamePrinter(Support) << "\n"); | 998 | 1 | return true; | 999 | 1 | } | 1000 | 3 | } | 1001 | 48 | | 1002 | 47 | return false; | 1003 | 48 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::HasProperSupport(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::HasProperSupport(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) Line | Count | Source | 984 | 590k | const TreeNodePtr TN) { | 985 | 590k | DEBUG(dbgs() << "IsReachableFromIDom " << BlockNamePrinter(TN) << "\n"); | 986 | 590k | for (const NodePtr Pred : | 987 | 210k | ChildrenGetter<!IsPostDom>::Get(TN->getBlock(), BUI)) { | 988 | 210k | DEBUG(dbgs() << "\tPred " << BlockNamePrinter(Pred) << "\n"); | 989 | 210k | if (!DT.getNode(Pred)210k ) continue32 ; | 990 | 210k | | 991 | 210k | const NodePtr Support = | 992 | 210k | DT.findNearestCommonDominator(TN->getBlock(), Pred); | 993 | 210k | DEBUG(dbgs() << "\tSupport " << BlockNamePrinter(Support) << "\n"); | 994 | 210k | if (Support != TN->getBlock()210k ) { | 995 | 179k | DEBUG(dbgs() << "\t" << BlockNamePrinter(TN) | 996 | 179k | << " is reachable from support " | 997 | 179k | << BlockNamePrinter(Support) << "\n"); | 998 | 179k | return true; | 999 | 179k | } | 1000 | 210k | } | 1001 | 590k | | 1002 | 411k | return false; | 1003 | 590k | } |
|
1004 | | |
1005 | | // Handle deletions that make destination node unreachable. |
1006 | | // (Based on the lemma 2.7 from the second paper.) |
1007 | | static void DeleteUnreachable(DomTreeT &DT, const BatchUpdatePtr BUI, |
1008 | 411k | const TreeNodePtr ToTN) { |
1009 | 411k | DEBUG(dbgs() << "Deleting unreachable subtree " << BlockNamePrinter(ToTN) |
1010 | 411k | << "\n"); |
1011 | 411k | assert(ToTN); |
1012 | 411k | assert(ToTN->getBlock()); |
1013 | 411k | |
1014 | 411k | if (IsPostDom411k ) { |
1015 | 47 | // Deletion makes a region reverse-unreachable and creates a new root. |
1016 | 47 | // Simulate that by inserting an edge from the virtual root to ToTN and |
1017 | 47 | // adding it as a new root. |
1018 | 47 | DEBUG(dbgs() << "\tDeletion made a region reverse-unreachable\n"); |
1019 | 47 | DEBUG(dbgs() << "\tAdding new root " << BlockNamePrinter(ToTN) << "\n"); |
1020 | 47 | DT.Roots.push_back(ToTN->getBlock()); |
1021 | 47 | InsertReachable(DT, BUI, DT.getNode(nullptr), ToTN); |
1022 | 47 | return; |
1023 | 47 | } |
1024 | 411k | |
1025 | 411k | SmallVector<NodePtr, 16> AffectedQueue; |
1026 | 411k | const unsigned Level = ToTN->getLevel(); |
1027 | 411k | |
1028 | 411k | // Traverse destination node's descendants with greater level in the tree |
1029 | 411k | // and collect visited nodes. |
1030 | 1.04M | auto DescendAndCollect = [Level, &AffectedQueue, &DT](NodePtr, NodePtr To) { |
1031 | 1.04M | const TreeNodePtr TN = DT.getNode(To); |
1032 | 1.04M | assert(TN); |
1033 | 1.04M | if (TN->getLevel() > Level1.04M ) return true579k ; |
1034 | 464k | if (464k llvm::find(AffectedQueue, To) == AffectedQueue.end()464k ) |
1035 | 423k | AffectedQueue.push_back(To); |
1036 | 464k | |
1037 | 464k | return false; |
1038 | 1.04M | }; llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const Line | Count | Source | 1030 | 1.04M | auto DescendAndCollect = [Level, &AffectedQueue, &DT](NodePtr, NodePtr To) { | 1031 | 1.04M | const TreeNodePtr TN = DT.getNode(To); | 1032 | 1.04M | assert(TN); | 1033 | 1.04M | if (TN->getLevel() > Level1.04M ) return true579k ; | 1034 | 464k | if (464k llvm::find(AffectedQueue, To) == AffectedQueue.end()464k ) | 1035 | 423k | AffectedQueue.push_back(To); | 1036 | 464k | | 1037 | 464k | return false; | 1038 | 1.04M | }; |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const |
1039 | 411k | |
1040 | 411k | SemiNCAInfo SNCA(BUI); |
1041 | 411k | unsigned LastDFSNum = |
1042 | 411k | SNCA.runDFS(ToTN->getBlock(), 0, DescendAndCollect, 0); |
1043 | 411k | |
1044 | 411k | TreeNodePtr MinNode = ToTN; |
1045 | 411k | |
1046 | 411k | // Identify the top of the subtree to rebuild by finding the NCD of all |
1047 | 411k | // the affected nodes. |
1048 | 423k | for (const NodePtr N : AffectedQueue) { |
1049 | 423k | const TreeNodePtr TN = DT.getNode(N); |
1050 | 423k | const NodePtr NCDBlock = |
1051 | 423k | DT.findNearestCommonDominator(TN->getBlock(), ToTN->getBlock()); |
1052 | 423k | assert(NCDBlock || DT.isPostDominator()); |
1053 | 423k | const TreeNodePtr NCD = DT.getNode(NCDBlock); |
1054 | 423k | assert(NCD); |
1055 | 423k | |
1056 | 423k | DEBUG(dbgs() << "Processing affected node " << BlockNamePrinter(TN) |
1057 | 423k | << " with NCD = " << BlockNamePrinter(NCD) |
1058 | 423k | << ", MinNode =" << BlockNamePrinter(MinNode) << "\n"); |
1059 | 423k | if (NCD != TN && 423k NCD->getLevel() < MinNode->getLevel()419k ) MinNode = NCD408k ; |
1060 | 423k | } |
1061 | 411k | |
1062 | 411k | // Root reached, rebuild the whole tree from scratch. |
1063 | 411k | if (!MinNode->getIDom()411k ) { |
1064 | 137k | DEBUG(dbgs() << "The entire tree needs to be rebuilt\n"); |
1065 | 137k | CalculateFromScratch(DT, BUI); |
1066 | 137k | return; |
1067 | 137k | } |
1068 | 411k | |
1069 | 411k | // Erase the unreachable subtree in reverse preorder to process all children |
1070 | 411k | // before deleting their parent. |
1071 | 871k | for (unsigned i = LastDFSNum; 274k i > 0871k ; --i597k ) { |
1072 | 597k | const NodePtr N = SNCA.NumToNode[i]; |
1073 | 597k | const TreeNodePtr TN = DT.getNode(N); |
1074 | 597k | DEBUG(dbgs() << "Erasing node " << BlockNamePrinter(TN) << "\n"); |
1075 | 597k | |
1076 | 597k | EraseNode(DT, TN); |
1077 | 597k | } |
1078 | 274k | |
1079 | 274k | // The affected subtree start at the To node -- there's no extra work to do. |
1080 | 274k | if (MinNode == ToTN274k ) return7.20k ; |
1081 | 274k | |
1082 | 267k | DEBUG267k (dbgs() << "DeleteUnreachable: running DFS with MinNode = " |
1083 | 267k | << BlockNamePrinter(MinNode) << "\n"); |
1084 | 267k | const unsigned MinLevel = MinNode->getLevel(); |
1085 | 267k | const TreeNodePtr PrevIDom = MinNode->getIDom(); |
1086 | 267k | assert(PrevIDom); |
1087 | 267k | SNCA.clear(); |
1088 | 267k | |
1089 | 267k | // Identify nodes that remain in the affected subtree. |
1090 | 8.91M | auto DescendBelow = [MinLevel, &DT](NodePtr, NodePtr To) { |
1091 | 8.91M | const TreeNodePtr ToTN = DT.getNode(To); |
1092 | 8.91M | return ToTN && ToTN->getLevel() > MinLevel; |
1093 | 8.91M | }; Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*)::'lambda0'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*)::'lambda0'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const Line | Count | Source | 1090 | 8.91M | auto DescendBelow = [MinLevel, &DT](NodePtr, NodePtr To) { | 1091 | 8.91M | const TreeNodePtr ToTN = DT.getNode(To); | 1092 | 8.91M | return ToTN && ToTN->getLevel() > MinLevel; | 1093 | 8.91M | }; |
|
1094 | 267k | SNCA.runDFS(MinNode->getBlock(), 0, DescendBelow, 0); |
1095 | 267k | |
1096 | 267k | DEBUG(dbgs() << "Previous IDom(MinNode) = " << BlockNamePrinter(PrevIDom) |
1097 | 411k | << "\nRunning Semi-NCA\n"); |
1098 | 411k | |
1099 | 411k | // Rebuild the remaining part of affected subtree. |
1100 | 411k | SNCA.runSemiNCA(DT, MinLevel); |
1101 | 411k | SNCA.reattachExistingSubtree(DT, PrevIDom); |
1102 | 411k | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) Line | Count | Source | 1008 | 47 | const TreeNodePtr ToTN) { | 1009 | 47 | DEBUG(dbgs() << "Deleting unreachable subtree " << BlockNamePrinter(ToTN) | 1010 | 47 | << "\n"); | 1011 | 47 | assert(ToTN); | 1012 | 47 | assert(ToTN->getBlock()); | 1013 | 47 | | 1014 | 47 | if (IsPostDom47 ) { | 1015 | 47 | // Deletion makes a region reverse-unreachable and creates a new root. | 1016 | 47 | // Simulate that by inserting an edge from the virtual root to ToTN and | 1017 | 47 | // adding it as a new root. | 1018 | 47 | DEBUG(dbgs() << "\tDeletion made a region reverse-unreachable\n"); | 1019 | 47 | DEBUG(dbgs() << "\tAdding new root " << BlockNamePrinter(ToTN) << "\n"); | 1020 | 47 | DT.Roots.push_back(ToTN->getBlock()); | 1021 | 47 | InsertReachable(DT, BUI, DT.getNode(nullptr), ToTN); | 1022 | 47 | return; | 1023 | 47 | } | 1024 | 47 | | 1025 | 0 | SmallVector<NodePtr, 16> AffectedQueue; | 1026 | 0 | const unsigned Level = ToTN->getLevel(); | 1027 | 0 |
| 1028 | 0 | // Traverse destination node's descendants with greater level in the tree | 1029 | 0 | // and collect visited nodes. | 1030 | 0 | auto DescendAndCollect = [Level, &AffectedQueue, &DT](NodePtr, NodePtr To) { | 1031 | 0 | const TreeNodePtr TN = DT.getNode(To); | 1032 | 0 | assert(TN); | 1033 | 0 | if (TN->getLevel() > Level) return true; | 1034 | 0 | if (llvm::find(AffectedQueue, To) == AffectedQueue.end()) | 1035 | 0 | AffectedQueue.push_back(To); | 1036 | 0 |
| 1037 | 0 | return false; | 1038 | 0 | }; | 1039 | 0 |
| 1040 | 0 | SemiNCAInfo SNCA(BUI); | 1041 | 0 | unsigned LastDFSNum = | 1042 | 0 | SNCA.runDFS(ToTN->getBlock(), 0, DescendAndCollect, 0); | 1043 | 0 |
| 1044 | 0 | TreeNodePtr MinNode = ToTN; | 1045 | 0 |
| 1046 | 0 | // Identify the top of the subtree to rebuild by finding the NCD of all | 1047 | 0 | // the affected nodes. | 1048 | 0 | for (const NodePtr N : AffectedQueue) { | 1049 | 0 | const TreeNodePtr TN = DT.getNode(N); | 1050 | 0 | const NodePtr NCDBlock = | 1051 | 0 | DT.findNearestCommonDominator(TN->getBlock(), ToTN->getBlock()); | 1052 | 0 | assert(NCDBlock || DT.isPostDominator()); | 1053 | 0 | const TreeNodePtr NCD = DT.getNode(NCDBlock); | 1054 | 0 | assert(NCD); | 1055 | 0 |
| 1056 | 0 | DEBUG(dbgs() << "Processing affected node " << BlockNamePrinter(TN) | 1057 | 0 | << " with NCD = " << BlockNamePrinter(NCD) | 1058 | 0 | << ", MinNode =" << BlockNamePrinter(MinNode) << "\n"); | 1059 | 0 | if (NCD != TN && 0 NCD->getLevel() < MinNode->getLevel()0 ) MinNode = NCD0 ; | 1060 | 0 | } | 1061 | 0 |
| 1062 | 0 | // Root reached, rebuild the whole tree from scratch. | 1063 | 0 | if (!MinNode->getIDom()0 ) { | 1064 | 0 | DEBUG(dbgs() << "The entire tree needs to be rebuilt\n"); | 1065 | 0 | CalculateFromScratch(DT, BUI); | 1066 | 0 | return; | 1067 | 0 | } | 1068 | 0 |
| 1069 | 0 | // Erase the unreachable subtree in reverse preorder to process all children | 1070 | 0 | // before deleting their parent. | 1071 | 0 | for (unsigned i = LastDFSNum; 0 i > 00 ; --i0 ) { | 1072 | 0 | const NodePtr N = SNCA.NumToNode[i]; | 1073 | 0 | const TreeNodePtr TN = DT.getNode(N); | 1074 | 0 | DEBUG(dbgs() << "Erasing node " << BlockNamePrinter(TN) << "\n"); | 1075 | 0 |
| 1076 | 0 | EraseNode(DT, TN); | 1077 | 0 | } | 1078 | 0 |
| 1079 | 0 | // The affected subtree start at the To node -- there's no extra work to do. | 1080 | 0 | if (MinNode == ToTN0 ) return0 ; | 1081 | 0 |
| 1082 | 0 | DEBUG0 (dbgs() << "DeleteUnreachable: running DFS with MinNode = " | 1083 | 0 | << BlockNamePrinter(MinNode) << "\n"); | 1084 | 0 | const unsigned MinLevel = MinNode->getLevel(); | 1085 | 0 | const TreeNodePtr PrevIDom = MinNode->getIDom(); | 1086 | 0 | assert(PrevIDom); | 1087 | 0 | SNCA.clear(); | 1088 | 0 |
| 1089 | 0 | // Identify nodes that remain in the affected subtree. | 1090 | 0 | auto DescendBelow = [MinLevel, &DT](NodePtr, NodePtr To) { | 1091 | 0 | const TreeNodePtr ToTN = DT.getNode(To); | 1092 | 0 | return ToTN && ToTN->getLevel() > MinLevel; | 1093 | 0 | }; | 1094 | 0 | SNCA.runDFS(MinNode->getBlock(), 0, DescendBelow, 0); | 1095 | 0 |
| 1096 | 0 | DEBUG(dbgs() << "Previous IDom(MinNode) = " << BlockNamePrinter(PrevIDom) | 1097 | 47 | << "\nRunning Semi-NCA\n"); | 1098 | 47 | | 1099 | 47 | // Rebuild the remaining part of affected subtree. | 1100 | 47 | SNCA.runSemiNCA(DT, MinLevel); | 1101 | 47 | SNCA.reattachExistingSubtree(DT, PrevIDom); | 1102 | 47 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::BasicBlock>*) Line | Count | Source | 1008 | 411k | const TreeNodePtr ToTN) { | 1009 | 411k | DEBUG(dbgs() << "Deleting unreachable subtree " << BlockNamePrinter(ToTN) | 1010 | 411k | << "\n"); | 1011 | 411k | assert(ToTN); | 1012 | 411k | assert(ToTN->getBlock()); | 1013 | 411k | | 1014 | 411k | if (IsPostDom411k ) { | 1015 | 0 | // Deletion makes a region reverse-unreachable and creates a new root. | 1016 | 0 | // Simulate that by inserting an edge from the virtual root to ToTN and | 1017 | 0 | // adding it as a new root. | 1018 | 0 | DEBUG(dbgs() << "\tDeletion made a region reverse-unreachable\n"); | 1019 | 0 | DEBUG(dbgs() << "\tAdding new root " << BlockNamePrinter(ToTN) << "\n"); | 1020 | 0 | DT.Roots.push_back(ToTN->getBlock()); | 1021 | 0 | InsertReachable(DT, BUI, DT.getNode(nullptr), ToTN); | 1022 | 0 | return; | 1023 | 0 | } | 1024 | 411k | | 1025 | 411k | SmallVector<NodePtr, 16> AffectedQueue; | 1026 | 411k | const unsigned Level = ToTN->getLevel(); | 1027 | 411k | | 1028 | 411k | // Traverse destination node's descendants with greater level in the tree | 1029 | 411k | // and collect visited nodes. | 1030 | 411k | auto DescendAndCollect = [Level, &AffectedQueue, &DT](NodePtr, NodePtr To) { | 1031 | 411k | const TreeNodePtr TN = DT.getNode(To); | 1032 | 411k | assert(TN); | 1033 | 411k | if (TN->getLevel() > Level) return true; | 1034 | 411k | if (llvm::find(AffectedQueue, To) == AffectedQueue.end()) | 1035 | 411k | AffectedQueue.push_back(To); | 1036 | 411k | | 1037 | 411k | return false; | 1038 | 411k | }; | 1039 | 411k | | 1040 | 411k | SemiNCAInfo SNCA(BUI); | 1041 | 411k | unsigned LastDFSNum = | 1042 | 411k | SNCA.runDFS(ToTN->getBlock(), 0, DescendAndCollect, 0); | 1043 | 411k | | 1044 | 411k | TreeNodePtr MinNode = ToTN; | 1045 | 411k | | 1046 | 411k | // Identify the top of the subtree to rebuild by finding the NCD of all | 1047 | 411k | // the affected nodes. | 1048 | 423k | for (const NodePtr N : AffectedQueue) { | 1049 | 423k | const TreeNodePtr TN = DT.getNode(N); | 1050 | 423k | const NodePtr NCDBlock = | 1051 | 423k | DT.findNearestCommonDominator(TN->getBlock(), ToTN->getBlock()); | 1052 | 423k | assert(NCDBlock || DT.isPostDominator()); | 1053 | 423k | const TreeNodePtr NCD = DT.getNode(NCDBlock); | 1054 | 423k | assert(NCD); | 1055 | 423k | | 1056 | 423k | DEBUG(dbgs() << "Processing affected node " << BlockNamePrinter(TN) | 1057 | 423k | << " with NCD = " << BlockNamePrinter(NCD) | 1058 | 423k | << ", MinNode =" << BlockNamePrinter(MinNode) << "\n"); | 1059 | 423k | if (NCD != TN && 423k NCD->getLevel() < MinNode->getLevel()419k ) MinNode = NCD408k ; | 1060 | 423k | } | 1061 | 411k | | 1062 | 411k | // Root reached, rebuild the whole tree from scratch. | 1063 | 411k | if (!MinNode->getIDom()411k ) { | 1064 | 137k | DEBUG(dbgs() << "The entire tree needs to be rebuilt\n"); | 1065 | 137k | CalculateFromScratch(DT, BUI); | 1066 | 137k | return; | 1067 | 137k | } | 1068 | 411k | | 1069 | 411k | // Erase the unreachable subtree in reverse preorder to process all children | 1070 | 411k | // before deleting their parent. | 1071 | 871k | for (unsigned i = LastDFSNum; 274k i > 0871k ; --i597k ) { | 1072 | 597k | const NodePtr N = SNCA.NumToNode[i]; | 1073 | 597k | const TreeNodePtr TN = DT.getNode(N); | 1074 | 597k | DEBUG(dbgs() << "Erasing node " << BlockNamePrinter(TN) << "\n"); | 1075 | 597k | | 1076 | 597k | EraseNode(DT, TN); | 1077 | 597k | } | 1078 | 274k | | 1079 | 274k | // The affected subtree start at the To node -- there's no extra work to do. | 1080 | 274k | if (MinNode == ToTN274k ) return7.20k ; | 1081 | 274k | | 1082 | 267k | DEBUG267k (dbgs() << "DeleteUnreachable: running DFS with MinNode = " | 1083 | 267k | << BlockNamePrinter(MinNode) << "\n"); | 1084 | 267k | const unsigned MinLevel = MinNode->getLevel(); | 1085 | 267k | const TreeNodePtr PrevIDom = MinNode->getIDom(); | 1086 | 267k | assert(PrevIDom); | 1087 | 267k | SNCA.clear(); | 1088 | 267k | | 1089 | 267k | // Identify nodes that remain in the affected subtree. | 1090 | 267k | auto DescendBelow = [MinLevel, &DT](NodePtr, NodePtr To) { | 1091 | 267k | const TreeNodePtr ToTN = DT.getNode(To); | 1092 | 267k | return ToTN && ToTN->getLevel() > MinLevel; | 1093 | 267k | }; | 1094 | 267k | SNCA.runDFS(MinNode->getBlock(), 0, DescendBelow, 0); | 1095 | 267k | | 1096 | 267k | DEBUG(dbgs() << "Previous IDom(MinNode) = " << BlockNamePrinter(PrevIDom) | 1097 | 411k | << "\nRunning Semi-NCA\n"); | 1098 | 411k | | 1099 | 411k | // Rebuild the remaining part of affected subtree. | 1100 | 411k | SNCA.runSemiNCA(DT, MinLevel); | 1101 | 411k | SNCA.reattachExistingSubtree(DT, PrevIDom); | 1102 | 411k | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::DeleteUnreachable(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo*, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) |
1103 | | |
1104 | | // Removes leaf tree nodes from the dominator tree. |
1105 | 597k | static void EraseNode(DomTreeT &DT, const TreeNodePtr TN) { |
1106 | 597k | assert(TN); |
1107 | 597k | assert(TN->getNumChildren() == 0 && "Not a tree leaf"); |
1108 | 597k | |
1109 | 597k | const TreeNodePtr IDom = TN->getIDom(); |
1110 | 597k | assert(IDom); |
1111 | 597k | |
1112 | 597k | auto ChIt = llvm::find(IDom->Children, TN); |
1113 | 597k | assert(ChIt != IDom->Children.end()); |
1114 | 597k | std::swap(*ChIt, IDom->Children.back()); |
1115 | 597k | IDom->Children.pop_back(); |
1116 | 597k | |
1117 | 597k | DT.DomTreeNodes.erase(TN->getBlock()); |
1118 | 597k | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::EraseNode(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::EraseNode(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeNodeBase<llvm::MachineBasicBlock>*) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::EraseNode(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeNodeBase<llvm::BasicBlock>*) Line | Count | Source | 1105 | 597k | static void EraseNode(DomTreeT &DT, const TreeNodePtr TN) { | 1106 | 597k | assert(TN); | 1107 | 597k | assert(TN->getNumChildren() == 0 && "Not a tree leaf"); | 1108 | 597k | | 1109 | 597k | const TreeNodePtr IDom = TN->getIDom(); | 1110 | 597k | assert(IDom); | 1111 | 597k | | 1112 | 597k | auto ChIt = llvm::find(IDom->Children, TN); | 1113 | 597k | assert(ChIt != IDom->Children.end()); | 1114 | 597k | std::swap(*ChIt, IDom->Children.back()); | 1115 | 597k | IDom->Children.pop_back(); | 1116 | 597k | | 1117 | 597k | DT.DomTreeNodes.erase(TN->getBlock()); | 1118 | 597k | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::EraseNode(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeNodeBase<llvm::BasicBlock>*) |
1119 | | |
1120 | | //~~ |
1121 | | //===--------------------- DomTree Batch Updater --------------------------=== |
1122 | | //~~ |
1123 | | |
1124 | 613k | static void ApplyUpdates(DomTreeT &DT, ArrayRef<UpdateT> Updates) { |
1125 | 613k | BatchUpdateInfo BUI; |
1126 | 613k | LegalizeUpdates(Updates, BUI.Updates); |
1127 | 613k | |
1128 | 613k | const size_t NumLegalized = BUI.Updates.size(); |
1129 | 613k | BUI.FutureSuccessors.reserve(NumLegalized); |
1130 | 613k | BUI.FuturePredecessors.reserve(NumLegalized); |
1131 | 613k | |
1132 | 613k | // Use the legalized future updates to initialize future successors and |
1133 | 613k | // predecessors. Note that these sets will only decrease size over time, as |
1134 | 613k | // the next CFG snapshots slowly approach the actual (current) CFG. |
1135 | 2.07M | for (UpdateT &U : BUI.Updates) { |
1136 | 2.07M | BUI.FutureSuccessors[U.getFrom()].insert({U.getTo(), U.getKind()}); |
1137 | 2.07M | BUI.FuturePredecessors[U.getTo()].insert({U.getFrom(), U.getKind()}); |
1138 | 2.07M | } |
1139 | 613k | |
1140 | 613k | DEBUG(dbgs() << "About to apply " << NumLegalized << " updates\n"); |
1141 | 613k | DEBUG(if (NumLegalized < 32) for (const auto &U |
1142 | 613k | : reverse(BUI.Updates)) dbgs() |
1143 | 613k | << '\t' << U << "\n"); |
1144 | 613k | DEBUG(dbgs() << "\n"); |
1145 | 613k | |
1146 | 613k | // If the DominatorTree was recalculated at some point, stop the batch |
1147 | 613k | // updates. Full recalculations ignore batch updates and look at the actual |
1148 | 613k | // CFG. |
1149 | 2.34M | for (size_t i = 0; i < NumLegalized && 2.34M !BUI.IsRecalculated1.87M ; ++i1.73M ) |
1150 | 1.73M | ApplyNextUpdate(DT, BUI); |
1151 | 613k | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ApplyUpdates(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::ArrayRef<llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> >) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ApplyUpdates(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::ArrayRef<llvm::DomTreeBuilder::Update<llvm::BasicBlock*> >) Line | Count | Source | 1124 | 358 | static void ApplyUpdates(DomTreeT &DT, ArrayRef<UpdateT> Updates) { | 1125 | 358 | BatchUpdateInfo BUI; | 1126 | 358 | LegalizeUpdates(Updates, BUI.Updates); | 1127 | 358 | | 1128 | 358 | const size_t NumLegalized = BUI.Updates.size(); | 1129 | 358 | BUI.FutureSuccessors.reserve(NumLegalized); | 1130 | 358 | BUI.FuturePredecessors.reserve(NumLegalized); | 1131 | 358 | | 1132 | 358 | // Use the legalized future updates to initialize future successors and | 1133 | 358 | // predecessors. Note that these sets will only decrease size over time, as | 1134 | 358 | // the next CFG snapshots slowly approach the actual (current) CFG. | 1135 | 324 | for (UpdateT &U : BUI.Updates) { | 1136 | 324 | BUI.FutureSuccessors[U.getFrom()].insert({U.getTo(), U.getKind()}); | 1137 | 324 | BUI.FuturePredecessors[U.getTo()].insert({U.getFrom(), U.getKind()}); | 1138 | 324 | } | 1139 | 358 | | 1140 | 358 | DEBUG(dbgs() << "About to apply " << NumLegalized << " updates\n"); | 1141 | 358 | DEBUG(if (NumLegalized < 32) for (const auto &U | 1142 | 358 | : reverse(BUI.Updates)) dbgs() | 1143 | 358 | << '\t' << U << "\n"); | 1144 | 358 | DEBUG(dbgs() << "\n"); | 1145 | 358 | | 1146 | 358 | // If the DominatorTree was recalculated at some point, stop the batch | 1147 | 358 | // updates. Full recalculations ignore batch updates and look at the actual | 1148 | 358 | // CFG. | 1149 | 513 | for (size_t i = 0; i < NumLegalized && 513 !BUI.IsRecalculated173 ; ++i155 ) | 1150 | 155 | ApplyNextUpdate(DT, BUI); | 1151 | 358 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ApplyUpdates(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::ArrayRef<llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> >) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ApplyUpdates(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::ArrayRef<llvm::DomTreeBuilder::Update<llvm::BasicBlock*> >) Line | Count | Source | 1124 | 613k | static void ApplyUpdates(DomTreeT &DT, ArrayRef<UpdateT> Updates) { | 1125 | 613k | BatchUpdateInfo BUI; | 1126 | 613k | LegalizeUpdates(Updates, BUI.Updates); | 1127 | 613k | | 1128 | 613k | const size_t NumLegalized = BUI.Updates.size(); | 1129 | 613k | BUI.FutureSuccessors.reserve(NumLegalized); | 1130 | 613k | BUI.FuturePredecessors.reserve(NumLegalized); | 1131 | 613k | | 1132 | 613k | // Use the legalized future updates to initialize future successors and | 1133 | 613k | // predecessors. Note that these sets will only decrease size over time, as | 1134 | 613k | // the next CFG snapshots slowly approach the actual (current) CFG. | 1135 | 2.06M | for (UpdateT &U : BUI.Updates) { | 1136 | 2.06M | BUI.FutureSuccessors[U.getFrom()].insert({U.getTo(), U.getKind()}); | 1137 | 2.06M | BUI.FuturePredecessors[U.getTo()].insert({U.getFrom(), U.getKind()}); | 1138 | 2.06M | } | 1139 | 613k | | 1140 | 613k | DEBUG(dbgs() << "About to apply " << NumLegalized << " updates\n"); | 1141 | 613k | DEBUG(if (NumLegalized < 32) for (const auto &U | 1142 | 613k | : reverse(BUI.Updates)) dbgs() | 1143 | 613k | << '\t' << U << "\n"); | 1144 | 613k | DEBUG(dbgs() << "\n"); | 1145 | 613k | | 1146 | 613k | // If the DominatorTree was recalculated at some point, stop the batch | 1147 | 613k | // updates. Full recalculations ignore batch updates and look at the actual | 1148 | 613k | // CFG. | 1149 | 2.34M | for (size_t i = 0; i < NumLegalized && 2.34M !BUI.IsRecalculated1.87M ; ++i1.73M ) | 1150 | 1.73M | ApplyNextUpdate(DT, BUI); | 1151 | 613k | } |
|
1152 | | |
1153 | | // This function serves double purpose: |
1154 | | // a) It removes redundant updates, which makes it easier to reverse-apply |
1155 | | // them when traversing CFG. |
1156 | | // b) It optimizes away updates that cancel each other out, as the end result |
1157 | | // is the same. |
1158 | | // |
1159 | | // It relies on the property of the incremental updates that says that the |
1160 | | // order of updates doesn't matter. This allows us to reorder them and end up |
1161 | | // with the exact same DomTree every time. |
1162 | | // |
1163 | | // Following the same logic, the function doesn't care about the order of |
1164 | | // input updates, so it's OK to pass it an unordered sequence of updates, that |
1165 | | // doesn't make sense when applied sequentially, eg. performing double |
1166 | | // insertions or deletions and then doing an opposite update. |
1167 | | // |
1168 | | // In the future, it should be possible to schedule updates in way that |
1169 | | // minimizes the amount of work needed done during incremental updates. |
1170 | | static void LegalizeUpdates(ArrayRef<UpdateT> AllUpdates, |
1171 | 613k | SmallVectorImpl<UpdateT> &Result) { |
1172 | 613k | DEBUG(dbgs() << "Legalizing " << AllUpdates.size() << " updates\n"); |
1173 | 613k | // Count the total number of inserions of each edge. |
1174 | 613k | // Each insertion adds 1 and deletion subtracts 1. The end number should be |
1175 | 613k | // one of {-1 (deletion), 0 (NOP), +1 (insertion)}. Otherwise, the sequence |
1176 | 613k | // of updates contains multiple updates of the same kind and we assert for |
1177 | 613k | // that case. |
1178 | 613k | SmallDenseMap<std::pair<NodePtr, NodePtr>, int, 4> Operations; |
1179 | 613k | Operations.reserve(AllUpdates.size()); |
1180 | 613k | |
1181 | 2.07M | for (const auto &U : AllUpdates) { |
1182 | 2.07M | NodePtr From = U.getFrom(); |
1183 | 2.07M | NodePtr To = U.getTo(); |
1184 | 2.07M | if (IsPostDom2.07M ) std::swap(From, To)331 ; // Reverse edge for postdominators. |
1185 | 2.07M | |
1186 | 2.07M | Operations[{From, To}] += (U.getKind() == UpdateKind::Insert ? 1955k : -11.11M ); |
1187 | 2.07M | } |
1188 | 613k | |
1189 | 613k | Result.clear(); |
1190 | 613k | Result.reserve(Operations.size()); |
1191 | 2.07M | for (auto &Op : Operations) { |
1192 | 2.07M | const int NumInsertions = Op.second; |
1193 | 2.07M | assert(std::abs(NumInsertions) <= 1 && "Unbalanced operations!"); |
1194 | 2.07M | if (NumInsertions == 02.07M ) continue2 ; |
1195 | 2.07M | const UpdateKind UK = |
1196 | 2.07M | NumInsertions > 0 ? UpdateKind::Insert955k : UpdateKind::Delete1.11M ; |
1197 | 2.07M | Result.push_back({UK, Op.first.first, Op.first.second}); |
1198 | 2.07M | } |
1199 | 613k | |
1200 | 613k | // Make the order consistent by not relying on pointer values within the |
1201 | 613k | // set. Reuse the old Operations map. |
1202 | 613k | // In the future, we should sort by something else to minimize the amount |
1203 | 613k | // of work needed to perform the series of updates. |
1204 | 2.68M | for (size_t i = 0, e = AllUpdates.size(); i != e2.68M ; ++i2.07M ) { |
1205 | 2.07M | const auto &U = AllUpdates[i]; |
1206 | 2.07M | if (!IsPostDom) |
1207 | 2.06M | Operations[{U.getFrom(), U.getTo()}] = int(i); |
1208 | 2.07M | else |
1209 | 331 | Operations[{U.getTo(), U.getFrom()}] = int(i); |
1210 | 2.07M | } |
1211 | 613k | |
1212 | 613k | std::sort(Result.begin(), Result.end(), |
1213 | 2.65M | [&Operations](const UpdateT &A, const UpdateT &B) { |
1214 | 2.65M | return Operations[{A.getFrom(), A.getTo()}] > |
1215 | 2.65M | Operations[{B.getFrom(), B.getTo()}]; |
1216 | 2.65M | }); llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::LegalizeUpdates(llvm::ArrayRef<llvm::DomTreeBuilder::Update<llvm::BasicBlock*> >, llvm::SmallVectorImpl<llvm::DomTreeBuilder::Update<llvm::BasicBlock*> >&)::'lambda'(llvm::DomTreeBuilder::Update<llvm::BasicBlock*> const&, llvm::DomTreeBuilder::Update<llvm::BasicBlock*> const&)::operator()(llvm::DomTreeBuilder::Update<llvm::BasicBlock*> const&, llvm::DomTreeBuilder::Update<llvm::BasicBlock*> const&) const Line | Count | Source | 1213 | 618 | [&Operations](const UpdateT &A, const UpdateT &B) { | 1214 | 618 | return Operations[{A.getFrom(), A.getTo()}] > | 1215 | 618 | Operations[{B.getFrom(), B.getTo()}]; | 1216 | 618 | }); |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::LegalizeUpdates(llvm::ArrayRef<llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> >, llvm::SmallVectorImpl<llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> >&)::'lambda'(llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> const&, llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> const&)::operator()(llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> const&, llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> const&) const Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::LegalizeUpdates(llvm::ArrayRef<llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> >, llvm::SmallVectorImpl<llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> >&)::'lambda'(llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> const&, llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> const&)::operator()(llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> const&, llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> const&) const llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::LegalizeUpdates(llvm::ArrayRef<llvm::DomTreeBuilder::Update<llvm::BasicBlock*> >, llvm::SmallVectorImpl<llvm::DomTreeBuilder::Update<llvm::BasicBlock*> >&)::'lambda'(llvm::DomTreeBuilder::Update<llvm::BasicBlock*> const&, llvm::DomTreeBuilder::Update<llvm::BasicBlock*> const&)::operator()(llvm::DomTreeBuilder::Update<llvm::BasicBlock*> const&, llvm::DomTreeBuilder::Update<llvm::BasicBlock*> const&) const Line | Count | Source | 1213 | 2.65M | [&Operations](const UpdateT &A, const UpdateT &B) { | 1214 | 2.65M | return Operations[{A.getFrom(), A.getTo()}] > | 1215 | 2.65M | Operations[{B.getFrom(), B.getTo()}]; | 1216 | 2.65M | }); |
|
1217 | 613k | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::LegalizeUpdates(llvm::ArrayRef<llvm::DomTreeBuilder::Update<llvm::BasicBlock*> >, llvm::SmallVectorImpl<llvm::DomTreeBuilder::Update<llvm::BasicBlock*> >&) Line | Count | Source | 1171 | 613k | SmallVectorImpl<UpdateT> &Result) { | 1172 | 613k | DEBUG(dbgs() << "Legalizing " << AllUpdates.size() << " updates\n"); | 1173 | 613k | // Count the total number of inserions of each edge. | 1174 | 613k | // Each insertion adds 1 and deletion subtracts 1. The end number should be | 1175 | 613k | // one of {-1 (deletion), 0 (NOP), +1 (insertion)}. Otherwise, the sequence | 1176 | 613k | // of updates contains multiple updates of the same kind and we assert for | 1177 | 613k | // that case. | 1178 | 613k | SmallDenseMap<std::pair<NodePtr, NodePtr>, int, 4> Operations; | 1179 | 613k | Operations.reserve(AllUpdates.size()); | 1180 | 613k | | 1181 | 2.06M | for (const auto &U : AllUpdates) { | 1182 | 2.06M | NodePtr From = U.getFrom(); | 1183 | 2.06M | NodePtr To = U.getTo(); | 1184 | 2.06M | if (IsPostDom2.06M ) std::swap(From, To)0 ; // Reverse edge for postdominators. | 1185 | 2.06M | | 1186 | 2.06M | Operations[{From, To}] += (U.getKind() == UpdateKind::Insert ? 1955k : -11.11M ); | 1187 | 2.06M | } | 1188 | 613k | | 1189 | 613k | Result.clear(); | 1190 | 613k | Result.reserve(Operations.size()); | 1191 | 2.06M | for (auto &Op : Operations) { | 1192 | 2.06M | const int NumInsertions = Op.second; | 1193 | 2.06M | assert(std::abs(NumInsertions) <= 1 && "Unbalanced operations!"); | 1194 | 2.06M | if (NumInsertions == 02.06M ) continue1 ; | 1195 | 2.06M | const UpdateKind UK = | 1196 | 2.06M | NumInsertions > 0 ? UpdateKind::Insert955k : UpdateKind::Delete1.11M ; | 1197 | 2.06M | Result.push_back({UK, Op.first.first, Op.first.second}); | 1198 | 2.06M | } | 1199 | 613k | | 1200 | 613k | // Make the order consistent by not relying on pointer values within the | 1201 | 613k | // set. Reuse the old Operations map. | 1202 | 613k | // In the future, we should sort by something else to minimize the amount | 1203 | 613k | // of work needed to perform the series of updates. | 1204 | 2.68M | for (size_t i = 0, e = AllUpdates.size(); i != e2.68M ; ++i2.06M ) { | 1205 | 2.06M | const auto &U = AllUpdates[i]; | 1206 | 2.06M | if (!IsPostDom) | 1207 | 2.06M | Operations[{U.getFrom(), U.getTo()}] = int(i); | 1208 | 2.06M | else | 1209 | 0 | Operations[{U.getTo(), U.getFrom()}] = int(i); | 1210 | 2.06M | } | 1211 | 613k | | 1212 | 613k | std::sort(Result.begin(), Result.end(), | 1213 | 613k | [&Operations](const UpdateT &A, const UpdateT &B) { | 1214 | 613k | return Operations[{A.getFrom(), A.getTo()}] > | 1215 | 613k | Operations[{B.getFrom(), B.getTo()}]; | 1216 | 613k | }); | 1217 | 613k | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::LegalizeUpdates(llvm::ArrayRef<llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> >, llvm::SmallVectorImpl<llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> >&) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::LegalizeUpdates(llvm::ArrayRef<llvm::DomTreeBuilder::Update<llvm::BasicBlock*> >, llvm::SmallVectorImpl<llvm::DomTreeBuilder::Update<llvm::BasicBlock*> >&) Line | Count | Source | 1171 | 359 | SmallVectorImpl<UpdateT> &Result) { | 1172 | 359 | DEBUG(dbgs() << "Legalizing " << AllUpdates.size() << " updates\n"); | 1173 | 359 | // Count the total number of inserions of each edge. | 1174 | 359 | // Each insertion adds 1 and deletion subtracts 1. The end number should be | 1175 | 359 | // one of {-1 (deletion), 0 (NOP), +1 (insertion)}. Otherwise, the sequence | 1176 | 359 | // of updates contains multiple updates of the same kind and we assert for | 1177 | 359 | // that case. | 1178 | 359 | SmallDenseMap<std::pair<NodePtr, NodePtr>, int, 4> Operations; | 1179 | 359 | Operations.reserve(AllUpdates.size()); | 1180 | 359 | | 1181 | 331 | for (const auto &U : AllUpdates) { | 1182 | 331 | NodePtr From = U.getFrom(); | 1183 | 331 | NodePtr To = U.getTo(); | 1184 | 331 | if (IsPostDom331 ) std::swap(From, To)331 ; // Reverse edge for postdominators. | 1185 | 331 | | 1186 | 331 | Operations[{From, To}] += (U.getKind() == UpdateKind::Insert ? 1128 : -1203 ); | 1187 | 331 | } | 1188 | 359 | | 1189 | 359 | Result.clear(); | 1190 | 359 | Result.reserve(Operations.size()); | 1191 | 328 | for (auto &Op : Operations) { | 1192 | 328 | const int NumInsertions = Op.second; | 1193 | 328 | assert(std::abs(NumInsertions) <= 1 && "Unbalanced operations!"); | 1194 | 328 | if (NumInsertions == 0328 ) continue1 ; | 1195 | 327 | const UpdateKind UK = | 1196 | 327 | NumInsertions > 0 ? UpdateKind::Insert126 : UpdateKind::Delete201 ; | 1197 | 328 | Result.push_back({UK, Op.first.first, Op.first.second}); | 1198 | 328 | } | 1199 | 359 | | 1200 | 359 | // Make the order consistent by not relying on pointer values within the | 1201 | 359 | // set. Reuse the old Operations map. | 1202 | 359 | // In the future, we should sort by something else to minimize the amount | 1203 | 359 | // of work needed to perform the series of updates. | 1204 | 690 | for (size_t i = 0, e = AllUpdates.size(); i != e690 ; ++i331 ) { | 1205 | 331 | const auto &U = AllUpdates[i]; | 1206 | 331 | if (!IsPostDom) | 1207 | 0 | Operations[{U.getFrom(), U.getTo()}] = int(i); | 1208 | 331 | else | 1209 | 331 | Operations[{U.getTo(), U.getFrom()}] = int(i); | 1210 | 331 | } | 1211 | 359 | | 1212 | 359 | std::sort(Result.begin(), Result.end(), | 1213 | 359 | [&Operations](const UpdateT &A, const UpdateT &B) { | 1214 | 359 | return Operations[{A.getFrom(), A.getTo()}] > | 1215 | 359 | Operations[{B.getFrom(), B.getTo()}]; | 1216 | 359 | }); | 1217 | 359 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::LegalizeUpdates(llvm::ArrayRef<llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> >, llvm::SmallVectorImpl<llvm::DomTreeBuilder::Update<llvm::MachineBasicBlock*> >&) |
1218 | | |
1219 | 1.73M | static void ApplyNextUpdate(DomTreeT &DT, BatchUpdateInfo &BUI) { |
1220 | 1.73M | assert(!BUI.Updates.empty() && "No updates to apply!"); |
1221 | 1.73M | UpdateT CurrentUpdate = BUI.Updates.pop_back_val(); |
1222 | 1.73M | DEBUG(dbgs() << "Applying update: " << CurrentUpdate << "\n"); |
1223 | 1.73M | |
1224 | 1.73M | // Move to the next snapshot of the CFG by removing the reverse-applied |
1225 | 1.73M | // current update. |
1226 | 1.73M | auto &FS = BUI.FutureSuccessors[CurrentUpdate.getFrom()]; |
1227 | 1.73M | FS.erase({CurrentUpdate.getTo(), CurrentUpdate.getKind()}); |
1228 | 1.73M | if (FS.empty()1.73M ) BUI.FutureSuccessors.erase(CurrentUpdate.getFrom())974k ; |
1229 | 1.73M | |
1230 | 1.73M | auto &FP = BUI.FuturePredecessors[CurrentUpdate.getTo()]; |
1231 | 1.73M | FP.erase({CurrentUpdate.getFrom(), CurrentUpdate.getKind()}); |
1232 | 1.73M | if (FP.empty()1.73M ) BUI.FuturePredecessors.erase(CurrentUpdate.getTo())1.15M ; |
1233 | 1.73M | |
1234 | 1.73M | if (CurrentUpdate.getKind() == UpdateKind::Insert) |
1235 | 787k | InsertEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo()); |
1236 | 1.73M | else |
1237 | 945k | DeleteEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo()); |
1238 | 1.73M | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::ApplyNextUpdate(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::BatchUpdateInfo&) Line | Count | Source | 1219 | 155 | static void ApplyNextUpdate(DomTreeT &DT, BatchUpdateInfo &BUI) { | 1220 | 155 | assert(!BUI.Updates.empty() && "No updates to apply!"); | 1221 | 155 | UpdateT CurrentUpdate = BUI.Updates.pop_back_val(); | 1222 | 155 | DEBUG(dbgs() << "Applying update: " << CurrentUpdate << "\n"); | 1223 | 155 | | 1224 | 155 | // Move to the next snapshot of the CFG by removing the reverse-applied | 1225 | 155 | // current update. | 1226 | 155 | auto &FS = BUI.FutureSuccessors[CurrentUpdate.getFrom()]; | 1227 | 155 | FS.erase({CurrentUpdate.getTo(), CurrentUpdate.getKind()}); | 1228 | 155 | if (FS.empty()155 ) BUI.FutureSuccessors.erase(CurrentUpdate.getFrom())142 ; | 1229 | 155 | | 1230 | 155 | auto &FP = BUI.FuturePredecessors[CurrentUpdate.getTo()]; | 1231 | 155 | FP.erase({CurrentUpdate.getFrom(), CurrentUpdate.getKind()}); | 1232 | 155 | if (FP.empty()155 ) BUI.FuturePredecessors.erase(CurrentUpdate.getTo())132 ; | 1233 | 155 | | 1234 | 155 | if (CurrentUpdate.getKind() == UpdateKind::Insert) | 1235 | 14 | InsertEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo()); | 1236 | 155 | else | 1237 | 141 | DeleteEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo()); | 1238 | 155 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::ApplyNextUpdate(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::BatchUpdateInfo&) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::ApplyNextUpdate(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::BatchUpdateInfo&) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::ApplyNextUpdate(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::BatchUpdateInfo&) Line | Count | Source | 1219 | 1.73M | static void ApplyNextUpdate(DomTreeT &DT, BatchUpdateInfo &BUI) { | 1220 | 1.73M | assert(!BUI.Updates.empty() && "No updates to apply!"); | 1221 | 1.73M | UpdateT CurrentUpdate = BUI.Updates.pop_back_val(); | 1222 | 1.73M | DEBUG(dbgs() << "Applying update: " << CurrentUpdate << "\n"); | 1223 | 1.73M | | 1224 | 1.73M | // Move to the next snapshot of the CFG by removing the reverse-applied | 1225 | 1.73M | // current update. | 1226 | 1.73M | auto &FS = BUI.FutureSuccessors[CurrentUpdate.getFrom()]; | 1227 | 1.73M | FS.erase({CurrentUpdate.getTo(), CurrentUpdate.getKind()}); | 1228 | 1.73M | if (FS.empty()1.73M ) BUI.FutureSuccessors.erase(CurrentUpdate.getFrom())974k ; | 1229 | 1.73M | | 1230 | 1.73M | auto &FP = BUI.FuturePredecessors[CurrentUpdate.getTo()]; | 1231 | 1.73M | FP.erase({CurrentUpdate.getFrom(), CurrentUpdate.getKind()}); | 1232 | 1.73M | if (FP.empty()1.73M ) BUI.FuturePredecessors.erase(CurrentUpdate.getTo())1.15M ; | 1233 | 1.73M | | 1234 | 1.73M | if (CurrentUpdate.getKind() == UpdateKind::Insert) | 1235 | 787k | InsertEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo()); | 1236 | 1.73M | else | 1237 | 945k | DeleteEdge(DT, &BUI, CurrentUpdate.getFrom(), CurrentUpdate.getTo()); | 1238 | 1.73M | } |
|
1239 | | |
1240 | | //~~ |
1241 | | //===--------------- DomTree correctness verification ---------------------=== |
1242 | | //~~ |
1243 | | |
1244 | | // Check if the tree has correct roots. A DominatorTree always has a single |
1245 | | // root which is the function's entry node. A PostDominatorTree can have |
1246 | | // multiple roots - one for each node with no successors and for infinite |
1247 | | // loops. |
1248 | 575 | bool verifyRoots(const DomTreeT &DT) { |
1249 | 575 | if (!DT.Parent && 575 !DT.Roots.empty()0 ) { |
1250 | 0 | errs() << "Tree has no parent but has roots!\n"; |
1251 | 0 | errs().flush(); |
1252 | 0 | return false; |
1253 | 0 | } |
1254 | 575 | |
1255 | 575 | if (575 !IsPostDom575 ) { |
1256 | 290 | if (DT.Roots.empty()290 ) { |
1257 | 0 | errs() << "Tree doesn't have a root!\n"; |
1258 | 0 | errs().flush(); |
1259 | 0 | return false; |
1260 | 0 | } |
1261 | 290 | |
1262 | 290 | if (290 DT.getRoot() != GetEntryNode(DT)290 ) { |
1263 | 0 | errs() << "Tree's root is not its parent's entry node!\n"; |
1264 | 0 | errs().flush(); |
1265 | 0 | return false; |
1266 | 0 | } |
1267 | 290 | } |
1268 | 575 | |
1269 | 575 | RootsT ComputedRoots = FindRoots(DT, nullptr); |
1270 | 575 | if (DT.Roots.size() != ComputedRoots.size() || |
1271 | 575 | !std::is_permutation(DT.Roots.begin(), DT.Roots.end(), |
1272 | 575 | ComputedRoots.begin())) { |
1273 | 0 | errs() << "Tree has different roots than freshly computed ones!\n"; |
1274 | 0 | errs() << "\tPDT roots: "; |
1275 | 0 | for (const NodePtr N : DT.Roots) errs() << BlockNamePrinter(N) << ", "; |
1276 | 0 | errs() << "\n\tComputed roots: "; |
1277 | 0 | for (const NodePtr N : ComputedRoots) |
1278 | 0 | errs() << BlockNamePrinter(N) << ", "; |
1279 | 0 | errs() << "\n"; |
1280 | 0 | errs().flush(); |
1281 | 0 | return false; |
1282 | 0 | } |
1283 | 575 | |
1284 | 575 | return true; |
1285 | 575 | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyRoots(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyRoots(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyRoots(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&) Line | Count | Source | 1248 | 285 | bool verifyRoots(const DomTreeT &DT) { | 1249 | 285 | if (!DT.Parent && 285 !DT.Roots.empty()0 ) { | 1250 | 0 | errs() << "Tree has no parent but has roots!\n"; | 1251 | 0 | errs().flush(); | 1252 | 0 | return false; | 1253 | 0 | } | 1254 | 285 | | 1255 | 285 | if (285 !IsPostDom285 ) { | 1256 | 0 | if (DT.Roots.empty()0 ) { | 1257 | 0 | errs() << "Tree doesn't have a root!\n"; | 1258 | 0 | errs().flush(); | 1259 | 0 | return false; | 1260 | 0 | } | 1261 | 0 |
| 1262 | 0 | if (0 DT.getRoot() != GetEntryNode(DT)0 ) { | 1263 | 0 | errs() << "Tree's root is not its parent's entry node!\n"; | 1264 | 0 | errs().flush(); | 1265 | 0 | return false; | 1266 | 0 | } | 1267 | 0 | } | 1268 | 285 | | 1269 | 285 | RootsT ComputedRoots = FindRoots(DT, nullptr); | 1270 | 285 | if (DT.Roots.size() != ComputedRoots.size() || | 1271 | 285 | !std::is_permutation(DT.Roots.begin(), DT.Roots.end(), | 1272 | 285 | ComputedRoots.begin())) { | 1273 | 0 | errs() << "Tree has different roots than freshly computed ones!\n"; | 1274 | 0 | errs() << "\tPDT roots: "; | 1275 | 0 | for (const NodePtr N : DT.Roots) errs() << BlockNamePrinter(N) << ", "; | 1276 | 0 | errs() << "\n\tComputed roots: "; | 1277 | 0 | for (const NodePtr N : ComputedRoots) | 1278 | 0 | errs() << BlockNamePrinter(N) << ", "; | 1279 | 0 | errs() << "\n"; | 1280 | 0 | errs().flush(); | 1281 | 0 | return false; | 1282 | 0 | } | 1283 | 285 | | 1284 | 285 | return true; | 1285 | 285 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyRoots(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&) Line | Count | Source | 1248 | 290 | bool verifyRoots(const DomTreeT &DT) { | 1249 | 290 | if (!DT.Parent && 290 !DT.Roots.empty()0 ) { | 1250 | 0 | errs() << "Tree has no parent but has roots!\n"; | 1251 | 0 | errs().flush(); | 1252 | 0 | return false; | 1253 | 0 | } | 1254 | 290 | | 1255 | 290 | if (290 !IsPostDom290 ) { | 1256 | 290 | if (DT.Roots.empty()290 ) { | 1257 | 0 | errs() << "Tree doesn't have a root!\n"; | 1258 | 0 | errs().flush(); | 1259 | 0 | return false; | 1260 | 0 | } | 1261 | 290 | | 1262 | 290 | if (290 DT.getRoot() != GetEntryNode(DT)290 ) { | 1263 | 0 | errs() << "Tree's root is not its parent's entry node!\n"; | 1264 | 0 | errs().flush(); | 1265 | 0 | return false; | 1266 | 0 | } | 1267 | 290 | } | 1268 | 290 | | 1269 | 290 | RootsT ComputedRoots = FindRoots(DT, nullptr); | 1270 | 290 | if (DT.Roots.size() != ComputedRoots.size() || | 1271 | 290 | !std::is_permutation(DT.Roots.begin(), DT.Roots.end(), | 1272 | 290 | ComputedRoots.begin())) { | 1273 | 0 | errs() << "Tree has different roots than freshly computed ones!\n"; | 1274 | 0 | errs() << "\tPDT roots: "; | 1275 | 0 | for (const NodePtr N : DT.Roots) errs() << BlockNamePrinter(N) << ", "; | 1276 | 0 | errs() << "\n\tComputed roots: "; | 1277 | 0 | for (const NodePtr N : ComputedRoots) | 1278 | 0 | errs() << BlockNamePrinter(N) << ", "; | 1279 | 0 | errs() << "\n"; | 1280 | 0 | errs().flush(); | 1281 | 0 | return false; | 1282 | 0 | } | 1283 | 290 | | 1284 | 290 | return true; | 1285 | 290 | } |
|
1286 | | |
1287 | | // Checks if the tree contains all reachable nodes in the input graph. |
1288 | 575 | bool verifyReachability(const DomTreeT &DT) { |
1289 | 575 | clear(); |
1290 | 575 | doFullDFSWalk(DT, AlwaysDescend); |
1291 | 575 | |
1292 | 6.11k | for (auto &NodeToTN : DT.DomTreeNodes) { |
1293 | 6.11k | const TreeNodePtr TN = NodeToTN.second.get(); |
1294 | 6.11k | const NodePtr BB = TN->getBlock(); |
1295 | 6.11k | |
1296 | 6.11k | // Virtual root has a corresponding virtual CFG node. |
1297 | 6.11k | if (DT.isVirtualRoot(TN)6.11k ) continue285 ; |
1298 | 6.11k | |
1299 | 5.82k | if (5.82k NodeToInfo.count(BB) == 05.82k ) { |
1300 | 0 | errs() << "DomTree node " << BlockNamePrinter(BB) |
1301 | 0 | << " not found by DFS walk!\n"; |
1302 | 0 | errs().flush(); |
1303 | 0 |
|
1304 | 0 | return false; |
1305 | 0 | } |
1306 | 6.11k | } |
1307 | 575 | |
1308 | 575 | for (const NodePtr N : NumToNode) 575 { |
1309 | 6.68k | if (N && 6.68k !DT.getNode(N)5.82k ) { |
1310 | 0 | errs() << "CFG node " << BlockNamePrinter(N) |
1311 | 0 | << " not found in the DomTree!\n"; |
1312 | 0 | errs().flush(); |
1313 | 0 |
|
1314 | 0 | return false; |
1315 | 0 | } |
1316 | 6.68k | } |
1317 | 575 | |
1318 | 575 | return true; |
1319 | 575 | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyReachability(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&) Line | Count | Source | 1288 | 290 | bool verifyReachability(const DomTreeT &DT) { | 1289 | 290 | clear(); | 1290 | 290 | doFullDFSWalk(DT, AlwaysDescend); | 1291 | 290 | | 1292 | 2.53k | for (auto &NodeToTN : DT.DomTreeNodes) { | 1293 | 2.53k | const TreeNodePtr TN = NodeToTN.second.get(); | 1294 | 2.53k | const NodePtr BB = TN->getBlock(); | 1295 | 2.53k | | 1296 | 2.53k | // Virtual root has a corresponding virtual CFG node. | 1297 | 2.53k | if (DT.isVirtualRoot(TN)2.53k ) continue0 ; | 1298 | 2.53k | | 1299 | 2.53k | if (2.53k NodeToInfo.count(BB) == 02.53k ) { | 1300 | 0 | errs() << "DomTree node " << BlockNamePrinter(BB) | 1301 | 0 | << " not found by DFS walk!\n"; | 1302 | 0 | errs().flush(); | 1303 | 0 |
| 1304 | 0 | return false; | 1305 | 0 | } | 1306 | 2.53k | } | 1307 | 290 | | 1308 | 290 | for (const NodePtr N : NumToNode) 290 { | 1309 | 2.82k | if (N && 2.82k !DT.getNode(N)2.53k ) { | 1310 | 0 | errs() << "CFG node " << BlockNamePrinter(N) | 1311 | 0 | << " not found in the DomTree!\n"; | 1312 | 0 | errs().flush(); | 1313 | 0 |
| 1314 | 0 | return false; | 1315 | 0 | } | 1316 | 2.82k | } | 1317 | 290 | | 1318 | 290 | return true; | 1319 | 290 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyReachability(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&) Line | Count | Source | 1288 | 285 | bool verifyReachability(const DomTreeT &DT) { | 1289 | 285 | clear(); | 1290 | 285 | doFullDFSWalk(DT, AlwaysDescend); | 1291 | 285 | | 1292 | 3.57k | for (auto &NodeToTN : DT.DomTreeNodes) { | 1293 | 3.57k | const TreeNodePtr TN = NodeToTN.second.get(); | 1294 | 3.57k | const NodePtr BB = TN->getBlock(); | 1295 | 3.57k | | 1296 | 3.57k | // Virtual root has a corresponding virtual CFG node. | 1297 | 3.57k | if (DT.isVirtualRoot(TN)3.57k ) continue285 ; | 1298 | 3.57k | | 1299 | 3.29k | if (3.29k NodeToInfo.count(BB) == 03.29k ) { | 1300 | 0 | errs() << "DomTree node " << BlockNamePrinter(BB) | 1301 | 0 | << " not found by DFS walk!\n"; | 1302 | 0 | errs().flush(); | 1303 | 0 |
| 1304 | 0 | return false; | 1305 | 0 | } | 1306 | 3.57k | } | 1307 | 285 | | 1308 | 285 | for (const NodePtr N : NumToNode) 285 { | 1309 | 3.86k | if (N && 3.86k !DT.getNode(N)3.29k ) { | 1310 | 0 | errs() << "CFG node " << BlockNamePrinter(N) | 1311 | 0 | << " not found in the DomTree!\n"; | 1312 | 0 | errs().flush(); | 1313 | 0 |
| 1314 | 0 | return false; | 1315 | 0 | } | 1316 | 3.86k | } | 1317 | 285 | | 1318 | 285 | return true; | 1319 | 285 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyReachability(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyReachability(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&) |
1320 | | |
1321 | | // Check if for every parent with a level L in the tree all of its children |
1322 | | // have level L + 1. |
1323 | 575 | static bool VerifyLevels(const DomTreeT &DT) { |
1324 | 6.11k | for (auto &NodeToTN : DT.DomTreeNodes) { |
1325 | 6.11k | const TreeNodePtr TN = NodeToTN.second.get(); |
1326 | 6.11k | const NodePtr BB = TN->getBlock(); |
1327 | 6.11k | if (!BB6.11k ) continue285 ; |
1328 | 6.11k | |
1329 | 5.82k | const TreeNodePtr IDom = TN->getIDom(); |
1330 | 5.82k | if (!IDom && 5.82k TN->getLevel() != 0290 ) { |
1331 | 0 | errs() << "Node without an IDom " << BlockNamePrinter(BB) |
1332 | 0 | << " has a nonzero level " << TN->getLevel() << "!\n"; |
1333 | 0 | errs().flush(); |
1334 | 0 |
|
1335 | 0 | return false; |
1336 | 0 | } |
1337 | 5.82k | |
1338 | 5.82k | if (5.82k IDom && 5.82k TN->getLevel() != IDom->getLevel() + 15.53k ) { |
1339 | 0 | errs() << "Node " << BlockNamePrinter(BB) << " has level " |
1340 | 0 | << TN->getLevel() << " while its IDom " |
1341 | 0 | << BlockNamePrinter(IDom->getBlock()) << " has level " |
1342 | 0 | << IDom->getLevel() << "!\n"; |
1343 | 0 | errs().flush(); |
1344 | 0 |
|
1345 | 0 | return false; |
1346 | 0 | } |
1347 | 6.11k | } |
1348 | 575 | |
1349 | 575 | return true; |
1350 | 575 | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::VerifyLevels(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&) Line | Count | Source | 1323 | 290 | static bool VerifyLevels(const DomTreeT &DT) { | 1324 | 2.53k | for (auto &NodeToTN : DT.DomTreeNodes) { | 1325 | 2.53k | const TreeNodePtr TN = NodeToTN.second.get(); | 1326 | 2.53k | const NodePtr BB = TN->getBlock(); | 1327 | 2.53k | if (!BB2.53k ) continue0 ; | 1328 | 2.53k | | 1329 | 2.53k | const TreeNodePtr IDom = TN->getIDom(); | 1330 | 2.53k | if (!IDom && 2.53k TN->getLevel() != 0290 ) { | 1331 | 0 | errs() << "Node without an IDom " << BlockNamePrinter(BB) | 1332 | 0 | << " has a nonzero level " << TN->getLevel() << "!\n"; | 1333 | 0 | errs().flush(); | 1334 | 0 |
| 1335 | 0 | return false; | 1336 | 0 | } | 1337 | 2.53k | | 1338 | 2.53k | if (2.53k IDom && 2.53k TN->getLevel() != IDom->getLevel() + 12.24k ) { | 1339 | 0 | errs() << "Node " << BlockNamePrinter(BB) << " has level " | 1340 | 0 | << TN->getLevel() << " while its IDom " | 1341 | 0 | << BlockNamePrinter(IDom->getBlock()) << " has level " | 1342 | 0 | << IDom->getLevel() << "!\n"; | 1343 | 0 | errs().flush(); | 1344 | 0 |
| 1345 | 0 | return false; | 1346 | 0 | } | 1347 | 2.53k | } | 1348 | 290 | | 1349 | 290 | return true; | 1350 | 290 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::VerifyLevels(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&) Line | Count | Source | 1323 | 285 | static bool VerifyLevels(const DomTreeT &DT) { | 1324 | 3.57k | for (auto &NodeToTN : DT.DomTreeNodes) { | 1325 | 3.57k | const TreeNodePtr TN = NodeToTN.second.get(); | 1326 | 3.57k | const NodePtr BB = TN->getBlock(); | 1327 | 3.57k | if (!BB3.57k ) continue285 ; | 1328 | 3.57k | | 1329 | 3.29k | const TreeNodePtr IDom = TN->getIDom(); | 1330 | 3.29k | if (!IDom && 3.29k TN->getLevel() != 00 ) { | 1331 | 0 | errs() << "Node without an IDom " << BlockNamePrinter(BB) | 1332 | 0 | << " has a nonzero level " << TN->getLevel() << "!\n"; | 1333 | 0 | errs().flush(); | 1334 | 0 |
| 1335 | 0 | return false; | 1336 | 0 | } | 1337 | 3.29k | | 1338 | 3.29k | if (3.29k IDom && 3.29k TN->getLevel() != IDom->getLevel() + 13.29k ) { | 1339 | 0 | errs() << "Node " << BlockNamePrinter(BB) << " has level " | 1340 | 0 | << TN->getLevel() << " while its IDom " | 1341 | 0 | << BlockNamePrinter(IDom->getBlock()) << " has level " | 1342 | 0 | << IDom->getLevel() << "!\n"; | 1343 | 0 | errs().flush(); | 1344 | 0 |
| 1345 | 0 | return false; | 1346 | 0 | } | 1347 | 3.57k | } | 1348 | 285 | | 1349 | 285 | return true; | 1350 | 285 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::VerifyLevels(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::VerifyLevels(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&) |
1351 | | |
1352 | | // Checks if for every edge From -> To in the graph |
1353 | | // NCD(From, To) == IDom(To) or To. |
1354 | 575 | bool verifyNCD(const DomTreeT &DT) { |
1355 | 575 | clear(); |
1356 | 575 | doFullDFSWalk(DT, AlwaysDescend); |
1357 | 575 | |
1358 | 6.11k | for (auto &BlockToInfo : NodeToInfo) { |
1359 | 6.11k | auto &Info = BlockToInfo.second; |
1360 | 6.11k | |
1361 | 6.11k | const NodePtr From = NumToNode[Info.Parent]; |
1362 | 6.11k | if (!From6.11k ) continue1.47k ; |
1363 | 6.11k | |
1364 | 4.64k | const NodePtr To = BlockToInfo.first; |
1365 | 4.64k | const TreeNodePtr ToTN = DT.getNode(To); |
1366 | 4.64k | assert(ToTN); |
1367 | 4.64k | |
1368 | 4.64k | const NodePtr NCD = DT.findNearestCommonDominator(From, To); |
1369 | 4.64k | const TreeNodePtr NCDTN = DT.getNode(NCD); |
1370 | 4.64k | const TreeNodePtr ToIDom = ToTN->getIDom(); |
1371 | 4.64k | if (NCDTN != ToTN && 4.64k NCDTN != ToIDom4.64k ) { |
1372 | 0 | errs() << "NearestCommonDominator verification failed:\n\tNCD(From:" |
1373 | 0 | << BlockNamePrinter(From) << ", To:" << BlockNamePrinter(To) |
1374 | 0 | << ") = " << BlockNamePrinter(NCD) |
1375 | 0 | << ",\t (should be To or IDom[To]: " << BlockNamePrinter(ToIDom) |
1376 | 0 | << ")\n"; |
1377 | 0 | errs().flush(); |
1378 | 0 |
|
1379 | 0 | return false; |
1380 | 0 | } |
1381 | 6.11k | } |
1382 | 575 | |
1383 | 575 | return true; |
1384 | 575 | } Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyNCD(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyNCD(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&) Line | Count | Source | 1354 | 290 | bool verifyNCD(const DomTreeT &DT) { | 1355 | 290 | clear(); | 1356 | 290 | doFullDFSWalk(DT, AlwaysDescend); | 1357 | 290 | | 1358 | 2.53k | for (auto &BlockToInfo : NodeToInfo) { | 1359 | 2.53k | auto &Info = BlockToInfo.second; | 1360 | 2.53k | | 1361 | 2.53k | const NodePtr From = NumToNode[Info.Parent]; | 1362 | 2.53k | if (!From2.53k ) continue290 ; | 1363 | 2.53k | | 1364 | 2.24k | const NodePtr To = BlockToInfo.first; | 1365 | 2.24k | const TreeNodePtr ToTN = DT.getNode(To); | 1366 | 2.24k | assert(ToTN); | 1367 | 2.24k | | 1368 | 2.24k | const NodePtr NCD = DT.findNearestCommonDominator(From, To); | 1369 | 2.24k | const TreeNodePtr NCDTN = DT.getNode(NCD); | 1370 | 2.24k | const TreeNodePtr ToIDom = ToTN->getIDom(); | 1371 | 2.24k | if (NCDTN != ToTN && 2.24k NCDTN != ToIDom2.24k ) { | 1372 | 0 | errs() << "NearestCommonDominator verification failed:\n\tNCD(From:" | 1373 | 0 | << BlockNamePrinter(From) << ", To:" << BlockNamePrinter(To) | 1374 | 0 | << ") = " << BlockNamePrinter(NCD) | 1375 | 0 | << ",\t (should be To or IDom[To]: " << BlockNamePrinter(ToIDom) | 1376 | 0 | << ")\n"; | 1377 | 0 | errs().flush(); | 1378 | 0 |
| 1379 | 0 | return false; | 1380 | 0 | } | 1381 | 2.53k | } | 1382 | 290 | | 1383 | 290 | return true; | 1384 | 290 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyNCD(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&) Line | Count | Source | 1354 | 285 | bool verifyNCD(const DomTreeT &DT) { | 1355 | 285 | clear(); | 1356 | 285 | doFullDFSWalk(DT, AlwaysDescend); | 1357 | 285 | | 1358 | 3.57k | for (auto &BlockToInfo : NodeToInfo) { | 1359 | 3.57k | auto &Info = BlockToInfo.second; | 1360 | 3.57k | | 1361 | 3.57k | const NodePtr From = NumToNode[Info.Parent]; | 1362 | 3.57k | if (!From3.57k ) continue1.18k ; | 1363 | 3.57k | | 1364 | 2.39k | const NodePtr To = BlockToInfo.first; | 1365 | 2.39k | const TreeNodePtr ToTN = DT.getNode(To); | 1366 | 2.39k | assert(ToTN); | 1367 | 2.39k | | 1368 | 2.39k | const NodePtr NCD = DT.findNearestCommonDominator(From, To); | 1369 | 2.39k | const TreeNodePtr NCDTN = DT.getNode(NCD); | 1370 | 2.39k | const TreeNodePtr ToIDom = ToTN->getIDom(); | 1371 | 2.39k | if (NCDTN != ToTN && 2.39k NCDTN != ToIDom2.39k ) { | 1372 | 0 | errs() << "NearestCommonDominator verification failed:\n\tNCD(From:" | 1373 | 0 | << BlockNamePrinter(From) << ", To:" << BlockNamePrinter(To) | 1374 | 0 | << ") = " << BlockNamePrinter(NCD) | 1375 | 0 | << ",\t (should be To or IDom[To]: " << BlockNamePrinter(ToIDom) | 1376 | 0 | << ")\n"; | 1377 | 0 | errs().flush(); | 1378 | 0 |
| 1379 | 0 | return false; | 1380 | 0 | } | 1381 | 3.57k | } | 1382 | 285 | | 1383 | 285 | return true; | 1384 | 285 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyNCD(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&) |
1385 | | |
1386 | | // The below routines verify the correctness of the dominator tree relative to |
1387 | | // the CFG it's coming from. A tree is a dominator tree iff it has two |
1388 | | // properties, called the parent property and the sibling property. Tarjan |
1389 | | // and Lengauer prove (but don't explicitly name) the properties as part of |
1390 | | // the proofs in their 1972 paper, but the proofs are mostly part of proving |
1391 | | // things about semidominators and idoms, and some of them are simply asserted |
1392 | | // based on even earlier papers (see, e.g., lemma 2). Some papers refer to |
1393 | | // these properties as "valid" and "co-valid". See, e.g., "Dominators, |
1394 | | // directed bipolar orders, and independent spanning trees" by Loukas |
1395 | | // Georgiadis and Robert E. Tarjan, as well as "Dominator Tree Verification |
1396 | | // and Vertex-Disjoint Paths " by the same authors. |
1397 | | |
1398 | | // A very simple and direct explanation of these properties can be found in |
1399 | | // "An Experimental Study of Dynamic Dominators", found at |
1400 | | // https://arxiv.org/abs/1604.02711 |
1401 | | |
1402 | | // The easiest way to think of the parent property is that it's a requirement |
1403 | | // of being a dominator. Let's just take immediate dominators. For PARENT to |
1404 | | // be an immediate dominator of CHILD, all paths in the CFG must go through |
1405 | | // PARENT before they hit CHILD. This implies that if you were to cut PARENT |
1406 | | // out of the CFG, there should be no paths to CHILD that are reachable. If |
1407 | | // there are, then you now have a path from PARENT to CHILD that goes around |
1408 | | // PARENT and still reaches CHILD, which by definition, means PARENT can't be |
1409 | | // a dominator of CHILD (let alone an immediate one). |
1410 | | |
1411 | | // The sibling property is similar. It says that for each pair of sibling |
1412 | | // nodes in the dominator tree (LEFT and RIGHT) , they must not dominate each |
1413 | | // other. If sibling LEFT dominated sibling RIGHT, it means there are no |
1414 | | // paths in the CFG from sibling LEFT to sibling RIGHT that do not go through |
1415 | | // LEFT, and thus, LEFT is really an ancestor (in the dominator tree) of |
1416 | | // RIGHT, not a sibling. |
1417 | | |
1418 | | // It is possible to verify the parent and sibling properties in |
1419 | | // linear time, but the algorithms are complex. Instead, we do it in a |
1420 | | // straightforward N^2 and N^3 way below, using direct path reachability. |
1421 | | |
1422 | | |
1423 | | // Checks if the tree has the parent property: if for all edges from V to W in |
1424 | | // the input graph, such that V is reachable, the parent of W in the tree is |
1425 | | // an ancestor of V in the tree. |
1426 | | // |
1427 | | // This means that if a node gets disconnected from the graph, then all of |
1428 | | // the nodes it dominated previously will now become unreachable. |
1429 | 575 | bool verifyParentProperty(const DomTreeT &DT) { |
1430 | 6.11k | for (auto &NodeToTN : DT.DomTreeNodes) { |
1431 | 6.11k | const TreeNodePtr TN = NodeToTN.second.get(); |
1432 | 6.11k | const NodePtr BB = TN->getBlock(); |
1433 | 6.11k | if (!BB || 6.11k TN->getChildren().empty()5.82k ) continue2.92k ; |
1434 | 6.11k | |
1435 | 3.19k | DEBUG3.19k (dbgs() << "Verifying parent property of node " |
1436 | 3.19k | << BlockNamePrinter(TN) << "\n"); |
1437 | 3.19k | clear(); |
1438 | 19.6k | doFullDFSWalk(DT, [BB](NodePtr From, NodePtr To) { |
1439 | 18.6k | return From != BB && To != BB; |
1440 | 19.6k | }); Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const Line | Count | Source | 1438 | 12.4k | doFullDFSWalk(DT, [BB](NodePtr From, NodePtr To) { | 1439 | 11.7k | return From != BB && To != BB; | 1440 | 12.4k | }); |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const Line | Count | Source | 1438 | 7.25k | doFullDFSWalk(DT, [BB](NodePtr From, NodePtr To) { | 1439 | 6.96k | return From != BB && To != BB; | 1440 | 7.25k | }); |
|
1441 | 3.19k | |
1442 | 3.19k | for (TreeNodePtr Child : TN->getChildren()) |
1443 | 4.19k | if (4.19k NodeToInfo.count(Child->getBlock()) != 04.19k ) { |
1444 | 0 | errs() << "Child " << BlockNamePrinter(Child) |
1445 | 0 | << " reachable after its parent " << BlockNamePrinter(BB) |
1446 | 0 | << " is removed!\n"; |
1447 | 0 | errs().flush(); |
1448 | 0 |
|
1449 | 0 | return false; |
1450 | 0 | } |
1451 | 6.11k | } |
1452 | 575 | |
1453 | 575 | return true; |
1454 | 575 | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&) Line | Count | Source | 1429 | 285 | bool verifyParentProperty(const DomTreeT &DT) { | 1430 | 3.57k | for (auto &NodeToTN : DT.DomTreeNodes) { | 1431 | 3.57k | const TreeNodePtr TN = NodeToTN.second.get(); | 1432 | 3.57k | const NodePtr BB = TN->getBlock(); | 1433 | 3.57k | if (!BB || 3.57k TN->getChildren().empty()3.29k ) continue1.95k ; | 1434 | 3.57k | | 1435 | 1.62k | DEBUG1.62k (dbgs() << "Verifying parent property of node " | 1436 | 1.62k | << BlockNamePrinter(TN) << "\n"); | 1437 | 1.62k | clear(); | 1438 | 1.62k | doFullDFSWalk(DT, [BB](NodePtr From, NodePtr To) { | 1439 | 1.62k | return From != BB && To != BB; | 1440 | 1.62k | }); | 1441 | 1.62k | | 1442 | 1.62k | for (TreeNodePtr Child : TN->getChildren()) | 1443 | 1.95k | if (1.95k NodeToInfo.count(Child->getBlock()) != 01.95k ) { | 1444 | 0 | errs() << "Child " << BlockNamePrinter(Child) | 1445 | 0 | << " reachable after its parent " << BlockNamePrinter(BB) | 1446 | 0 | << " is removed!\n"; | 1447 | 0 | errs().flush(); | 1448 | 0 |
| 1449 | 0 | return false; | 1450 | 0 | } | 1451 | 3.57k | } | 1452 | 285 | | 1453 | 285 | return true; | 1454 | 285 | } |
llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&) Line | Count | Source | 1429 | 290 | bool verifyParentProperty(const DomTreeT &DT) { | 1430 | 2.53k | for (auto &NodeToTN : DT.DomTreeNodes) { | 1431 | 2.53k | const TreeNodePtr TN = NodeToTN.second.get(); | 1432 | 2.53k | const NodePtr BB = TN->getBlock(); | 1433 | 2.53k | if (!BB || 2.53k TN->getChildren().empty()2.53k ) continue968 ; | 1434 | 2.53k | | 1435 | 1.56k | DEBUG1.56k (dbgs() << "Verifying parent property of node " | 1436 | 1.56k | << BlockNamePrinter(TN) << "\n"); | 1437 | 1.56k | clear(); | 1438 | 1.56k | doFullDFSWalk(DT, [BB](NodePtr From, NodePtr To) { | 1439 | 1.56k | return From != BB && To != BB; | 1440 | 1.56k | }); | 1441 | 1.56k | | 1442 | 1.56k | for (TreeNodePtr Child : TN->getChildren()) | 1443 | 2.24k | if (2.24k NodeToInfo.count(Child->getBlock()) != 02.24k ) { | 1444 | 0 | errs() << "Child " << BlockNamePrinter(Child) | 1445 | 0 | << " reachable after its parent " << BlockNamePrinter(BB) | 1446 | 0 | << " is removed!\n"; | 1447 | 0 | errs().flush(); | 1448 | 0 |
| 1449 | 0 | return false; | 1450 | 0 | } | 1451 | 2.53k | } | 1452 | 290 | | 1453 | 290 | return true; | 1454 | 290 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&) Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifyParentProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&) |
1455 | | |
1456 | | // Check if the tree has sibling property: if a node V does not dominate a |
1457 | | // node W for all siblings V and W in the tree. |
1458 | | // |
1459 | | // This means that if a node gets disconnected from the graph, then all of its |
1460 | | // siblings will now still be reachable. |
1461 | 575 | bool verifySiblingProperty(const DomTreeT &DT) { |
1462 | 6.11k | for (auto &NodeToTN : DT.DomTreeNodes) { |
1463 | 6.11k | const TreeNodePtr TN = NodeToTN.second.get(); |
1464 | 6.11k | const NodePtr BB = TN->getBlock(); |
1465 | 6.11k | if (!BB || 6.11k TN->getChildren().empty()5.82k ) continue2.92k ; |
1466 | 6.11k | |
1467 | 3.19k | const auto &Siblings = TN->getChildren(); |
1468 | 4.19k | for (const TreeNodePtr N : Siblings) { |
1469 | 4.19k | clear(); |
1470 | 4.19k | NodePtr BBN = N->getBlock(); |
1471 | 32.4k | doFullDFSWalk(DT, [BBN](NodePtr From, NodePtr To) { |
1472 | 32.4k | return From != BBN && To != BBN; |
1473 | 32.4k | }); Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const Line | Count | Source | 1471 | 15.7k | doFullDFSWalk(DT, [BBN](NodePtr From, NodePtr To) { | 1472 | 15.7k | return From != BBN && To != BBN; | 1473 | 15.7k | }); |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&)::'lambda'(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*)::operator()(llvm::MachineBasicBlock*, llvm::MachineBasicBlock*) const llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&)::'lambda'(llvm::BasicBlock*, llvm::BasicBlock*)::operator()(llvm::BasicBlock*, llvm::BasicBlock*) const Line | Count | Source | 1471 | 16.7k | doFullDFSWalk(DT, [BBN](NodePtr From, NodePtr To) { | 1472 | 16.7k | return From != BBN && To != BBN; | 1473 | 16.7k | }); |
|
1474 | 4.19k | |
1475 | 6.71k | for (const TreeNodePtr S : Siblings) { |
1476 | 6.71k | if (S == N6.71k ) continue4.19k ; |
1477 | 6.71k | |
1478 | 2.51k | if (2.51k NodeToInfo.count(S->getBlock()) == 02.51k ) { |
1479 | 0 | errs() << "Node " << BlockNamePrinter(S) |
1480 | 0 | << " not reachable when its sibling " << BlockNamePrinter(N) |
1481 | 0 | << " is removed!\n"; |
1482 | 0 | errs().flush(); |
1483 | 0 |
|
1484 | 0 | return false; |
1485 | 0 | } |
1486 | 6.71k | } |
1487 | 4.19k | } |
1488 | 6.11k | } |
1489 | 575 | |
1490 | 575 | return true; |
1491 | 575 | } llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&) Line | Count | Source | 1461 | 290 | bool verifySiblingProperty(const DomTreeT &DT) { | 1462 | 2.53k | for (auto &NodeToTN : DT.DomTreeNodes) { | 1463 | 2.53k | const TreeNodePtr TN = NodeToTN.second.get(); | 1464 | 2.53k | const NodePtr BB = TN->getBlock(); | 1465 | 2.53k | if (!BB || 2.53k TN->getChildren().empty()2.53k ) continue968 ; | 1466 | 2.53k | | 1467 | 1.56k | const auto &Siblings = TN->getChildren(); | 1468 | 2.24k | for (const TreeNodePtr N : Siblings) { | 1469 | 2.24k | clear(); | 1470 | 2.24k | NodePtr BBN = N->getBlock(); | 1471 | 2.24k | doFullDFSWalk(DT, [BBN](NodePtr From, NodePtr To) { | 1472 | 2.24k | return From != BBN && To != BBN; | 1473 | 2.24k | }); | 1474 | 2.24k | | 1475 | 4.04k | for (const TreeNodePtr S : Siblings) { | 1476 | 4.04k | if (S == N4.04k ) continue2.24k ; | 1477 | 4.04k | | 1478 | 1.79k | if (1.79k NodeToInfo.count(S->getBlock()) == 01.79k ) { | 1479 | 0 | errs() << "Node " << BlockNamePrinter(S) | 1480 | 0 | << " not reachable when its sibling " << BlockNamePrinter(N) | 1481 | 0 | << " is removed!\n"; | 1482 | 0 | errs().flush(); | 1483 | 0 |
| 1484 | 0 | return false; | 1485 | 0 | } | 1486 | 4.04k | } | 1487 | 2.24k | } | 1488 | 2.53k | } | 1489 | 290 | | 1490 | 290 | return true; | 1491 | 290 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&) llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::BasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&) Line | Count | Source | 1461 | 285 | bool verifySiblingProperty(const DomTreeT &DT) { | 1462 | 3.57k | for (auto &NodeToTN : DT.DomTreeNodes) { | 1463 | 3.57k | const TreeNodePtr TN = NodeToTN.second.get(); | 1464 | 3.57k | const NodePtr BB = TN->getBlock(); | 1465 | 3.57k | if (!BB || 3.57k TN->getChildren().empty()3.29k ) continue1.95k ; | 1466 | 3.57k | | 1467 | 1.62k | const auto &Siblings = TN->getChildren(); | 1468 | 1.95k | for (const TreeNodePtr N : Siblings) { | 1469 | 1.95k | clear(); | 1470 | 1.95k | NodePtr BBN = N->getBlock(); | 1471 | 1.95k | doFullDFSWalk(DT, [BBN](NodePtr From, NodePtr To) { | 1472 | 1.95k | return From != BBN && To != BBN; | 1473 | 1.95k | }); | 1474 | 1.95k | | 1475 | 2.67k | for (const TreeNodePtr S : Siblings) { | 1476 | 2.67k | if (S == N2.67k ) continue1.95k ; | 1477 | 2.67k | | 1478 | 718 | if (718 NodeToInfo.count(S->getBlock()) == 0718 ) { | 1479 | 0 | errs() << "Node " << BlockNamePrinter(S) | 1480 | 0 | << " not reachable when its sibling " << BlockNamePrinter(N) | 1481 | 0 | << " is removed!\n"; | 1482 | 0 | errs().flush(); | 1483 | 0 |
| 1484 | 0 | return false; | 1485 | 0 | } | 1486 | 2.67k | } | 1487 | 1.95k | } | 1488 | 3.57k | } | 1489 | 285 | | 1490 | 285 | return true; | 1491 | 285 | } |
Unexecuted instantiation: llvm::DomTreeBuilder::SemiNCAInfo<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >::verifySiblingProperty(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&) |
1492 | | }; |
1493 | | |
1494 | | template <class DomTreeT> |
1495 | 18.0M | void Calculate(DomTreeT &DT) { |
1496 | 18.0M | SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr); |
1497 | 18.0M | } void llvm::DomTreeBuilder::Calculate<llvm::DominatorTreeBase<llvm::BasicBlock, false> >(llvm::DominatorTreeBase<llvm::BasicBlock, false>&) Line | Count | Source | 1495 | 12.0M | void Calculate(DomTreeT &DT) { | 1496 | 12.0M | SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr); | 1497 | 12.0M | } |
void llvm::DomTreeBuilder::Calculate<llvm::DominatorTreeBase<llvm::BasicBlock, true> >(llvm::DominatorTreeBase<llvm::BasicBlock, true>&) Line | Count | Source | 1495 | 581k | void Calculate(DomTreeT &DT) { | 1496 | 581k | SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr); | 1497 | 581k | } |
void llvm::DomTreeBuilder::Calculate<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&) Line | Count | Source | 1495 | 1.77M | void Calculate(DomTreeT &DT) { | 1496 | 1.77M | SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr); | 1497 | 1.77M | } |
void llvm::DomTreeBuilder::Calculate<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&) Line | Count | Source | 1495 | 3.66M | void Calculate(DomTreeT &DT) { | 1496 | 3.66M | SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr); | 1497 | 3.66M | } |
void llvm::DomTreeBuilder::Calculate<llvm::DominatorTreeBase<clang::CFGBlock, false> >(llvm::DominatorTreeBase<clang::CFGBlock, false>&) Line | Count | Source | 1495 | 5 | void Calculate(DomTreeT &DT) { | 1496 | 5 | SemiNCAInfo<DomTreeT>::CalculateFromScratch(DT, nullptr); | 1497 | 5 | } |
|
1498 | | |
1499 | | template <class DomTreeT> |
1500 | | void InsertEdge(DomTreeT &DT, typename DomTreeT::NodePtr From, |
1501 | 31.9k | typename DomTreeT::NodePtr To) { |
1502 | 31.9k | if (DT.isPostDominator()31.9k ) std::swap(From, To)140 ; |
1503 | 31.9k | SemiNCAInfo<DomTreeT>::InsertEdge(DT, nullptr, From, To); |
1504 | 31.9k | } Unexecuted instantiation: void llvm::DomTreeBuilder::InsertEdge<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>::NodePtr, llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>::NodePtr) void llvm::DomTreeBuilder::InsertEdge<llvm::DominatorTreeBase<llvm::BasicBlock, false> >(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DominatorTreeBase<llvm::BasicBlock, false>::NodePtr, llvm::DominatorTreeBase<llvm::BasicBlock, false>::NodePtr) Line | Count | Source | 1501 | 31.7k | typename DomTreeT::NodePtr To) { | 1502 | 31.7k | if (DT.isPostDominator()31.7k ) std::swap(From, To)0 ; | 1503 | 31.7k | SemiNCAInfo<DomTreeT>::InsertEdge(DT, nullptr, From, To); | 1504 | 31.7k | } |
void llvm::DomTreeBuilder::InsertEdge<llvm::DominatorTreeBase<llvm::BasicBlock, true> >(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DominatorTreeBase<llvm::BasicBlock, true>::NodePtr, llvm::DominatorTreeBase<llvm::BasicBlock, true>::NodePtr) Line | Count | Source | 1501 | 140 | typename DomTreeT::NodePtr To) { | 1502 | 140 | if (DT.isPostDominator()140 ) std::swap(From, To)140 ; | 1503 | 140 | SemiNCAInfo<DomTreeT>::InsertEdge(DT, nullptr, From, To); | 1504 | 140 | } |
Unexecuted instantiation: void llvm::DomTreeBuilder::InsertEdge<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>::NodePtr, llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>::NodePtr) |
1505 | | |
1506 | | template <class DomTreeT> |
1507 | | void DeleteEdge(DomTreeT &DT, typename DomTreeT::NodePtr From, |
1508 | 78.5k | typename DomTreeT::NodePtr To) { |
1509 | 78.5k | if (DT.isPostDominator()78.5k ) std::swap(From, To)77 ; |
1510 | 78.5k | SemiNCAInfo<DomTreeT>::DeleteEdge(DT, nullptr, From, To); |
1511 | 78.5k | } void llvm::DomTreeBuilder::DeleteEdge<llvm::DominatorTreeBase<llvm::BasicBlock, true> >(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::DominatorTreeBase<llvm::BasicBlock, true>::NodePtr, llvm::DominatorTreeBase<llvm::BasicBlock, true>::NodePtr) Line | Count | Source | 1508 | 77 | typename DomTreeT::NodePtr To) { | 1509 | 77 | if (DT.isPostDominator()77 ) std::swap(From, To)77 ; | 1510 | 77 | SemiNCAInfo<DomTreeT>::DeleteEdge(DT, nullptr, From, To); | 1511 | 77 | } |
void llvm::DomTreeBuilder::DeleteEdge<llvm::DominatorTreeBase<llvm::BasicBlock, false> >(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::DominatorTreeBase<llvm::BasicBlock, false>::NodePtr, llvm::DominatorTreeBase<llvm::BasicBlock, false>::NodePtr) Line | Count | Source | 1508 | 78.5k | typename DomTreeT::NodePtr To) { | 1509 | 78.5k | if (DT.isPostDominator()78.5k ) std::swap(From, To)0 ; | 1510 | 78.5k | SemiNCAInfo<DomTreeT>::DeleteEdge(DT, nullptr, From, To); | 1511 | 78.5k | } |
Unexecuted instantiation: void llvm::DomTreeBuilder::DeleteEdge<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>::NodePtr, llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>::NodePtr) Unexecuted instantiation: void llvm::DomTreeBuilder::DeleteEdge<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>::NodePtr, llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>::NodePtr) |
1512 | | |
1513 | | template <class DomTreeT> |
1514 | | void ApplyUpdates(DomTreeT &DT, |
1515 | 613k | ArrayRef<typename DomTreeT::UpdateType> Updates) { |
1516 | 613k | SemiNCAInfo<DomTreeT>::ApplyUpdates(DT, Updates); |
1517 | 613k | } Unexecuted instantiation: void llvm::DomTreeBuilder::ApplyUpdates<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>&, llvm::ArrayRef<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false>::UpdateType>) Unexecuted instantiation: void llvm::DomTreeBuilder::ApplyUpdates<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>&, llvm::ArrayRef<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true>::UpdateType>) void llvm::DomTreeBuilder::ApplyUpdates<llvm::DominatorTreeBase<llvm::BasicBlock, true> >(llvm::DominatorTreeBase<llvm::BasicBlock, true>&, llvm::ArrayRef<llvm::DominatorTreeBase<llvm::BasicBlock, true>::UpdateType>) Line | Count | Source | 1515 | 358 | ArrayRef<typename DomTreeT::UpdateType> Updates) { | 1516 | 358 | SemiNCAInfo<DomTreeT>::ApplyUpdates(DT, Updates); | 1517 | 358 | } |
void llvm::DomTreeBuilder::ApplyUpdates<llvm::DominatorTreeBase<llvm::BasicBlock, false> >(llvm::DominatorTreeBase<llvm::BasicBlock, false>&, llvm::ArrayRef<llvm::DominatorTreeBase<llvm::BasicBlock, false>::UpdateType>) Line | Count | Source | 1515 | 613k | ArrayRef<typename DomTreeT::UpdateType> Updates) { | 1516 | 613k | SemiNCAInfo<DomTreeT>::ApplyUpdates(DT, Updates); | 1517 | 613k | } |
|
1518 | | |
1519 | | template <class DomTreeT> |
1520 | 575 | bool Verify(const DomTreeT &DT) { |
1521 | 575 | SemiNCAInfo<DomTreeT> SNCA(nullptr); |
1522 | 575 | return SNCA.verifyRoots(DT) && SNCA.verifyReachability(DT) && |
1523 | 575 | SNCA.VerifyLevels(DT)575 && SNCA.verifyNCD(DT)575 && |
1524 | 575 | SNCA.verifyParentProperty(DT)575 && SNCA.verifySiblingProperty(DT)575 ; |
1525 | 575 | } Unexecuted instantiation: bool llvm::DomTreeBuilder::Verify<llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, true> const&) bool llvm::DomTreeBuilder::Verify<llvm::DominatorTreeBase<llvm::BasicBlock, true> >(llvm::DominatorTreeBase<llvm::BasicBlock, true> const&) Line | Count | Source | 1520 | 285 | bool Verify(const DomTreeT &DT) { | 1521 | 285 | SemiNCAInfo<DomTreeT> SNCA(nullptr); | 1522 | 285 | return SNCA.verifyRoots(DT) && SNCA.verifyReachability(DT) && | 1523 | 285 | SNCA.VerifyLevels(DT)285 && SNCA.verifyNCD(DT)285 && | 1524 | 285 | SNCA.verifyParentProperty(DT)285 && SNCA.verifySiblingProperty(DT)285 ; | 1525 | 285 | } |
Unexecuted instantiation: bool llvm::DomTreeBuilder::Verify<llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> >(llvm::DominatorTreeBase<llvm::MachineBasicBlock, false> const&) bool llvm::DomTreeBuilder::Verify<llvm::DominatorTreeBase<llvm::BasicBlock, false> >(llvm::DominatorTreeBase<llvm::BasicBlock, false> const&) Line | Count | Source | 1520 | 290 | bool Verify(const DomTreeT &DT) { | 1521 | 290 | SemiNCAInfo<DomTreeT> SNCA(nullptr); | 1522 | 290 | return SNCA.verifyRoots(DT) && SNCA.verifyReachability(DT) && | 1523 | 290 | SNCA.VerifyLevels(DT)290 && SNCA.verifyNCD(DT)290 && | 1524 | 290 | SNCA.verifyParentProperty(DT)290 && SNCA.verifySiblingProperty(DT)290 ; | 1525 | 290 | } |
|
1526 | | |
1527 | | } // namespace DomTreeBuilder |
1528 | | } // namespace llvm |
1529 | | |
1530 | | #undef DEBUG_TYPE |
1531 | | |
1532 | | #endif |