diff options
author | Michael Gottesman <mgottesman@apple.com> | 2013-04-03 23:16:05 +0000 |
---|---|---|
committer | Michael Gottesman <mgottesman@apple.com> | 2013-04-03 23:16:05 +0000 |
commit | 681f258ae33c114c1525114e6be882ee281be3a6 (patch) | |
tree | aeb5a426f1bb7f9a4cbf93cbf262b35b5f05a115 /lib/Transforms/ObjCARC/ObjCARCOpts.cpp | |
parent | 7d2166a643a7c16b9b0c87441b662f66e79b131f (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.cpp | 50 |
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, |