[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