bool Loop::isLoopExit(const BasicBlock *BB) const {
for (BasicBlock::succ_const_iterator SI = succ_begin(BB), SE = succ_end(BB);
SI != SE; ++SI) {
- if (! contains(*SI))
+ if (!contains(*SI))
return true;
}
return false;
}
unsigned Loop::getNumBackEdges() const {
- unsigned numBackEdges = 0;
- BasicBlock *header = Blocks.front();
+ unsigned NumBackEdges = 0;
+ BasicBlock *H = getHeader();
for (std::vector<BasicBlock*>::const_iterator I = Blocks.begin(),
- E = Blocks.end(); I != E; ++I) {
+ E = Blocks.end(); I != E; ++I)
for (BasicBlock::succ_iterator SI = succ_begin(*I), SE = succ_end(*I);
SI != SE; ++SI)
- if (header == *SI)
- ++numBackEdges;
- }
- return numBackEdges;
+ if (*SI == H)
+ ++NumBackEdges;
+
+ return NumBackEdges;
}
void Loop::print(std::ostream &OS) const {
for (unsigned i = 0; i < getBlocks().size(); ++i) {
if (i) OS << ",";
- WriteAsOperand(OS, (const Value*)getBlocks()[i]);
+ WriteAsOperand(OS, getBlocks()[i], false);
+ }
+ if (!ExitBlocks.empty()) {
+ OS << "\tExitBlocks: ";
+ for (unsigned i = 0; i < getExitBlocks().size(); ++i) {
+ if (i) OS << ",";
+ WriteAsOperand(OS, getExitBlocks()[i], false);
+ }
}
+
OS << "\n";
for (unsigned i = 0, e = getSubLoops().size(); i != e; ++i)
getSubLoops()[i]->print(OS);
}
+void Loop::dump() const {
+ print(std::cerr);
+}
+
+
//===----------------------------------------------------------------------===//
// LoopInfo implementation
//
void LoopInfo::print(std::ostream &OS) const {
for (unsigned i = 0; i < TopLevelLoops.size(); ++i)
TopLevelLoops[i]->print(OS);
+#if 0
+ for (std::map<BasicBlock*, Loop*>::const_iterator I = BBMap.begin(),
+ E = BBMap.end(); I != E; ++I)
+ OS << "BB '" << I->first->getName() << "' level = "
+ << I->second->LoopDepth << "\n";
+#endif
}
Loop *LoopInfo::ConsiderForLoop(BasicBlock *BB, const DominatorSet &DS) {
std::vector<BasicBlock *> TodoStack;
// Scan the predecessors of BB, checking to see if BB dominates any of
- // them.
+ // them. This identifies backedges which target this node...
for (pred_iterator I = pred_begin(BB), E = pred_end(BB); I != E; ++I)
if (DS.dominates(BB, *I)) // If BB dominates it's predecessor...
TodoStack.push_back(*I);
- if (TodoStack.empty()) return 0; // Doesn't dominate any predecessors...
+ if (TodoStack.empty()) return 0; // No backedges to this block...
// Create a new loop to represent this basic block...
Loop *L = new Loop(BB);
BasicBlock *X = TodoStack.back();
TodoStack.pop_back();
- if (!L->contains(X)) { // As of yet unprocessed??
- L->Blocks.push_back(X);
+ if (!L->contains(X)) { // As of yet unprocessed??
+ // Check to see if this block already belongs to a loop. If this occurs
+ // then we have a case where a loop that is supposed to be a child of the
+ // current loop was processed before the current loop. When this occurs,
+ // this child loop gets added to a part of the current loop, making it a
+ // sibling to the current loop. We have to reparent this loop.
+ if (Loop *SubLoop = const_cast<Loop*>(getLoopFor(X)))
+ if (SubLoop->getHeader() == X && X != BB) {
+ // Remove the subloop from it's current parent...
+ assert(SubLoop->ParentLoop && SubLoop->ParentLoop != L);
+ Loop *SLP = SubLoop->ParentLoop; // SubLoopParent
+ std::vector<Loop*>::iterator I =
+ std::find(SLP->SubLoops.begin(), SLP->SubLoops.end(), SubLoop);
+ assert(I != SLP->SubLoops.end() && "SubLoop not a child of parent?");
+ SLP->SubLoops.erase(I); // Remove from parent...
+
+ // Add the subloop to THIS loop...
+ SubLoop->ParentLoop = L;
+ L->SubLoops.push_back(SubLoop);
+ }
+ // Normal case, add the block to our loop...
+ L->Blocks.push_back(X);
+
// Add all of the predecessors of X to the end of the work stack...
TodoStack.insert(TodoStack.end(), pred_begin(X), pred_end(X));
}
}
+ // If there are any loops nested within this loop, create them now!
+ for (std::vector<BasicBlock*>::iterator I = L->Blocks.begin(),
+ E = L->Blocks.end(); I != E; ++I)
+ if (Loop *NewLoop = ConsiderForLoop(*I, DS)) {
+ L->SubLoops.push_back(NewLoop);
+ NewLoop->ParentLoop = L;
+ }
+
+
// Add the basic blocks that comprise this loop to the BBMap so that this
- // loop can be found for them. Also check subsidary basic blocks to see if
- // they start subloops of their own.
+ // loop can be found for them.
//
- for (std::vector<BasicBlock*>::reverse_iterator I = L->Blocks.rbegin(),
- E = L->Blocks.rend(); I != E; ++I)
-
- // Check to see if this block starts a new loop
- if (*I != BB)
- if (Loop *NewLoop = ConsiderForLoop(*I, DS)) {
- L->SubLoops.push_back(NewLoop);
- NewLoop->ParentLoop = L;
- } else {
- std::map<BasicBlock*, Loop*>::iterator BBMI = BBMap.lower_bound(*I);
- if (BBMI == BBMap.end() || BBMI->first != *I) { // Not in map yet...
- BBMap.insert(BBMI, std::make_pair(*I, L));
- } else {
- // If this is already in the BBMap then this means that we already added
- // a loop for it, but incorrectly added the loop to a higher level loop
- // instead of the current loop we are creating. Fix this now by moving
- // the loop into the correct subloop.
- //
- Loop *SubLoop = BBMI->second;
- Loop *OldSubLoopParent = SubLoop->getParentLoop();
- if (OldSubLoopParent != L) {
- // Remove SubLoop from OldSubLoopParent's list of subloops...
- std::vector<Loop*>::iterator I =
- std::find(OldSubLoopParent->SubLoops.begin(),
- OldSubLoopParent->SubLoops.end(), SubLoop);
- assert(I != OldSubLoopParent->SubLoops.end()
- && "Loop parent doesn't contain loop?");
- OldSubLoopParent->SubLoops.erase(I);
- SubLoop->ParentLoop = L;
- L->SubLoops.push_back(SubLoop);
- }
- }
- }
+ for (std::vector<BasicBlock*>::iterator I = L->Blocks.begin(),
+ E = L->Blocks.end(); I != E; ++I) {
+ std::map<BasicBlock*, Loop*>::iterator BBMI = BBMap.lower_bound(*I);
+ if (BBMI == BBMap.end() || BBMI->first != *I) // Not in map yet...
+ BBMap.insert(BBMI, std::make_pair(*I, L)); // Must be at this level
+ }
+
+ // Now that we know all of the blocks that make up this loop, see if there are
+ // any branches to outside of the loop... building the ExitBlocks list.
+ for (std::vector<BasicBlock*>::iterator BI = L->Blocks.begin(),
+ BE = L->Blocks.end(); BI != BE; ++BI)
+ for (succ_iterator I = succ_begin(*BI), E = succ_end(*BI); I != E; ++I)
+ if (!L->contains(*I)) // Not in current loop?
+ L->ExitBlocks.push_back(*I); // It must be an exit block...
return L;
}
return 0; // Multiple predecessors outside the loop
Out = *PI;
}
+
+ // Make sure there is only one exit out of the preheader...
+ succ_iterator SI = succ_begin(Out);
+ ++SI;
+ if (SI != succ_end(Out))
+ return 0; // Multiple exits from the block, must not be a preheader.
+
// If there is exactly one preheader, return it. If there was zero, then Out
// is still null.
L = L->getParentLoop();
}
}
+
+/// changeExitBlock - This method is used to update loop information. All
+/// instances of the specified Old basic block are removed from the exit list
+/// and replaced with New.
+///
+void Loop::changeExitBlock(BasicBlock *Old, BasicBlock *New) {
+ assert(Old != New && "Cannot changeExitBlock to the same thing!");
+ assert(Old && New && "Cannot changeExitBlock to or from a null node!");
+ assert(hasExitBlock(Old) && "Old exit block not found!");
+ std::vector<BasicBlock*>::iterator
+ I = std::find(ExitBlocks.begin(), ExitBlocks.end(), Old);
+ while (I != ExitBlocks.end()) {
+ *I = New;
+ I = std::find(I+1, ExitBlocks.end(), Old);
+ }
+}