Skip to content

Commit 2ed3a76

Browse files
committed
[ObjC][ARC] Add and use a function which finds and returns the single
dependency. NFC Use findSingleDependency in place of FindDependencies and stop passing a set of Instructions around. Modify FindDependencies to return a boolean flag which indicates whether the dependencies it has found are all valid.
1 parent 00d0974 commit 2ed3a76

File tree

4 files changed

+64
-82
lines changed

4 files changed

+64
-82
lines changed

llvm/lib/Transforms/ObjCARC/DependencyAnalysis.cpp

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,10 @@ llvm::objcarc::Depends(DependenceKind Flavor, Instruction *Inst,
208208
/// non-local dependencies on Arg.
209209
///
210210
/// TODO: Cache results?
211-
void
212-
llvm::objcarc::FindDependencies(DependenceKind Flavor,
213-
const Value *Arg,
214-
BasicBlock *StartBB, Instruction *StartInst,
215-
SmallPtrSetImpl<Instruction *> &DependingInsts,
216-
ProvenanceAnalysis &PA) {
211+
static bool findDependencies(DependenceKind Flavor, const Value *Arg,
212+
BasicBlock *StartBB, Instruction *StartInst,
213+
SmallPtrSetImpl<Instruction *> &DependingInsts,
214+
ProvenanceAnalysis &PA) {
217215
BasicBlock::iterator StartPos = StartInst->getIterator();
218216

219217
SmallPtrSet<const BasicBlock *, 4> Visited;
@@ -229,15 +227,14 @@ llvm::objcarc::FindDependencies(DependenceKind Flavor,
229227
if (LocalStartPos == StartBBBegin) {
230228
pred_iterator PI(LocalStartBB), PE(LocalStartBB, false);
231229
if (PI == PE)
232-
// If we've reached the function entry, produce a null dependence.
233-
DependingInsts.insert(nullptr);
234-
else
235-
// Add the predecessors to the worklist.
236-
do {
237-
BasicBlock *PredBB = *PI;
238-
if (Visited.insert(PredBB).second)
239-
Worklist.push_back(std::make_pair(PredBB, PredBB->end()));
240-
} while (++PI != PE);
230+
// Return if we've reached the function entry.
231+
return false;
232+
// Add the predecessors to the worklist.
233+
do {
234+
BasicBlock *PredBB = *PI;
235+
if (Visited.insert(PredBB).second)
236+
Worklist.push_back(std::make_pair(PredBB, PredBB->end()));
237+
} while (++PI != PE);
241238
break;
242239
}
243240

@@ -256,9 +253,22 @@ llvm::objcarc::FindDependencies(DependenceKind Flavor,
256253
if (BB == StartBB)
257254
continue;
258255
for (const BasicBlock *Succ : successors(BB))
259-
if (Succ != StartBB && !Visited.count(Succ)) {
260-
DependingInsts.insert(reinterpret_cast<Instruction *>(-1));
261-
return;
262-
}
256+
if (Succ != StartBB && !Visited.count(Succ))
257+
return false;
263258
}
259+
260+
return true;
261+
}
262+
263+
llvm::Instruction *llvm::objcarc::findSingleDependency(DependenceKind Flavor,
264+
const Value *Arg,
265+
BasicBlock *StartBB,
266+
Instruction *StartInst,
267+
ProvenanceAnalysis &PA) {
268+
SmallPtrSet<Instruction *, 4> DependingInsts;
269+
270+
if (!findDependencies(Flavor, Arg, StartBB, StartInst, DependingInsts, PA) ||
271+
DependingInsts.size() != 1)
272+
return nullptr;
273+
return *DependingInsts.begin();
264274
}

llvm/lib/Transforms/ObjCARC/DependencyAnalysis.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,12 @@ enum DependenceKind {
5050
RetainRVDep ///< Blocks objc_retainAutoreleasedReturnValue.
5151
};
5252

53-
void FindDependencies(DependenceKind Flavor,
54-
const Value *Arg,
55-
BasicBlock *StartBB, Instruction *StartInst,
56-
SmallPtrSetImpl<Instruction *> &DependingInstructions,
57-
ProvenanceAnalysis &PA);
53+
/// Find dependent instructions. If there is exactly one dependent instruction,
54+
/// return it. Otherwise, return null.
55+
llvm::Instruction *findSingleDependency(DependenceKind Flavor, const Value *Arg,
56+
BasicBlock *StartBB,
57+
Instruction *StartInst,
58+
ProvenanceAnalysis &PA);
5859

5960
bool
6061
Depends(DependenceKind Flavor, Instruction *Inst, const Value *Arg,

llvm/lib/Transforms/ObjCARC/ObjCARCContract.cpp

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -161,20 +161,11 @@ bool ObjCARCContract::contractAutorelease(Function &F, Instruction *Autorelease,
161161

162162
// Check that there are no instructions between the retain and the autorelease
163163
// (such as an autorelease_pop) which may change the count.
164-
CallInst *Retain = nullptr;
165-
SmallPtrSet<Instruction *, 4> DependingInstructions;
166-
167-
if (Class == ARCInstKind::AutoreleaseRV)
168-
FindDependencies(RetainAutoreleaseRVDep, Arg, Autorelease->getParent(),
169-
Autorelease, DependingInstructions, PA);
170-
else
171-
FindDependencies(RetainAutoreleaseDep, Arg, Autorelease->getParent(),
172-
Autorelease, DependingInstructions, PA);
173-
174-
if (DependingInstructions.size() != 1)
175-
return false;
176-
177-
Retain = dyn_cast_or_null<CallInst>(*DependingInstructions.begin());
164+
DependenceKind DK = Class == ARCInstKind::AutoreleaseRV
165+
? RetainAutoreleaseRVDep
166+
: RetainAutoreleaseDep;
167+
auto *Retain = dyn_cast_or_null<CallInst>(
168+
findSingleDependency(DK, Arg, Autorelease->getParent(), Autorelease, PA));
178169

179170
if (!Retain || GetBasicARCInstKind(Retain) != ARCInstKind::Retain ||
180171
GetArgRCIdentityRoot(Retain) != Arg)

llvm/lib/Transforms/ObjCARC/ObjCARCOpts.cpp

Lines changed: 24 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1125,7 +1125,7 @@ void ObjCARCOpt::OptimizeIndividualCallImpl(
11251125
if (!HasNull)
11261126
continue;
11271127

1128-
SmallPtrSet<Instruction *, 4> DependingInstructions;
1128+
Instruction *DepInst = nullptr;
11291129

11301130
// Check that there is nothing that cares about the reference
11311131
// count between the call and the phi.
@@ -1137,13 +1137,13 @@ void ObjCARCOpt::OptimizeIndividualCallImpl(
11371137
case ARCInstKind::Release:
11381138
// These can't be moved across things that care about the retain
11391139
// count.
1140-
FindDependencies(NeedsPositiveRetainCount, Arg, Inst->getParent(), Inst,
1141-
DependingInstructions, PA);
1140+
DepInst = findSingleDependency(NeedsPositiveRetainCount, Arg,
1141+
Inst->getParent(), Inst, PA);
11421142
break;
11431143
case ARCInstKind::Autorelease:
11441144
// These can't be moved across autorelease pool scope boundaries.
1145-
FindDependencies(AutoreleasePoolBoundary, Arg, Inst->getParent(), Inst,
1146-
DependingInstructions, PA);
1145+
DepInst = findSingleDependency(AutoreleasePoolBoundary, Arg,
1146+
Inst->getParent(), Inst, PA);
11471147
break;
11481148
case ARCInstKind::ClaimRV:
11491149
case ARCInstKind::RetainRV:
@@ -1157,9 +1157,7 @@ void ObjCARCOpt::OptimizeIndividualCallImpl(
11571157
llvm_unreachable("Invalid dependence flavor");
11581158
}
11591159

1160-
if (DependingInstructions.size() != 1)
1161-
continue;
1162-
if (*DependingInstructions.begin() != PN)
1160+
if (DepInst != PN)
11631161
continue;
11641162

11651163
Changed = true;
@@ -2233,24 +2231,21 @@ bool ObjCARCOpt::OptimizeSequences(Function &F) {
22332231
/// Check if there is a dependent call earlier that does not have anything in
22342232
/// between the Retain and the call that can affect the reference count of their
22352233
/// shared pointer argument. Note that Retain need not be in BB.
2236-
static bool
2237-
HasSafePathToPredecessorCall(const Value *Arg, Instruction *Retain,
2238-
SmallPtrSetImpl<Instruction *> &DepInsts,
2239-
ProvenanceAnalysis &PA) {
2240-
FindDependencies(CanChangeRetainCount, Arg, Retain->getParent(), Retain,
2241-
DepInsts, PA);
2242-
if (DepInsts.size() != 1)
2243-
return false;
2244-
2245-
auto *Call = dyn_cast_or_null<CallInst>(*DepInsts.begin());
2234+
static CallInst *HasSafePathToPredecessorCall(const Value *Arg,
2235+
Instruction *Retain,
2236+
ProvenanceAnalysis &PA) {
2237+
auto *Call = dyn_cast_or_null<CallInst>(findSingleDependency(
2238+
CanChangeRetainCount, Arg, Retain->getParent(), Retain, PA));
22462239

22472240
// Check that the pointer is the return value of the call.
22482241
if (!Call || Arg != Call)
2249-
return false;
2242+
return nullptr;
22502243

22512244
// Check that the call is a regular call.
22522245
ARCInstKind Class = GetBasicARCInstKind(Call);
2253-
return Class == ARCInstKind::CallOrUser || Class == ARCInstKind::Call;
2246+
return Class == ARCInstKind::CallOrUser || Class == ARCInstKind::Call
2247+
? Call
2248+
: nullptr;
22542249
}
22552250

22562251
/// Find a dependent retain that precedes the given autorelease for which there
@@ -2260,12 +2255,8 @@ static CallInst *
22602255
FindPredecessorRetainWithSafePath(const Value *Arg, BasicBlock *BB,
22612256
Instruction *Autorelease,
22622257
ProvenanceAnalysis &PA) {
2263-
SmallPtrSet<Instruction *, 4> DepInsts;
2264-
FindDependencies(CanChangeRetainCount, Arg, BB, Autorelease, DepInsts, PA);
2265-
if (DepInsts.size() != 1)
2266-
return nullptr;
2267-
2268-
auto *Retain = dyn_cast_or_null<CallInst>(*DepInsts.begin());
2258+
auto *Retain = dyn_cast_or_null<CallInst>(
2259+
findSingleDependency(CanChangeRetainCount, Arg, BB, Autorelease, PA));
22692260

22702261
// Check that we found a retain with the same argument.
22712262
if (!Retain || !IsRetain(GetBasicARCInstKind(Retain)) ||
@@ -2284,11 +2275,9 @@ FindPredecessorAutoreleaseWithSafePath(const Value *Arg, BasicBlock *BB,
22842275
ReturnInst *Ret,
22852276
ProvenanceAnalysis &PA) {
22862277
SmallPtrSet<Instruction *, 4> DepInsts;
2287-
FindDependencies(NeedsPositiveRetainCount, Arg, BB, Ret, DepInsts, PA);
2288-
if (DepInsts.size() != 1)
2289-
return nullptr;
2278+
auto *Autorelease = dyn_cast_or_null<CallInst>(
2279+
findSingleDependency(NeedsPositiveRetainCount, Arg, BB, Ret, PA));
22902280

2291-
auto *Autorelease = dyn_cast_or_null<CallInst>(*DepInsts.begin());
22922281
if (!Autorelease)
22932282
return nullptr;
22942283
ARCInstKind AutoreleaseClass = GetBasicARCInstKind(Autorelease);
@@ -2314,7 +2303,6 @@ void ObjCARCOpt::OptimizeReturns(Function &F) {
23142303

23152304
LLVM_DEBUG(dbgs() << "\n== ObjCARCOpt::OptimizeReturns ==\n");
23162305

2317-
SmallPtrSet<Instruction *, 4> DependingInstructions;
23182306
for (BasicBlock &BB: F) {
23192307
ReturnInst *Ret = dyn_cast<ReturnInst>(&BB.back());
23202308
if (!Ret)
@@ -2341,21 +2329,13 @@ void ObjCARCOpt::OptimizeReturns(Function &F) {
23412329

23422330
// Check that there is nothing that can affect the reference count
23432331
// between the retain and the call. Note that Retain need not be in BB.
2344-
bool HasSafePathToCall =
2345-
HasSafePathToPredecessorCall(Arg, Retain, DependingInstructions, PA);
2332+
CallInst *Call = HasSafePathToPredecessorCall(Arg, Retain, PA);
23462333

23472334
// Don't remove retainRV/autoreleaseRV pairs if the call isn't a tail call.
2348-
if (HasSafePathToCall &&
2349-
GetBasicARCInstKind(Retain) == ARCInstKind::RetainRV &&
2350-
GetBasicARCInstKind(Autorelease) == ARCInstKind::AutoreleaseRV &&
2351-
!cast<CallInst>(*DependingInstructions.begin())->isTailCall()) {
2352-
DependingInstructions.clear();
2353-
continue;
2354-
}
2355-
2356-
DependingInstructions.clear();
2357-
2358-
if (!HasSafePathToCall)
2335+
if (!Call ||
2336+
(!Call->isTailCall() &&
2337+
GetBasicARCInstKind(Retain) == ARCInstKind::RetainRV &&
2338+
GetBasicARCInstKind(Autorelease) == ARCInstKind::AutoreleaseRV))
23592339
continue;
23602340

23612341
// If so, we can zap the retain and autorelease.

0 commit comments

Comments
 (0)