summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/ObjCARC
diff options
context:
space:
mode:
authorPete Cooper <peter_cooper@apple.com>2019-01-03 01:38:08 +0000
committerPete Cooper <peter_cooper@apple.com>2019-01-03 01:38:08 +0000
commit697281df42916d736cc23e74c2a2b2275786c43f (patch)
treeb9ee5c2c9551079578769dc8bf5a081b65cc8df5 /llvm/lib/Transforms/ObjCARC
parentddc62017ea18ea08afc6c4b1e5c57198f1222e36 (diff)
downloadbcm5719-llvm-697281df42916d736cc23e74c2a2b2275786c43f.tar.gz
bcm5719-llvm-697281df42916d736cc23e74c2a2b2275786c43f.zip
Teach ObjCARC optimizer about equivalent PHIs when eliminating autoreleaseRV/retainRV pairs
OptimizeAutoreleaseRVCall skips optimizing llvm.objc.autoreleaseReturnValue if it sees a user which is llvm.objc.retainAutoreleasedReturnValue, and if they have equivalent arguments (either identical or equivalent PHIs). It then assumes that ObjCARCOpt::OptimizeRetainRVCall will optimize the pair instead. Trouble is, ObjCARCOpt::OptimizeRetainRVCall doesn't know about equivalent PHIs so optimizes in a different way and we are left with an unoptimized llvm.objc.autoreleaseReturnValue. This teaches ObjCARCOpt::OptimizeRetainRVCall to also understand PHI equivalence. rdar://problem/47005143 Reviewed By: ahatanak Differential Revision: https://reviews.llvm.org/D56235 llvm-svn: 350284
Diffstat (limited to 'llvm/lib/Transforms/ObjCARC')
-rw-r--r--llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp13
1 files changed, 12 insertions, 1 deletions
diff --git a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
index 6ffaadc2b5f..9a02174556f 100644
--- a/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
+++ b/llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
@@ -600,6 +600,17 @@ ObjCARCOpt::OptimizeRetainRVCall(Function &F, Instruction *RetainRV) {
}
}
+ // Track PHIs which are equivalent to our Arg.
+ SmallDenseSet<const Value*, 2> EquivalentArgs;
+ EquivalentArgs.insert(Arg);
+
+ // Add PHIs that are equivalent to Arg to ArgUsers.
+ if (const PHINode *PN = dyn_cast<PHINode>(Arg)) {
+ SmallVector<const Value *, 2> ArgUsers;
+ getEquivalentPHIs(*PN, ArgUsers);
+ EquivalentArgs.insert(ArgUsers.begin(), ArgUsers.end());
+ }
+
// Check for being preceded by an objc_autoreleaseReturnValue on the same
// pointer. In this case, we can delete the pair.
BasicBlock::iterator I = RetainRV->getIterator(),
@@ -609,7 +620,7 @@ ObjCARCOpt::OptimizeRetainRVCall(Function &F, Instruction *RetainRV) {
--I;
while (I != Begin && IsNoopInstruction(&*I));
if (GetBasicARCInstKind(&*I) == ARCInstKind::AutoreleaseRV &&
- GetArgRCIdentityRoot(&*I) == Arg) {
+ EquivalentArgs.count(GetArgRCIdentityRoot(&*I))) {
Changed = true;
++NumPeeps;
OpenPOWER on IntegriCloud