[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