diff options
author | Michael Gottesman <mgottesman@apple.com> | 2013-01-13 22:12:06 +0000 |
---|---|---|
committer | Michael Gottesman <mgottesman@apple.com> | 2013-01-13 22:12:06 +0000 |
commit | 6056b85bb5e863f3b174ed21bd70e22a03ed61f7 (patch) | |
tree | 6939da537bb45a4812166763b4b856e4fca4ca74 /lib/Transforms | |
parent | 50c023d4960ee492014391b6b84a259e1e02da82 (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.cpp | 17 |
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. |