[llvm-commits] [llvm] r42248 - in /llvm/trunk: include/llvm/Analysis/Dominators.h include/llvm/Analysis/PostDominators.h lib/VMCore/DominatorCalculation.h lib/VMCore/Dominators.cpp
Tanya Lattner
lattner at apple.com
Mon Sep 24 09:42:25 PDT 2007
Owen,
Could you please add doxygen style comments for the new functions you
are adding/moving? Its useful to have comments before the function
describing what it does.
Thanks,
Tanya
On Sep 23, 2007, at 2:31 PM, Owen Anderson wrote:
> Author: resistor
> Date: Sun Sep 23 16:31:44 2007
> New Revision: 42248
>
> URL: http://llvm.org/viewvc/llvm-project?rev=42248&view=rev
> Log:
> Factor the dominator tree calculation details out into
> DominatorCalculation.h. This
> change is not useful in and of itself, but it lays the groundwork
> for combining
> the dominator and postdominator implementations.
>
> Also, factor a few methods that are common to DominatorTree and
> PostDominatorTree
> into DominatorTreeBase. Again, this will make merging the two
> calculation methods
> simpler in the future.
>
> Added:
> llvm/trunk/lib/VMCore/DominatorCalculation.h
> Modified:
> llvm/trunk/include/llvm/Analysis/Dominators.h
> llvm/trunk/include/llvm/Analysis/PostDominators.h
> llvm/trunk/lib/VMCore/Dominators.cpp
>
> Modified: llvm/trunk/include/llvm/Analysis/Dominators.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
> Analysis/Dominators.h?rev=42248&r1=42247&r2=42248&view=diff
>
> ======================================================================
> ========
> --- llvm/trunk/include/llvm/Analysis/Dominators.h (original)
> +++ llvm/trunk/include/llvm/Analysis/Dominators.h Sun Sep 23
> 16:31:44 2007
> @@ -129,6 +129,7 @@
>
> // Info - Collection of information used during the computation
> of idoms.
> DenseMap<BasicBlock*, InfoRec> Info;
> + unsigned DFSPass(BasicBlock *V, unsigned N);
>
> public:
> DominatorTreeBase(intptr_t ID, bool isPostDom)
> @@ -278,6 +279,13 @@
> /// updateDFSNumbers - Assign In and Out numbers to the nodes
> while walking
> /// dominator tree in dfs order.
> void updateDFSNumbers();
> +
> + DomTreeNode *getNodeForBlock(BasicBlock *BB);
> +
> + inline BasicBlock *getIDom(BasicBlock *BB) const {
> + DenseMap<BasicBlock*, BasicBlock*>::const_iterator I =
> IDoms.find(BB);
> + return I != IDoms.end() ? I->second : 0;
> + }
> };
>
> //===-------------------------------------
> @@ -304,17 +312,13 @@
> /// BB is split and now it has one successor. Update dominator
> tree to
> /// reflect this change.
> void splitBlock(BasicBlock *BB);
> +
> private:
> - void calculate(Function& F);
> - DomTreeNode *getNodeForBlock(BasicBlock *BB);
> - unsigned DFSPass(BasicBlock *V, unsigned N);
> - void Compress(BasicBlock *V);
> - BasicBlock *Eval(BasicBlock *v);
> - void Link(BasicBlock *V, BasicBlock *W, InfoRec &WInfo);
> - inline BasicBlock *getIDom(BasicBlock *BB) const {
> - DenseMap<BasicBlock*, BasicBlock*>::const_iterator I =
> IDoms.find(BB);
> - return I != IDoms.end() ? I->second : 0;
> - }
> + friend void DTcalculate(DominatorTree& DT, Function& F);
> + friend void DTCompress(DominatorTree& DT, BasicBlock *VIn);
> + friend BasicBlock *DTEval(DominatorTree& DT, BasicBlock *v);
> + friend void DTLink(DominatorTree& DT, BasicBlock *V,
> + BasicBlock *W, InfoRec &WInfo);
> };
>
> //===-------------------------------------
>
> Modified: llvm/trunk/include/llvm/Analysis/PostDominators.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
> Analysis/PostDominators.h?rev=42248&r1=42247&r2=42248&view=diff
>
> ======================================================================
> ========
> --- llvm/trunk/include/llvm/Analysis/PostDominators.h (original)
> +++ llvm/trunk/include/llvm/Analysis/PostDominators.h Sun Sep 23
> 16:31:44 2007
> @@ -38,16 +38,10 @@
> }
> private:
> void calculate(Function &F);
> - DomTreeNode *getNodeForBlock(BasicBlock *BB);
> unsigned DFSPass(BasicBlock *V, unsigned N);
> void Compress(BasicBlock *V, InfoRec &VInfo);
> BasicBlock *Eval(BasicBlock *V);
> void Link(BasicBlock *V, BasicBlock *W, InfoRec &WInfo);
> -
> - inline BasicBlock *getIDom(BasicBlock *BB) const {
> - DenseMap<BasicBlock*, BasicBlock*>::const_iterator I =
> IDoms.find(BB);
> - return I != IDoms.end() ? I->second : 0;
> - }
> };
>
>
>
> Added: llvm/trunk/lib/VMCore/DominatorCalculation.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/
> DominatorCalculation.h?rev=42248&view=auto
>
> ======================================================================
> ========
> --- llvm/trunk/lib/VMCore/DominatorCalculation.h (added)
> +++ llvm/trunk/lib/VMCore/DominatorCalculation.h Sun Sep 23
> 16:31:44 2007
> @@ -0,0 +1,213 @@
> +//==- llvm/VMCore/DominatorCalculation.h - Dominator Calculation -
> *- C++ -*-==//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file was developed by Owen Anderson and is distributed under
> +// the University of Illinois Open Source License. See LICENSE.TXT
> for details.
> +//
> +//
> ===-------------------------------------------------------------------
> ---===//
> +
> +#ifndef LLVM_VMCORE_DOMINATOR_CALCULATION_H
> +#define LLVM_VMCORE_DOMINATOR_CALCULATION_H
> +
> +#include "llvm/Analysis/Dominators.h"
> +
> +//
> ===-------------------------------------------------------------------
> ---===//
> +//
> +// DominatorTree construction - This pass constructs immediate
> dominator
> +// information for a flow-graph based on the algorithm described
> in this
> +// document:
> +//
> +// A Fast Algorithm for Finding Dominators in a Flowgraph
> +// T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141.
> +//
> +// This implements both the O(n*ack(n)) and the O(n*log(n))
> versions of EVAL and
> +// LINK, but it turns out that the theoretically slower O(n*log(n))
> +// implementation is actually faster than the "efficient"
> algorithm (even for
> +// large CFGs) because the constant overheads are substantially
> smaller. The
> +// lower-complexity version can be enabled with the following
> #define:
> +//
> +#define BALANCE_IDOM_TREE 0
> +//
> +//
> ===-------------------------------------------------------------------
> ---===//
> +
> +namespace llvm {
> +
> +void DTCompress(DominatorTree& DT, BasicBlock *VIn) {
> +
> + std::vector<BasicBlock *> Work;
> + SmallPtrSet<BasicBlock *, 32> Visited;
> + BasicBlock *VInAncestor = DT.Info[VIn].Ancestor;
> + DominatorTree::InfoRec &VInVAInfo = DT.Info[VInAncestor];
> +
> + if (VInVAInfo.Ancestor != 0)
> + Work.push_back(VIn);
> +
> + while (!Work.empty()) {
> + BasicBlock *V = Work.back();
> + DominatorTree::InfoRec &VInfo = DT.Info[V];
> + BasicBlock *VAncestor = VInfo.Ancestor;
> + DominatorTree::InfoRec &VAInfo = DT.Info[VAncestor];
> +
> + // Process Ancestor first
> + if (Visited.insert(VAncestor) &&
> + VAInfo.Ancestor != 0) {
> + Work.push_back(VAncestor);
> + continue;
> + }
> + Work.pop_back();
> +
> + // Update VInfo based on Ancestor info
> + if (VAInfo.Ancestor == 0)
> + continue;
> + BasicBlock *VAncestorLabel = VAInfo.Label;
> + BasicBlock *VLabel = VInfo.Label;
> + if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi)
> + VInfo.Label = VAncestorLabel;
> + VInfo.Ancestor = VAInfo.Ancestor;
> + }
> +}
> +
> +BasicBlock *DTEval(DominatorTree& DT, BasicBlock *V) {
> + DominatorTree::InfoRec &VInfo = DT.Info[V];
> +#if !BALANCE_IDOM_TREE
> + // Higher-complexity but faster implementation
> + if (VInfo.Ancestor == 0)
> + return V;
> + DTCompress(DT, V);
> + return VInfo.Label;
> +#else
> + // Lower-complexity but slower implementation
> + if (VInfo.Ancestor == 0)
> + return VInfo.Label;
> + DTCompress(DT, V);
> + BasicBlock *VLabel = VInfo.Label;
> +
> + BasicBlock *VAncestorLabel = DT.Info[VInfo.Ancestor].Label;
> + if (DT.Info[VAncestorLabel].Semi >= DT.Info[VLabel].Semi)
> + return VLabel;
> + else
> + return VAncestorLabel;
> +#endif
> +}
> +
> +void DTLink(DominatorTree& DT, BasicBlock *V, BasicBlock *W,
> + DominatorTree::InfoRec &WInfo) {
> +#if !BALANCE_IDOM_TREE
> + // Higher-complexity but faster implementation
> + WInfo.Ancestor = V;
> +#else
> + // Lower-complexity but slower implementation
> + BasicBlock *WLabel = WInfo.Label;
> + unsigned WLabelSemi = Info[WLabel].Semi;
> + BasicBlock *S = W;
> + InfoRec *SInfo = &Info[S];
> +
> + BasicBlock *SChild = SInfo->Child;
> + InfoRec *SChildInfo = &Info[SChild];
> +
> + while (WLabelSemi < Info[SChildInfo->Label].Semi) {
> + BasicBlock *SChildChild = SChildInfo->Child;
> + if (SInfo->Size+Info[SChildChild].Size >= 2*SChildInfo->Size) {
> + SChildInfo->Ancestor = S;
> + SInfo->Child = SChild = SChildChild;
> + SChildInfo = &Info[SChild];
> + } else {
> + SChildInfo->Size = SInfo->Size;
> + S = SInfo->Ancestor = SChild;
> + SInfo = SChildInfo;
> + SChild = SChildChild;
> + SChildInfo = &Info[SChild];
> + }
> + }
> +
> + InfoRec &VInfo = Info[V];
> + SInfo->Label = WLabel;
> +
> + assert(V != W && "The optimization here will not work in this
> case!");
> + unsigned WSize = WInfo.Size;
> + unsigned VSize = (VInfo.Size += WSize);
> +
> + if (VSize < 2*WSize)
> + std::swap(S, VInfo.Child);
> +
> + while (S) {
> + SInfo = &Info[S];
> + SInfo->Ancestor = V;
> + S = SInfo->Child;
> + }
> +#endif
> +}
> +
> +void DTcalculate(DominatorTree& DT, Function &F) {
> + BasicBlock* Root = DT.Roots[0];
> +
> + // Add a node for the root...
> + DT.DomTreeNodes[Root] = DT.RootNode = new DomTreeNode(Root, 0);
> +
> + DT.Vertex.push_back(0);
> +
> + // Step #1: Number blocks in depth-first order and initialize
> variables used
> + // in later stages of the algorithm.
> + unsigned N = DT.DFSPass(Root, 0);
> +
> + for (unsigned i = N; i >= 2; --i) {
> + BasicBlock *W = DT.Vertex[i];
> + DominatorTree::InfoRec &WInfo = DT.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 (DT.Info.count(*PI)) { // Only if this predecessor is
> reachable!
> + unsigned SemiU = DT.Info[DTEval(DT, *PI)].Semi;
> + if (SemiU < WInfo.Semi)
> + WInfo.Semi = SemiU;
> + }
> +
> + DT.Info[DT.Vertex[WInfo.Semi]].Bucket.push_back(W);
> +
> + BasicBlock *WParent = WInfo.Parent;
> + DTLink(DT, WParent, W, WInfo);
> +
> + // Step #3: Implicitly define the immediate dominator of vertices
> + std::vector<BasicBlock*> &WParentBucket = DT.Info
> [WParent].Bucket;
> + while (!WParentBucket.empty()) {
> + BasicBlock *V = WParentBucket.back();
> + WParentBucket.pop_back();
> + BasicBlock *U = DTEval(DT, V);
> + DT.IDoms[V] = DT.Info[U].Semi < DT.Info[V].Semi ? U : WParent;
> + }
> + }
> +
> + // Step #4: Explicitly define the immediate dominator of each
> vertex
> + for (unsigned i = 2; i <= N; ++i) {
> + BasicBlock *W = DT.Vertex[i];
> + BasicBlock *&WIDom = DT.IDoms[W];
> + if (WIDom != DT.Vertex[DT.Info[W].Semi])
> + WIDom = DT.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 = DT.getIDom(I)) { // Reachable block.
> + DomTreeNode *BBNode = DT.DomTreeNodes[I];
> + if (BBNode) continue; // Haven't calculated this node yet?
> +
> + // Get or calculate the node for the immediate dominator
> + DomTreeNode *IDomNode = DT.getNodeForBlock(ImmDom);
> +
> + // Add a new tree node for this BasicBlock, and link it as a
> child of
> + // IDomNode
> + DomTreeNode *C = new DomTreeNode(I, IDomNode);
> + DT.DomTreeNodes[I] = IDomNode->addChild(C);
> + }
> +
> + // Free temporary memory used to construct idom's
> + DT.Info.clear();
> + DT.IDoms.clear();
> + std::vector<BasicBlock*>().swap(DT.Vertex);
> +
> + DT.updateDFSNumbers();
> +}
> +
> +}
> +#endif
> \ No newline at end of file
>
> Modified: llvm/trunk/lib/VMCore/Dominators.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/
> Dominators.cpp?rev=42248&r1=42247&r2=42248&view=diff
>
> ======================================================================
> ========
> --- llvm/trunk/lib/VMCore/Dominators.cpp (original)
> +++ llvm/trunk/lib/VMCore/Dominators.cpp Sun Sep 23 16:31:44 2007
> @@ -23,6 +23,7 @@
> #include "llvm/ADT/SmallVector.h"
> #include "llvm/Instructions.h"
> #include "llvm/Support/Streams.h"
> +#include "DominatorCalculation.h"
> #include <algorithm>
> using namespace llvm;
>
> @@ -43,20 +44,8 @@
> // DominatorTree Implementation
> //
> ===-------------------------------------------------------------------
> ---===//
> //
> -// DominatorTree construction - This pass constructs immediate
> dominator
> -// information for a flow-graph based on the algorithm described
> in this
> -// document:
> -//
> -// A Fast Algorithm for Finding Dominators in a Flowgraph
> -// T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141.
> -//
> -// This implements both the O(n*ack(n)) and the O(n*log(n))
> versions of EVAL and
> -// LINK, but it turns out that the theoretically slower O(n*log(n))
> -// implementation is actually faster than the "efficient"
> algorithm (even for
> -// large CFGs) because the constant overheads are substantially
> smaller. The
> -// lower-complexity version can be enabled with the following
> #define:
> -//
> -#define BALANCE_IDOM_TREE 0
> +// Provide public access to DominatorTree information.
> Implementation details
> +// can be found in DominatorCalculation.h.
> //
> //
> ===-------------------------------------------------------------------
> ---===//
>
> @@ -64,6 +53,68 @@
> static RegisterPass<DominatorTree>
> E("domtree", "Dominator Tree Construction", true);
>
> +unsigned DominatorTreeBase::DFSPass(BasicBlock *V, unsigned N) {
> + // This is more understandable as a recursive algorithm, but we
> can't use the
> + // recursive algorithm due to stack depth issues. Keep it here for
> + // documentation purposes.
> +#if 0
> + InfoRec &VInfo = Info[Roots[i]];
> + VInfo.Semi = ++N;
> + VInfo.Label = V;
> +
> + Vertex.push_back(V); // Vertex[n] = V;
> + //Info[V].Ancestor = 0; // Ancestor[n] = 0
> + //Info[V].Child = 0; // Child[v] = 0
> + VInfo.Size = 1; // Size[v] = 1
> +
> + for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E;
> ++SI) {
> + InfoRec &SuccVInfo = Info[*SI];
> + if (SuccVInfo.Semi == 0) {
> + SuccVInfo.Parent = V;
> + N = DFSPass(*SI, N);
> + }
> + }
> +#else
> + std::vector<std::pair<BasicBlock*, unsigned> > Worklist;
> + Worklist.push_back(std::make_pair(V, 0U));
> + while (!Worklist.empty()) {
> + BasicBlock *BB = Worklist.back().first;
> + unsigned NextSucc = Worklist.back().second;
> +
> + // First time we visited this BB?
> + if (NextSucc == 0) {
> + InfoRec &BBInfo = Info[BB];
> + BBInfo.Semi = ++N;
> + BBInfo.Label = BB;
> +
> + Vertex.push_back(BB); // Vertex[n] = V;
> + //BBInfo[V].Ancestor = 0; // Ancestor[n] = 0
> + //BBInfo[V].Child = 0; // Child[v] = 0
> + BBInfo.Size = 1; // Size[v] = 1
> + }
> +
> + // If we are done with this block, remove it from the worklist.
> + if (NextSucc == BB->getTerminator()->getNumSuccessors()) {
> + Worklist.pop_back();
> + continue;
> + }
> +
> + // Otherwise, increment the successor number for the next time
> we get to it.
> + ++Worklist.back().second;
> +
> + // Visit the successor next, if it isn't already visited.
> + BasicBlock *Succ = BB->getTerminator()->getSuccessor(NextSucc);
> +
> + InfoRec &SuccVInfo = Info[Succ];
> + if (SuccVInfo.Semi == 0) {
> + SuccVInfo.Parent = BB;
> + Worklist.push_back(std::make_pair(Succ, 0U));
> + }
> + }
> +#endif
> + return N;
> +}
> +
> // NewBB is split and now it has one successor. Update dominator
> tree to
> // reflect this change.
> void DominatorTree::splitBlock(BasicBlock *NewBB) {
> @@ -146,243 +197,6 @@
> }
> }
>
> -unsigned DominatorTree::DFSPass(BasicBlock *V, unsigned N) {
> - // This is more understandable as a recursive algorithm, but we
> can't use the
> - // recursive algorithm due to stack depth issues. Keep it here for
> - // documentation purposes.
> -#if 0
> - InfoRec &VInfo = Info[Roots[i]];
> - VInfo.Semi = ++N;
> - VInfo.Label = V;
> -
> - Vertex.push_back(V); // Vertex[n] = V;
> - //Info[V].Ancestor = 0; // Ancestor[n] = 0
> - //Info[V].Child = 0; // Child[v] = 0
> - VInfo.Size = 1; // Size[v] = 1
> -
> - for (succ_iterator SI = succ_begin(V), E = succ_end(V); SI != E;
> ++SI) {
> - InfoRec &SuccVInfo = Info[*SI];
> - if (SuccVInfo.Semi == 0) {
> - SuccVInfo.Parent = V;
> - N = DFSPass(*SI, N);
> - }
> - }
> -#else
> - std::vector<std::pair<BasicBlock*, unsigned> > Worklist;
> - Worklist.push_back(std::make_pair(V, 0U));
> - while (!Worklist.empty()) {
> - BasicBlock *BB = Worklist.back().first;
> - unsigned NextSucc = Worklist.back().second;
> -
> - // First time we visited this BB?
> - if (NextSucc == 0) {
> - InfoRec &BBInfo = Info[BB];
> - BBInfo.Semi = ++N;
> - BBInfo.Label = BB;
> -
> - Vertex.push_back(BB); // Vertex[n] = V;
> - //BBInfo[V].Ancestor = 0; // Ancestor[n] = 0
> - //BBInfo[V].Child = 0; // Child[v] = 0
> - BBInfo.Size = 1; // Size[v] = 1
> - }
> -
> - // If we are done with this block, remove it from the worklist.
> - if (NextSucc == BB->getTerminator()->getNumSuccessors()) {
> - Worklist.pop_back();
> - continue;
> - }
> -
> - // Otherwise, increment the successor number for the next time
> we get to it.
> - ++Worklist.back().second;
> -
> - // Visit the successor next, if it isn't already visited.
> - BasicBlock *Succ = BB->getTerminator()->getSuccessor(NextSucc);
> -
> - InfoRec &SuccVInfo = Info[Succ];
> - if (SuccVInfo.Semi == 0) {
> - SuccVInfo.Parent = BB;
> - Worklist.push_back(std::make_pair(Succ, 0U));
> - }
> - }
> -#endif
> - return N;
> -}
> -
> -void DominatorTree::Compress(BasicBlock *VIn) {
> -
> - std::vector<BasicBlock *> Work;
> - SmallPtrSet<BasicBlock *, 32> Visited;
> - BasicBlock *VInAncestor = Info[VIn].Ancestor;
> - InfoRec &VInVAInfo = Info[VInAncestor];
> -
> - if (VInVAInfo.Ancestor != 0)
> - Work.push_back(VIn);
> -
> - while (!Work.empty()) {
> - BasicBlock *V = Work.back();
> - InfoRec &VInfo = Info[V];
> - BasicBlock *VAncestor = VInfo.Ancestor;
> - InfoRec &VAInfo = Info[VAncestor];
> -
> - // Process Ancestor first
> - if (Visited.insert(VAncestor) &&
> - VAInfo.Ancestor != 0) {
> - Work.push_back(VAncestor);
> - continue;
> - }
> - Work.pop_back();
> -
> - // Update VInfo based on Ancestor info
> - if (VAInfo.Ancestor == 0)
> - continue;
> - BasicBlock *VAncestorLabel = VAInfo.Label;
> - BasicBlock *VLabel = VInfo.Label;
> - if (Info[VAncestorLabel].Semi < Info[VLabel].Semi)
> - VInfo.Label = VAncestorLabel;
> - VInfo.Ancestor = VAInfo.Ancestor;
> - }
> -}
> -
> -BasicBlock *DominatorTree::Eval(BasicBlock *V) {
> - InfoRec &VInfo = Info[V];
> -#if !BALANCE_IDOM_TREE
> - // Higher-complexity but faster implementation
> - if (VInfo.Ancestor == 0)
> - return V;
> - Compress(V);
> - return VInfo.Label;
> -#else
> - // Lower-complexity but slower implementation
> - if (VInfo.Ancestor == 0)
> - return VInfo.Label;
> - Compress(V);
> - BasicBlock *VLabel = VInfo.Label;
> -
> - BasicBlock *VAncestorLabel = Info[VInfo.Ancestor].Label;
> - if (Info[VAncestorLabel].Semi >= Info[VLabel].Semi)
> - return VLabel;
> - else
> - return VAncestorLabel;
> -#endif
> -}
> -
> -void DominatorTree::Link(BasicBlock *V, BasicBlock *W, InfoRec
> &WInfo){
> -#if !BALANCE_IDOM_TREE
> - // Higher-complexity but faster implementation
> - WInfo.Ancestor = V;
> -#else
> - // Lower-complexity but slower implementation
> - BasicBlock *WLabel = WInfo.Label;
> - unsigned WLabelSemi = Info[WLabel].Semi;
> - BasicBlock *S = W;
> - InfoRec *SInfo = &Info[S];
> -
> - BasicBlock *SChild = SInfo->Child;
> - InfoRec *SChildInfo = &Info[SChild];
> -
> - while (WLabelSemi < Info[SChildInfo->Label].Semi) {
> - BasicBlock *SChildChild = SChildInfo->Child;
> - if (SInfo->Size+Info[SChildChild].Size >= 2*SChildInfo->Size) {
> - SChildInfo->Ancestor = S;
> - SInfo->Child = SChild = SChildChild;
> - SChildInfo = &Info[SChild];
> - } else {
> - SChildInfo->Size = SInfo->Size;
> - S = SInfo->Ancestor = SChild;
> - SInfo = SChildInfo;
> - SChild = SChildChild;
> - SChildInfo = &Info[SChild];
> - }
> - }
> -
> - InfoRec &VInfo = Info[V];
> - SInfo->Label = WLabel;
> -
> - assert(V != W && "The optimization here will not work in this
> case!");
> - unsigned WSize = WInfo.Size;
> - unsigned VSize = (VInfo.Size += WSize);
> -
> - if (VSize < 2*WSize)
> - std::swap(S, VInfo.Child);
> -
> - while (S) {
> - SInfo = &Info[S];
> - SInfo->Ancestor = V;
> - S = SInfo->Child;
> - }
> -#endif
> -}
> -
> -void DominatorTree::calculate(Function &F) {
> - BasicBlock* Root = Roots[0];
> -
> - // Add a node for the root...
> - DomTreeNodes[Root] = RootNode = new DomTreeNode(Root, 0);
> -
> - Vertex.push_back(0);
> -
> - // Step #1: Number blocks in depth-first order and initialize
> variables used
> - // in later stages of the algorithm.
> - unsigned N = DFSPass(Root, 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.
> - DomTreeNode *BBNode = DomTreeNodes[I];
> - if (BBNode) continue; // Haven't calculated this node yet?
> -
> - // Get or calculate the node for the immediate dominator
> - DomTreeNode *IDomNode = getNodeForBlock(ImmDom);
> -
> - // Add a new tree node for this BasicBlock, and link it as a
> child of
> - // IDomNode
> - DomTreeNode *C = new DomTreeNode(I, IDomNode);
> - DomTreeNodes[I] = IDomNode->addChild(C);
> - }
> -
> - // Free temporary memory used to construct idom's
> - Info.clear();
> - IDoms.clear();
> - std::vector<BasicBlock*>().swap(Vertex);
> -
> - updateDFSNumbers();
> -}
> -
> void DominatorTreeBase::updateDFSNumbers() {
> unsigned DFSNum = 0;
>
> @@ -462,6 +276,21 @@
> RootNode = 0;
> }
>
> +DomTreeNode *DominatorTreeBase::getNodeForBlock(BasicBlock *BB) {
> + if (DomTreeNode *BBNode = DomTreeNodes[BB])
> + return BBNode;
> +
> + // Haven't calculated this node yet? Get or calculate the node
> for the
> + // immediate dominator.
> + BasicBlock *IDom = getIDom(BB);
> + DomTreeNode *IDomNode = getNodeForBlock(IDom);
> +
> + // Add a new tree node for this BasicBlock, and link it as a
> child of
> + // IDomNode
> + DomTreeNode *C = new DomTreeNode(BB, IDomNode);
> + return DomTreeNodes[BB] = IDomNode->addChild(C);
> +}
> +
> /// findNearestCommonDominator - Find nearest common dominator
> basic block
> /// for basic block A and B. If there is no such block then return
> NULL.
> BasicBlock *DominatorTreeBase::findNearestCommonDominator
> (BasicBlock *A,
> @@ -525,21 +354,6 @@
> }
> }
>
> -DomTreeNode *DominatorTree::getNodeForBlock(BasicBlock *BB) {
> - if (DomTreeNode *BBNode = DomTreeNodes[BB])
> - return BBNode;
> -
> - // Haven't calculated this node yet? Get or calculate the node
> for the
> - // immediate dominator.
> - BasicBlock *IDom = getIDom(BB);
> - DomTreeNode *IDomNode = getNodeForBlock(IDom);
> -
> - // Add a new tree node for this BasicBlock, and link it as a
> child of
> - // IDomNode
> - DomTreeNode *C = new DomTreeNode(BB, IDomNode);
> - return DomTreeNodes[BB] = IDomNode->addChild(C);
> -}
> -
> static std::ostream &operator<<(std::ostream &o, const DomTreeNode
> *Node) {
> if (Node->getBlock())
> WriteAsOperand(o, Node->getBlock(), false);
> @@ -599,7 +413,7 @@
> bool DominatorTree::runOnFunction(Function &F) {
> reset(); // Reset from the last time we were run...
> Roots.push_back(&F.getEntryBlock());
> - calculate(F);
> + DTcalculate(*this, F);
> return false;
> }
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list