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)) |