mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-18 12:29:21 +00:00
Teach UpdateDomInfoForRevectoredPreds to handle revectored preds that are not
reachable, making it general purpose enough for use by InsertPreheaderForLoop. Eliminate custom dominfo updating code in InsertPreheaderForLoop, using UpdateDomInfoForRevectoredPreds instead. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@30586 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
e87a4b6cb0
commit
c3984578be
@ -353,9 +353,10 @@ void LoopSimplify::InsertPreheaderForLoop(Loop *L) {
|
|||||||
if (!L->contains(*PI)) // Coming in from outside the loop?
|
if (!L->contains(*PI)) // Coming in from outside the loop?
|
||||||
OutsideBlocks.push_back(*PI); // Keep track of it...
|
OutsideBlocks.push_back(*PI); // Keep track of it...
|
||||||
|
|
||||||
// Split out the loop pre-header
|
// Split out the loop pre-header.
|
||||||
BasicBlock *NewBB =
|
BasicBlock *NewBB =
|
||||||
SplitBlockPredecessors(Header, ".preheader", OutsideBlocks);
|
SplitBlockPredecessors(Header, ".preheader", OutsideBlocks);
|
||||||
|
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Update analysis results now that we have performed the transformation
|
// Update analysis results now that we have performed the transformation
|
||||||
@ -365,86 +366,7 @@ void LoopSimplify::InsertPreheaderForLoop(Loop *L) {
|
|||||||
if (Loop *Parent = L->getParentLoop())
|
if (Loop *Parent = L->getParentLoop())
|
||||||
Parent->addBasicBlockToLoop(NewBB, *LI);
|
Parent->addBasicBlockToLoop(NewBB, *LI);
|
||||||
|
|
||||||
DominatorSet &DS = getAnalysis<DominatorSet>(); // Update dominator info
|
UpdateDomInfoForRevectoredPreds(NewBB, OutsideBlocks);
|
||||||
DominatorTree &DT = getAnalysis<DominatorTree>();
|
|
||||||
|
|
||||||
|
|
||||||
// Update the dominator tree information.
|
|
||||||
// The immediate dominator of the preheader is the immediate dominator of
|
|
||||||
// the old header.
|
|
||||||
DominatorTree::Node *PHDomTreeNode =
|
|
||||||
DT.createNewNode(NewBB, DT.getNode(Header)->getIDom());
|
|
||||||
BasicBlock *oldHeaderIDom = DT.getNode(Header)->getIDom()->getBlock();
|
|
||||||
|
|
||||||
// Change the header node so that PNHode is the new immediate dominator
|
|
||||||
DT.changeImmediateDominator(DT.getNode(Header), PHDomTreeNode);
|
|
||||||
|
|
||||||
{
|
|
||||||
// The blocks that dominate NewBB are the blocks that dominate Header,
|
|
||||||
// minus Header, plus NewBB.
|
|
||||||
DominatorSet::DomSetType DomSet = DS.getDominators(Header);
|
|
||||||
DomSet.erase(Header); // Header does not dominate us...
|
|
||||||
DS.addBasicBlock(NewBB, DomSet);
|
|
||||||
|
|
||||||
// The newly created basic block dominates all nodes dominated by Header.
|
|
||||||
for (df_iterator<DominatorTree::Node*> DFI = df_begin(PHDomTreeNode),
|
|
||||||
E = df_end(PHDomTreeNode); DFI != E; ++DFI)
|
|
||||||
DS.addDominator((*DFI)->getBlock(), NewBB);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update immediate dominator information if we have it...
|
|
||||||
if (ImmediateDominators *ID = getAnalysisToUpdate<ImmediateDominators>()) {
|
|
||||||
// Whatever i-dominated the header node now immediately dominates NewBB
|
|
||||||
ID->addNewBlock(NewBB, ID->get(Header));
|
|
||||||
|
|
||||||
// The preheader now is the immediate dominator for the header node...
|
|
||||||
ID->setImmediateDominator(Header, NewBB);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update ET Forest information if we have it...
|
|
||||||
if (ETForest *EF = getAnalysisToUpdate<ETForest>()) {
|
|
||||||
// Whatever i-dominated the header node now immediately dominates NewBB
|
|
||||||
EF->addNewBlock(NewBB, oldHeaderIDom);
|
|
||||||
|
|
||||||
// The preheader now is the immediate dominator for the header node...
|
|
||||||
EF->setImmediateDominator(Header, NewBB);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update dominance frontier information...
|
|
||||||
if (DominanceFrontier *DF = getAnalysisToUpdate<DominanceFrontier>()) {
|
|
||||||
// The DF(NewBB) is just (DF(Header)-Header), because NewBB dominates
|
|
||||||
// everything that Header does, and it strictly dominates Header in
|
|
||||||
// addition.
|
|
||||||
assert(DF->find(Header) != DF->end() && "Header node doesn't have DF set?");
|
|
||||||
DominanceFrontier::DomSetType NewDFSet = DF->find(Header)->second;
|
|
||||||
NewDFSet.erase(Header);
|
|
||||||
DF->addBasicBlock(NewBB, NewDFSet);
|
|
||||||
|
|
||||||
// Now we must loop over all of the dominance frontiers in the function,
|
|
||||||
// replacing occurrences of Header with NewBB in some cases. If a block
|
|
||||||
// dominates a (now) predecessor of NewBB, but did not strictly dominate
|
|
||||||
// Header, it will have Header in it's DF set, but should now have NewBB in
|
|
||||||
// its set.
|
|
||||||
for (unsigned i = 0, e = OutsideBlocks.size(); i != e; ++i) {
|
|
||||||
// Get all of the dominators of the predecessor...
|
|
||||||
const DominatorSet::DomSetType &PredDoms =
|
|
||||||
DS.getDominators(OutsideBlocks[i]);
|
|
||||||
for (DominatorSet::DomSetType::const_iterator PDI = PredDoms.begin(),
|
|
||||||
PDE = PredDoms.end(); PDI != PDE; ++PDI) {
|
|
||||||
BasicBlock *PredDom = *PDI;
|
|
||||||
// If the loop header is in DF(PredDom), then PredDom didn't dominate
|
|
||||||
// the header but did dominate a predecessor outside of the loop. Now
|
|
||||||
// we change this entry to include the preheader in the DF instead of
|
|
||||||
// the header.
|
|
||||||
DominanceFrontier::iterator DFI = DF->find(PredDom);
|
|
||||||
assert(DFI != DF->end() && "No dominance frontier for node?");
|
|
||||||
if (DFI->second.count(Header)) {
|
|
||||||
DF->removeFromFrontier(DFI, Header);
|
|
||||||
DF->addToFrontier(DFI, NewBB);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// RewriteLoopExitBlock - Ensure that the loop preheader dominates all exit
|
/// RewriteLoopExitBlock - Ensure that the loop preheader dominates all exit
|
||||||
@ -727,10 +649,26 @@ void LoopSimplify::UpdateDomInfoForRevectoredPreds(BasicBlock *NewBB,
|
|||||||
// intersection of the dominators of predecessors, plus the block itself.
|
// intersection of the dominators of predecessors, plus the block itself.
|
||||||
//
|
//
|
||||||
DominatorSet::DomSetType NewBBDomSet = DS.getDominators(PredBlocks[0]);
|
DominatorSet::DomSetType NewBBDomSet = DS.getDominators(PredBlocks[0]);
|
||||||
for (unsigned i = 1, e = PredBlocks.size(); i != e; ++i)
|
{
|
||||||
set_intersect(NewBBDomSet, DS.getDominators(PredBlocks[i]));
|
unsigned i, e = PredBlocks.size();
|
||||||
NewBBDomSet.insert(NewBB); // All blocks dominate themselves...
|
// It is possible for some preds to not be reachable, and thus have empty
|
||||||
DS.addBasicBlock(NewBB, NewBBDomSet);
|
// dominator sets (all blocks must dom themselves, so no domset would
|
||||||
|
// otherwise be empty). If we see any of these, don't intersect with them,
|
||||||
|
// as that would certainly leave the resultant set empty.
|
||||||
|
for (i = 1; NewBBDomSet.empty(); ++i) {
|
||||||
|
assert(i != e && "Didn't find reachable pred?");
|
||||||
|
NewBBDomSet = DS.getDominators(PredBlocks[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intersect the rest of the non-empty sets.
|
||||||
|
for (; i != e; ++i) {
|
||||||
|
const DominatorSet::DomSetType &PredDS = DS.getDominators(PredBlocks[i]);
|
||||||
|
if (!PredDS.empty())
|
||||||
|
set_intersect(NewBBDomSet, PredDS);
|
||||||
|
}
|
||||||
|
NewBBDomSet.insert(NewBB); // All blocks dominate themselves.
|
||||||
|
DS.addBasicBlock(NewBB, NewBBDomSet);
|
||||||
|
}
|
||||||
|
|
||||||
// The newly inserted basic block will dominate existing basic blocks iff the
|
// The newly inserted basic block will dominate existing basic blocks iff the
|
||||||
// PredBlocks dominate all of the non-pred blocks. If all predblocks dominate
|
// PredBlocks dominate all of the non-pred blocks. If all predblocks dominate
|
||||||
@ -739,8 +677,14 @@ void LoopSimplify::UpdateDomInfoForRevectoredPreds(BasicBlock *NewBB,
|
|||||||
bool NewBBDominatesNewBBSucc = true;
|
bool NewBBDominatesNewBBSucc = true;
|
||||||
{
|
{
|
||||||
BasicBlock *OnePred = PredBlocks[0];
|
BasicBlock *OnePred = PredBlocks[0];
|
||||||
for (unsigned i = 1, e = PredBlocks.size(); i != e; ++i)
|
unsigned i, e = PredBlocks.size();
|
||||||
if (PredBlocks[i] != OnePred) {
|
for (i = 1; !DS.isReachable(OnePred); ++i) {
|
||||||
|
assert(i != e && "Didn't find reachable pred?");
|
||||||
|
OnePred = PredBlocks[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i != e; ++i)
|
||||||
|
if (PredBlocks[i] != OnePred && DS.isReachable(PredBlocks[i])) {
|
||||||
NewBBDominatesNewBBSucc = false;
|
NewBBDominatesNewBBSucc = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -777,15 +721,22 @@ void LoopSimplify::UpdateDomInfoForRevectoredPreds(BasicBlock *NewBB,
|
|||||||
DS.addDominator(I, NewBB);
|
DS.addDominator(I, NewBB);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update immediate dominator information if we have it...
|
// Update immediate dominator information if we have it.
|
||||||
BasicBlock *NewBBIDom = 0;
|
BasicBlock *NewBBIDom = 0;
|
||||||
if (ImmediateDominators *ID = getAnalysisToUpdate<ImmediateDominators>()) {
|
if (ImmediateDominators *ID = getAnalysisToUpdate<ImmediateDominators>()) {
|
||||||
// To find the immediate dominator of the new exit node, we trace up the
|
// To find the immediate dominator of the new exit node, we trace up the
|
||||||
// immediate dominators of a predecessor until we find a basic block that
|
// immediate dominators of a predecessor until we find a basic block that
|
||||||
// dominates the exit block.
|
// dominates the exit block.
|
||||||
//
|
//
|
||||||
BasicBlock *Dom = PredBlocks[0]; // Some random predecessor...
|
BasicBlock *Dom = PredBlocks[0]; // Some random predecessor.
|
||||||
while (!NewBBDomSet.count(Dom)) { // Loop until we find a dominator...
|
|
||||||
|
// Find a reachable pred.
|
||||||
|
for (unsigned i = 1; !DS.isReachable(Dom); ++i) {
|
||||||
|
assert(i != PredBlocks.size() && "Didn't find reachable pred!");
|
||||||
|
Dom = PredBlocks[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!NewBBDomSet.count(Dom)) { // Loop until we find a dominator.
|
||||||
assert(Dom != 0 && "No shared dominator found???");
|
assert(Dom != 0 && "No shared dominator found???");
|
||||||
Dom = ID->get(Dom);
|
Dom = ID->get(Dom);
|
||||||
}
|
}
|
||||||
@ -809,7 +760,14 @@ void LoopSimplify::UpdateDomInfoForRevectoredPreds(BasicBlock *NewBB,
|
|||||||
if (NewBBIDom) {
|
if (NewBBIDom) {
|
||||||
NewBBIDomNode = DT->getNode(NewBBIDom);
|
NewBBIDomNode = DT->getNode(NewBBIDom);
|
||||||
} else {
|
} else {
|
||||||
NewBBIDomNode = DT->getNode(PredBlocks[0]); // Random pred
|
// Scan all the pred blocks that were pulled out. Any individual one may
|
||||||
|
// actually be unreachable, which would mean it doesn't have dom info.
|
||||||
|
NewBBIDomNode = 0;
|
||||||
|
for (unsigned i = 0; !NewBBIDomNode; ++i) {
|
||||||
|
assert(i != PredBlocks.size() && "No reachable preds?");
|
||||||
|
NewBBIDomNode = DT->getNode(PredBlocks[i]);
|
||||||
|
}
|
||||||
|
|
||||||
while (!NewBBDomSet.count(NewBBIDomNode->getBlock())) {
|
while (!NewBBDomSet.count(NewBBIDomNode->getBlock())) {
|
||||||
NewBBIDomNode = NewBBIDomNode->getIDom();
|
NewBBIDomNode = NewBBIDomNode->getIDom();
|
||||||
assert(NewBBIDomNode && "No shared dominator found??");
|
assert(NewBBIDomNode && "No shared dominator found??");
|
||||||
|
Loading…
Reference in New Issue
Block a user