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 | f15c0bb49593c08c06380bd6d26f06591c3674af (patch) | |
tree | b256ebb9162aacee21d65335f8bb3a975d515438 /llvm/lib/Transforms | |
parent | 765396f2f05f7c95557f1e0b5c3bf7026b2ef911 (diff) | |
download | bcm5719-llvm-f15c0bb49593c08c06380bd6d26f06591c3674af.tar.gz bcm5719-llvm-f15c0bb49593c08c06380bd6d26f06591c3674af.zip |
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.
llvm-svn: 172368
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Scalar/ObjCARC.cpp | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/ObjCARC.cpp b/llvm/lib/Transforms/Scalar/ObjCARC.cpp index 794d354ed6d..2e75bb9391c 100644 --- a/llvm/lib/Transforms/Scalar/ObjCARC.cpp +++ b/llvm/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. |