1 //===- DependencyAnalysis.cpp - ObjC ARC Optimization ---------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// This file defines special dependency analysis routines used in Objective C
12 /// ARC Optimizations.
14 /// WARNING: This file knows about certain library functions. It recognizes them
15 /// by name, and hardwires knowledge of their semantics.
17 /// WARNING: This file knows about how certain Objective-C library functions are
18 /// used. Naive LLVM IR transformations which would otherwise be
19 /// behavior-preserving may break these assumptions.
21 //===----------------------------------------------------------------------===//
23 #include "DependencyAnalysis.h"
25 #include "ProvenanceAnalysis.h"
26 #include "llvm/IR/CFG.h"
29 using namespace llvm::objcarc
;
31 #define DEBUG_TYPE "objc-arc-dependency"
33 /// Test whether the given instruction can result in a reference count
34 /// modification (positive or negative) for the pointer's object.
35 bool llvm::objcarc::CanAlterRefCount(const Instruction
*Inst
, const Value
*Ptr
,
36 ProvenanceAnalysis
&PA
,
39 case ARCInstKind::Autorelease
:
40 case ARCInstKind::AutoreleaseRV
:
41 case ARCInstKind::IntrinsicUser
:
42 case ARCInstKind::User
:
43 // These operations never directly modify a reference count.
48 ImmutableCallSite
CS(Inst
);
49 assert(CS
&& "Only calls can alter reference counts!");
51 // See if AliasAnalysis can help us with the call.
52 FunctionModRefBehavior MRB
= PA
.getAA()->getModRefBehavior(CS
);
53 if (AliasAnalysis::onlyReadsMemory(MRB
))
55 if (AliasAnalysis::onlyAccessesArgPointees(MRB
)) {
56 const DataLayout
&DL
= Inst
->getModule()->getDataLayout();
57 for (ImmutableCallSite::arg_iterator I
= CS
.arg_begin(), E
= CS
.arg_end();
60 if (IsPotentialRetainableObjPtr(Op
, *PA
.getAA()) &&
61 PA
.related(Ptr
, Op
, DL
))
71 bool llvm::objcarc::CanDecrementRefCount(const Instruction
*Inst
,
73 ProvenanceAnalysis
&PA
,
75 // First perform a quick check if Class can not touch ref counts.
76 if (!CanDecrementRefCount(Class
))
79 // Otherwise, just use CanAlterRefCount for now.
80 return CanAlterRefCount(Inst
, Ptr
, PA
, Class
);
83 /// Test whether the given instruction can "use" the given pointer's object in a
84 /// way that requires the reference count to be positive.
85 bool llvm::objcarc::CanUse(const Instruction
*Inst
, const Value
*Ptr
,
86 ProvenanceAnalysis
&PA
, ARCInstKind Class
) {
87 // ARCInstKind::Call operations (as opposed to
88 // ARCInstKind::CallOrUser) never "use" objc pointers.
89 if (Class
== ARCInstKind::Call
)
92 const DataLayout
&DL
= Inst
->getModule()->getDataLayout();
94 // Consider various instructions which may have pointer arguments which are
96 if (const ICmpInst
*ICI
= dyn_cast
<ICmpInst
>(Inst
)) {
97 // Comparing a pointer with null, or any other constant, isn't really a use,
98 // because we don't care what the pointer points to, or about the values
99 // of any other dynamic reference-counted pointers.
100 if (!IsPotentialRetainableObjPtr(ICI
->getOperand(1), *PA
.getAA()))
102 } else if (auto CS
= ImmutableCallSite(Inst
)) {
103 // For calls, just check the arguments (and not the callee operand).
104 for (ImmutableCallSite::arg_iterator OI
= CS
.arg_begin(),
105 OE
= CS
.arg_end(); OI
!= OE
; ++OI
) {
106 const Value
*Op
= *OI
;
107 if (IsPotentialRetainableObjPtr(Op
, *PA
.getAA()) &&
108 PA
.related(Ptr
, Op
, DL
))
112 } else if (const StoreInst
*SI
= dyn_cast
<StoreInst
>(Inst
)) {
113 // Special-case stores, because we don't care about the stored value, just
114 // the store address.
115 const Value
*Op
= GetUnderlyingObjCPtr(SI
->getPointerOperand(), DL
);
116 // If we can't tell what the underlying object was, assume there is a
118 return IsPotentialRetainableObjPtr(Op
, *PA
.getAA()) &&
119 PA
.related(Op
, Ptr
, DL
);
122 // Check each operand for a match.
123 for (User::const_op_iterator OI
= Inst
->op_begin(), OE
= Inst
->op_end();
125 const Value
*Op
= *OI
;
126 if (IsPotentialRetainableObjPtr(Op
, *PA
.getAA()) && PA
.related(Ptr
, Op
, DL
))
132 /// Test if there can be dependencies on Inst through Arg. This function only
133 /// tests dependencies relevant for removing pairs of calls.
135 llvm::objcarc::Depends(DependenceKind Flavor
, Instruction
*Inst
,
136 const Value
*Arg
, ProvenanceAnalysis
&PA
) {
137 // If we've reached the definition of Arg, stop.
142 case NeedsPositiveRetainCount
: {
143 ARCInstKind Class
= GetARCInstKind(Inst
);
145 case ARCInstKind::AutoreleasepoolPop
:
146 case ARCInstKind::AutoreleasepoolPush
:
147 case ARCInstKind::None
:
150 return CanUse(Inst
, Arg
, PA
, Class
);
154 case AutoreleasePoolBoundary
: {
155 ARCInstKind Class
= GetARCInstKind(Inst
);
157 case ARCInstKind::AutoreleasepoolPop
:
158 case ARCInstKind::AutoreleasepoolPush
:
159 // These mark the end and begin of an autorelease pool scope.
162 // Nothing else does this.
167 case CanChangeRetainCount
: {
168 ARCInstKind Class
= GetARCInstKind(Inst
);
170 case ARCInstKind::AutoreleasepoolPop
:
171 // Conservatively assume this can decrement any count.
173 case ARCInstKind::AutoreleasepoolPush
:
174 case ARCInstKind::None
:
177 return CanAlterRefCount(Inst
, Arg
, PA
, Class
);
181 case RetainAutoreleaseDep
:
182 switch (GetBasicARCInstKind(Inst
)) {
183 case ARCInstKind::AutoreleasepoolPop
:
184 case ARCInstKind::AutoreleasepoolPush
:
185 // Don't merge an objc_autorelease with an objc_retain inside a different
186 // autoreleasepool scope.
188 case ARCInstKind::Retain
:
189 case ARCInstKind::RetainRV
:
190 // Check for a retain of the same pointer for merging.
191 return GetArgRCIdentityRoot(Inst
) == Arg
;
193 // Nothing else matters for objc_retainAutorelease formation.
197 case RetainAutoreleaseRVDep
: {
198 ARCInstKind Class
= GetBasicARCInstKind(Inst
);
200 case ARCInstKind::Retain
:
201 case ARCInstKind::RetainRV
:
202 // Check for a retain of the same pointer for merging.
203 return GetArgRCIdentityRoot(Inst
) == Arg
;
205 // Anything that can autorelease interrupts
206 // retainAutoreleaseReturnValue formation.
207 return CanInterruptRV(Class
);
212 return CanInterruptRV(GetBasicARCInstKind(Inst
));
215 llvm_unreachable("Invalid dependence flavor");
218 /// Walk up the CFG from StartPos (which is in StartBB) and find local and
219 /// non-local dependencies on Arg.
221 /// TODO: Cache results?
223 llvm::objcarc::FindDependencies(DependenceKind Flavor
,
225 BasicBlock
*StartBB
, Instruction
*StartInst
,
226 SmallPtrSetImpl
<Instruction
*> &DependingInsts
,
227 SmallPtrSetImpl
<const BasicBlock
*> &Visited
,
228 ProvenanceAnalysis
&PA
) {
229 BasicBlock::iterator StartPos
= StartInst
->getIterator();
231 SmallVector
<std::pair
<BasicBlock
*, BasicBlock::iterator
>, 4> Worklist
;
232 Worklist
.push_back(std::make_pair(StartBB
, StartPos
));
234 std::pair
<BasicBlock
*, BasicBlock::iterator
> Pair
=
235 Worklist
.pop_back_val();
236 BasicBlock
*LocalStartBB
= Pair
.first
;
237 BasicBlock::iterator LocalStartPos
= Pair
.second
;
238 BasicBlock::iterator StartBBBegin
= LocalStartBB
->begin();
240 if (LocalStartPos
== StartBBBegin
) {
241 pred_iterator
PI(LocalStartBB
), PE(LocalStartBB
, false);
243 // If we've reached the function entry, produce a null dependence.
244 DependingInsts
.insert(nullptr);
246 // Add the predecessors to the worklist.
248 BasicBlock
*PredBB
= *PI
;
249 if (Visited
.insert(PredBB
).second
)
250 Worklist
.push_back(std::make_pair(PredBB
, PredBB
->end()));
251 } while (++PI
!= PE
);
255 Instruction
*Inst
= &*--LocalStartPos
;
256 if (Depends(Flavor
, Inst
, Arg
, PA
)) {
257 DependingInsts
.insert(Inst
);
261 } while (!Worklist
.empty());
263 // Determine whether the original StartBB post-dominates all of the blocks we
264 // visited. If not, insert a sentinal indicating that most optimizations are
266 for (const BasicBlock
*BB
: Visited
) {
269 const TerminatorInst
*TI
= cast
<TerminatorInst
>(&BB
->back());
270 for (succ_const_iterator
SI(TI
), SE(TI
, false); SI
!= SE
; ++SI
) {
271 const BasicBlock
*Succ
= *SI
;
272 if (Succ
!= StartBB
&& !Visited
.count(Succ
)) {
273 DependingInsts
.insert(reinterpret_cast<Instruction
*>(-1));