blob: b197c970ed35af1e69cef90d98eb0c4feafa8fb7 [file] [log] [blame]
Michael Gottesman778138e2013-01-29 03:03:03 +00001//===- DependencyAnalysis.cpp - ObjC ARC Optimization ---------------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10///
11/// This file defines special dependency analysis routines used in Objective C
12/// ARC Optimizations.
13///
14/// WARNING: This file knows about certain library functions. It recognizes them
15/// by name, and hardwires knowledge of their semantics.
16///
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.
20///
21//===----------------------------------------------------------------------===//
22
Michael Gottesman778138e2013-01-29 03:03:03 +000023#include "ObjCARC.h"
Michael Gottesman778138e2013-01-29 03:03:03 +000024#include "DependencyAnalysis.h"
Michael Gottesman278266f2013-01-29 04:20:52 +000025#include "ProvenanceAnalysis.h"
Chandler Carruth1305dc32014-03-04 11:45:46 +000026#include "llvm/IR/CFG.h"
Michael Gottesman778138e2013-01-29 03:03:03 +000027
28using namespace llvm;
29using namespace llvm::objcarc;
30
Chandler Carruth964daaa2014-04-22 02:55:47 +000031#define DEBUG_TYPE "objc-arc-dependency"
32
Michael Gottesman778138e2013-01-29 03:03:03 +000033/// Test whether the given instruction can result in a reference count
34/// modification (positive or negative) for the pointer's object.
Michael Gottesman6f729fa2015-02-19 19:51:32 +000035bool llvm::objcarc::CanAlterRefCount(const Instruction *Inst, const Value *Ptr,
36 ProvenanceAnalysis &PA,
37 ARCInstKind Class) {
Michael Gottesman778138e2013-01-29 03:03:03 +000038 switch (Class) {
Michael Gottesman6f729fa2015-02-19 19:51:32 +000039 case ARCInstKind::Autorelease:
40 case ARCInstKind::AutoreleaseRV:
41 case ARCInstKind::IntrinsicUser:
42 case ARCInstKind::User:
Michael Gottesman778138e2013-01-29 03:03:03 +000043 // These operations never directly modify a reference count.
44 return false;
45 default: break;
46 }
47
48 ImmutableCallSite CS = static_cast<const Value *>(Inst);
49 assert(CS && "Only calls can alter reference counts!");
50
51 // See if AliasAnalysis can help us with the call.
52 AliasAnalysis::ModRefBehavior MRB = PA.getAA()->getModRefBehavior(CS);
53 if (AliasAnalysis::onlyReadsMemory(MRB))
54 return false;
55 if (AliasAnalysis::onlyAccessesArgPointees(MRB)) {
Mehdi Aminia28d91d2015-03-10 02:37:25 +000056 const DataLayout &DL = Inst->getModule()->getDataLayout();
Michael Gottesman778138e2013-01-29 03:03:03 +000057 for (ImmutableCallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
58 I != E; ++I) {
59 const Value *Op = *I;
Mehdi Aminia28d91d2015-03-10 02:37:25 +000060 if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) &&
61 PA.related(Ptr, Op, DL))
Michael Gottesman778138e2013-01-29 03:03:03 +000062 return true;
63 }
64 return false;
65 }
66
67 // Assume the worst.
68 return true;
69}
70
Michael Gottesman5ab64de2015-02-20 00:02:45 +000071bool llvm::objcarc::CanDecrementRefCount(const Instruction *Inst,
72 const Value *Ptr,
73 ProvenanceAnalysis &PA,
74 ARCInstKind Class) {
75 // First perform a quick check if Class can not touch ref counts.
76 if (!CanDecrementRefCount(Class))
77 return false;
78
79 // Otherwise, just use CanAlterRefCount for now.
80 return CanAlterRefCount(Inst, Ptr, PA, Class);
81}
82
Michael Gottesman778138e2013-01-29 03:03:03 +000083/// Test whether the given instruction can "use" the given pointer's object in a
84/// way that requires the reference count to be positive.
Michael Gottesman6f729fa2015-02-19 19:51:32 +000085bool 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)
Michael Gottesman778138e2013-01-29 03:03:03 +000090 return false;
91
Mehdi Aminia28d91d2015-03-10 02:37:25 +000092 const DataLayout &DL = Inst->getModule()->getDataLayout();
93
Michael Gottesman778138e2013-01-29 03:03:03 +000094 // Consider various instructions which may have pointer arguments which are
95 // not "uses".
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()))
101 return false;
102 } else if (ImmutableCallSite CS = static_cast<const Value *>(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;
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000107 if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) &&
108 PA.related(Ptr, Op, DL))
Michael Gottesman778138e2013-01-29 03:03:03 +0000109 return true;
110 }
111 return false;
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.
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000115 const Value *Op = GetUnderlyingObjCPtr(SI->getPointerOperand(), DL);
Michael Gottesman778138e2013-01-29 03:03:03 +0000116 // If we can't tell what the underlying object was, assume there is a
117 // dependence.
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000118 return IsPotentialRetainableObjPtr(Op, *PA.getAA()) &&
119 PA.related(Op, Ptr, DL);
Michael Gottesman778138e2013-01-29 03:03:03 +0000120 }
121
122 // Check each operand for a match.
123 for (User::const_op_iterator OI = Inst->op_begin(), OE = Inst->op_end();
124 OI != OE; ++OI) {
125 const Value *Op = *OI;
Mehdi Aminia28d91d2015-03-10 02:37:25 +0000126 if (IsPotentialRetainableObjPtr(Op, *PA.getAA()) && PA.related(Ptr, Op, DL))
Michael Gottesman778138e2013-01-29 03:03:03 +0000127 return true;
128 }
129 return false;
130}
131
132/// Test if there can be dependencies on Inst through Arg. This function only
133/// tests dependencies relevant for removing pairs of calls.
134bool
135llvm::objcarc::Depends(DependenceKind Flavor, Instruction *Inst,
136 const Value *Arg, ProvenanceAnalysis &PA) {
137 // If we've reached the definition of Arg, stop.
138 if (Inst == Arg)
139 return true;
140
141 switch (Flavor) {
142 case NeedsPositiveRetainCount: {
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000143 ARCInstKind Class = GetARCInstKind(Inst);
Michael Gottesman778138e2013-01-29 03:03:03 +0000144 switch (Class) {
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000145 case ARCInstKind::AutoreleasepoolPop:
146 case ARCInstKind::AutoreleasepoolPush:
147 case ARCInstKind::None:
Michael Gottesman778138e2013-01-29 03:03:03 +0000148 return false;
149 default:
150 return CanUse(Inst, Arg, PA, Class);
151 }
152 }
153
154 case AutoreleasePoolBoundary: {
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000155 ARCInstKind Class = GetARCInstKind(Inst);
Michael Gottesman778138e2013-01-29 03:03:03 +0000156 switch (Class) {
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000157 case ARCInstKind::AutoreleasepoolPop:
158 case ARCInstKind::AutoreleasepoolPush:
Michael Gottesman778138e2013-01-29 03:03:03 +0000159 // These mark the end and begin of an autorelease pool scope.
160 return true;
161 default:
162 // Nothing else does this.
163 return false;
164 }
165 }
166
167 case CanChangeRetainCount: {
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000168 ARCInstKind Class = GetARCInstKind(Inst);
Michael Gottesman778138e2013-01-29 03:03:03 +0000169 switch (Class) {
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000170 case ARCInstKind::AutoreleasepoolPop:
Michael Gottesman778138e2013-01-29 03:03:03 +0000171 // Conservatively assume this can decrement any count.
172 return true;
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000173 case ARCInstKind::AutoreleasepoolPush:
174 case ARCInstKind::None:
Michael Gottesman778138e2013-01-29 03:03:03 +0000175 return false;
176 default:
177 return CanAlterRefCount(Inst, Arg, PA, Class);
178 }
179 }
180
181 case RetainAutoreleaseDep:
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000182 switch (GetBasicARCInstKind(Inst)) {
183 case ARCInstKind::AutoreleasepoolPop:
184 case ARCInstKind::AutoreleasepoolPush:
Michael Gottesman778138e2013-01-29 03:03:03 +0000185 // Don't merge an objc_autorelease with an objc_retain inside a different
186 // autoreleasepool scope.
187 return true;
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000188 case ARCInstKind::Retain:
189 case ARCInstKind::RetainRV:
Michael Gottesman778138e2013-01-29 03:03:03 +0000190 // Check for a retain of the same pointer for merging.
Michael Gottesmane5ad66f2015-02-19 00:42:38 +0000191 return GetArgRCIdentityRoot(Inst) == Arg;
Michael Gottesman778138e2013-01-29 03:03:03 +0000192 default:
193 // Nothing else matters for objc_retainAutorelease formation.
194 return false;
195 }
196
197 case RetainAutoreleaseRVDep: {
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000198 ARCInstKind Class = GetBasicARCInstKind(Inst);
Michael Gottesman778138e2013-01-29 03:03:03 +0000199 switch (Class) {
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000200 case ARCInstKind::Retain:
201 case ARCInstKind::RetainRV:
Michael Gottesman778138e2013-01-29 03:03:03 +0000202 // Check for a retain of the same pointer for merging.
Michael Gottesmane5ad66f2015-02-19 00:42:38 +0000203 return GetArgRCIdentityRoot(Inst) == Arg;
Michael Gottesman778138e2013-01-29 03:03:03 +0000204 default:
205 // Anything that can autorelease interrupts
206 // retainAutoreleaseReturnValue formation.
207 return CanInterruptRV(Class);
208 }
209 }
210
211 case RetainRVDep:
Michael Gottesman6f729fa2015-02-19 19:51:32 +0000212 return CanInterruptRV(GetBasicARCInstKind(Inst));
Michael Gottesman778138e2013-01-29 03:03:03 +0000213 }
214
215 llvm_unreachable("Invalid dependence flavor");
216}
217
218/// Walk up the CFG from StartPos (which is in StartBB) and find local and
219/// non-local dependencies on Arg.
220///
221/// TODO: Cache results?
222void
223llvm::objcarc::FindDependencies(DependenceKind Flavor,
224 const Value *Arg,
225 BasicBlock *StartBB, Instruction *StartInst,
Craig Topper71b7b682014-08-21 05:55:13 +0000226 SmallPtrSetImpl<Instruction *> &DependingInsts,
227 SmallPtrSetImpl<const BasicBlock *> &Visited,
Michael Gottesman778138e2013-01-29 03:03:03 +0000228 ProvenanceAnalysis &PA) {
229 BasicBlock::iterator StartPos = StartInst;
230
231 SmallVector<std::pair<BasicBlock *, BasicBlock::iterator>, 4> Worklist;
232 Worklist.push_back(std::make_pair(StartBB, StartPos));
233 do {
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();
239 for (;;) {
240 if (LocalStartPos == StartBBBegin) {
241 pred_iterator PI(LocalStartBB), PE(LocalStartBB, false);
242 if (PI == PE)
243 // If we've reached the function entry, produce a null dependence.
Craig Topperf40110f2014-04-25 05:29:35 +0000244 DependingInsts.insert(nullptr);
Michael Gottesman778138e2013-01-29 03:03:03 +0000245 else
246 // Add the predecessors to the worklist.
247 do {
248 BasicBlock *PredBB = *PI;
David Blaikie70573dc2014-11-19 07:49:26 +0000249 if (Visited.insert(PredBB).second)
Michael Gottesman778138e2013-01-29 03:03:03 +0000250 Worklist.push_back(std::make_pair(PredBB, PredBB->end()));
251 } while (++PI != PE);
252 break;
253 }
254
255 Instruction *Inst = --LocalStartPos;
256 if (Depends(Flavor, Inst, Arg, PA)) {
257 DependingInsts.insert(Inst);
258 break;
259 }
260 }
261 } while (!Worklist.empty());
262
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
265 // not safe.
Craig Topper46276792014-08-24 23:23:06 +0000266 for (const BasicBlock *BB : Visited) {
Michael Gottesman778138e2013-01-29 03:03:03 +0000267 if (BB == StartBB)
268 continue;
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));
274 return;
275 }
276 }
277 }
278}