diff options
| author | Michael Gottesman <mgottesman@apple.com> | 2013-08-07 23:56:41 +0000 |
|---|---|---|
| committer | Michael Gottesman <mgottesman@apple.com> | 2013-08-07 23:56:41 +0000 |
| commit | ddc89fcccd3ef16aff3f479f3a9397f7a5b7dba4 (patch) | |
| tree | c2230e4b4e965bd1fbdf237c2f515463e5325567 /llvm/lib/Transforms/ObjCARC | |
| parent | 0fecf98955ef7d3ac905e8078bb9f2cc52dc6839 (diff) | |
| download | bcm5719-llvm-ddc89fcccd3ef16aff3f479f3a9397f7a5b7dba4.tar.gz bcm5719-llvm-ddc89fcccd3ef16aff3f479f3a9397f7a5b7dba4.zip | |
[objc-arc] Track if we encountered an additive overflow while computing {TopDown,BottomUp}PathCounts and do nothing if it occured.
rdar://14590914
llvm-svn: 187941
Diffstat (limited to 'llvm/lib/Transforms/ObjCARC')
| -rw-r--r-- | llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index 6d4ff659b40..582f7ea8352 100644 --- a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -648,6 +648,8 @@ PtrState::Merge(const PtrState &Other, bool TopDown) { namespace { /// \brief Per-BasicBlock state. class BBState { + static const unsigned OverflowOccurredValue; + /// The number of unique control paths from the entry which can reach this /// block. unsigned TopDownPathCount; @@ -674,7 +676,7 @@ namespace { SmallVector<BasicBlock *, 2> Succs; public: - BBState() : TopDownPathCount(0), BottomUpPathCount(0) {} + BBState() : TopDownPathCount(0), BottomUpPathCount(0) { } typedef MapTy::iterator ptr_iterator; typedef MapTy::const_iterator ptr_const_iterator; @@ -745,8 +747,9 @@ namespace { /// Returns true if overflow occured. Returns false if overflow did not /// occur. bool GetAllPathCountWithOverflow(unsigned &PathCount) const { - assert(TopDownPathCount != 0); - assert(BottomUpPathCount != 0); + if (TopDownPathCount == OverflowOccurredValue || + BottomUpPathCount == OverflowOccurredValue) + return false; unsigned long long Product = (unsigned long long)TopDownPathCount*BottomUpPathCount; PathCount = Product; @@ -766,6 +769,8 @@ namespace { bool isExit() const { return Succs.empty(); } }; + + const unsigned BBState::OverflowOccurredValue = -1; } void BBState::InitFromPred(const BBState &Other) { @@ -781,13 +786,25 @@ void BBState::InitFromSucc(const BBState &Other) { /// The top-down traversal uses this to merge information about predecessors to /// form the initial state for a new block. void BBState::MergePred(const BBState &Other) { + if (TopDownPathCount == OverflowOccurredValue) + return; + // Other.TopDownPathCount can be 0, in which case it is either dead or a // loop backedge. Loop backedges are special. TopDownPathCount += Other.TopDownPathCount; + // In order to be consistent, we clear the top down pointers when by adding + // TopDownPathCount becomes OverflowOccurredValue even though "true" overflow + // has not occured. + if (TopDownPathCount == OverflowOccurredValue) { + clearTopDownPointers(); + return; + } + // Check for overflow. If we have overflow, fall back to conservative // behavior. if (TopDownPathCount < Other.TopDownPathCount) { + TopDownPathCount = OverflowOccurredValue; clearTopDownPointers(); return; } @@ -813,13 +830,25 @@ void BBState::MergePred(const BBState &Other) { /// The bottom-up traversal uses this to merge information about successors to /// form the initial state for a new block. void BBState::MergeSucc(const BBState &Other) { + if (BottomUpPathCount == OverflowOccurredValue) + return; + // Other.BottomUpPathCount can be 0, in which case it is either dead or a // loop backedge. Loop backedges are special. BottomUpPathCount += Other.BottomUpPathCount; + // In order to be consistent, we clear the top down pointers when by adding + // BottomUpPathCount becomes OverflowOccurredValue even though "true" overflow + // has not occured. + if (BottomUpPathCount == OverflowOccurredValue) { + clearBottomUpPointers(); + return; + } + // Check for overflow. If we have overflow, fall back to conservative // behavior. if (BottomUpPathCount < Other.BottomUpPathCount) { + BottomUpPathCount = OverflowOccurredValue; clearBottomUpPointers(); return; } |

