1 //===- DominanceFrontier.cpp - Dominance Frontier Calculation -------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/Analysis/DominanceFrontier.h"
11 #include "llvm/Support/Debug.h"
12 #include "llvm/ADT/SmallPtrSet.h"
13 #include "llvm/Assembly/Writer.h"
14 #include "llvm/Support/raw_ostream.h"
17 char DominanceFrontier::ID
= 0;
18 INITIALIZE_PASS_BEGIN(DominanceFrontier
, "domfrontier",
19 "Dominance Frontier Construction", true, true)
20 INITIALIZE_PASS_DEPENDENCY(DominatorTree
)
21 INITIALIZE_PASS_END(DominanceFrontier
, "domfrontier",
22 "Dominance Frontier Construction", true, true)
25 class DFCalculateWorkObject
{
27 DFCalculateWorkObject(BasicBlock
*B
, BasicBlock
*P
,
29 const DomTreeNode
*PN
)
30 : currentBB(B
), parentBB(P
), Node(N
), parentNode(PN
) {}
31 BasicBlock
*currentBB
;
33 const DomTreeNode
*Node
;
34 const DomTreeNode
*parentNode
;
38 const DominanceFrontier::DomSetType
&
39 DominanceFrontier::calculate(const DominatorTree
&DT
,
40 const DomTreeNode
*Node
) {
41 BasicBlock
*BB
= Node
->getBlock();
42 DomSetType
*Result
= NULL
;
44 std::vector
<DFCalculateWorkObject
> workList
;
45 SmallPtrSet
<BasicBlock
*, 32> visited
;
47 workList
.push_back(DFCalculateWorkObject(BB
, NULL
, Node
, NULL
));
49 DFCalculateWorkObject
*currentW
= &workList
.back();
50 assert (currentW
&& "Missing work object.");
52 BasicBlock
*currentBB
= currentW
->currentBB
;
53 BasicBlock
*parentBB
= currentW
->parentBB
;
54 const DomTreeNode
*currentNode
= currentW
->Node
;
55 const DomTreeNode
*parentNode
= currentW
->parentNode
;
56 assert (currentBB
&& "Invalid work object. Missing current Basic Block");
57 assert (currentNode
&& "Invalid work object. Missing current Node");
58 DomSetType
&S
= Frontiers
[currentBB
];
60 // Visit each block only once.
61 if (visited
.count(currentBB
) == 0) {
62 visited
.insert(currentBB
);
64 // Loop over CFG successors to calculate DFlocal[currentNode]
65 for (succ_iterator SI
= succ_begin(currentBB
), SE
= succ_end(currentBB
);
67 // Does Node immediately dominate this successor?
68 if (DT
[*SI
]->getIDom() != currentNode
)
73 // At this point, S is DFlocal. Now we union in DFup's of our children...
74 // Loop through and visit the nodes that Node immediately dominates (Node's
75 // children in the IDomTree)
76 bool visitChild
= false;
77 for (DomTreeNode::const_iterator NI
= currentNode
->begin(),
78 NE
= currentNode
->end(); NI
!= NE
; ++NI
) {
79 DomTreeNode
*IDominee
= *NI
;
80 BasicBlock
*childBB
= IDominee
->getBlock();
81 if (visited
.count(childBB
) == 0) {
82 workList
.push_back(DFCalculateWorkObject(childBB
, currentBB
,
83 IDominee
, currentNode
));
88 // If all children are visited or there is any child then pop this block
97 DomSetType::const_iterator CDFI
= S
.begin(), CDFE
= S
.end();
98 DomSetType
&parentSet
= Frontiers
[parentBB
];
99 for (; CDFI
!= CDFE
; ++CDFI
) {
100 if (!DT
.properlyDominates(parentNode
, DT
[*CDFI
]))
101 parentSet
.insert(*CDFI
);
106 } while (!workList
.empty());
111 void DominanceFrontierBase::print(raw_ostream
&OS
, const Module
* ) const {
112 for (const_iterator I
= begin(), E
= end(); I
!= E
; ++I
) {
113 OS
<< " DomFrontier for BB ";
115 WriteAsOperand(OS
, I
->first
, false);
117 OS
<< " <<exit node>>";
120 const std::set
<BasicBlock
*> &BBs
= I
->second
;
122 for (std::set
<BasicBlock
*>::const_iterator I
= BBs
.begin(), E
= BBs
.end();
126 WriteAsOperand(OS
, *I
, false);
128 OS
<< "<<exit node>>";
134 void DominanceFrontierBase::dump() const {