+ bool AnyPairsCompletelyEliminated = PerformCodePlacement(BBStates, Retains,
+ Releases,
+ F.getParent());
+
+ // Cleanup.
+ MultiOwnersSet.clear();
+
+ return AnyPairsCompletelyEliminated && 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;
+}
+
+/// 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 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<Instruction *, 4> &DepInsts,
+ SmallPtrSet<const BasicBlock *, 4> &V,
+ ProvenanceAnalysis &PA) {
+ FindDependencies(NeedsPositiveRetainCount, Arg,
+ BB, Ret, DepInsts, V, PA);
+ if (DepInsts.size() != 1)
+ return 0;
+
+ CallInst *Autorelease =
+ dyn_cast_or_null<CallInst>(*DepInsts.begin());
+ if (!Autorelease)
+ return 0;
+ InstructionClass AutoreleaseClass = GetBasicInstructionClass(Autorelease);
+ if (!IsAutorelease(AutoreleaseClass))
+ return 0;
+ if (GetObjCArg(Autorelease) != Arg)
+ return 0;
+
+ return Autorelease;