-// Postdominator set construction. This converts the specified function to only
-// have a single exit node (return stmt), then calculates the post dominance
-// sets for the function.
-//
-bool PostDominatorSet::runOnFunction(Function &F) {
- Doms.clear(); // Reset from the last time we were run...
-
- // Scan the function looking for the root nodes of the post-dominance
- // relationships. These blocks end with return and unwind instructions.
- // While we are iterating over the function, we also initialize all of the
- // domsets to empty.
- Roots.clear();
- for (Function::iterator I = F.begin(), E = F.end(); I != E; ++I) {
- Doms[I]; // Initialize to empty
-
- if (succ_begin(I) == succ_end(I))
- Roots.push_back(I);
- }
-
- // If there are no exit nodes for the function, postdomsets are all empty.
- // This can happen if the function just contains an infinite loop, for
- // example.
- if (Roots.empty()) return false;
-
- // If we have more than one root, we insert an artificial "null" exit, which
- // has "virtual edges" to each of the real exit nodes.
- if (Roots.size() > 1)
- Doms[0].insert(0);
-
- bool Changed;
- do {
- Changed = false;
-
- std::set<BasicBlock*> Visited;
- DomSetType WorkingSet;
-
- for (unsigned i = 0, e = Roots.size(); i != e; ++i)
- for (idf_ext_iterator<BasicBlock*> It = idf_ext_begin(Roots[i], Visited),
- E = idf_ext_end(Roots[i], Visited); It != E; ++It) {
- BasicBlock *BB = *It;
- succ_iterator SI = succ_begin(BB), SE = succ_end(BB);
- if (SI != SE) { // Is there SOME successor?
- // Loop until we get to a successor that has had it's dom set filled
- // in at least once. We are guaranteed to have this because we are
- // traversing the graph in DFO and have handled start nodes specially.
- //
- while (Doms[*SI].size() == 0) ++SI;
- WorkingSet = Doms[*SI];
-
- for (++SI; SI != SE; ++SI) { // Intersect all of the successor sets
- DomSetType &SuccSet = Doms[*SI];
- if (SuccSet.size())
- set_intersect(WorkingSet, SuccSet);
- }
- } else {
- // If this node has no successors, it must be one of the root nodes.
- // We will already take care of the notion that the node
- // post-dominates itself. The only thing we have to add is that if
- // there are multiple root nodes, we want to insert a special "null"
- // exit node which dominates the roots as well.
- if (Roots.size() > 1)
- WorkingSet.insert(0);
- }
-
- WorkingSet.insert(BB); // A block always dominates itself
- DomSetType &BBSet = Doms[BB];
- if (BBSet != WorkingSet) {
- BBSet.swap(WorkingSet); // Constant time operation!
- Changed = true; // The sets changed.
- }
- WorkingSet.clear(); // Clear out the set for next iteration
- }
- } while (Changed);