[llvm] r314934 - [LoopDeletion] Move deleteDeadLoop to to LoopUtils. NFC

Davide Italiano via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 4 14:13:52 PDT 2017


Thanks. Are you planning to introduce new consumers?

On Wed, Oct 4, 2017 at 1:42 PM, Marcello Maggioni via llvm-commits
<llvm-commits at lists.llvm.org> wrote:
> Author: mggm
> Date: Wed Oct  4 13:42:46 2017
> New Revision: 314934
>
> URL: http://llvm.org/viewvc/llvm-project?rev=314934&view=rev
> Log:
> [LoopDeletion] Move deleteDeadLoop to to LoopUtils. NFC
>
> Modified:
>     llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h
>     llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp
>     llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp
>
> Modified: llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h?rev=314934&r1=314933&r2=314934&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h (original)
> +++ llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h Wed Oct  4 13:42:46 2017
> @@ -439,6 +439,20 @@ bool hoistRegion(DomTreeNode *, AliasAna
>                   TargetLibraryInfo *, Loop *, AliasSetTracker *,
>                   LoopSafetyInfo *, OptimizationRemarkEmitter *ORE);
>
> +/// This function deletes dead loops. The caller of this function needs to
> +/// guarantee that the loop is infact dead.
> +/// The function requires a bunch or prerequisites to be present:
> +///   - The loop needs to be in LCSSA form
> +///   - The loop needs to have a Preheader
> +///   - A unique dedicated exit block must exist
> +///
> +/// This also updates the relevant analysis information in \p DT, \p SE, and \p
> +/// LI if pointers to those are provided.
> +/// It also updates the loop PM if an updater struct is provided.
> +
> +void deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE,
> +                    LoopInfo *LI);
> +
>  /// \brief Try to promote memory values to scalars by sinking stores out of
>  /// the loop and moving loads to before the loop.  We do this by looping over
>  /// the stores in the loop, looking for stores to Must pointers which are
>
> Modified: llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp?rev=314934&r1=314933&r2=314934&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp (original)
> +++ llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Wed Oct  4 13:42:46 2017
> @@ -30,21 +30,6 @@ using namespace llvm;
>
>  STATISTIC(NumDeleted, "Number of loops deleted");
>
> -/// This function deletes dead loops. The caller of this function needs to
> -/// guarantee that the loop is infact dead. Here we handle two kinds of dead
> -/// loop. The first kind (\p isLoopDead) is where only invariant values from
> -/// within the loop are used outside of it. The second kind (\p
> -/// isLoopNeverExecuted) is where the loop is provably never executed. We can
> -/// always remove never executed loops since they will not cause any difference
> -/// to program behaviour.
> -///
> -/// This also updates the relevant analysis information in \p DT, \p SE, and \p
> -/// LI. It also updates the loop PM if an updater struct is provided.
> -// TODO: This function will be used by loop-simplifyCFG as well. So, move this
> -// to LoopUtils.cpp
> -static void deleteDeadLoop(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
> -                           LoopInfo &LI);
> -
>  enum class LoopDeletionResult {
>    Unmodified,
>    Modified,
> @@ -183,7 +168,7 @@ static LoopDeletionResult deleteLoopIfDe
>          P->setIncomingValue(i, UndefValue::get(P->getType()));
>        BI++;
>      }
> -    deleteDeadLoop(L, DT, SE, LI);
> +    deleteDeadLoop(L, &DT, &SE, &LI);
>      ++NumDeleted;
>      return LoopDeletionResult::Deleted;
>    }
> @@ -219,129 +204,12 @@ static LoopDeletionResult deleteLoopIfDe
>    }
>
>    DEBUG(dbgs() << "Loop is invariant, delete it!");
> -  deleteDeadLoop(L, DT, SE, LI);
> +  deleteDeadLoop(L, &DT, &SE, &LI);
>    ++NumDeleted;
>
>    return LoopDeletionResult::Deleted;
>  }
>
> -static void deleteDeadLoop(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
> -                           LoopInfo &LI) {
> -  assert(L->isLCSSAForm(DT) && "Expected LCSSA!");
> -  auto *Preheader = L->getLoopPreheader();
> -  assert(Preheader && "Preheader should exist!");
> -
> -  // Now that we know the removal is safe, remove the loop by changing the
> -  // branch from the preheader to go to the single exit block.
> -  //
> -  // Because we're deleting a large chunk of code at once, the sequence in which
> -  // we remove things is very important to avoid invalidation issues.
> -
> -  // Tell ScalarEvolution that the loop is deleted. Do this before
> -  // deleting the loop so that ScalarEvolution can look at the loop
> -  // to determine what it needs to clean up.
> -  SE.forgetLoop(L);
> -
> -  auto *ExitBlock = L->getUniqueExitBlock();
> -  assert(ExitBlock && "Should have a unique exit block!");
> -  assert(L->hasDedicatedExits() && "Loop should have dedicated exits!");
> -
> -  auto *OldBr = dyn_cast<BranchInst>(Preheader->getTerminator());
> -  assert(OldBr && "Preheader must end with a branch");
> -  assert(OldBr->isUnconditional() && "Preheader must have a single successor");
> -  // Connect the preheader to the exit block. Keep the old edge to the header
> -  // around to perform the dominator tree update in two separate steps
> -  // -- #1 insertion of the edge preheader -> exit and #2 deletion of the edge
> -  // preheader -> header.
> -  //
> -  //
> -  // 0.  Preheader          1.  Preheader           2.  Preheader
> -  //        |                    |   |                   |
> -  //        V                    |   V                   |
> -  //      Header <--\            | Header <--\           | Header <--\
> -  //       |  |     |            |  |  |     |           |  |  |     |
> -  //       |  V     |            |  |  V     |           |  |  V     |
> -  //       | Body --/            |  | Body --/           |  | Body --/
> -  //       V                     V  V                    V  V
> -  //      Exit                   Exit                    Exit
> -  //
> -  // By doing this is two separate steps we can perform the dominator tree
> -  // update without using the batch update API.
> -  //
> -  // Even when the loop is never executed, we cannot remove the edge from the
> -  // source block to the exit block. Consider the case where the unexecuted loop
> -  // branches back to an outer loop. If we deleted the loop and removed the edge
> -  // coming to this inner loop, this will break the outer loop structure (by
> -  // deleting the backedge of the outer loop). If the outer loop is indeed a
> -  // non-loop, it will be deleted in a future iteration of loop deletion pass.
> -  IRBuilder<> Builder(OldBr);
> -  Builder.CreateCondBr(Builder.getFalse(), L->getHeader(), ExitBlock);
> -  // Remove the old branch. The conditional branch becomes a new terminator.
> -  OldBr->eraseFromParent();
> -
> -  // Update the dominator tree by informing it about the new edge from the
> -  // preheader to the exit.
> -  DT.insertEdge(Preheader, ExitBlock);
> -
> -  // Rewrite phis in the exit block to get their inputs from the Preheader
> -  // instead of the exiting block.
> -  BasicBlock::iterator BI = ExitBlock->begin();
> -  while (PHINode *P = dyn_cast<PHINode>(BI)) {
> -    // Set the zero'th element of Phi to be from the preheader and remove all
> -    // other incoming values. Given the loop has dedicated exits, all other
> -    // incoming values must be from the exiting blocks.
> -    int PredIndex = 0;
> -    P->setIncomingBlock(PredIndex, Preheader);
> -    // Removes all incoming values from all other exiting blocks (including
> -    // duplicate values from an exiting block).
> -    // Nuke all entries except the zero'th entry which is the preheader entry.
> -    // NOTE! We need to remove Incoming Values in the reverse order as done
> -    // below, to keep the indices valid for deletion (removeIncomingValues
> -    // updates getNumIncomingValues and shifts all values down into the operand
> -    // being deleted).
> -    for (unsigned i = 0, e = P->getNumIncomingValues() - 1; i != e; ++i)
> -      P->removeIncomingValue(e-i, false);
> -
> -    assert((P->getNumIncomingValues() == 1 &&
> -            P->getIncomingBlock(PredIndex) == Preheader) &&
> -           "Should have exactly one value and that's from the preheader!");
> -    ++BI;
> -  }
> -
> -  // Disconnect the loop body by branching directly to its exit.
> -  Builder.SetInsertPoint(Preheader->getTerminator());
> -  Builder.CreateBr(ExitBlock);
> -  // Remove the old branch.
> -  Preheader->getTerminator()->eraseFromParent();
> -
> -  // Inform the dominator tree about the removed edge.
> -  DT.deleteEdge(Preheader, L->getHeader());
> -
> -  // Remove the block from the reference counting scheme, so that we can
> -  // delete it freely later.
> -  for (auto *Block : L->blocks())
> -    Block->dropAllReferences();
> -
> -  // Erase the instructions and the blocks without having to worry
> -  // about ordering because we already dropped the references.
> -  // NOTE: This iteration is safe because erasing the block does not remove its
> -  // entry from the loop's block list.  We do that in the next section.
> -  for (Loop::block_iterator LI = L->block_begin(), LE = L->block_end();
> -       LI != LE; ++LI)
> -    (*LI)->eraseFromParent();
> -
> -  // Finally, the blocks from loopinfo.  This has to happen late because
> -  // otherwise our loop iterators won't work.
> -
> -  SmallPtrSet<BasicBlock *, 8> blocks;
> -  blocks.insert(L->block_begin(), L->block_end());
> -  for (BasicBlock *BB : blocks)
> -    LI.removeBlock(BB);
> -
> -  // The last step is to update LoopInfo now that we've eliminated this loop.
> -  LI.erase(L);
> -}
> -
>  PreservedAnalyses LoopDeletionPass::run(Loop &L, LoopAnalysisManager &AM,
>                                          LoopStandardAnalysisResults &AR,
>                                          LPMUpdater &Updater) {
>
> Modified: llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp?rev=314934&r1=314933&r2=314934&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp (original)
> +++ llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp Wed Oct  4 13:42:46 2017
> @@ -1137,6 +1137,128 @@ llvm::collectChildrenInLoop(DomTreeNode
>    return Worklist;
>  }
>
> +void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT = nullptr,
> +                          ScalarEvolution *SE = nullptr,
> +                          LoopInfo *LI = nullptr) {
> +  assert(!DT || L->isLCSSAForm(*DT) && "Expected LCSSA!");
> +  auto *Preheader = L->getLoopPreheader();
> +  assert(Preheader && "Preheader should exist!");
> +
> +  // Now that we know the removal is safe, remove the loop by changing the
> +  // branch from the preheader to go to the single exit block.
> +  //
> +  // Because we're deleting a large chunk of code at once, the sequence in which
> +  // we remove things is very important to avoid invalidation issues.
> +
> +  // Tell ScalarEvolution that the loop is deleted. Do this before
> +  // deleting the loop so that ScalarEvolution can look at the loop
> +  // to determine what it needs to clean up.
> +  if (SE)
> +    SE->forgetLoop(L);
> +
> +  auto *ExitBlock = L->getUniqueExitBlock();
> +  assert(ExitBlock && "Should have a unique exit block!");
> +  assert(L->hasDedicatedExits() && "Loop should have dedicated exits!");
> +
> +  auto *OldBr = dyn_cast<BranchInst>(Preheader->getTerminator());
> +  assert(OldBr && "Preheader must end with a branch");
> +  assert(OldBr->isUnconditional() && "Preheader must have a single successor");
> +  // Connect the preheader to the exit block. Keep the old edge to the header
> +  // around to perform the dominator tree update in two separate steps
> +  // -- #1 insertion of the edge preheader -> exit and #2 deletion of the edge
> +  // preheader -> header.
> +  //
> +  //
> +  // 0.  Preheader          1.  Preheader           2.  Preheader
> +  //        |                    |   |                   |
> +  //        V                    |   V                   |
> +  //      Header <--\            | Header <--\           | Header <--\
> +  //       |  |     |            |  |  |     |           |  |  |     |
> +  //       |  V     |            |  |  V     |           |  |  V     |
> +  //       | Body --/            |  | Body --/           |  | Body --/
> +  //       V                     V  V                    V  V
> +  //      Exit                   Exit                    Exit
> +  //
> +  // By doing this is two separate steps we can perform the dominator tree
> +  // update without using the batch update API.
> +  //
> +  // Even when the loop is never executed, we cannot remove the edge from the
> +  // source block to the exit block. Consider the case where the unexecuted loop
> +  // branches back to an outer loop. If we deleted the loop and removed the edge
> +  // coming to this inner loop, this will break the outer loop structure (by
> +  // deleting the backedge of the outer loop). If the outer loop is indeed a
> +  // non-loop, it will be deleted in a future iteration of loop deletion pass.
> +  IRBuilder<> Builder(OldBr);
> +  Builder.CreateCondBr(Builder.getFalse(), L->getHeader(), ExitBlock);
> +  // Remove the old branch. The conditional branch becomes a new terminator.
> +  OldBr->eraseFromParent();
> +
> +  // Rewrite phis in the exit block to get their inputs from the Preheader
> +  // instead of the exiting block.
> +  BasicBlock::iterator BI = ExitBlock->begin();
> +  while (PHINode *P = dyn_cast<PHINode>(BI)) {
> +    // Set the zero'th element of Phi to be from the preheader and remove all
> +    // other incoming values. Given the loop has dedicated exits, all other
> +    // incoming values must be from the exiting blocks.
> +    int PredIndex = 0;
> +    P->setIncomingBlock(PredIndex, Preheader);
> +    // Removes all incoming values from all other exiting blocks (including
> +    // duplicate values from an exiting block).
> +    // Nuke all entries except the zero'th entry which is the preheader entry.
> +    // NOTE! We need to remove Incoming Values in the reverse order as done
> +    // below, to keep the indices valid for deletion (removeIncomingValues
> +    // updates getNumIncomingValues and shifts all values down into the operand
> +    // being deleted).
> +    for (unsigned i = 0, e = P->getNumIncomingValues() - 1; i != e; ++i)
> +      P->removeIncomingValue(e - i, false);
> +
> +    assert((P->getNumIncomingValues() == 1 &&
> +            P->getIncomingBlock(PredIndex) == Preheader) &&
> +           "Should have exactly one value and that's from the preheader!");
> +    ++BI;
> +  }
> +
> +  // Disconnect the loop body by branching directly to its exit.
> +  Builder.SetInsertPoint(Preheader->getTerminator());
> +  Builder.CreateBr(ExitBlock);
> +  // Remove the old branch.
> +  Preheader->getTerminator()->eraseFromParent();
> +
> +  if (DT) {
> +    // Update the dominator tree by informing it about the new edge from the
> +    // preheader to the exit.
> +    DT->insertEdge(Preheader, ExitBlock);
> +    // Inform the dominator tree about the removed edge.
> +    DT->deleteEdge(Preheader, L->getHeader());
> +  }
> +
> +  // Remove the block from the reference counting scheme, so that we can
> +  // delete it freely later.
> +  for (auto *Block : L->blocks())
> +    Block->dropAllReferences();
> +
> +  if (LI) {
> +    // Erase the instructions and the blocks without having to worry
> +    // about ordering because we already dropped the references.
> +    // NOTE: This iteration is safe because erasing the block does not remove
> +    // its entry from the loop's block list.  We do that in the next section.
> +    for (Loop::block_iterator LpI = L->block_begin(), LpE = L->block_end();
> +         LpI != LpE; ++LpI)
> +      (*LpI)->eraseFromParent();
> +
> +    // Finally, the blocks from loopinfo.  This has to happen late because
> +    // otherwise our loop iterators won't work.
> +
> +    SmallPtrSet<BasicBlock *, 8> blocks;
> +    blocks.insert(L->block_begin(), L->block_end());
> +    for (BasicBlock *BB : blocks)
> +      LI->removeBlock(BB);
> +
> +    // The last step is to update LoopInfo now that we've eliminated this loop.
> +    LI->erase(L);
> +  }
> +}
> +
>  /// Returns true if the instruction in a loop is guaranteed to execute at least
>  /// once.
>  bool llvm::isGuaranteedToExecute(const Instruction &Inst,
>
>
> _______________________________________________
> 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