diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/Analysis/MustExecute.h | 7 | ||||
| -rw-r--r-- | llvm/lib/Analysis/MustExecute.cpp | 16 | 
2 files changed, 15 insertions, 8 deletions
diff --git a/llvm/include/llvm/Analysis/MustExecute.h b/llvm/include/llvm/Analysis/MustExecute.h index 82387476a6d..e643e4ec563 100644 --- a/llvm/include/llvm/Analysis/MustExecute.h +++ b/llvm/include/llvm/Analysis/MustExecute.h @@ -65,13 +65,16 @@ public:    /// abnormally.    bool headerMayThrow() const; +  /// Returns true iff the block \p BB potentially may throw exception. It can +  /// be false-positive in cases when we want to avoid complex analysis. +  bool blockMayThrow(const BasicBlock *BB) const; +    /// Returns true iff any block of the loop for which this info is contains an    /// instruction that may throw or otherwise exit abnormally.    bool anyBlockMayThrow() const;    /// Return true if we must reach the block \p BB under assumption that the -  /// loop \p CurLoop is entered and no instruction throws or otherwise exits -  /// abnormally. +  /// loop \p CurLoop is entered.    bool allLoopPathsLeadToBlock(const Loop *CurLoop, const BasicBlock *BB,                                 const DominatorTree *DT) const; diff --git a/llvm/lib/Analysis/MustExecute.cpp b/llvm/lib/Analysis/MustExecute.cpp index 7c1ce86d15b..7f0912de26b 100644 --- a/llvm/lib/Analysis/MustExecute.cpp +++ b/llvm/lib/Analysis/MustExecute.cpp @@ -26,6 +26,11 @@ bool LoopSafetyInfo::headerMayThrow() const {    return HeaderMayThrow;  } +bool LoopSafetyInfo::blockMayThrow(const BasicBlock *BB) const { +  (void)BB; +  return anyBlockMayThrow(); +} +  bool LoopSafetyInfo::anyBlockMayThrow() const {    return MayThrow;  } @@ -148,7 +153,10 @@ bool LoopSafetyInfo::allLoopPathsLeadToBlock(const Loop *CurLoop,    // 3) Exit blocks which are not taken on 1st iteration.    // Memoize blocks we've already checked.    SmallPtrSet<const BasicBlock *, 4> CheckedSuccessors; -  for (auto *Pred : Predecessors) +  for (auto *Pred : Predecessors) { +    // Predecessor block may throw, so it has a side exit. +    if (blockMayThrow(Pred)) +      return false;      for (auto *Succ : successors(Pred))        if (CheckedSuccessors.insert(Succ).second &&            Succ != BB && !Predecessors.count(Succ)) @@ -169,6 +177,7 @@ bool LoopSafetyInfo::allLoopPathsLeadToBlock(const Loop *CurLoop,          if (CurLoop->contains(Succ) ||              !CanProveNotTakenFirstIteration(Succ, DT, CurLoop))            return false; +  }    // All predecessors can only lead us to BB.    return true; @@ -194,11 +203,6 @@ bool LoopSafetyInfo::isGuaranteedToExecute(const Instruction &Inst,      return !headerMayThrow() ||             Inst.getParent()->getFirstNonPHIOrDbg() == &Inst; -  // Somewhere in this loop there is an instruction which may throw and make us -  // exit the loop. -  if (anyBlockMayThrow()) -    return false; -    // If there is a path from header to exit or latch that doesn't lead to our    // instruction's block, return false.    if (!allLoopPathsLeadToBlock(CurLoop, Inst.getParent(), DT))  | 

