summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/include/llvm/Analysis/MustExecute.h7
-rw-r--r--llvm/lib/Analysis/MustExecute.cpp16
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))
OpenPOWER on IntegriCloud