diff options
author | Michael Gottesman <mgottesman@apple.com> | 2013-04-03 23:04:28 +0000 |
---|---|---|
committer | Michael Gottesman <mgottesman@apple.com> | 2013-04-03 23:04:28 +0000 |
commit | ca4cb5b6df545517e31a374c7bd8a689aea9a962 (patch) | |
tree | 7d2caec18a62283ee8bfed2d15fdde389b68649e /lib | |
parent | 60d1c0bca35d78feb780ac831d42ba1688d73461 (diff) |
Refactored out a part of ObjCARCOpt::OptimizeReturns into its own method HasSafePathToPredecessorCall.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178710 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Transforms/ObjCARC/ObjCARCOpts.cpp | 55 |
1 files changed, 33 insertions, 22 deletions
diff --git a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index f4ecf16270..8623433f96 100644 --- a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -2779,6 +2779,34 @@ bool ObjCARCOpt::OptimizeSequences(Function &F) { NestingDetected; } +// Check if there is a dependent call earlier that does not have anything in +// between the Retain and the call that can affect the reference count of their +// shared pointer argument. Note that Retain need not be in BB. +static bool +HasSafePathToPredecessorCall(const Value *Arg, Instruction *Retain, + SmallPtrSet<Instruction *, 4> &DepInsts, + SmallPtrSet<const BasicBlock *, 4> &Visited, + ProvenanceAnalysis &PA) { + FindDependencies(CanChangeRetainCount, Arg, Retain->getParent(), Retain, + DepInsts, Visited, PA); + if (DepInsts.size() != 1) + return false; + + CallInst *Call = + dyn_cast_or_null<CallInst>(*DepInsts.begin()); + + // Check that the pointer is the return value of the call. + if (!Call || Arg != Call) + return false; + + // Check that the call is a regular call. + InstructionClass Class = GetBasicInstructionClass(Call); + if (Class != IC_CallOrUser && Class != IC_Call) + return false; + + return true; +} + /// Look for this pattern: /// \code /// %call = call i8* @something(...) @@ -2840,28 +2868,11 @@ void ObjCARCOpt::OptimizeReturns(Function &F) { 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. - FindDependencies(CanChangeRetainCount, Arg, Retain->getParent(), Retain, - DependingInstructions, Visited, PA); - if (DependingInstructions.size() != 1) - goto next_block; - - { - CallInst *Call = - dyn_cast_or_null<CallInst>(*DependingInstructions.begin()); - - // Check that the pointer is the return value of the call. - if (!Call || Arg != Call) - goto next_block; - - // Check that the call is a regular call. - InstructionClass Class = GetBasicInstructionClass(Call); - if (Class != IC_CallOrUser && Class != IC_Call) - goto next_block; - + + // 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, + Visited, PA)) { // If so, we can zap the retain and autorelease. Changed = true; ++NumRets; |