llvm.org GIT mirror llvm / 662f95d
[Dominators] Move InfoRec outside of DominatorTreeBase Summary: The InfoRec struct is used only during tree construction, so there is no point having it as a DominatorTreeBase member. This patch moves it into the Calculate function instead and makes it pass it to its helper functions. Reviewers: sanjoy, dberlin, chandlerc Reviewed By: dberlin Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D34305 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306572 91177308-0d34-0410-b5e6-96231b3b80d8 Jakub Kuderski 3 years ago
2 changed file(s) with 68 addition(s) and 66 deletion(s). Raw diff Collapse all Expand all
228228 void wipe() {
229229 DomTreeNodes.clear();
230230 IDoms.clear();
231 Info.clear();
232231 RootNode = nullptr;
233232 }
234233
240239
241240 mutable bool DFSInfoValid = false;
242241 mutable unsigned int SlowQueries = 0;
243 // Information record used during immediate dominators computation.
244 struct InfoRec {
245 unsigned DFSNum = 0;
246 unsigned Parent = 0;
247 unsigned Semi = 0;
248 NodeT *Label = nullptr;
249
250 InfoRec() = default;
251 };
252242
253243 DenseMap IDoms;
254
255 // Info - Collection of information used during the computation of idoms.
256 DenseMap Info;
257244
258245 void reset() {
259246 DomTreeNodes.clear();
333320 RootNode(std::move(Arg.RootNode)),
334321 DFSInfoValid(std::move(Arg.DFSInfoValid)),
335322 SlowQueries(std::move(Arg.SlowQueries)),
336 IDoms(std::move(Arg.IDoms)),
337 Info(std::move(Arg.Info)) {
323 IDoms(std::move(Arg.IDoms)) {
338324 Arg.wipe();
339325 }
340326
346332 DFSInfoValid = std::move(RHS.DFSInfoValid);
347333 SlowQueries = std::move(RHS.SlowQueries);
348334 IDoms = std::move(RHS.IDoms);
349 Info = std::move(RHS.Info);
350335 RHS.wipe();
351336 return *this;
352337 }
668653 }
669654
670655 protected:
656 // Information record used by Semi-NCA during tree construction.
657 struct SemiNCAInfo {
658 using NodePtr = NodeT *;
659 struct InfoRec {
660 unsigned DFSNum = 0;
661 unsigned Parent = 0;
662 unsigned Semi = 0;
663 NodePtr Label = nullptr;
664 };
665
666 std::vector NumToNode;
667 DenseMap NodeToInfo;
668 };
669
671670 template
672671 friend typename GraphT::NodeRef Eval(
673672 DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V,
674 const std::vector &NumToNode,
673 typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &Info,
675674 unsigned LastLinked);
676675
677676 template
678677 friend unsigned ReverseDFSPass(
679678 DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V,
680 std::vector &NumToNode, unsigned N);
679 typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &Info,
680 unsigned N);
681681
682682 template
683 friend unsigned DFSPass(DominatorTreeBaseByGraphTraits &DT,
684 typename GraphT::NodeRef V,
685 std::vector &NumToNode,
686 unsigned N);
683 friend unsigned DFSPass(
684 DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V,
685 typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &Info,
686 unsigned N);
687687
688688 template
689689 friend void Calculate(DominatorTreeBaseByGraphTraits> &DT,
4949 };
5050
5151 template
52 unsigned ReverseDFSPass(DominatorTreeBaseByGraphTraits &DT,
53 typename GraphT::NodeRef V,
54 std::vector &NumToNode,
55 unsigned N) {
56 df_iterator_dom_storage<
57 typename GraphT::NodeRef,
58 typename DominatorTreeBaseByGraphTraits::InfoRec>
59 DFStorage(DT.Info);
52 unsigned ReverseDFSPass(
53 DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V,
54 typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &SNCA,
55 unsigned N) {
56 using SNCAInfoTy = typename std::remove_reference::type;
57 df_iterator_dom_storage
58 typename SNCAInfoTy::InfoRec>
59 DFStorage(SNCA.NodeToInfo);
60
6061 bool IsChildOfArtificialExit = (N != 0);
6162 for (auto I = idf_ext_begin(V, DFStorage), E = idf_ext_end(V, DFStorage);
6263 I != E; ++I) {
6364 typename GraphT::NodeRef BB = *I;
64 auto &BBInfo = DT.Info[BB];
65 auto &BBInfo = SNCA.NodeToInfo[BB];
6566 BBInfo.DFSNum = BBInfo.Semi = ++N;
6667 BBInfo.Label = BB;
6768 // Set the parent to the top of the visited stack. The stack includes us,
6869 // and is 1 based, so we subtract to account for both of these.
6970 if (I.getPathLength() > 1)
70 BBInfo.Parent = DT.Info[I.getPath(I.getPathLength() - 2)].DFSNum;
71 NumToNode.push_back(BB); // NumToNode[n] = V;
71 BBInfo.Parent = SNCA.NodeToInfo[I.getPath(I.getPathLength() - 2)].DFSNum;
72 SNCA.NumToNode.push_back(BB); // NumToNode[n] = V;
7273
7374 if (IsChildOfArtificialExit)
7475 BBInfo.Parent = 1;
7879 return N;
7980 }
8081 template
81 unsigned DFSPass(DominatorTreeBaseByGraphTraits &DT,
82 typename GraphT::NodeRef V,
83 std::vector &NumToNode, unsigned N) {
84 df_iterator_dom_storage<
85 typename GraphT::NodeRef,
86 typename DominatorTreeBaseByGraphTraits::InfoRec>
87 DFStorage(DT.Info);
82 unsigned DFSPass(
83 DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V,
84 typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &SNCA,
85 unsigned N) {
86 using SNCAInfoTy = typename std::remove_reference::type;
87 df_iterator_dom_storage
88 typename SNCAInfoTy::InfoRec>
89 DFStorage(SNCA.NodeToInfo);
8890 for (auto I = df_ext_begin(V, DFStorage), E = df_ext_end(V, DFStorage);
8991 I != E; ++I) {
9092 typename GraphT::NodeRef BB = *I;
91 auto &BBInfo = DT.Info[BB];
93 auto &BBInfo = SNCA.NodeToInfo[BB];
9294 BBInfo.DFSNum = BBInfo.Semi = ++N;
9395 BBInfo.Label = BB;
9496 // Set the parent to the top of the visited stack. The stack includes us,
9597 // and is 1 based, so we subtract to account for both of these.
9698 if (I.getPathLength() > 1)
97 BBInfo.Parent = DT.Info[I.getPath(I.getPathLength() - 2)].DFSNum;
98 NumToNode.push_back(BB); // NumToNode[n] = V;
99 BBInfo.Parent = SNCA.NodeToInfo[I.getPath(I.getPathLength() - 2)].DFSNum;
100 SNCA.NumToNode.push_back(BB); // NumToNode[n] = V;
99101 }
100102 return N;
101103 }
103105 template
104106 typename GraphT::NodeRef Eval(
105107 DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef VIn,
106 const std::vector &NumToNode,
108 typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &SNCA,
107109 unsigned LastLinked) {
108110 using NodePtr = typename GraphT::NodeRef;
109111
110 auto &VInInfo = DT.Info[VIn];
112 auto &VInInfo = SNCA.NodeToInfo[VIn];
111113 if (VInInfo.DFSNum < LastLinked)
112114 return VIn;
113115
119121
120122 while (!Work.empty()) {
121123 NodePtr V = Work.back();
122 auto &VInfo = DT.Info[V];
123 NodePtr VAncestor = NumToNode[VInfo.Parent];
124 auto &VInfo = SNCA.NodeToInfo[V];
125 NodePtr VAncestor = SNCA.NumToNode[VInfo.Parent];
124126
125127 // Process Ancestor first
126128 if (Visited.insert(VAncestor).second && VInfo.Parent >= LastLinked) {
133135 if (VInfo.Parent < LastLinked)
134136 continue;
135137
136 auto &VAInfo = DT.Info[VAncestor];
138 auto &VAInfo = SNCA.NodeToInfo[VAncestor];
137139 NodePtr VAncestorLabel = VAInfo.Label;
138140 NodePtr VLabel = VInfo.Label;
139 if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi)
141 if (SNCA.NodeToInfo[VAncestorLabel].Semi < SNCA.NodeToInfo[VLabel].Semi)
140142 VInfo.Label = VAncestorLabel;
141143 VInfo.Parent = VAInfo.Parent;
142144 }
154156 using NodeType = typename std::remove_pointer::type;
155157
156158 unsigned N = 0;
157 std::vector NumToNode = {nullptr};
159 typename DominatorTreeBaseByGraphTraits::SemiNCAInfo SNCA;
160 SNCA.NumToNode.push_back(nullptr);
158161
159162 bool MultipleRoots = (DT.Roots.size() > 1);
160163 if (MultipleRoots) {
161 auto &BBInfo = DT.Info[nullptr];
164 auto &BBInfo = SNCA.NodeToInfo[nullptr];
162165 BBInfo.DFSNum = BBInfo.Semi = ++N;
163166 BBInfo.Label = nullptr;
164167
165 NumToNode.push_back(nullptr); // NumToNode[n] = V;
168 SNCA.NumToNode.push_back(nullptr); // NumToNode[n] = V;
166169 }
167170
168171 // Step #1: Number blocks in depth-first order and initialize variables used
170173 if (DT.isPostDominator()){
171174 for (unsigned i = 0, e = static_cast(DT.Roots.size());
172175 i != e; ++i)
173 N = ReverseDFSPass(DT, DT.Roots[i], NumToNode, N);
176 N = ReverseDFSPass(DT, DT.Roots[i], SNCA, N);
174177 } else {
175 N = DFSPass(DT, DT.Roots[0], NumToNode, N);
178 N = DFSPass(DT, DT.Roots[0], SNCA, N);
176179 }
177180
178181 // It might be that some blocks did not get a DFS number (e.g., blocks of
181184
182185 // Initialize IDoms to spanning tree parents.
183186 for (unsigned i = 1; i <= N; ++i) {
184 const NodePtr V = NumToNode[i];
185 DT.IDoms[V] = NumToNode[DT.Info[V].Parent];
187 const NodePtr V = SNCA.NumToNode[i];
188 DT.IDoms[V] = SNCA.NumToNode[SNCA.NodeToInfo[V].Parent];
186189 }
187190
188191 // Step #2: Calculate the semidominators of all vertices.
189192 for (unsigned i = N; i >= 2; --i) {
190 NodePtr W = NumToNode[i];
191 auto &WInfo = DT.Info[W];
193 NodePtr W = SNCA.NumToNode[i];
194 auto &WInfo = SNCA.NodeToInfo[W];
192195
193196 // Initialize the semi dominator to point to the parent node.
194197 WInfo.Semi = WInfo.Parent;
195198 for (const auto &N : inverse_children(W))
196 if (DT.Info.count(N)) { // Only if this predecessor is reachable!
197 unsigned SemiU = DT.Info[Eval(DT, N, NumToNode, i + 1)].Semi;
199 if (SNCA.NodeToInfo.count(N)) { // Only if this predecessor is reachable!
200 unsigned SemiU = SNCA.NodeToInfo[Eval(DT, N, SNCA, i + 1)].Semi;
198201 if (SemiU < WInfo.Semi)
199202 WInfo.Semi = SemiU;
200203 }
206209 // Note that the parents were stored in IDoms and later got invalidated during
207210 // path compression in Eval.
208211 for (unsigned i = 2; i <= N; ++i) {
209 const NodePtr W = NumToNode[i];
210 const auto &WInfo = DT.Info[W];
211 const unsigned SDomNum = DT.Info[NumToNode[WInfo.Semi]].DFSNum;
212 const NodePtr W = SNCA.NumToNode[i];
213 const auto &WInfo = SNCA.NodeToInfo[W];
214 const unsigned SDomNum = SNCA.NodeToInfo[SNCA.NumToNode[WInfo.Semi]].DFSNum;
212215 NodePtr WIDomCandidate = DT.IDoms[W];
213 while (DT.Info[WIDomCandidate].DFSNum > SDomNum)
216 while (SNCA.NodeToInfo[WIDomCandidate].DFSNum > SDomNum)
214217 WIDomCandidate = DT.IDoms[WIDomCandidate];
215218
216219 DT.IDoms[W] = WIDomCandidate;
231234
232235 // Loop over all of the reachable blocks in the function...
233236 for (unsigned i = 2; i <= N; ++i) {
234 NodePtr W = NumToNode[i];
237 NodePtr W = SNCA.NumToNode[i];
235238
236239 // Don't replace this with 'count', the insertion side effect is important
237240 if (DT.DomTreeNodes[W])
252255
253256 // Free temporary memory used to construct idom's
254257 DT.IDoms.clear();
255 DT.Info.clear();
256258
257259 DT.updateDFSNumbers();
258260 }