aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
diff options
context:
space:
mode:
authorMichael Gottesman <mgottesman@apple.com>2013-04-03 23:16:05 +0000
committerMichael Gottesman <mgottesman@apple.com>2013-04-03 23:16:05 +0000
commit681f258ae33c114c1525114e6be882ee281be3a6 (patch)
treeaeb5a426f1bb7f9a4cbf93cbf262b35b5f05a115 /lib/Transforms/ObjCARC/ObjCARCOpts.cpp
parent7d2166a643a7c16b9b0c87441b662f66e79b131f (diff)
Refactored out the helper function FindPredecessorRetainWithSafePath from ObjCARCOpt::OptimizeReturns.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178714 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/ObjCARC/ObjCARCOpts.cpp')
-rw-r--r--lib/Transforms/ObjCARC/ObjCARCOpts.cpp50
1 files changed, 32 insertions, 18 deletions
diff --git a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
index 301eac178d..552d04e2c9 100644
--- a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
+++ b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp
@@ -2807,6 +2807,33 @@ HasSafePathToPredecessorCall(const Value *Arg, Instruction *Retain,
return true;
}
+/// Find a dependent retain that precedes the given autorelease for which there
+/// is nothing in between the two instructions that can affect the ref count of
+/// Arg.
+static CallInst *
+FindPredecessorRetainWithSafePath(const Value *Arg, BasicBlock *BB,
+ Instruction *Autorelease,
+ SmallPtrSet<Instruction *, 4> &DepInsts,
+ SmallPtrSet<const BasicBlock *, 4> &Visited,
+ ProvenanceAnalysis &PA) {
+ FindDependencies(CanChangeRetainCount, Arg,
+ BB, Autorelease, DepInsts, Visited, PA);
+ if (DepInsts.size() != 1)
+ return 0;
+
+ CallInst *Retain =
+ dyn_cast_or_null<CallInst>(*DepInsts.begin());
+
+ // Check that we found a retain with the same argument.
+ if (!Retain ||
+ !IsRetain(GetBasicInstructionClass(Retain)) ||
+ GetObjCArg(Retain) != Arg) {
+ return 0;
+ }
+
+ return Retain;
+}
+
/// Look for this pattern:
/// \code
/// %call = call i8* @something(...)
@@ -2849,26 +2876,13 @@ void ObjCARCOpt::OptimizeReturns(Function &F) {
DependingInstructions.clear();
Visited.clear();
- // Check that there is nothing that can affect the reference
- // count between the autorelease and the retain.
- FindDependencies(CanChangeRetainCount, Arg,
- BB, Autorelease, DependingInstructions, Visited, PA);
- if (DependingInstructions.size() != 1)
- goto next_block;
-
- {
- CallInst *Retain =
- dyn_cast_or_null<CallInst>(*DependingInstructions.begin());
-
- // Check that we found a retain with the same argument.
- if (!Retain ||
- !IsRetain(GetBasicInstructionClass(Retain)) ||
- GetObjCArg(Retain) != Arg)
- goto next_block;
-
+ CallInst *Retain = 0;
+ if ((Retain = FindPredecessorRetainWithSafePath(Arg, BB, Autorelease,
+ DependingInstructions,
+ Visited, PA))) {
DependingInstructions.clear();
Visited.clear();
-
+
// Check that there is nothing that can affect the reference count
// between the retain and the call. Note that Retain need not be in BB.
if (HasSafePathToPredecessorCall(Arg, Retain, DependingInstructions,