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:
parent
8157505fae
commit
630d2954be
|
|
@ -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";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue