[llvm-commits] [llvm] r137276 - in /llvm/trunk: include/llvm/Analysis/LoopInfo.h lib/Analysis/LoopInfo.cpp lib/Analysis/LoopPass.cpp
Nick Lewycky
nicholas at mxc.ca
Wed Aug 10 21:19:33 PDT 2011
Andrew Trick wrote:
> Author: atrick
> Date: Wed Aug 10 18:22:57 2011
> New Revision: 137276
>
> URL: http://llvm.org/viewvc/llvm-project?rev=137276&view=rev
> Log:
> Reapplying r136844.
>
> An algorithm for incrementally updating LoopInfo within a
> LoopPassManager. The incremental update should be extremely cheap in
> most cases and can be used in places where it's not feasible to
> regenerate the entire loop forest.
>
> - "Unloop" is a node in the loop tree whose last backedge has been removed.
> - Perform reverse dataflow on the block inside Unloop to propagate the
> nearest loop from the block's successors.
> - For reducible CFG, each block in unloop is visited exactly
> once. This is because unloop no longer has a backedge and blocks
> within subloops don't change parents.
> - Immediate subloops are summarized by the nearest loop reachable from
> their exits or exits within nested subloops.
> - At completion the unloop blocks each have a new parent loop, and
> each immediate subloop has a new parent.
Awesome!
> +/// updateSubloopParents - Update the parent loop for all subloops directly
> +/// nested within unloop.
> +void UnloopUpdater::updateSubloopParents() {
> + while (!Unloop->empty()) {
> + Loop *Subloop = *(Unloop->end()-1);
> + Unloop->removeChildLoop(Unloop->end()-1);
I think you want "llvm::prior(Unloop->end())" instead.
> +
> + assert(SubloopParents.count(Subloop)&& "DFS failed to visit subloop");
> + if (SubloopParents[Subloop])
> + SubloopParents[Subloop]->addChildLoop(Subloop);
> + }
> +}
> +
> +/// getNearestLoop - Return the nearest parent loop among this block's
> +/// successors. If a successor is a subloop header, consider its parent to be
> +/// the nearest parent of the subloop's exits.
> +///
> +/// For subloop blocks, simply update SubloopParents and return NULL.
> +Loop *UnloopUpdater::getNearestLoop(BasicBlock *BB, Loop *BBLoop) {
> +
> + // Initialy for blocks directly contained by Unloop, NearLoop == Unloop and is
Typo, "Initialy".
> @@ -392,6 +560,82 @@
> return false;
> }
>
> +/// 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 necessarilly have valid dominators at this
Typo, "neccessarilly".
> +/// 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) {
> +
> + // First handle the special case of no parent loop to simplify the algorithm.
> + if (!Unloop->getParentLoop()) {
> + // Since BBLoop had no parent, Unloop blocks are no longer in a loop.
> + for (Loop::block_iterator I = Unloop->block_begin(),
> + E = Unloop->block_end(); I != E; ++I) {
> +
> + // Don't reparent blocks in subloops.
> + if (getLoopFor(*I) != Unloop)
> + continue;
> +
> + // Blocks no longer have a parent but are still referenced by Unloop until
> + // the Unloop object is deleted.
> + LI.changeLoopFor(*I, 0);
> + }
> +
> + // Remove the loop from the top-level LoopInfo object.
> + for (LoopInfo::iterator I = LI.begin(), E = LI.end();; ++I) {
> + assert(I != E&& "Couldn't find loop");
> + if (*I == Unloop) {
> + LI.removeLoop(I);
> + break;
> + }
> + }
> +
> + // Move all of the subloops to the top-level.
> + while (!Unloop->empty())
> + LI.addTopLevelLoop(Unloop->removeChildLoop(Unloop->end()-1));
llvm::prior again.
Nick
More information about the llvm-commits
mailing list