[llvm] r300255 - [LCSSA] Efficiently compute blocks dominating at least one exit.

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Sun Apr 16 14:21:43 PDT 2017


This caused non-determinism as we're iterating over a SmallPtrSet.
I checked in a speculative fix as I'm not able to reproduce this
locally, I'll revert if the bot doesn't come back to green soon.

https://reviews.llvm.org/rL300431

On Thu, Apr 13, 2017 at 1:37 PM, Davide Italiano via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: davide
> Date: Thu Apr 13 15:36:59 2017
> New Revision: 300255
>
> URL: http://llvm.org/viewvc/llvm-project?rev=300255&view=rev
> Log:
> [LCSSA] Efficiently compute blocks dominating at least one exit.
>
> For LCSSA purposes, loop BBs not dominating any of the exits aren't
> interesting, as none of the values defined in these blocks can be
> used outside the loop.
>
> The way the code computed this information was by comparing each
> BB of the loop with each of the exit blocks and ask the dominator tree
> about their dominance relation. This is slow.
>
> A more efficient way, implemented here, is that of starting from the
> exit blocks and walking the dom upwards until we hit an header. By
> transitivity, all the blocks we encounter in our path dominate an exit.
>
> For the testcase provided in PR31851, this reduces compile time on
> `opt -O2` by ~25%, going from 1m47s to 1m22s.
>
> Thanks to Dan/MichaelZ for discussions/suggesting the approach/review.
>
> Differential Revision:  https://reviews.llvm.org/D31843
>
> Modified:
>     llvm/trunk/lib/Transforms/Utils/LCSSA.cpp
>
> Modified: llvm/trunk/lib/Transforms/Utils/LCSSA.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LCSSA.cpp?rev=300255&r1=300254&r2=300255&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/LCSSA.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/LCSSA.cpp Thu Apr 13 15:36:59 2017
> @@ -238,40 +238,75 @@ bool llvm::formLCSSAForInstructions(Smal
>    return Changed;
>  }
>
> -/// Return true if the specified block dominates at least
> -/// one of the blocks in the specified list.
> -static bool
> -blockDominatesAnExit(BasicBlock *BB,
> -                     DominatorTree &DT,
> -                     const SmallVectorImpl<BasicBlock *> &ExitBlocks) {
> -  DomTreeNode *DomNode = DT.getNode(BB);
> -  return any_of(ExitBlocks, [&](BasicBlock *EB) {
> -    return DT.dominates(DomNode, DT.getNode(EB));
> -  });
> +// Compute the set of BasicBlocks in the loop `L` dominating at least one exit.
> +static void computeBlocksDominatingExits(
> +    Loop &L, DominatorTree &DT, SmallVector<BasicBlock *, 8> &ExitBlocks,
> +    SmallPtrSet<BasicBlock *, 8> &BlocksDominatingExits) {
> +  SmallVector<BasicBlock *, 8> BBWorklist;
> +
> +  // We start from the exit blocks, as every block trivially dominates itself
> +  // (not strictly).
> +  for (BasicBlock *BB : ExitBlocks)
> +    BBWorklist.push_back(BB);
> +
> +  while (!BBWorklist.empty()) {
> +    BasicBlock *BB = BBWorklist.pop_back_val();
> +
> +    // Check if this is a loop header. If this is the case, we're done.
> +    if (L.getHeader() == BB)
> +      continue;
> +
> +    // Otherwise, add its immediate predecessor in the dominator tree to the
> +    // worklist, unless we visited it already.
> +    BasicBlock *IDomBB = DT.getNode(BB)->getIDom()->getBlock();
> +
> +    // Exit blocks can have an immediate dominator not beloinging to the
> +    // loop. For an exit block to be immediately dominated by another block
> +    // outside the loop, it implies not all paths from that dominator, to the
> +    // exit block, go through the loop.
> +    // Example:
> +    //
> +    // |---- A
> +    // |     |
> +    // |     B<--
> +    // |     |  |
> +    // |---> C --
> +    //       |
> +    //       D
> +    //
> +    // C is the exit block of the loop and it's immediately dominated by A,
> +    // which doesn't belong to the loop.
> +    if (!L.contains(IDomBB))
> +      continue;
> +
> +    if (BlocksDominatingExits.insert(IDomBB).second)
> +      BBWorklist.push_back(IDomBB);
> +  }
>  }
>
>  bool llvm::formLCSSA(Loop &L, DominatorTree &DT, LoopInfo *LI,
>                       ScalarEvolution *SE) {
>    bool Changed = false;
>
> -  // Get the set of exiting blocks.
>    SmallVector<BasicBlock *, 8> ExitBlocks;
>    L.getExitBlocks(ExitBlocks);
> -
>    if (ExitBlocks.empty())
>      return false;
>
> +  SmallPtrSet<BasicBlock *, 8> BlocksDominatingExits;
> +
> +  // We want to avoid use-scanning leveraging dominance informations.
> +  // If a block doesn't dominate any of the loop exits, the none of the values
> +  // defined in the loop can be used outside.
> +  // We compute the set of blocks fullfilling the conditions in advance
> +  // walking the dominator tree upwards until we hit a loop header.
> +  computeBlocksDominatingExits(L, DT, ExitBlocks, BlocksDominatingExits);
> +
>    SmallVector<Instruction *, 8> Worklist;
>
>    // Look at all the instructions in the loop, checking to see if they have uses
>    // outside the loop.  If so, put them into the worklist to rewrite those uses.
> -  for (BasicBlock *BB : L.blocks()) {
> -    // For large loops, avoid use-scanning by using dominance information:  In
> -    // particular, if a block does not dominate any of the loop exits, then none
> -    // of the values defined in the block could be used outside the loop.
> -    if (!blockDominatesAnExit(BB, DT, ExitBlocks))
> -      continue;
> -
> +  for (BasicBlock *BB : BlocksDominatingExits) {
>      for (Instruction &I : *BB) {
>        // Reject two common cases fast: instructions with no uses (like stores)
>        // and instructions with one use that is in the same block as this.
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits

-- 
Davide

"There are no solved problems; there are only problems that are more
or less solved" -- Henri Poincare


More information about the llvm-commits mailing list