Have PostDomTree use the newly templated DFSPass.
[oota-llvm.git] / lib / VMCore / DominatorInternals.cpp
1 //==- DominatorInternals.cpp - Dominator Calculation -------------*- C++ -*-==//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Owen Anderson and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "llvm/Analysis/Dominators.h"
11 #include "llvm/ADT/DenseMap.h"
12 #include "llvm/ADT/SmallPtrSet.h"
13 //===----------------------------------------------------------------------===//
14 //
15 // DominatorTree construction - This pass constructs immediate dominator
16 // information for a flow-graph based on the algorithm described in this
17 // document:
18 //
19 //   A Fast Algorithm for Finding Dominators in a Flowgraph
20 //   T. Lengauer & R. Tarjan, ACM TOPLAS July 1979, pgs 121-141.
21 //
22 // This implements both the O(n*ack(n)) and the O(n*log(n)) versions of EVAL and
23 // LINK, but it turns out that the theoretically slower O(n*log(n))
24 // implementation is actually faster than the "efficient" algorithm (even for
25 // large CFGs) because the constant overheads are substantially smaller.  The
26 // lower-complexity version can be enabled with the following #define:
27 //
28 #define BALANCE_IDOM_TREE 0
29 //
30 //===----------------------------------------------------------------------===//
31
32 namespace llvm {
33
34 void Compress(DominatorTreeBase& DT, BasicBlock *VIn) {
35
36   std::vector<BasicBlock *> Work;
37   SmallPtrSet<BasicBlock *, 32> Visited;
38   BasicBlock *VInAncestor = DT.Info[VIn].Ancestor;
39   DominatorTreeBase::InfoRec &VInVAInfo = DT.Info[VInAncestor];
40
41   if (VInVAInfo.Ancestor != 0)
42     Work.push_back(VIn);
43   
44   while (!Work.empty()) {
45     BasicBlock *V = Work.back();
46     DominatorTree::InfoRec &VInfo = DT.Info[V];
47     BasicBlock *VAncestor = VInfo.Ancestor;
48     DominatorTreeBase::InfoRec &VAInfo = DT.Info[VAncestor];
49
50     // Process Ancestor first
51     if (Visited.insert(VAncestor) &&
52         VAInfo.Ancestor != 0) {
53       Work.push_back(VAncestor);
54       continue;
55     } 
56     Work.pop_back(); 
57
58     // Update VInfo based on Ancestor info
59     if (VAInfo.Ancestor == 0)
60       continue;
61     BasicBlock *VAncestorLabel = VAInfo.Label;
62     BasicBlock *VLabel = VInfo.Label;
63     if (DT.Info[VAncestorLabel].Semi < DT.Info[VLabel].Semi)
64       VInfo.Label = VAncestorLabel;
65     VInfo.Ancestor = VAInfo.Ancestor;
66   }
67 }
68
69 BasicBlock *Eval(DominatorTreeBase& DT, BasicBlock *V) {
70                  DominatorTreeBase::InfoRec &VInfo = DT.Info[V];
71 #if !BALANCE_IDOM_TREE
72   // Higher-complexity but faster implementation
73   if (VInfo.Ancestor == 0)
74     return V;
75   Compress(DT, V);
76   return VInfo.Label;
77 #else
78   // Lower-complexity but slower implementation
79   if (VInfo.Ancestor == 0)
80     return VInfo.Label;
81   Compress(DT, V);
82   BasicBlock *VLabel = VInfo.Label;
83
84   BasicBlock *VAncestorLabel = DT.Info[VInfo.Ancestor].Label;
85   if (DT.Info[VAncestorLabel].Semi >= DT.Info[VLabel].Semi)
86     return VLabel;
87   else
88     return VAncestorLabel;
89 #endif
90 }
91
92 void Link(DominatorTreeBase& DT, BasicBlock *V, BasicBlock *W,
93           DominatorTreeBase::InfoRec &WInfo) {
94 #if !BALANCE_IDOM_TREE
95   // Higher-complexity but faster implementation
96   WInfo.Ancestor = V;
97 #else
98   // Lower-complexity but slower implementation
99   BasicBlock *WLabel = WInfo.Label;
100   unsigned WLabelSemi = DT.Info[WLabel].Semi;
101   BasicBlock *S = W;
102   InfoRec *SInfo = &DT.Info[S];
103
104   BasicBlock *SChild = SInfo->Child;
105   InfoRec *SChildInfo = &DT.Info[SChild];
106
107   while (WLabelSemi < DT.Info[SChildInfo->Label].Semi) {
108     BasicBlock *SChildChild = SChildInfo->Child;
109     if (SInfo->Size+DT.Info[SChildChild].Size >= 2*SChildInfo->Size) {
110       SChildInfo->Ancestor = S;
111       SInfo->Child = SChild = SChildChild;
112       SChildInfo = &DT.Info[SChild];
113     } else {
114       SChildInfo->Size = SInfo->Size;
115       S = SInfo->Ancestor = SChild;
116       SInfo = SChildInfo;
117       SChild = SChildChild;
118       SChildInfo = &DT.Info[SChild];
119     }
120   }
121
122   DominatorTreeBase::InfoRec &VInfo = DT.Info[V];
123   SInfo->Label = WLabel;
124
125   assert(V != W && "The optimization here will not work in this case!");
126   unsigned WSize = WInfo.Size;
127   unsigned VSize = (VInfo.Size += WSize);
128
129   if (VSize < 2*WSize)
130     std::swap(S, VInfo.Child);
131
132   while (S) {
133     SInfo = &DT.Info[S];
134     SInfo->Ancestor = V;
135     S = SInfo->Child;
136   }
137 #endif
138 }
139
140 }