dsa算法(17)
1.3.2.2.3.Lengauer-Tarjan算法第四步
在第四步,240行的DT.Vertex[i]得到的是序號為i的節點。如果DT.IDoms中的節點與Semi所指的節點不一致(即直接支配者節點與半支配者節點不一致),把DT.IDoms調整為DT.IDoms[DT.IDoms[W]]。因為推論1中,當sdom(w) != sdom(v)時,Idom(w) = Idom(v),第三步并沒有計算該部分,這由第四步來完成,并且239行的循環從靠近樹根處開始,以確保DT.IDoms[DT.IDoms[W]]一定有意義。
?
Calculate(續)
?
238??? ? // Step #4:Explicitly define the immediate dominator of ea ch vertex
239??? ? for (unsignedi = 2; i <= N; ++i) {
240??? ??? typenameGraphT::NodeType* W = DT.Vertex[i];
241??? ??? typenameGraphT::NodeType*& WIDom = DT.IDoms[W];
242??? ??? if (WIDom != DT.Vertex[DT.Info[W].Semi])
243??? ????? WIDom = DT.IDoms[WIDom];
244??? ? }
245???
246??? ? if (DT.Roots.empty()) return;
247???
248??? ? // Add a node forthe root.? This node might be the actualroot, if there is
249??? ? // one exit block,or it may be the virtual exit (denoted by (BasicBlock *)0)
250??? ? // which postdominates all real exits ifthere are multiple exit blocks, or
251??? ? // an infiniteloop.
252??? ? typenameGraphT::NodeType* Root = !MultipleRoots ? DT.Roots[0] : 0;
253???
254??? ? DT.DomTreeNodes[Root] = DT.RootNode =
255??? ??????????????????????? new DomTreeNodeBase<typenameGraphT::NodeType>(Root, 0);
256???
257??? ? // Loop over all ofthe reachable blocks in the function...
258??? ? for (unsignedi = 2; i <= N; ++i) {
259??? ??? typenameGraphT::NodeType* W = DT.Vertex[i];
260???
261??? ??? DomTreeNodeBase<typenameGraphT::NodeType> *BBNode = DT.DomTreeNodes[W];
262??? ??? if (BBNode) continue;? // Haven'tcalculated this node yet?
263???
264??? ??? typenameGraphT::NodeType* ImmDom = DT.getIDom(W);
265???
266??? ??? assert(ImmDom|| DT.DomTreeNodes[NULL]);
267???
268??? ??? // Get orcalculate the node for the immediate dominator
269??? ??? DomTreeNodeBase<typenameGraphT::NodeType> *IDomNode =
270??? ????????????????????????????????????????????????????DT.getNodeForBlock(ImmDom);
271???
272??? ??? // Add a new treenode for this BasicBlock, and link it as a child of
273??? ??? // IDomNode
274??? ??? DomTreeNodeBase<typenameGraphT::NodeType> *C =
275??? ??????????????????? newDomTreeNodeBase<typenameGraphT::NodeType>(W, IDomNode);
276??? ??? DT.DomTreeNodes[W] = IDomNode->addChild(C);
277??? ? }
278???
279??? ? // Free temporarymemory used to construct idom's
280??? ? DT.IDoms.clear();
281??? ? DT.Info.clear();
282??? ? std::vector<typenameGraphT::NodeType*>().swap(DT.Vertex);
283???
284??? ? DT.updateDFSNumbers();
285??? }
?
余下的代碼則是構建一棵支配樹(dominator tree)。我們例子的支配樹如下圖所示。
284行的updateDFSNumbers函數以深度優先序遍歷配置樹,對DomTreeNodeBase中的DFSNumIn及DFSNumOut域賦值。
?
579??? ? void updateDFSNumbers(){
580??? ??? unsigned DFSNum = 0;
581???
582??? ??? SmallVector<std::pair<DomTreeNodeBase<NodeT>*,
583??? ??????????????? typenameDomTreeNodeBase<NodeT>::iterator>, 32> WorkStack;
584???
585??? ??? DomTreeNodeBase<NodeT> *ThisRoot =getRootNode();
586???
587??? ??? if (!ThisRoot)
588??? ????? return;
589???
590??? ??? // Even in thecase of multiple exits that form the post dominator root
591??? ??? // nodes, do notiterate over all exits, but start from the virtual root
592??? ??? // node.Otherwise bbs, that are not post dominated by any exit but by the
593??? ??? // virtual rootnode, will never be assigned a DFS number.
594??? ???WorkStack.push_back(std::make_pair(ThisRoot, ThisRoot->begin()));
595??? ??? ThisRoot->DFSNumIn = DFSNum++;
596???
597??? ??? while(!WorkStack.empty()) {
598??? ????? DomTreeNodeBase<NodeT> *Node =WorkStack.back().first;
599??? ????? typename DomTreeNodeBase<NodeT>::iteratorChildIt =
600??? ??????? WorkStack.back().second;
601???
602??? ????? // If wevisited all of the children of this node, "recurse" back up the
603??? ????? // stacksetting the DFOutNum.
604??? ????? if (ChildIt == Node->end()) {
605??? ??????? Node->DFSNumOut = DFSNum++;
606??? ??????? WorkStack.pop_back();
607??? ????? } else {
608??? ??????? // Otherwise,recursively visit this child.
609??? ??????? DomTreeNodeBase<NodeT> *Child =*ChildIt;
610??? ??????? ++WorkStack.back().second;
611???
612??? ??????? WorkStack.push_back(std::make_pair(Child,Child->begin()));
613??? ??????? Child->DFSNumIn = DFSNum++;
614??? ????? }
615??? ??? }
616???
617??? ??? SlowQueries = 0;
618??? ??? DFSInfoValid = true;
619??? ? }
?
編號的結果如上圖所示。注意DT是DominatorTree中的成員,因此這些內容可以帶到下一個遍使用。
總結
- 上一篇: 单片机无线调试-看见心跳-手机显示心率波
- 下一篇: app端分页 简单的分页 java