diff options
Diffstat (limited to 'lib/Transforms/Utils/LoopUtils.cpp')
| -rw-r--r-- | lib/Transforms/Utils/LoopUtils.cpp | 68 | 
1 files changed, 66 insertions, 2 deletions
| diff --git a/lib/Transforms/Utils/LoopUtils.cpp b/lib/Transforms/Utils/LoopUtils.cpp index 412f6129407e..0ed33945ef40 100644 --- a/lib/Transforms/Utils/LoopUtils.cpp +++ b/lib/Transforms/Utils/LoopUtils.cpp @@ -12,6 +12,7 @@  //===----------------------------------------------------------------------===//  #include "llvm/Transforms/Utils/LoopUtils.h" +#include "llvm/ADT/ScopeExit.h"  #include "llvm/Analysis/AliasAnalysis.h"  #include "llvm/Analysis/BasicAliasAnalysis.h"  #include "llvm/Analysis/GlobalsModRef.h" @@ -29,6 +30,7 @@  #include "llvm/IR/ValueHandle.h"  #include "llvm/Pass.h"  #include "llvm/Support/Debug.h" +#include "llvm/Transforms/Utils/BasicBlockUtils.h"  using namespace llvm;  using namespace llvm::PatternMatch; @@ -87,8 +89,7 @@ RecurrenceDescriptor::lookThroughAnd(PHINode *Phi, Type *&RT,    // Matches either I & 2^x-1 or 2^x-1 & I. If we find a match, we update RT    // with a new integer type of the corresponding bit width. -  if (match(J, m_CombineOr(m_And(m_Instruction(I), m_APInt(M)), -                           m_And(m_APInt(M), m_Instruction(I))))) { +  if (match(J, m_c_And(m_Instruction(I), m_APInt(M)))) {      int32_t Bits = (*M + 1).exactLogBase2();      if (Bits > 0) {        RT = IntegerType::get(Phi->getContext(), Bits); @@ -923,6 +924,69 @@ bool InductionDescriptor::isInductionPHI(PHINode *Phi, const Loop *TheLoop,    return true;  } +bool llvm::formDedicatedExitBlocks(Loop *L, DominatorTree *DT, LoopInfo *LI, +                                   bool PreserveLCSSA) { +  bool Changed = false; + +  // We re-use a vector for the in-loop predecesosrs. +  SmallVector<BasicBlock *, 4> InLoopPredecessors; + +  auto RewriteExit = [&](BasicBlock *BB) { +    assert(InLoopPredecessors.empty() && +           "Must start with an empty predecessors list!"); +    auto Cleanup = make_scope_exit([&] { InLoopPredecessors.clear(); }); + +    // See if there are any non-loop predecessors of this exit block and +    // keep track of the in-loop predecessors. +    bool IsDedicatedExit = true; +    for (auto *PredBB : predecessors(BB)) +      if (L->contains(PredBB)) { +        if (isa<IndirectBrInst>(PredBB->getTerminator())) +          // We cannot rewrite exiting edges from an indirectbr. +          return false; + +        InLoopPredecessors.push_back(PredBB); +      } else { +        IsDedicatedExit = false; +      } + +    assert(!InLoopPredecessors.empty() && "Must have *some* loop predecessor!"); + +    // Nothing to do if this is already a dedicated exit. +    if (IsDedicatedExit) +      return false; + +    auto *NewExitBB = SplitBlockPredecessors( +        BB, InLoopPredecessors, ".loopexit", DT, LI, PreserveLCSSA); + +    if (!NewExitBB) +      DEBUG(dbgs() << "WARNING: Can't create a dedicated exit block for loop: " +                   << *L << "\n"); +    else +      DEBUG(dbgs() << "LoopSimplify: Creating dedicated exit block " +                   << NewExitBB->getName() << "\n"); +    return true; +  }; + +  // Walk the exit blocks directly rather than building up a data structure for +  // them, but only visit each one once. +  SmallPtrSet<BasicBlock *, 4> Visited; +  for (auto *BB : L->blocks()) +    for (auto *SuccBB : successors(BB)) { +      // We're looking for exit blocks so skip in-loop successors. +      if (L->contains(SuccBB)) +        continue; + +      // Visit each exit block exactly once. +      if (!Visited.insert(SuccBB).second) +        continue; + +      Changed |= RewriteExit(SuccBB); +    } + +  return Changed; +} +  /// \brief Returns the instructions that use values defined in the loop.  SmallVector<Instruction *, 8> llvm::findDefsUsedOutsideOfLoop(Loop *L) {    SmallVector<Instruction *, 8> UsedOutside; | 
