const Value *Arg,
BasicBlock *StartBB, Instruction *StartInst,
SmallPtrSetImpl<Instruction *> &DependingInsts,
- SmallPtrSetImpl<const BasicBlock *> &Visited,
ProvenanceAnalysis &PA) {
BasicBlock::iterator StartPos = StartInst->getIterator();
+ SmallPtrSet<const BasicBlock *, 4> Visited;
SmallVector<std::pair<BasicBlock *, BasicBlock::iterator>, 4> Worklist;
Worklist.push_back(std::make_pair(StartBB, StartPos));
do {
const Value *Arg,
BasicBlock *StartBB, Instruction *StartInst,
SmallPtrSetImpl<Instruction *> &DependingInstructions,
- SmallPtrSetImpl<const BasicBlock *> &Visited,
ProvenanceAnalysis &PA);
bool
/// Returns true if we eliminated Inst.
bool tryToPeepholeInstruction(
Function &F, Instruction *Inst, inst_iterator &Iter,
- SmallPtrSetImpl<const BasicBlock *> &Visited, bool &TailOkForStoreStrong,
+ bool &TailOkForStoreStrong,
const DenseMap<BasicBlock *, ColorVector> &BlockColors);
bool optimizeRetainCall(Function &F, Instruction *Retain);
- bool
- contractAutorelease(Function &F, Instruction *Autorelease, ARCInstKind Class,
- SmallPtrSetImpl<const BasicBlock *> &Visited);
+ bool contractAutorelease(Function &F, Instruction *Autorelease,
+ ARCInstKind Class);
void tryToContractReleaseIntoStoreStrong(
Instruction *Release, inst_iterator &Iter,
}
/// Merge an autorelease with a retain into a fused call.
-bool ObjCARCContract::contractAutorelease(
- Function &F, Instruction *Autorelease, ARCInstKind Class,
- SmallPtrSetImpl<const BasicBlock *> &Visited) {
+bool ObjCARCContract::contractAutorelease(Function &F, Instruction *Autorelease,
+ ARCInstKind Class) {
const Value *Arg = GetArgRCIdentityRoot(Autorelease);
// Check that there are no instructions between the retain and the autorelease
SmallPtrSet<Instruction *, 4> DependingInstructions;
if (Class == ARCInstKind::AutoreleaseRV)
- FindDependencies(RetainAutoreleaseRVDep, Arg,
- Autorelease->getParent(), Autorelease,
- DependingInstructions, Visited, PA);
+ FindDependencies(RetainAutoreleaseRVDep, Arg, Autorelease->getParent(),
+ Autorelease, DependingInstructions, PA);
else
- FindDependencies(RetainAutoreleaseDep, Arg,
- Autorelease->getParent(), Autorelease,
- DependingInstructions, Visited, PA);
+ FindDependencies(RetainAutoreleaseDep, Arg, Autorelease->getParent(),
+ Autorelease, DependingInstructions, PA);
- Visited.clear();
if (DependingInstructions.size() != 1)
return false;
bool ObjCARCContract::tryToPeepholeInstruction(
Function &F, Instruction *Inst, inst_iterator &Iter,
- SmallPtrSetImpl<const BasicBlock *> &Visited, bool &TailOkForStoreStrongs,
+ bool &TailOkForStoreStrongs,
const DenseMap<BasicBlock *, ColorVector> &BlockColors) {
// Only these library routines return their argument. In particular,
// objc_retainBlock does not necessarily return its argument.
return false;
case ARCInstKind::Autorelease:
case ARCInstKind::AutoreleaseRV:
- return contractAutorelease(F, Inst, Class, Visited);
+ return contractAutorelease(F, Inst, Class);
case ARCInstKind::Retain:
// Attempt to convert retains to retainrvs if they are next to function
// calls.
// For ObjC library calls which return their argument, replace uses of the
// argument with uses of the call return value, if it dominates the use. This
// reduces register pressure.
- SmallPtrSet<const BasicBlock *, 4> Visited;
-
for (inst_iterator I = inst_begin(&F), E = inst_end(&F); I != E;) {
Instruction *Inst = &*I++;
// First try to peephole Inst. If there is nothing further we can do in
// terms of undoing objc-arc-expand, process the next inst.
- if (tryToPeepholeInstruction(F, Inst, I, Visited, TailOkForStoreStrongs,
+ if (tryToPeepholeInstruction(F, Inst, I, TailOkForStoreStrongs,
BlockColors))
continue;
continue;
SmallPtrSet<Instruction *, 4> DependingInstructions;
- SmallPtrSet<const BasicBlock *, 4> Visited;
// Check that there is nothing that cares about the reference
// count between the call and the phi.
// These can't be moved across things that care about the retain
// count.
FindDependencies(NeedsPositiveRetainCount, Arg, Inst->getParent(), Inst,
- DependingInstructions, Visited, PA);
+ DependingInstructions, PA);
break;
case ARCInstKind::Autorelease:
// These can't be moved across autorelease pool scope boundaries.
FindDependencies(AutoreleasePoolBoundary, Arg, Inst->getParent(), Inst,
- DependingInstructions, Visited, PA);
+ DependingInstructions, PA);
break;
case ARCInstKind::ClaimRV:
case ARCInstKind::RetainRV:
static bool
HasSafePathToPredecessorCall(const Value *Arg, Instruction *Retain,
SmallPtrSetImpl<Instruction *> &DepInsts,
- SmallPtrSetImpl<const BasicBlock *> &Visited,
ProvenanceAnalysis &PA) {
FindDependencies(CanChangeRetainCount, Arg, Retain->getParent(), Retain,
- DepInsts, Visited, PA);
+ DepInsts, PA);
if (DepInsts.size() != 1)
return false;
static CallInst *
FindPredecessorRetainWithSafePath(const Value *Arg, BasicBlock *BB,
Instruction *Autorelease,
- SmallPtrSetImpl<const BasicBlock *> &Visited,
ProvenanceAnalysis &PA) {
SmallPtrSet<Instruction *, 4> DepInsts;
- FindDependencies(CanChangeRetainCount, Arg,
- BB, Autorelease, DepInsts, Visited, PA);
+ FindDependencies(CanChangeRetainCount, Arg, BB, Autorelease, DepInsts, PA);
if (DepInsts.size() != 1)
return nullptr;
static CallInst *
FindPredecessorAutoreleaseWithSafePath(const Value *Arg, BasicBlock *BB,
ReturnInst *Ret,
- SmallPtrSetImpl<const BasicBlock *> &V,
ProvenanceAnalysis &PA) {
SmallPtrSet<Instruction *, 4> DepInsts;
- FindDependencies(NeedsPositiveRetainCount, Arg,
- BB, Ret, DepInsts, V, PA);
+ FindDependencies(NeedsPositiveRetainCount, Arg, BB, Ret, DepInsts, PA);
if (DepInsts.size() != 1)
return nullptr;
LLVM_DEBUG(dbgs() << "\n== ObjCARCOpt::OptimizeReturns ==\n");
SmallPtrSet<Instruction *, 4> DependingInstructions;
- SmallPtrSet<const BasicBlock *, 4> Visited;
for (BasicBlock &BB: F) {
ReturnInst *Ret = dyn_cast<ReturnInst>(&BB.back());
if (!Ret)
// 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, Visited, PA);
- Visited.clear();
+ FindPredecessorAutoreleaseWithSafePath(Arg, &BB, Ret, PA);
if (!Autorelease)
continue;
CallInst *Retain = FindPredecessorRetainWithSafePath(
- Arg, Autorelease->getParent(), Autorelease, Visited, PA);
- Visited.clear();
+ Arg, Autorelease->getParent(), Autorelease, PA);
if (!Retain)
continue;
// 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.
- bool HasSafePathToCall = HasSafePathToPredecessorCall(Arg, Retain,
- DependingInstructions,
- Visited, PA);
+ bool HasSafePathToCall =
+ HasSafePathToPredecessorCall(Arg, Retain, DependingInstructions, PA);
// Don't remove retainRV/autoreleaseRV pairs if the call isn't a tail call.
if (HasSafePathToCall &&
GetBasicARCInstKind(Autorelease) == ARCInstKind::AutoreleaseRV &&
!cast<CallInst>(*DependingInstructions.begin())->isTailCall()) {
DependingInstructions.clear();
- Visited.clear();
continue;
}
DependingInstructions.clear();
- Visited.clear();
if (!HasSafePathToCall)
continue;