Add and use DominatorTreeBase::findNearestCommonDominator().

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@37545 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Devang Patel 2007-06-11 23:31:22 +00:00
parent 976e2da081
commit fe7d4e50b8
3 changed files with 50 additions and 1 deletions

View File

@ -234,6 +234,10 @@ protected:
return dominates(getNode(A), getNode(B));
}
/// findNearestCommonDominator - Find nearest common dominator basic block
/// for basic block A and B. If there is no such block then return NULL.
BasicBlock *findNearestCommonDominator(BasicBlock *A, BasicBlock *B);
// dominates - Return true if A dominates B. This performs the
// special checks necessary if A and B are in the same basic block.
bool dominates(Instruction *A, Instruction *B);

View File

@ -768,7 +768,7 @@ void LoopSimplify::UpdateDomInfoForRevectoredPreds(BasicBlock *NewBB,
assert(i != PredBlocks.size() && "No reachable preds?");
for (i = i + 1; i < PredBlocks.size(); ++i) {
if (DT.isReachableFromEntry(PredBlocks[i]))
NewBBIDom = DT.nearestCommonDominator(NewBBIDom, PredBlocks[i]);
NewBBIDom = DT.findNearestCommonDominator(NewBBIDom, PredBlocks[i]);
}
assert(NewBBIDom && "No immediate dominator found??");

View File

@ -23,6 +23,7 @@
#include "llvm/Instructions.h"
#include "llvm/Support/Streams.h"
#include <algorithm>
#include <set>
using namespace llvm;
namespace llvm {
@ -369,6 +370,50 @@ void DominatorTreeBase::reset() {
RootNode = 0;
}
/// findNearestCommonDominator - Find nearest common dominator basic block
/// for basic block A and B. If there is no such block then return NULL.
BasicBlock *DominatorTreeBase::findNearestCommonDominator(BasicBlock *A, BasicBlock *B) {
assert (!isPostDominator() && "This is not implemented for post dominators");
assert (A->getParent() == B->getParent() && "Two blocks are not in same function");
// If either A or B is a entry block then it is nearest common dominator.
BasicBlock &Entry = A->getParent()->getEntryBlock();
if (A == &Entry || B == &Entry)
return &Entry;
// If A and B are same then A is nearest common dominator.
DomTreeNode *NodeA = getNode(A);
if (A != 0 && A == B)
return A;
DomTreeNode *NodeB = getNode(B);
// Collect NodeA dominators set.
std::set<DomTreeNode *> NodeADoms;
NodeADoms.insert(NodeA);
DomTreeNode *IDomA = NodeA->getIDom();
while(IDomA) {
NodeADoms.insert(IDomA);
IDomA = IDomA->getIDom();
}
// If B dominates A then B is nearest common dominator.
if (NodeADoms.count(NodeB) != 0)
return B;
// Walk NodeB immediate dominators chain and find common dominator node.
DomTreeNode *IDomB = NodeB->getIDom();
while(IDomB) {
if (NodeADoms.count(IDomB) != 0)
return IDomB->getBlock();
IDomB = IDomB->getIDom();
}
return NULL;
}
void DomTreeNode::setIDom(DomTreeNode *NewIDom) {
assert(IDom && "No immediate dominator?");
if (IDom != NewIDom) {