aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms
diff options
context:
space:
mode:
authorMichael Gottesman <mgottesman@apple.com>2013-01-13 22:12:06 +0000
committerMichael Gottesman <mgottesman@apple.com>2013-01-13 22:12:06 +0000
commit6056b85bb5e863f3b174ed21bd70e22a03ed61f7 (patch)
tree6939da537bb45a4812166763b4b856e4fca4ca74 /lib/Transforms
parent50c023d4960ee492014391b6b84a259e1e02da82 (diff)
Fixed an infinite loop in the block escape in analysis in ObjCARC caused by 2x blocks each assigned a value via a phi-node causing each to depend on the other.
A test case is provided as well. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172368 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms')
-rw-r--r--lib/Transforms/Scalar/ObjCARC.cpp17
1 files changed, 14 insertions, 3 deletions
diff --git a/lib/Transforms/Scalar/ObjCARC.cpp b/lib/Transforms/Scalar/ObjCARC.cpp
index 794d354ed6..2e75bb9391 100644
--- a/lib/Transforms/Scalar/ObjCARC.cpp
+++ b/lib/Transforms/Scalar/ObjCARC.cpp
@@ -30,6 +30,7 @@
#define DEBUG_TYPE "objc-arc"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
@@ -625,6 +626,10 @@ static bool DoesObjCBlockEscape(const Value *BlockPtr) {
// Walk the def-use chains.
SmallVector<const Value *, 4> Worklist;
Worklist.push_back(BlockPtr);
+
+ // Ensure we do not visit any value twice.
+ SmallPtrSet<const Value *, 4> VisitedSet;
+
do {
const Value *V = Worklist.pop_back_val();
@@ -655,9 +660,15 @@ static bool DoesObjCBlockEscape(const Value *BlockPtr) {
// result is an escape.
if (isa<BitCastInst>(UUser) || isa<GetElementPtrInst>(UUser) ||
isa<PHINode>(UUser) || isa<SelectInst>(UUser)) {
- DEBUG(dbgs() << "DoesObjCBlockEscape: User copies value. Escapes if "
- "result escapes. Adding to list.\n");
- Worklist.push_back(UUser);
+
+ if (!VisitedSet.count(UUser)) {
+ DEBUG(dbgs() << "DoesObjCBlockEscape: User copies value. Escapes if "
+ "result escapes. Adding to list.\n");
+ VisitedSet.insert(V);
+ Worklist.push_back(UUser);
+ } else {
+ DEBUG(dbgs() << "DoesObjCBlockEscape: Already visited node.\n");
+ }
continue;
}
// Use by a load is not an escape.