aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/Scalar/ObjCARC.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2012-02-13 22:57:02 +0000
committerDan Gohman <gohman@apple.com>2012-02-13 22:57:02 +0000
commita3b08d68bd281773b0300222edb4149abce4b4b8 (patch)
treec5e30e534f4abdbc00371de7854a29f94e6af78f /lib/Transforms/Scalar/ObjCARC.cpp
parent60ebb1947faed42e493179e569c5db0c01d38a2a (diff)
downloadexternal_llvm-a3b08d68bd281773b0300222edb4149abce4b4b8.zip
external_llvm-a3b08d68bd281773b0300222edb4149abce4b4b8.tar.gz
external_llvm-a3b08d68bd281773b0300222edb4149abce4b4b8.tar.bz2
Just like in regular escape analysis, loads and stores through
(but not of) a block pointer do not cause the block pointer to escape. This fixes rdar://10803830. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150424 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/ObjCARC.cpp')
-rw-r--r--lib/Transforms/Scalar/ObjCARC.cpp10
1 files changed, 10 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/ObjCARC.cpp b/lib/Transforms/Scalar/ObjCARC.cpp
index 9284401..673e1a4 100644
--- a/lib/Transforms/Scalar/ObjCARC.cpp
+++ b/lib/Transforms/Scalar/ObjCARC.cpp
@@ -618,11 +618,21 @@ static bool DoesObjCBlockEscape(const Value *BlockPtr) {
// to be an escape.
if (isa<CallInst>(UUser) || isa<InvokeInst>(UUser))
continue;
+ // Use by an instruction which copies the value is an escape if the
+ // result is an escape.
if (isa<BitCastInst>(UUser) || isa<GetElementPtrInst>(UUser) ||
isa<PHINode>(UUser) || isa<SelectInst>(UUser)) {
Worklist.push_back(UUser);
continue;
}
+ // Use by a load is not an escape.
+ if (isa<LoadInst>(UUser))
+ continue;
+ // Use by a store is not an escape if the use is the address.
+ if (const StoreInst *SI = dyn_cast<StoreInst>(UUser))
+ if (V != SI->getValueOperand())
+ continue;
+ // Otherwise, conservatively assume an escape.
return true;
}
} while (!Worklist.empty());