Refactored out the helper function FindPredecessorRetainWithSafePath from ObjCARCOpt::OptimizeReturns.

llvm-svn: 178714
This commit is contained in:
Michael Gottesman 2013-04-03 23:16:05 +00:00
parent 51a7a9d712
commit 6908db148b
1 changed files with 32 additions and 18 deletions

View File

@ -2807,6 +2807,33 @@ HasSafePathToPredecessorCall(const Value *Arg, Instruction *Retain,
return true; 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: /// Look for this pattern:
/// \code /// \code
/// %call = call i8* @something(...) /// %call = call i8* @something(...)
@ -2849,26 +2876,13 @@ void ObjCARCOpt::OptimizeReturns(Function &F) {
DependingInstructions.clear(); DependingInstructions.clear();
Visited.clear(); Visited.clear();
// Check that there is nothing that can affect the reference CallInst *Retain = 0;
// count between the autorelease and the retain. if ((Retain = FindPredecessorRetainWithSafePath(Arg, BB, Autorelease,
FindDependencies(CanChangeRetainCount, Arg, DependingInstructions,
BB, Autorelease, DependingInstructions, Visited, PA); 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;
DependingInstructions.clear(); DependingInstructions.clear();
Visited.clear(); Visited.clear();
// Check that there is nothing that can affect the reference count // 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. // between the retain and the call. Note that Retain need not be in BB.
if (HasSafePathToPredecessorCall(Arg, Retain, DependingInstructions, if (HasSafePathToPredecessorCall(Arg, Retain, DependingInstructions,