1 //===- DependencyAnalysis.cpp - ObjC ARC Optimization ---------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
10 /// This file defines special dependency analysis routines used in Objective C
11 /// ARC Optimizations.
13 /// WARNING: This file knows about certain library functions. It recognizes them
14 /// by name, and hardwires knowledge of their semantics.
16 /// WARNING: This file knows about how certain Objective-C library functions are
17 /// used. Naive LLVM IR transformations which would otherwise be
18 /// behavior-preserving may break these assumptions.
20 //===----------------------------------------------------------------------===//
22 #include "DependencyAnalysis.h"
24 #include "ProvenanceAnalysis.h"
25 #include "llvm/IR/CFG.h"
28 using namespace llvm::objcarc
;
30 #define DEBUG_TYPE "objc-arc-dependency"
32 /// Test whether the given instruction can result in a reference count
33 /// modification (positive or negative) for the pointer's object.
34 bool llvm::objcarc::CanAlterRefCount(const Instruction
*Inst
, const Value
*Ptr
,
35 ProvenanceAnalysis
&PA
,
38 case ARCInstKind::Autorelease
:
39 case ARCInstKind::AutoreleaseRV
:
40 case ARCInstKind::IntrinsicUser
:
41 case ARCInstKind::User
:
42 // These operations never directly modify a reference count.
47 const auto *Call
= cast
<CallBase
>(Inst
);
49 // See if AliasAnalysis can help us with the call.
50 FunctionModRefBehavior MRB
= PA
.getAA()->getModRefBehavior(Call
);
51 if (AliasAnalysis::onlyReadsMemory(MRB
))
53 if (AliasAnalysis::onlyAccessesArgPointees(MRB
)) {
54 const DataLayout
&DL
= Inst
->getModule()->getDataLayout();
55 for (const Value
*Op
: Call
->args()) {
56 if (IsPotentialRetainableObjPtr(Op
, *PA
.getAA()) &&
57 PA
.related(Ptr
, Op
, DL
))
67 bool llvm::objcarc::CanDecrementRefCount(const Instruction
*Inst
,
69 ProvenanceAnalysis
&PA
,
71 // First perform a quick check if Class can not touch ref counts.
72 if (!CanDecrementRefCount(Class
))
75 // Otherwise, just use CanAlterRefCount for now.
76 return CanAlterRefCount(Inst
, Ptr
, PA
, Class
);
79 /// Test whether the given instruction can "use" the given pointer's object in a
80 /// way that requires the reference count to be positive.
81 bool llvm::objcarc::CanUse(const Instruction
*Inst
, const Value
*Ptr
,
82 ProvenanceAnalysis
&PA
, ARCInstKind Class
) {
83 // ARCInstKind::Call operations (as opposed to
84 // ARCInstKind::CallOrUser) never "use" objc pointers.
85 if (Class
== ARCInstKind::Call
)
88 const DataLayout
&DL
= Inst
->getModule()->getDataLayout();
90 // Consider various instructions which may have pointer arguments which are
92 if (const ICmpInst
*ICI
= dyn_cast
<ICmpInst
>(Inst
)) {
93 // Comparing a pointer with null, or any other constant, isn't really a use,
94 // because we don't care what the pointer points to, or about the values
95 // of any other dynamic reference-counted pointers.
96 if (!IsPotentialRetainableObjPtr(ICI
->getOperand(1), *PA
.getAA()))
98 } else if (auto CS
= ImmutableCallSite(Inst
)) {
99 // For calls, just check the arguments (and not the callee operand).
100 for (ImmutableCallSite::arg_iterator OI
= CS
.arg_begin(),
101 OE
= CS
.arg_end(); OI
!= OE
; ++OI
) {
102 const Value
*Op
= *OI
;
103 if (IsPotentialRetainableObjPtr(Op
, *PA
.getAA()) &&
104 PA
.related(Ptr
, Op
, DL
))
108 } else if (const StoreInst
*SI
= dyn_cast
<StoreInst
>(Inst
)) {
109 // Special-case stores, because we don't care about the stored value, just
110 // the store address.
111 const Value
*Op
= GetUnderlyingObjCPtr(SI
->getPointerOperand(), DL
);
112 // If we can't tell what the underlying object was, assume there is a
114 return IsPotentialRetainableObjPtr(Op
, *PA
.getAA()) &&
115 PA
.related(Op
, Ptr
, DL
);
118 // Check each operand for a match.
119 for (User::const_op_iterator OI
= Inst
->op_begin(), OE
= Inst
->op_end();
121 const Value
*Op
= *OI
;
122 if (IsPotentialRetainableObjPtr(Op
, *PA
.getAA()) && PA
.related(Ptr
, Op
, DL
))
128 /// Test if there can be dependencies on Inst through Arg. This function only
129 /// tests dependencies relevant for removing pairs of calls.
131 llvm::objcarc::Depends(DependenceKind Flavor
, Instruction
*Inst
,
132 const Value
*Arg
, ProvenanceAnalysis
&PA
) {
133 // If we've reached the definition of Arg, stop.
138 case NeedsPositiveRetainCount
: {
139 ARCInstKind Class
= GetARCInstKind(Inst
);
141 case ARCInstKind::AutoreleasepoolPop
:
142 case ARCInstKind::AutoreleasepoolPush
:
143 case ARCInstKind::None
:
146 return CanUse(Inst
, Arg
, PA
, Class
);
150 case AutoreleasePoolBoundary
: {
151 ARCInstKind Class
= GetARCInstKind(Inst
);
153 case ARCInstKind::AutoreleasepoolPop
:
154 case ARCInstKind::AutoreleasepoolPush
:
155 // These mark the end and begin of an autorelease pool scope.
158 // Nothing else does this.
163 case CanChangeRetainCount
: {
164 ARCInstKind Class
= GetARCInstKind(Inst
);
166 case ARCInstKind::AutoreleasepoolPop
:
167 // Conservatively assume this can decrement any count.
169 case ARCInstKind::AutoreleasepoolPush
:
170 case ARCInstKind::None
:
173 return CanAlterRefCount(Inst
, Arg
, PA
, Class
);
177 case RetainAutoreleaseDep
:
178 switch (GetBasicARCInstKind(Inst
)) {
179 case ARCInstKind::AutoreleasepoolPop
:
180 case ARCInstKind::AutoreleasepoolPush
:
181 // Don't merge an objc_autorelease with an objc_retain inside a different
182 // autoreleasepool scope.
184 case ARCInstKind::Retain
:
185 case ARCInstKind::RetainRV
:
186 // Check for a retain of the same pointer for merging.
187 return GetArgRCIdentityRoot(Inst
) == Arg
;
189 // Nothing else matters for objc_retainAutorelease formation.
193 case RetainAutoreleaseRVDep
: {
194 ARCInstKind Class
= GetBasicARCInstKind(Inst
);
196 case ARCInstKind::Retain
:
197 case ARCInstKind::RetainRV
:
198 // Check for a retain of the same pointer for merging.
199 return GetArgRCIdentityRoot(Inst
) == Arg
;
201 // Anything that can autorelease interrupts
202 // retainAutoreleaseReturnValue formation.
203 return CanInterruptRV(Class
);
208 return CanInterruptRV(GetBasicARCInstKind(Inst
));
211 llvm_unreachable("Invalid dependence flavor");
214 /// Walk up the CFG from StartPos (which is in StartBB) and find local and
215 /// non-local dependencies on Arg.
217 /// TODO: Cache results?
219 llvm::objcarc::FindDependencies(DependenceKind Flavor
,
221 BasicBlock
*StartBB
, Instruction
*StartInst
,
222 SmallPtrSetImpl
<Instruction
*> &DependingInsts
,
223 SmallPtrSetImpl
<const BasicBlock
*> &Visited
,
224 ProvenanceAnalysis
&PA
) {
225 BasicBlock::iterator StartPos
= StartInst
->getIterator();
227 SmallVector
<std::pair
<BasicBlock
*, BasicBlock::iterator
>, 4> Worklist
;
228 Worklist
.push_back(std::make_pair(StartBB
, StartPos
));
230 std::pair
<BasicBlock
*, BasicBlock::iterator
> Pair
=
231 Worklist
.pop_back_val();
232 BasicBlock
*LocalStartBB
= Pair
.first
;
233 BasicBlock::iterator LocalStartPos
= Pair
.second
;
234 BasicBlock::iterator StartBBBegin
= LocalStartBB
->begin();
236 if (LocalStartPos
== StartBBBegin
) {
237 pred_iterator
PI(LocalStartBB
), PE(LocalStartBB
, false);
239 // If we've reached the function entry, produce a null dependence.
240 DependingInsts
.insert(nullptr);
242 // Add the predecessors to the worklist.
244 BasicBlock
*PredBB
= *PI
;
245 if (Visited
.insert(PredBB
).second
)
246 Worklist
.push_back(std::make_pair(PredBB
, PredBB
->end()));
247 } while (++PI
!= PE
);
251 Instruction
*Inst
= &*--LocalStartPos
;
252 if (Depends(Flavor
, Inst
, Arg
, PA
)) {
253 DependingInsts
.insert(Inst
);
257 } while (!Worklist
.empty());
259 // Determine whether the original StartBB post-dominates all of the blocks we
260 // visited. If not, insert a sentinal indicating that most optimizations are
262 for (const BasicBlock
*BB
: Visited
) {
265 for (const BasicBlock
*Succ
: successors(BB
))
266 if (Succ
!= StartBB
&& !Visited
.count(Succ
)) {
267 DependingInsts
.insert(reinterpret_cast<Instruction
*>(-1));