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 | 7f1a7d4137ce535558480f8e044238f35a8654e6 (patch) | |
tree | 63df74685a98f2917e19d7ba7ef3c93fa75d0ec9 /lib/Transforms | |
parent | b0fd15f645a05480467136f94d5e5baacd1905a9 (diff) | |
download | external_llvm-7f1a7d4137ce535558480f8e044238f35a8654e6.zip external_llvm-7f1a7d4137ce535558480f8e044238f35a8654e6.tar.gz external_llvm-7f1a7d4137ce535558480f8e044238f35a8654e6.tar.bz2 |
[objc-arc] Track if we encountered an additive overflow while computing {TopDown,BottomUp}PathCounts and do nothing if it occured.
rdar://14590914
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@187941 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r-- | lib/Transforms/ObjCARC/ObjCARCOpts.cpp | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index 6d4ff65..582f7ea 100644 --- a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/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; } |