From 296ffab5625fe83d804f1dd5d5517954082b6622 Mon Sep 17 00:00:00 2001 From: Michael Gottesman Date: Wed, 3 Apr 2013 23:39:14 +0000 Subject: Refactored out the helper method FindPredecessorAutoreleaseWithSafePath from ObjCARCOpt::OptimizeReturns. Now ObjCARCOpt::OptimizeReturns is easy to read and reason about. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178715 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/ObjCARC/ObjCARCOpts.cpp | 70 ++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 25 deletions(-) (limited to 'lib/Transforms/ObjCARC/ObjCARCOpts.cpp') diff --git a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp index 552d04e2c9..92d6fc4767 100644 --- a/lib/Transforms/ObjCARC/ObjCARCOpts.cpp +++ b/lib/Transforms/ObjCARC/ObjCARCOpts.cpp @@ -2834,6 +2834,33 @@ FindPredecessorRetainWithSafePath(const Value *Arg, BasicBlock *BB, return Retain; } +/// Look for an ``autorelease'' instruction dependent on Arg such that there are +/// no instructions dependent on Arg that need a positive ref count in between +/// the autorelease and the ret. +static CallInst * +FindPredecessorAutoreleaseWithSafePath(const Value *Arg, BasicBlock *BB, + ReturnInst *Ret, + SmallPtrSet &DepInsts, + SmallPtrSet &V, + ProvenanceAnalysis &PA) { + FindDependencies(NeedsPositiveRetainCount, Arg, + BB, Ret, DepInsts, V, PA); + if (DepInsts.size() != 1) + return 0; + + CallInst *Autorelease = + dyn_cast_or_null(*DepInsts.begin()); + if (!Autorelease) + return 0; + InstructionClass AutoreleaseClass = GetBasicInstructionClass(Autorelease); + if (!IsAutorelease(AutoreleaseClass)) + return 0; + if (GetObjCArg(Autorelease) != Arg) + return 0; + + return Autorelease; +} + /// Look for this pattern: /// \code /// %call = call i8* @something(...) @@ -2854,32 +2881,26 @@ void ObjCARCOpt::OptimizeReturns(Function &F) { DEBUG(dbgs() << "ObjCARCOpt::OptimizeReturns: Visiting: " << *Ret << "\n"); - if (!Ret) continue; - + if (!Ret) + continue; + const Value *Arg = StripPointerCastsAndObjCCalls(Ret->getOperand(0)); - FindDependencies(NeedsPositiveRetainCount, Arg, - BB, Ret, DependingInstructions, Visited, PA); - if (DependingInstructions.size() != 1) - goto next_block; - - { - CallInst *Autorelease = - dyn_cast_or_null(*DependingInstructions.begin()); - if (!Autorelease) - goto next_block; - InstructionClass AutoreleaseClass = GetBasicInstructionClass(Autorelease); - if (!IsAutorelease(AutoreleaseClass)) - goto next_block; - if (GetObjCArg(Autorelease) != Arg) - goto next_block; - + + // Look for an ``autorelease'' instruction that is a predecssor of Ret and + // dependent on Arg such that there are no instructions dependent on Arg + // that need a positive ref count in between the autorelease and Ret. + CallInst *Autorelease = + FindPredecessorAutoreleaseWithSafePath(Arg, BB, Ret, + DependingInstructions, Visited, + PA); + if (Autorelease) { DependingInstructions.clear(); Visited.clear(); - - CallInst *Retain = 0; - if ((Retain = FindPredecessorRetainWithSafePath(Arg, BB, Autorelease, - DependingInstructions, - Visited, PA))) { + + CallInst *Retain = + FindPredecessorRetainWithSafePath(Arg, BB, Autorelease, + DependingInstructions, Visited, PA); + if (Retain) { DependingInstructions.clear(); Visited.clear(); @@ -2898,8 +2919,7 @@ void ObjCARCOpt::OptimizeReturns(Function &F) { } } } - - next_block: + DependingInstructions.clear(); Visited.clear(); } -- cgit v1.2.3-18-g5258