summaryrefslogtreecommitdiff
path: root/lib/Transforms/ObjCARC
diff options
context:
space:
mode:
authorMichael Gottesman <mgottesman@apple.com>2013-08-07 23:56:41 +0000
committerMichael Gottesman <mgottesman@apple.com>2013-08-07 23:56:41 +0000
commit7f1a7d4137ce535558480f8e044238f35a8654e6 (patch)
tree63df74685a98f2917e19d7ba7ef3c93fa75d0ec9 /lib/Transforms/ObjCARC
parentb0fd15f645a05480467136f94d5e5baacd1905a9 (diff)
downloadllvm-7f1a7d4137ce535558480f8e044238f35a8654e6.tar.gz
llvm-7f1a7d4137ce535558480f8e044238f35a8654e6.tar.bz2
llvm-7f1a7d4137ce535558480f8e044238f35a8654e6.tar.xz
[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/ObjCARC')
-rw-r--r--lib/Transforms/ObjCARC/ObjCARCOpts.cpp35
1 files changed, 32 insertions, 3 deletions
diff --git a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
index 6d4ff659b4..582f7ea835 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;
}