blob: b8d833e23d7501a55c7c5262f7e63e842f5c3c48 [file] [log] [blame]
Dan Gohmanf17a25c2007-07-18 16:29:46 +00001//===- PostDominators.cpp - Post-Dominator Calculation --------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the post-dominator construction algorithms.
11//
12//===----------------------------------------------------------------------===//
13
14#include "llvm/Analysis/PostDominators.h"
15#include "llvm/Instructions.h"
16#include "llvm/Support/CFG.h"
17#include "llvm/ADT/DepthFirstIterator.h"
18#include "llvm/ADT/SetOperations.h"
Owen Anderson0ce522f2007-09-23 22:21:00 +000019#include "PostDominatorCalculation.h"
Dan Gohmanf17a25c2007-07-18 16:29:46 +000020using namespace llvm;
21
22//===----------------------------------------------------------------------===//
23// PostDominatorTree Implementation
24//===----------------------------------------------------------------------===//
25
26char PostDominatorTree::ID = 0;
27char PostDominanceFrontier::ID = 0;
28static RegisterPass<PostDominatorTree>
29F("postdomtree", "Post-Dominator Tree Construction", true);
30
Chris Lattnere2649cb2007-08-05 00:02:00 +000031unsigned PostDominatorTree::DFSPass(BasicBlock *V, unsigned N) {
32 std::vector<BasicBlock *> workStack;
Chris Lattner33607b02007-08-05 00:15:57 +000033 SmallPtrSet<BasicBlock *, 32> Visited;
Chris Lattnere2649cb2007-08-05 00:02:00 +000034 workStack.push_back(V);
Dan Gohmanf17a25c2007-07-18 16:29:46 +000035
36 do {
Chris Lattnere2649cb2007-08-05 00:02:00 +000037 BasicBlock *currentBB = workStack.back();
38 InfoRec &CurVInfo = Info[currentBB];
Dan Gohmanf17a25c2007-07-18 16:29:46 +000039
40 // Visit each block only once.
Chris Lattner33607b02007-08-05 00:15:57 +000041 if (Visited.insert(currentBB)) {
Chris Lattnere2649cb2007-08-05 00:02:00 +000042 CurVInfo.Semi = ++N;
43 CurVInfo.Label = currentBB;
Dan Gohmanf17a25c2007-07-18 16:29:46 +000044
45 Vertex.push_back(currentBB); // Vertex[n] = current;
46 // Info[currentBB].Ancestor = 0;
47 // Ancestor[n] = 0
48 // Child[currentBB] = 0;
Chris Lattnere2649cb2007-08-05 00:02:00 +000049 CurVInfo.Size = 1; // Size[currentBB] = 1
Dan Gohmanf17a25c2007-07-18 16:29:46 +000050 }
51
52 // Visit children
53 bool visitChild = false;
54 for (pred_iterator PI = pred_begin(currentBB), PE = pred_end(currentBB);
55 PI != PE && !visitChild; ++PI) {
56 InfoRec &SuccVInfo = Info[*PI];
57 if (SuccVInfo.Semi == 0) {
58 SuccVInfo.Parent = currentBB;
Chris Lattner33607b02007-08-05 00:15:57 +000059 if (!Visited.count(*PI)) {
Chris Lattnere2649cb2007-08-05 00:02:00 +000060 workStack.push_back(*PI);
Dan Gohmanf17a25c2007-07-18 16:29:46 +000061 visitChild = true;
62 }
63 }
64 }
65
66 // If all children are visited or if this block has no child then pop this
67 // block out of workStack.
68 if (!visitChild)
69 workStack.pop_back();
70
71 } while (!workStack.empty());
72
73 return N;
74}
75
Dan Gohmanf17a25c2007-07-18 16:29:46 +000076//===----------------------------------------------------------------------===//
77// PostDominanceFrontier Implementation
78//===----------------------------------------------------------------------===//
79
80static RegisterPass<PostDominanceFrontier>
81H("postdomfrontier", "Post-Dominance Frontier Construction", true);
82
83const DominanceFrontier::DomSetType &
84PostDominanceFrontier::calculate(const PostDominatorTree &DT,
85 const DomTreeNode *Node) {
86 // Loop over CFG successors to calculate DFlocal[Node]
87 BasicBlock *BB = Node->getBlock();
88 DomSetType &S = Frontiers[BB]; // The new set to fill in...
89 if (getRoots().empty()) return S;
90
91 if (BB)
92 for (pred_iterator SI = pred_begin(BB), SE = pred_end(BB);
93 SI != SE; ++SI) {
94 // Does Node immediately dominate this predecessor?
95 DomTreeNode *SINode = DT[*SI];
96 if (SINode && SINode->getIDom() != Node)
97 S.insert(*SI);
98 }
99
100 // At this point, S is DFlocal. Now we union in DFup's of our children...
101 // Loop through and visit the nodes that Node immediately dominates (Node's
102 // children in the IDomTree)
103 //
104 for (DomTreeNode::const_iterator
105 NI = Node->begin(), NE = Node->end(); NI != NE; ++NI) {
106 DomTreeNode *IDominee = *NI;
107 const DomSetType &ChildDF = calculate(DT, IDominee);
108
109 DomSetType::const_iterator CDFI = ChildDF.begin(), CDFE = ChildDF.end();
110 for (; CDFI != CDFE; ++CDFI) {
111 if (!DT.properlyDominates(Node, DT[*CDFI]))
112 S.insert(*CDFI);
113 }
114 }
115
116 return S;
117}
118
119// Ensure that this .cpp file gets linked when PostDominators.h is used.
120DEFINING_FILE_FOR(PostDominanceFrontier)