SmallPtrSet<const BlockT*, 8> DenseBlockSet;
+ /// Indicator that this loops has been "unlooped", so there's no loop here
+ /// anymore.
+ bool IsUnloop = false;
+
LoopBase(const LoopBase<BlockT, LoopT> &) = delete;
const LoopBase<BlockT, LoopT>&
operator=(const LoopBase<BlockT, LoopT> &) = delete;
return Blocks.size();
}
+ /// Mark this loop as having been unlooped - the last backedge was removed and
+ /// we no longer have a loop.
+ void markUnlooped() { IsUnloop = true; }
+
+ /// Return true if this no longer represents a loop.
+ bool isUnloop() const { return IsUnloop; }
+
/// isLoopExiting - True if terminator in the block can branch to another
/// block that is outside of the current loop.
///
/// updateUnloop - Update LoopInfo after removing the last backedge from a
/// loop--now the "unloop". This updates the loop forest and parent loops for
- /// each block so that Unloop is no longer referenced, but the caller must
- /// actually delete the Unloop object.
+ /// each block so that Unloop is no longer referenced, but does not actually
+ /// delete the Unloop object. Generally, the loop pass manager should manage
+ /// deleting the Unloop.
void updateUnloop(Loop *Unloop);
/// replacementPreservesLCSSAForm - Returns true if replacing From with To
analyze(DomTree);
}
-/// updateUnloop - The last backedge has been removed from a loop--now the
-/// "unloop". Find a new parent for the blocks contained within unloop and
-/// update the loop tree. We don't necessarily have valid dominators at this
-/// point, but LoopInfo is still valid except for the removal of this loop.
-///
-/// Note that Unloop may now be an empty loop. Calling Loop::getHeader without
-/// checking first is illegal.
void LoopInfo::updateUnloop(Loop *Unloop) {
+ Unloop->markAsUnloop();
// First handle the special case of no parent loop to simplify the algorithm.
if (!Unloop->getParentLoop()) {
LPPassManager::LPPassManager()
: FunctionPass(ID), PMDataManager() {
- skipThisLoop = false;
LI = nullptr;
CurrentLoop = nullptr;
}
/// Delete loop from the loop queue and loop hierarchy (LoopInfo).
void LPPassManager::deleteLoopFromQueue(Loop *L) {
-
+ assert(CurrentLoop == L && "deleting a loop that is not being operated on");
LI->updateUnloop(L);
-
- // Notify passes that the loop is being deleted.
- deleteSimpleAnalysisLoop(L);
-
- // If L is current loop then skip rest of the passes and let
- // runOnFunction remove L from LQ. Otherwise, remove L from LQ now
- // and continue applying other passes on CurrentLoop.
- if (CurrentLoop == L)
- skipThisLoop = true;
-
- delete L;
-
- if (skipThisLoop)
- return;
-
- for (std::deque<Loop *>::iterator I = LQ.begin(),
- E = LQ.end(); I != E; ++I) {
- if (*I == L) {
- LQ.erase(I);
- break;
- }
- }
}
// Inset loop into loop nest (LoopInfo) and loop queue (LQ).
// Walk Loops
while (!LQ.empty()) {
- CurrentLoop = LQ.back();
- skipThisLoop = false;
-
+ CurrentLoop = LQ.back();
// Run all passes on the current Loop.
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
LoopPass *P = getContainedPass(Index);
if (Changed)
dumpPassInfo(P, MODIFICATION_MSG, ON_LOOP_MSG,
- skipThisLoop ? "<deleted>" :
- CurrentLoop->getHeader()->getName());
+ CurrentLoop->isUnloop()
+ ? "<deleted>"
+ : CurrentLoop->getHeader()->getName());
dumpPreservedSet(P);
- if (!skipThisLoop) {
+ if (CurrentLoop->isUnloop()) {
+ // Notify passes that the loop is being deleted.
+ deleteSimpleAnalysisLoop(CurrentLoop);
+ } else {
// Manually check that this loop is still healthy. This is done
// instead of relying on LoopInfo::verifyLoop since LoopInfo
// is a function pass and it's really expensive to verify every
removeNotPreservedAnalysis(P);
recordAvailableAnalysis(P);
- removeDeadPasses(P,
- skipThisLoop ? "<deleted>" :
- CurrentLoop->getHeader()->getName(),
+ removeDeadPasses(P, CurrentLoop->isUnloop()
+ ? "<deleted>"
+ : CurrentLoop->getHeader()->getName(),
ON_LOOP_MSG);
- if (skipThisLoop)
+ if (CurrentLoop->isUnloop())
// Do not run other passes on this loop.
break;
}
// If the loop was deleted, release all the loop passes. This frees up
// some memory, and avoids trouble with the pass manager trying to call
// verifyAnalysis on them.
- if (skipThisLoop)
+ if (CurrentLoop->isUnloop()) {
for (unsigned Index = 0; Index < getNumContainedPasses(); ++Index) {
Pass *P = getContainedPass(Index);
freePass(P, "<deleted>", ON_LOOP_MSG);
}
+ delete CurrentLoop;
+ }
// Pop the loop from queue after running all passes.
LQ.pop_back();