forked from OSchip/llvm-project
Refactored out the helper function FindPredecessorRetainWithSafePath from ObjCARCOpt::OptimizeReturns.
llvm-svn: 178714
This commit is contained in:
parent
51a7a9d712
commit
6908db148b
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue