在第四步,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中的成员,因此这些内容可以带到下一个遍使用。