Rework dominator interfaces to handle changes in the post-dominance

construction.  Now there may be multiple root blocks, and null is a
special node used to mark the "virtual" exit node of a CFG.

llvm-svn: 8461
This commit is contained in:
Chris Lattner 2003-09-10 20:37:51 +00:00
parent 8157505fae
commit 630d2954be
1 changed files with 47 additions and 28 deletions

View File

@ -65,7 +65,8 @@ void DominatorSet::calculateDominatorsFromBlock(BasicBlock *RootBB) {
} }
} }
} else { } else {
assert(BB == Root && "We got into unreachable code somehow!"); assert(Roots.size() == 1 && BB == Roots[0] &&
"We got into unreachable code somehow!");
} }
WorkingSet.insert(BB); // A block always dominates itself WorkingSet.insert(BB); // A block always dominates itself
@ -86,7 +87,9 @@ void DominatorSet::calculateDominatorsFromBlock(BasicBlock *RootBB) {
// specified function. // specified function.
// //
bool DominatorSet::runOnFunction(Function &F) { bool DominatorSet::runOnFunction(Function &F) {
Root = &F.getEntryNode(); BasicBlock *Root = &F.getEntryNode();
Roots.clear();
Roots.push_back(Root);
assert(pred_begin(Root) == pred_end(Root) && assert(pred_begin(Root) == pred_end(Root) &&
"Root node has predecessors in function!"); "Root node has predecessors in function!");
recalculate(); recalculate();
@ -94,16 +97,17 @@ bool DominatorSet::runOnFunction(Function &F) {
} }
void DominatorSet::recalculate() { void DominatorSet::recalculate() {
assert(Roots.size() == 1 && "DominatorSet should have single root block!");
Doms.clear(); // Reset from the last time we were run... Doms.clear(); // Reset from the last time we were run...
// Calculate dominator sets for the reachable basic blocks... // Calculate dominator sets for the reachable basic blocks...
calculateDominatorsFromBlock(Root); calculateDominatorsFromBlock(Roots[0]);
// Loop through the function, ensuring that every basic block has at least an // Loop through the function, ensuring that every basic block has at least an
// empty set of nodes. This is important for the case when there is // empty set of nodes. This is important for the case when there is
// unreachable blocks. // unreachable blocks.
Function *F = Root->getParent(); Function *F = Roots[0]->getParent();
for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) Doms[I]; for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) Doms[I];
} }
@ -111,20 +115,22 @@ void DominatorSet::recalculate() {
static std::ostream &operator<<(std::ostream &o, static std::ostream &operator<<(std::ostream &o,
const std::set<BasicBlock*> &BBs) { const std::set<BasicBlock*> &BBs) {
for (std::set<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end(); for (std::set<BasicBlock*>::const_iterator I = BBs.begin(), E = BBs.end();
I != E; ++I) { I != E; ++I)
o << " "; if (*I)
WriteAsOperand(o, *I, false); WriteAsOperand(o, *I, false);
o << "\n"; else
} o << " <<exit node>>";
return o; return o;
} }
void DominatorSetBase::print(std::ostream &o) const { void DominatorSetBase::print(std::ostream &o) const {
for (const_iterator I = begin(), E = end(); I != E; ++I) { for (const_iterator I = begin(), E = end(); I != E; ++I) {
o << "=============================--------------------------------\n" o << " DomSet For BB: ";
<< "\nDominator Set For Basic Block: "; if (I->first)
WriteAsOperand(o, I->first, false); WriteAsOperand(o, I->first, false);
o << "\n-------------------------------\n" << I->second << "\n"; else
o << " <<exit node>>";
o << " is:\t" << I->second << "\n";
} }
} }
@ -173,13 +179,19 @@ void ImmediateDominatorsBase::calcIDoms(const DominatorSetBase &DS) {
void ImmediateDominatorsBase::print(std::ostream &o) const { void ImmediateDominatorsBase::print(std::ostream &o) const {
for (const_iterator I = begin(), E = end(); I != E; ++I) { for (const_iterator I = begin(), E = end(); I != E; ++I) {
o << "=============================--------------------------------\n" o << " Immediate Dominator For Basic Block:";
<< "\nImmediate Dominator For Basic Block:"; if (I->first)
WriteAsOperand(o, I->first, false); WriteAsOperand(o, I->first, false);
else
o << " <<exit node>>";
o << " is:"; o << " is:";
WriteAsOperand(o, I->second, false); if (I->second)
WriteAsOperand(o, I->second, false);
else
o << " <<exit node>>";
o << "\n"; o << "\n";
} }
o << "\n";
} }
@ -196,6 +208,7 @@ void DominatorTreeBase::reset() {
for (NodeMapType::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) for (NodeMapType::iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I)
delete I->second; delete I->second;
Nodes.clear(); Nodes.clear();
RootNode = 0;
} }
void DominatorTreeBase::Node2::setIDom(Node2 *NewIDom) { void DominatorTreeBase::Node2::setIDom(Node2 *NewIDom) {
@ -217,7 +230,9 @@ void DominatorTreeBase::Node2::setIDom(Node2 *NewIDom) {
void DominatorTree::calculate(const DominatorSet &DS) { void DominatorTree::calculate(const DominatorSet &DS) {
Nodes[Root] = new Node(Root, 0); // Add a node for the root... assert(Roots.size() == 1 && "DominatorTree should have 1 root block!");
BasicBlock *Root = Roots[0];
Nodes[Root] = RootNode = new Node(Root, 0); // Add a node for the root...
// Iterate over all nodes in depth first order... // Iterate over all nodes in depth first order...
for (df_iterator<BasicBlock*> I = df_begin(Root), E = df_end(Root); for (df_iterator<BasicBlock*> I = df_begin(Root), E = df_end(Root);
@ -264,23 +279,25 @@ void DominatorTree::calculate(const DominatorSet &DS) {
static std::ostream &operator<<(std::ostream &o, static std::ostream &operator<<(std::ostream &o,
const DominatorTreeBase::Node *Node) { const DominatorTreeBase::Node *Node) {
return o << Node->getNode() if (Node->getNode())
<< "\n------------------------------------------\n"; WriteAsOperand(o, Node->getNode(), false);
else
o << " <<exit node>>";
return o << "\n";
} }
static void PrintDomTree(const DominatorTreeBase::Node *N, std::ostream &o, static void PrintDomTree(const DominatorTreeBase::Node *N, std::ostream &o,
unsigned Lev) { unsigned Lev) {
o << "Level #" << Lev << ": " << N; o << std::string(2*Lev, ' ') << "[" << Lev << "] " << N;
for (DominatorTreeBase::Node::const_iterator I = N->begin(), E = N->end(); for (DominatorTreeBase::Node::const_iterator I = N->begin(), E = N->end();
I != E; ++I) { I != E; ++I)
PrintDomTree(*I, o, Lev+1); PrintDomTree(*I, o, Lev+1);
}
} }
void DominatorTreeBase::print(std::ostream &o) const { void DominatorTreeBase::print(std::ostream &o) const {
o << "=============================--------------------------------\n" o << "=============================--------------------------------\n"
<< "Inorder Dominator Tree:\n"; << "Inorder Dominator Tree:\n";
PrintDomTree(Nodes.find(getRoot())->second, o, 1); PrintDomTree(getRootNode(), o, 1);
} }
@ -326,9 +343,11 @@ DominanceFrontier::calculate(const DominatorTree &DT,
void DominanceFrontierBase::print(std::ostream &o) const { void DominanceFrontierBase::print(std::ostream &o) const {
for (const_iterator I = begin(), E = end(); I != E; ++I) { for (const_iterator I = begin(), E = end(); I != E; ++I) {
o << "=============================--------------------------------\n" o << " DomFrontier for BB";
<< "\nDominance Frontier For Basic Block\n"; if (I->first)
WriteAsOperand(o, I->first, false); WriteAsOperand(o, I->first, false);
o << " is: \n" << I->second << "\n"; else
o << " <<exit node>>";
o << " is:\t" << I->second << "\n";
} }
} }