llvm.org GIT mirror llvm / 370f3b8
[Dominators] Move SemiNCAInfo and helper functions out of DominatorTreeBase Summary: This moves SemiNCAInfo from DeminatorTreeBase to GenericDomTreeConstruction. It also put helper functions used during tree constructions in the same file. The point of this change is to further clean up DominatorTreeBase and make it easier to construct and verify (in future patches). Reviewers: dberlin, sanjoy, chandlerc Reviewed By: dberlin Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D34420 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306576 91177308-0d34-0410-b5e6-96231b3b80d8 Jakub Kuderski 3 years ago
2 changed file(s) with 89 addition(s) and 97 deletion(s). Raw diff Collapse all Expand all
200200 PrintDomTree(*I, O, Lev + 1);
201201 }
202202
203 namespace DomTreeBuilder {
204 template
205 struct SemiNCAInfo;
206 } // namespace DomTreeBuilder
207
203208 // The calculate routine is provided in a separate header but referenced here.
204209 template
205210 void Calculate(DominatorTreeBaseByGraphTraits> &DT, FuncT &F);
647652 }
648653
649654 protected:
650 // Information record used by Semi-NCA during tree construction.
651 struct SemiNCAInfo {
652 using NodePtr = NodeT *;
653 struct InfoRec {
654 unsigned DFSNum = 0;
655 unsigned Parent = 0;
656 unsigned Semi = 0;
657 NodePtr Label = nullptr;
658 NodePtr IDom = nullptr;
659 };
660
661 std::vector NumToNode;
662 DenseMap NodeToInfo;
663
664 NodeT *getIDom(NodeT *BB) const {
665 auto InfoIt = NodeToInfo.find(BB);
666 if (InfoIt == NodeToInfo.end()) return nullptr;
667
668 return InfoIt->second.IDom;
669 }
670 };
671
672 template
673 friend typename GraphT::NodeRef Eval(
674 DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V,
675 typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &Info,
676 unsigned LastLinked);
677
678 template
679 friend unsigned ReverseDFSPass(
680 DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V,
681 typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &Info,
682 unsigned N);
683
684 template
685 friend unsigned DFSPass(
686 DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef V,
687 typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &Info,
688 unsigned N);
689
690 template
691 friend void Calculate(DominatorTreeBaseByGraphTraits> &DT,
692 FuncT &F);
693
694 DomTreeNodeBase *getNodeForBlock(NodeT *BB,
695 const SemiNCAInfo& SNCAInfo) {
696 if (DomTreeNodeBase *Node = getNode(BB))
697 return Node;
698
699 // Haven't calculated this node yet? Get or calculate the node for the
700 // immediate dominator.
701 NodeT *IDom = SNCAInfo.getIDom(BB);
702
703 assert(IDom || DomTreeNodes[nullptr]);
704 DomTreeNodeBase *IDomNode = getNodeForBlock(IDom, SNCAInfo);
705
706 // Add a new tree node for this NodeT, and link it as a child of
707 // IDomNode
708 return (DomTreeNodes[BB] = IDomNode->addChild(
709 llvm::make_unique>(BB, IDomNode))).get();
710 }
711
712 void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
655 friend struct DomTreeBuilder::SemiNCAInfo;
656 using SNCAInfoTy = DomTreeBuilder::SemiNCAInfo;
657
658 template
659 friend void Calculate(DominatorTreeBaseByGraphTraits> &DT,
660 FuncT &F);
661
662 void addRoot(NodeT *BB) { this->Roots.push_back(BB); }
713663
714664 public:
715665 /// updateDFSNumbers - Assign In and Out numbers to the nodes while walking
3030
3131 namespace llvm {
3232
33 namespace DomTreeBuilder {
34 // Information record used by Semi-NCA during tree construction.
35 template
36 struct SemiNCAInfo {
37 using NodePtr = NodeT *;
38 using DomTreeT = DominatorTreeBase;
39 using TreeNodePtr = DomTreeNodeBase *;
40
41 struct InfoRec {
42 unsigned DFSNum = 0;
43 unsigned Parent = 0;
44 unsigned Semi = 0;
45 NodePtr Label = nullptr;
46 NodePtr IDom = nullptr;
47 };
48
49 DomTreeT &DT;
50 std::vector NumToNode;
51 DenseMap NodeToInfo;
52
53 SemiNCAInfo(DomTreeT &DT) : DT(DT) {}
54
55 NodePtr getIDom(NodePtr BB) const {
56 auto InfoIt = NodeToInfo.find(BB);
57 if (InfoIt == NodeToInfo.end()) return nullptr;
58
59 return InfoIt->second.IDom;
60 }
61
62 TreeNodePtr getNodeForBlock(NodePtr BB) {
63 if (TreeNodePtr Node = DT.getNode(BB)) return Node;
64
65 // Haven't calculated this node yet? Get or calculate the node for the
66 // immediate dominator.
67 NodePtr IDom = getIDom(BB);
68
69 assert(IDom || DT.DomTreeNodes[nullptr]);
70 TreeNodePtr IDomNode = getNodeForBlock(IDom);
71
72 // Add a new tree node for this NodeT, and link it as a child of
73 // IDomNode
74 return (DT.DomTreeNodes[BB] = IDomNode->addChild(
75 llvm::make_unique>(BB, IDomNode)))
76 .get();
77 }
78 };
79 } // namespace DomTreeBuilder
80
3381 // External storage for depth first iterator that reuses the info lookup map
3482 // domtree already has. We don't have a set, but a map instead, so we are
3583 // converting the one argument insert calls.
4896 BaseSet &Storage;
4997 };
5098
51 template
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);
99 template
100 class NodeT = typename std::remove_pointer::type>
101 unsigned ReverseDFSPass(NodePtr V, DomTreeBuilder::SemiNCAInfo &SNCA,
102 unsigned N) {
103 using SNCAInfoTy = DomTreeBuilder::SemiNCAInfo;
104 df_iterator_dom_storage DFStorage(
105 SNCA.NodeToInfo);
60106
61107 bool IsChildOfArtificialExit = (N != 0);
62108 for (auto I = idf_ext_begin(V, DFStorage), E = idf_ext_end(V, DFStorage);
63109 I != E; ++I) {
64 typename GraphT::NodeRef BB = *I;
110 NodePtr BB = *I;
65111 auto &BBInfo = SNCA.NodeToInfo[BB];
66112 BBInfo.DFSNum = BBInfo.Semi = ++N;
67113 BBInfo.Label = BB;
78124 }
79125 return N;
80126 }
81 template
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);
127
128 template
129 class NodeT = typename std::remove_pointer::type>
130 unsigned DFSPass(NodePtr V, DomTreeBuilder::SemiNCAInfo &SNCA, unsigned N) {
131 using SNCAInfoTy = DomTreeBuilder::SemiNCAInfo;
132 df_iterator_dom_storage DFStorage(
133 SNCA.NodeToInfo);
134
90135 for (auto I = df_ext_begin(V, DFStorage), E = df_ext_end(V, DFStorage);
91136 I != E; ++I) {
92 typename GraphT::NodeRef BB = *I;
137 NodePtr BB = *I;
93138 auto &BBInfo = SNCA.NodeToInfo[BB];
94139 BBInfo.DFSNum = BBInfo.Semi = ++N;
95140 BBInfo.Label = BB;
102147 return N;
103148 }
104149
105 template
106 typename GraphT::NodeRef Eval(
107 DominatorTreeBaseByGraphTraits &DT, typename GraphT::NodeRef VIn,
108 typename DominatorTreeBaseByGraphTraits::SemiNCAInfo &SNCA,
109 unsigned LastLinked) {
110 using NodePtr = typename GraphT::NodeRef;
111
150 template
151 class NodeT = typename std::remove_pointer::type>
152 NodePtr Eval(NodePtr VIn, DomTreeBuilder::SemiNCAInfo &SNCA,
153 unsigned LastLinked) {
112154 auto &VInInfo = SNCA.NodeToInfo[VIn];
113155 if (VInInfo.DFSNum < LastLinked)
114156 return VIn;
152194 using GraphT = GraphTraits;
153195 using NodePtr = typename GraphT::NodeRef;
154196 static_assert(std::is_pointer::value,
155 "NodeRef should be pointer type");
197 "NodePtr should be a pointer type");
156198 using NodeType = typename std::remove_pointer::type;
157199
158200 unsigned N = 0;
159 typename DominatorTreeBaseByGraphTraits::SemiNCAInfo SNCA;
201 DomTreeBuilder::SemiNCAInfo SNCA(DT);
160202 SNCA.NumToNode.push_back(nullptr);
161203
162204 bool MultipleRoots = (DT.Roots.size() > 1);
173215 if (DT.isPostDominator()){
174216 for (unsigned i = 0, e = static_cast(DT.Roots.size());
175217 i != e; ++i)
176 N = ReverseDFSPass<GraphT>(DT, DT.Roots[i], SNCA, N);
218 N = ReverseDFSPass<NodePtr>(DT.Roots[i], SNCA, N);
177219 } else {
178 N = DFSPass<GraphT>(DT, DT.Roots[0], SNCA, N);
220 N = DFSPass<NodePtr>(DT.Roots[0], SNCA, N);
179221 }
180222
181223 // It might be that some blocks did not get a DFS number (e.g., blocks of
198240 WInfo.Semi = WInfo.Parent;
199241 for (const auto &N : inverse_children(W))
200242 if (SNCA.NodeToInfo.count(N)) { // Only if this predecessor is reachable!
201 unsigned SemiU = SNCA.NodeToInfo[Eval<GraphT>(DT, N, SNCA, i + 1)].Semi;
243 unsigned SemiU = SNCA.NodeToInfo[Eval<NodePtr>(N, SNCA, i + 1)].Semi;
202244 if (SemiU < WInfo.Semi)
203245 WInfo.Semi = SemiU;
204246 }
246288 assert(ImmDom || DT.DomTreeNodes[nullptr]);
247289
248290 // Get or calculate the node for the immediate dominator
249 DomTreeNodeBase *IDomNode = DT.getNodeForBlock(ImmDom, SNCA);
291 DomTreeNodeBase *IDomNode = SNCA.getNodeForBlock(ImmDom);
250292
251293 // Add a new tree node for this BasicBlock, and link it as a child of
252294 // IDomNode
256298
257299 DT.updateDFSNumbers();
258300 }
259 }
301 } // namespace DomTreeBuilder
260302
261303 #endif