-void DominatorTree::calculate(Function& F) {
- BasicBlock* Root = Roots[0];
-
- Nodes[Root] = RootNode = new Node(Root, 0); // Add a node for the root...
-
- Vertex.push_back(0);
-
- // Step #1: Number blocks in depth-first order and initialize variables used
- // in later stages of the algorithm.
- unsigned N = 0;
- for (unsigned i = 0, e = Roots.size(); i != e; ++i)
- N = DFSPass(Roots[i], Info[Roots[i]], 0);
-
- for (unsigned i = N; i >= 2; --i) {
- BasicBlock *W = Vertex[i];
- InfoRec &WInfo = Info[W];
-
- // Step #2: Calculate the semidominators of all vertices
- for (pred_iterator PI = pred_begin(W), E = pred_end(W); PI != E; ++PI)
- if (Info.count(*PI)) { // Only if this predecessor is reachable!
- unsigned SemiU = Info[Eval(*PI)].Semi;
- if (SemiU < WInfo.Semi)
- WInfo.Semi = SemiU;
- }
-
- Info[Vertex[WInfo.Semi]].Bucket.push_back(W);
-
- BasicBlock *WParent = WInfo.Parent;
- Link(WParent, W, WInfo);
-
- // Step #3: Implicitly define the immediate dominator of vertices
- std::vector<BasicBlock*> &WParentBucket = Info[WParent].Bucket;
- while (!WParentBucket.empty()) {
- BasicBlock *V = WParentBucket.back();
- WParentBucket.pop_back();
- BasicBlock *U = Eval(V);
- IDoms[V] = Info[U].Semi < Info[V].Semi ? U : WParent;
- }
- }
-
- // Step #4: Explicitly define the immediate dominator of each vertex
- for (unsigned i = 2; i <= N; ++i) {
- BasicBlock *W = Vertex[i];
- BasicBlock *&WIDom = IDoms[W];
- if (WIDom != Vertex[Info[W].Semi])
- WIDom = IDoms[WIDom];
- }
-
- // Loop over all of the reachable blocks in the function...
- for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I)
- if (BasicBlock *ImmDom = getIDom(I)) { // Reachable block.
- Node *&BBNode = Nodes[I];
- if (!BBNode) { // Haven't calculated this node yet?
- // Get or calculate the node for the immediate dominator
- Node *IDomNode = getNodeForBlock(ImmDom);
-
- // Add a new tree node for this BasicBlock, and link it as a child of
- // IDomNode
- BBNode = IDomNode->addChild(new Node(I, IDomNode));
- }
- }
-
- // Free temporary memory used to construct idom's
- Info.clear();
- IDoms.clear();
- std::vector<BasicBlock*>().swap(Vertex);
-}
-
-// DominatorTreeBase::reset - Free all of the tree node memory.
-//
-void DominatorTreeBase::reset() {
- for (NodeMapType::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I)
- delete I->second;
- Nodes.clear();
- IDoms.clear();
- Roots.clear();
- Vertex.clear();
- RootNode = 0;
-}
-
-void DominatorTreeBase::Node::setIDom(Node *NewIDom) {
- assert(IDom && "No immediate dominator?");
- if (IDom != NewIDom) {
- std::vector<Node*>::iterator I =
- std::find(IDom->Children.begin(), IDom->Children.end(), this);
- assert(I != IDom->Children.end() &&
- "Not in immediate dominator children set!");
- // I am no longer your child...
- IDom->Children.erase(I);
-
- // Switch to new dominator
- IDom = NewIDom;
- IDom->Children.push_back(this);
- }
-}
-
-DominatorTreeBase::Node *DominatorTree::getNodeForBlock(BasicBlock *BB) {
- Node *&BBNode = Nodes[BB];
- if (BBNode) return BBNode;
-
- // Haven't calculated this node yet? Get or calculate the node for the
- // immediate dominator.
- BasicBlock *IDom = getIDom(BB);
- Node *IDomNode = getNodeForBlock(IDom);
-
- // Add a new tree node for this BasicBlock, and link it as a child of
- // IDomNode
- return BBNode = IDomNode->addChild(new Node(BB, IDomNode));
-}
-
-static std::ostream &operator<<(std::ostream &o,
- const DominatorTreeBase::Node *Node) {
- if (Node->getBlock())
- WriteAsOperand(o, Node->getBlock(), false);
- else
- o << " <<exit node>>";
- return o << "\n";
-}
-
-static void PrintDomTree(const DominatorTreeBase::Node *N, std::ostream &o,
- unsigned Lev) {
- o << std::string(2*Lev, ' ') << "[" << Lev << "] " << N;
- for (DominatorTreeBase::Node::const_iterator I = N->begin(), E = N->end();
- I != E; ++I)
- PrintDomTree(*I, o, Lev+1);
-}
-
-void DominatorTreeBase::print(std::ostream &o, const Module* ) const {
- o << "=============================--------------------------------\n"
- << "Inorder Dominator Tree:\n";
- PrintDomTree(getRootNode(), o, 1);
-}