| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 1 | //===- DominatorSet.cpp - Dominator Set Calculation --------------*- C++ -*--=// | 
|  | 2 | // | 
|  | 3 | // This file provides a simple class to calculate the dominator set of a method. | 
|  | 4 | // | 
|  | 5 | //===----------------------------------------------------------------------===// | 
|  | 6 |  | 
|  | 7 | #include "llvm/Analysis/Dominators.h" | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 8 | #include "llvm/Transforms/UnifyMethodExitNodes.h" | 
| Chris Lattner | 3ff4387 | 2001-09-28 22:56:31 +0000 | [diff] [blame] | 9 | #include "llvm/Method.h" | 
| Chris Lattner | cee8f9a | 2001-11-27 00:03:19 +0000 | [diff] [blame] | 10 | #include "Support/DepthFirstIterator.h" | 
|  | 11 | #include "Support/STLExtras.h" | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 12 | #include <algorithm> | 
| Chris Lattner | 697954c | 2002-01-20 22:54:45 +0000 | [diff] [blame] | 13 | using std::set; | 
|  | 14 |  | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 15 |  | 
|  | 16 | //===----------------------------------------------------------------------===// | 
|  | 17 | //  Helper Template | 
|  | 18 | //===----------------------------------------------------------------------===// | 
|  | 19 |  | 
|  | 20 | // set_intersect - Identical to set_intersection, except that it works on | 
|  | 21 | // set<>'s and is nicer to use.  Functionally, this iterates through S1, | 
|  | 22 | // removing elements that are not contained in S2. | 
|  | 23 | // | 
|  | 24 | template <class Ty, class Ty2> | 
|  | 25 | void set_intersect(set<Ty> &S1, const set<Ty2> &S2) { | 
|  | 26 | for (typename set<Ty>::iterator I = S1.begin(); I != S1.end();) { | 
|  | 27 | const Ty &E = *I; | 
|  | 28 | ++I; | 
|  | 29 | if (!S2.count(E)) S1.erase(E);   // Erase element if not in S2 | 
|  | 30 | } | 
|  | 31 | } | 
|  | 32 |  | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 33 | //===----------------------------------------------------------------------===// | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 34 | //  DominatorSet Implementation | 
|  | 35 | //===----------------------------------------------------------------------===// | 
|  | 36 |  | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 37 | AnalysisID cfg::DominatorSet::ID(AnalysisID::create<cfg::DominatorSet>()); | 
|  | 38 | AnalysisID cfg::DominatorSet::PostDomID(AnalysisID::create<cfg::DominatorSet>()); | 
|  | 39 |  | 
|  | 40 | bool cfg::DominatorSet::runOnMethod(Method *M) { | 
|  | 41 | Doms.clear();   // Reset from the last time we were run... | 
|  | 42 |  | 
|  | 43 | if (isPostDominator()) | 
|  | 44 | calcPostDominatorSet(M); | 
|  | 45 | else | 
|  | 46 | calcForwardDominatorSet(M); | 
|  | 47 | return false; | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 48 | } | 
|  | 49 |  | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 50 |  | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 51 | // calcForwardDominatorSet - This method calculates the forward dominator sets | 
|  | 52 | // for the specified method. | 
|  | 53 | // | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 54 | void cfg::DominatorSet::calcForwardDominatorSet(Method *M) { | 
|  | 55 | Root = M->getEntryNode(); | 
| Chris Lattner | ff5a8c4 | 2001-11-26 18:52:02 +0000 | [diff] [blame] | 56 | assert(Root->pred_begin() == Root->pred_end() && | 
|  | 57 | "Root node has predecessors in method!"); | 
|  | 58 |  | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 59 | bool Changed; | 
|  | 60 | do { | 
|  | 61 | Changed = false; | 
|  | 62 |  | 
|  | 63 | DomSetType WorkingSet; | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 64 | df_iterator<Method*> It = df_begin(M), End = df_end(M); | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 65 | for ( ; It != End; ++It) { | 
|  | 66 | const BasicBlock *BB = *It; | 
| Chris Lattner | f0604b8 | 2001-10-01 13:19:53 +0000 | [diff] [blame] | 67 | BasicBlock::pred_const_iterator PI = BB->pred_begin(), | 
|  | 68 | PEnd = BB->pred_end(); | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 69 | if (PI != PEnd) {                // Is there SOME predecessor? | 
|  | 70 | // Loop until we get to a predecessor that has had it's dom set filled | 
|  | 71 | // in at least once.  We are guaranteed to have this because we are | 
|  | 72 | // traversing the graph in DFO and have handled start nodes specially. | 
|  | 73 | // | 
|  | 74 | while (Doms[*PI].size() == 0) ++PI; | 
|  | 75 | WorkingSet = Doms[*PI]; | 
|  | 76 |  | 
|  | 77 | for (++PI; PI != PEnd; ++PI) { // Intersect all of the predecessor sets | 
|  | 78 | DomSetType &PredSet = Doms[*PI]; | 
|  | 79 | if (PredSet.size()) | 
|  | 80 | set_intersect(WorkingSet, PredSet); | 
|  | 81 | } | 
|  | 82 | } | 
|  | 83 |  | 
|  | 84 | WorkingSet.insert(BB);           // A block always dominates itself | 
|  | 85 | DomSetType &BBSet = Doms[BB]; | 
|  | 86 | if (BBSet != WorkingSet) { | 
|  | 87 | BBSet.swap(WorkingSet);        // Constant time operation! | 
|  | 88 | Changed = true;                // The sets changed. | 
|  | 89 | } | 
|  | 90 | WorkingSet.clear();              // Clear out the set for next iteration | 
|  | 91 | } | 
|  | 92 | } while (Changed); | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 93 | } | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 94 |  | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 95 | // Postdominator set constructor.  This ctor converts the specified method to | 
|  | 96 | // only have a single exit node (return stmt), then calculates the post | 
|  | 97 | // dominance sets for the method. | 
|  | 98 | // | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 99 | void cfg::DominatorSet::calcPostDominatorSet(Method *M) { | 
|  | 100 | // Since we require that the unify all exit nodes pass has been run, we know | 
|  | 101 | // that there can be at most one return instruction in the method left. | 
|  | 102 | // Get it. | 
|  | 103 | // | 
|  | 104 | Root = getAnalysis<UnifyMethodExitNodes>().getExitNode(); | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 105 |  | 
| Chris Lattner | 384e5b1 | 2001-08-23 17:07:19 +0000 | [diff] [blame] | 106 | if (Root == 0) {  // No exit node for the method?  Postdomsets are all empty | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 107 | for (Method::const_iterator MI = M->begin(), ME = M->end(); MI != ME; ++MI) | 
| Chris Lattner | 384e5b1 | 2001-08-23 17:07:19 +0000 | [diff] [blame] | 108 | Doms[*MI] = DomSetType(); | 
|  | 109 | return; | 
|  | 110 | } | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 111 |  | 
|  | 112 | bool Changed; | 
|  | 113 | do { | 
|  | 114 | Changed = false; | 
|  | 115 |  | 
|  | 116 | set<const BasicBlock*> Visited; | 
|  | 117 | DomSetType WorkingSet; | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 118 | idf_iterator<BasicBlock*> It = idf_begin(Root), End = idf_end(Root); | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 119 | for ( ; It != End; ++It) { | 
|  | 120 | const BasicBlock *BB = *It; | 
| Chris Lattner | f0604b8 | 2001-10-01 13:19:53 +0000 | [diff] [blame] | 121 | BasicBlock::succ_const_iterator PI = BB->succ_begin(), | 
|  | 122 | PEnd = BB->succ_end(); | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 123 | if (PI != PEnd) {                // Is there SOME predecessor? | 
|  | 124 | // Loop until we get to a successor that has had it's dom set filled | 
|  | 125 | // in at least once.  We are guaranteed to have this because we are | 
|  | 126 | // traversing the graph in DFO and have handled start nodes specially. | 
|  | 127 | // | 
|  | 128 | while (Doms[*PI].size() == 0) ++PI; | 
|  | 129 | WorkingSet = Doms[*PI]; | 
|  | 130 |  | 
|  | 131 | for (++PI; PI != PEnd; ++PI) { // Intersect all of the successor sets | 
|  | 132 | DomSetType &PredSet = Doms[*PI]; | 
|  | 133 | if (PredSet.size()) | 
|  | 134 | set_intersect(WorkingSet, PredSet); | 
|  | 135 | } | 
|  | 136 | } | 
|  | 137 |  | 
|  | 138 | WorkingSet.insert(BB);           // A block always dominates itself | 
|  | 139 | DomSetType &BBSet = Doms[BB]; | 
|  | 140 | if (BBSet != WorkingSet) { | 
|  | 141 | BBSet.swap(WorkingSet);        // Constant time operation! | 
|  | 142 | Changed = true;                // The sets changed. | 
|  | 143 | } | 
|  | 144 | WorkingSet.clear();              // Clear out the set for next iteration | 
|  | 145 | } | 
|  | 146 | } while (Changed); | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 147 | } | 
|  | 148 |  | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 149 | // getAnalysisUsageInfo - This obviously provides a dominator set, but it also | 
|  | 150 | // uses the UnifyMethodExitNodes pass if building post-dominators | 
|  | 151 | // | 
|  | 152 | void cfg::DominatorSet::getAnalysisUsageInfo(Pass::AnalysisSet &Requires, | 
|  | 153 | Pass::AnalysisSet &Destroyed, | 
|  | 154 | Pass::AnalysisSet &Provided) { | 
|  | 155 | if (isPostDominator()) | 
|  | 156 | Requires.push_back(UnifyMethodExitNodes::ID); | 
|  | 157 |  | 
|  | 158 | Provided.push_back(ID); | 
|  | 159 | } | 
|  | 160 |  | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 161 |  | 
|  | 162 | //===----------------------------------------------------------------------===// | 
|  | 163 | //  ImmediateDominators Implementation | 
|  | 164 | //===----------------------------------------------------------------------===// | 
|  | 165 |  | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 166 | AnalysisID cfg::ImmediateDominators::ID(AnalysisID::create<cfg::ImmediateDominators>()); | 
|  | 167 | AnalysisID cfg::ImmediateDominators::PostDomID(AnalysisID::create<cfg::ImmediateDominators>()); | 
|  | 168 |  | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 169 | // calcIDoms - Calculate the immediate dominator mapping, given a set of | 
|  | 170 | // dominators for every basic block. | 
|  | 171 | void cfg::ImmediateDominators::calcIDoms(const DominatorSet &DS) { | 
|  | 172 | // Loop over all of the nodes that have dominators... figuring out the IDOM | 
|  | 173 | // for each node... | 
|  | 174 | // | 
|  | 175 | for (DominatorSet::const_iterator DI = DS.begin(), DEnd = DS.end(); | 
|  | 176 | DI != DEnd; ++DI) { | 
|  | 177 | const BasicBlock *BB = DI->first; | 
|  | 178 | const DominatorSet::DomSetType &Dominators = DI->second; | 
|  | 179 | unsigned DomSetSize = Dominators.size(); | 
|  | 180 | if (DomSetSize == 1) continue;  // Root node... IDom = null | 
|  | 181 |  | 
|  | 182 | // Loop over all dominators of this node.  This corresponds to looping over | 
|  | 183 | // nodes in the dominator chain, looking for a node whose dominator set is | 
|  | 184 | // equal to the current nodes, except that the current node does not exist | 
|  | 185 | // in it.  This means that it is one level higher in the dom chain than the | 
|  | 186 | // current node, and it is our idom! | 
|  | 187 | // | 
|  | 188 | DominatorSet::DomSetType::const_iterator I = Dominators.begin(); | 
|  | 189 | DominatorSet::DomSetType::const_iterator End = Dominators.end(); | 
|  | 190 | for (; I != End; ++I) {   // Iterate over dominators... | 
|  | 191 | // All of our dominators should form a chain, where the number of elements | 
|  | 192 | // in the dominator set indicates what level the node is at in the chain. | 
|  | 193 | // We want the node immediately above us, so it will have an identical | 
|  | 194 | // dominator set, except that BB will not dominate it... therefore it's | 
|  | 195 | // dominator set size will be one less than BB's... | 
|  | 196 | // | 
|  | 197 | if (DS.getDominators(*I).size() == DomSetSize - 1) { | 
|  | 198 | IDoms[BB] = *I; | 
|  | 199 | break; | 
|  | 200 | } | 
|  | 201 | } | 
|  | 202 | } | 
|  | 203 | } | 
|  | 204 |  | 
|  | 205 |  | 
|  | 206 | //===----------------------------------------------------------------------===// | 
|  | 207 | //  DominatorTree Implementation | 
|  | 208 | //===----------------------------------------------------------------------===// | 
|  | 209 |  | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 210 | AnalysisID cfg::DominatorTree::ID(AnalysisID::create<cfg::DominatorTree>()); | 
|  | 211 | AnalysisID cfg::DominatorTree::PostDomID(AnalysisID::create<cfg::DominatorTree>()); | 
|  | 212 |  | 
|  | 213 | // DominatorTree::reset - Free all of the tree node memory. | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 214 | // | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 215 | void cfg::DominatorTree::reset() { | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 216 | for (NodeMapType::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) | 
|  | 217 | delete I->second; | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 218 | Nodes.clear(); | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 219 | } | 
|  | 220 |  | 
|  | 221 |  | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 222 | #if 0 | 
|  | 223 | // Given immediate dominators, we can also calculate the dominator tree | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 224 | cfg::DominatorTree::DominatorTree(const ImmediateDominators &IDoms) | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 225 | : DominatorBase(IDoms.getRoot()) { | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 226 | const Method *M = Root->getParent(); | 
|  | 227 |  | 
|  | 228 | Nodes[Root] = new Node(Root, 0);   // Add a node for the root... | 
|  | 229 |  | 
|  | 230 | // Iterate over all nodes in depth first order... | 
| Chris Lattner | 3ff4387 | 2001-09-28 22:56:31 +0000 | [diff] [blame] | 231 | for (df_iterator<const Method*> I = df_begin(M), E = df_end(M); I != E; ++I) { | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 232 | const BasicBlock *BB = *I, *IDom = IDoms[*I]; | 
|  | 233 |  | 
|  | 234 | if (IDom != 0) {   // Ignore the root node and other nasty nodes | 
|  | 235 | // We know that the immediate dominator should already have a node, | 
|  | 236 | // because we are traversing the CFG in depth first order! | 
|  | 237 | // | 
|  | 238 | assert(Nodes[IDom] && "No node for IDOM?"); | 
|  | 239 | Node *IDomNode = Nodes[IDom]; | 
|  | 240 |  | 
|  | 241 | // Add a new tree node for this BasicBlock, and link it as a child of | 
|  | 242 | // IDomNode | 
|  | 243 | Nodes[BB] = IDomNode->addChild(new Node(BB, IDomNode)); | 
|  | 244 | } | 
|  | 245 | } | 
|  | 246 | } | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 247 | #endif | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 248 |  | 
|  | 249 | void cfg::DominatorTree::calculate(const DominatorSet &DS) { | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 250 | Nodes[Root] = new Node(Root, 0);   // Add a node for the root... | 
|  | 251 |  | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 252 | if (!isPostDominator()) { | 
|  | 253 | // Iterate over all nodes in depth first order... | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 254 | for (df_iterator<BasicBlock*> I = df_begin(Root), E = df_end(Root); | 
| Chris Lattner | 3ff4387 | 2001-09-28 22:56:31 +0000 | [diff] [blame] | 255 | I != E; ++I) { | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 256 | const BasicBlock *BB = *I; | 
|  | 257 | const DominatorSet::DomSetType &Dominators = DS.getDominators(BB); | 
|  | 258 | unsigned DomSetSize = Dominators.size(); | 
|  | 259 | if (DomSetSize == 1) continue;  // Root node... IDom = null | 
|  | 260 |  | 
| Chris Lattner | 3ff4387 | 2001-09-28 22:56:31 +0000 | [diff] [blame] | 261 | // Loop over all dominators of this node. This corresponds to looping over | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 262 | // nodes in the dominator chain, looking for a node whose dominator set is | 
|  | 263 | // equal to the current nodes, except that the current node does not exist | 
| Chris Lattner | 3ff4387 | 2001-09-28 22:56:31 +0000 | [diff] [blame] | 264 | // in it. This means that it is one level higher in the dom chain than the | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 265 | // current node, and it is our idom!  We know that we have already added | 
|  | 266 | // a DominatorTree node for our idom, because the idom must be a | 
|  | 267 | // predecessor in the depth first order that we are iterating through the | 
|  | 268 | // method. | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 269 | // | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 270 | DominatorSet::DomSetType::const_iterator I = Dominators.begin(); | 
|  | 271 | DominatorSet::DomSetType::const_iterator End = Dominators.end(); | 
|  | 272 | for (; I != End; ++I) {   // Iterate over dominators... | 
| Chris Lattner | 3ff4387 | 2001-09-28 22:56:31 +0000 | [diff] [blame] | 273 | // All of our dominators should form a chain, where the number of | 
|  | 274 | // elements in the dominator set indicates what level the node is at in | 
|  | 275 | // the chain.  We want the node immediately above us, so it will have | 
|  | 276 | // an identical dominator set, except that BB will not dominate it... | 
|  | 277 | // therefore it's dominator set size will be one less than BB's... | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 278 | // | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 279 | if (DS.getDominators(*I).size() == DomSetSize - 1) { | 
|  | 280 | // We know that the immediate dominator should already have a node, | 
|  | 281 | // because we are traversing the CFG in depth first order! | 
|  | 282 | // | 
|  | 283 | Node *IDomNode = Nodes[*I]; | 
|  | 284 | assert(IDomNode && "No node for IDOM?"); | 
|  | 285 |  | 
|  | 286 | // Add a new tree node for this BasicBlock, and link it as a child of | 
|  | 287 | // IDomNode | 
|  | 288 | Nodes[BB] = IDomNode->addChild(new Node(BB, IDomNode)); | 
|  | 289 | break; | 
|  | 290 | } | 
|  | 291 | } | 
|  | 292 | } | 
| Chris Lattner | 384e5b1 | 2001-08-23 17:07:19 +0000 | [diff] [blame] | 293 | } else if (Root) { | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 294 | // Iterate over all nodes in depth first order... | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 295 | for (idf_iterator<BasicBlock*> I = idf_begin(Root), E = idf_end(Root); | 
| Chris Lattner | 3ff4387 | 2001-09-28 22:56:31 +0000 | [diff] [blame] | 296 | I != E; ++I) { | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 297 | const BasicBlock *BB = *I; | 
|  | 298 | const DominatorSet::DomSetType &Dominators = DS.getDominators(BB); | 
|  | 299 | unsigned DomSetSize = Dominators.size(); | 
|  | 300 | if (DomSetSize == 1) continue;  // Root node... IDom = null | 
|  | 301 |  | 
| Chris Lattner | 3ff4387 | 2001-09-28 22:56:31 +0000 | [diff] [blame] | 302 | // Loop over all dominators of this node.  This corresponds to looping | 
|  | 303 | // over nodes in the dominator chain, looking for a node whose dominator | 
|  | 304 | // set is equal to the current nodes, except that the current node does | 
|  | 305 | // not exist in it.  This means that it is one level higher in the dom | 
|  | 306 | // chain than the current node, and it is our idom!  We know that we have | 
|  | 307 | // already added a DominatorTree node for our idom, because the idom must | 
|  | 308 | // be a predecessor in the depth first order that we are iterating through | 
|  | 309 | // the method. | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 310 | // | 
|  | 311 | DominatorSet::DomSetType::const_iterator I = Dominators.begin(); | 
|  | 312 | DominatorSet::DomSetType::const_iterator End = Dominators.end(); | 
|  | 313 | for (; I != End; ++I) {   // Iterate over dominators... | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 314 | // All of our dominators should form a chain, where the number | 
|  | 315 | // of elements in the dominator set indicates what level the | 
|  | 316 | // node is at in the chain.  We want the node immediately | 
|  | 317 | // above us, so it will have an identical dominator set, | 
|  | 318 | // except that BB will not dominate it... therefore it's | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 319 | // dominator set size will be one less than BB's... | 
|  | 320 | // | 
|  | 321 | if (DS.getDominators(*I).size() == DomSetSize - 1) { | 
|  | 322 | // We know that the immediate dominator should already have a node, | 
|  | 323 | // because we are traversing the CFG in depth first order! | 
|  | 324 | // | 
|  | 325 | Node *IDomNode = Nodes[*I]; | 
|  | 326 | assert(IDomNode && "No node for IDOM?"); | 
|  | 327 |  | 
|  | 328 | // Add a new tree node for this BasicBlock, and link it as a child of | 
|  | 329 | // IDomNode | 
|  | 330 | Nodes[BB] = IDomNode->addChild(new Node(BB, IDomNode)); | 
|  | 331 | break; | 
|  | 332 | } | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 333 | } | 
|  | 334 | } | 
|  | 335 | } | 
|  | 336 | } | 
|  | 337 |  | 
|  | 338 |  | 
|  | 339 |  | 
|  | 340 | //===----------------------------------------------------------------------===// | 
|  | 341 | //  DominanceFrontier Implementation | 
|  | 342 | //===----------------------------------------------------------------------===// | 
|  | 343 |  | 
| Chris Lattner | 93193f8 | 2002-01-31 00:42:27 +0000 | [diff] [blame^] | 344 | AnalysisID cfg::DominanceFrontier::ID(AnalysisID::create<cfg::DominanceFrontier>()); | 
|  | 345 | AnalysisID cfg::DominanceFrontier::PostDomID(AnalysisID::create<cfg::DominanceFrontier>()); | 
|  | 346 |  | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 347 | const cfg::DominanceFrontier::DomSetType & | 
|  | 348 | cfg::DominanceFrontier::calcDomFrontier(const DominatorTree &DT, | 
|  | 349 | const DominatorTree::Node *Node) { | 
|  | 350 | // Loop over CFG successors to calculate DFlocal[Node] | 
|  | 351 | const BasicBlock *BB = Node->getNode(); | 
|  | 352 | DomSetType &S = Frontiers[BB];       // The new set to fill in... | 
|  | 353 |  | 
| Chris Lattner | f0604b8 | 2001-10-01 13:19:53 +0000 | [diff] [blame] | 354 | for (BasicBlock::succ_const_iterator SI = BB->succ_begin(), | 
|  | 355 | SE = BB->succ_end(); SI != SE; ++SI) { | 
| Chris Lattner | 1715229 | 2001-07-02 05:46:38 +0000 | [diff] [blame] | 356 | // Does Node immediately dominate this successor? | 
|  | 357 | if (DT[*SI]->getIDom() != Node) | 
|  | 358 | S.insert(*SI); | 
|  | 359 | } | 
|  | 360 |  | 
|  | 361 | // At this point, S is DFlocal.  Now we union in DFup's of our children... | 
|  | 362 | // Loop through and visit the nodes that Node immediately dominates (Node's | 
|  | 363 | // children in the IDomTree) | 
|  | 364 | // | 
|  | 365 | for (DominatorTree::Node::const_iterator NI = Node->begin(), NE = Node->end(); | 
|  | 366 | NI != NE; ++NI) { | 
|  | 367 | DominatorTree::Node *IDominee = *NI; | 
|  | 368 | const DomSetType &ChildDF = calcDomFrontier(DT, IDominee); | 
|  | 369 |  | 
|  | 370 | DomSetType::const_iterator CDFI = ChildDF.begin(), CDFE = ChildDF.end(); | 
|  | 371 | for (; CDFI != CDFE; ++CDFI) { | 
|  | 372 | if (!Node->dominates(DT[*CDFI])) | 
|  | 373 | S.insert(*CDFI); | 
|  | 374 | } | 
|  | 375 | } | 
|  | 376 |  | 
|  | 377 | return S; | 
|  | 378 | } | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 379 |  | 
|  | 380 | const cfg::DominanceFrontier::DomSetType & | 
|  | 381 | cfg::DominanceFrontier::calcPostDomFrontier(const DominatorTree &DT, | 
|  | 382 | const DominatorTree::Node *Node) { | 
|  | 383 | // Loop over CFG successors to calculate DFlocal[Node] | 
|  | 384 | const BasicBlock *BB = Node->getNode(); | 
|  | 385 | DomSetType &S = Frontiers[BB];       // The new set to fill in... | 
| Chris Lattner | 384e5b1 | 2001-08-23 17:07:19 +0000 | [diff] [blame] | 386 | if (!Root) return S; | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 387 |  | 
| Chris Lattner | f0604b8 | 2001-10-01 13:19:53 +0000 | [diff] [blame] | 388 | for (BasicBlock::pred_const_iterator SI = BB->pred_begin(), | 
|  | 389 | SE = BB->pred_end(); SI != SE; ++SI) { | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 390 | // Does Node immediately dominate this predeccessor? | 
|  | 391 | if (DT[*SI]->getIDom() != Node) | 
|  | 392 | S.insert(*SI); | 
|  | 393 | } | 
|  | 394 |  | 
|  | 395 | // At this point, S is DFlocal.  Now we union in DFup's of our children... | 
|  | 396 | // Loop through and visit the nodes that Node immediately dominates (Node's | 
|  | 397 | // children in the IDomTree) | 
|  | 398 | // | 
|  | 399 | for (DominatorTree::Node::const_iterator NI = Node->begin(), NE = Node->end(); | 
|  | 400 | NI != NE; ++NI) { | 
|  | 401 | DominatorTree::Node *IDominee = *NI; | 
| Chris Lattner | 3590830 | 2001-07-08 05:54:09 +0000 | [diff] [blame] | 402 | const DomSetType &ChildDF = calcPostDomFrontier(DT, IDominee); | 
| Chris Lattner | 94108ab | 2001-07-06 16:58:22 +0000 | [diff] [blame] | 403 |  | 
|  | 404 | DomSetType::const_iterator CDFI = ChildDF.begin(), CDFE = ChildDF.end(); | 
|  | 405 | for (; CDFI != CDFE; ++CDFI) { | 
|  | 406 | if (!Node->dominates(DT[*CDFI])) | 
|  | 407 | S.insert(*CDFI); | 
|  | 408 | } | 
|  | 409 | } | 
|  | 410 |  | 
|  | 411 | return S; | 
|  | 412 | } |