1*9880d681SAndroid Build Coastguard Worker //===- ARCInstKind.cpp - ObjC ARC Optimization ----------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker /// \file
10*9880d681SAndroid Build Coastguard Worker /// This file defines several utility functions used by various ARC
11*9880d681SAndroid Build Coastguard Worker /// optimizations which are IMHO too big to be in a header file.
12*9880d681SAndroid Build Coastguard Worker ///
13*9880d681SAndroid Build Coastguard Worker /// WARNING: This file knows about certain library functions. It recognizes them
14*9880d681SAndroid Build Coastguard Worker /// by name, and hardwires knowledge of their semantics.
15*9880d681SAndroid Build Coastguard Worker ///
16*9880d681SAndroid Build Coastguard Worker /// WARNING: This file knows about how certain Objective-C library functions are
17*9880d681SAndroid Build Coastguard Worker /// used. Naive LLVM IR transformations which would otherwise be
18*9880d681SAndroid Build Coastguard Worker /// behavior-preserving may break these assumptions.
19*9880d681SAndroid Build Coastguard Worker ///
20*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ObjCARCInstKind.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ObjCARCAnalysisUtils.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringSwitch.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/Intrinsics.h"
26*9880d681SAndroid Build Coastguard Worker
27*9880d681SAndroid Build Coastguard Worker using namespace llvm;
28*9880d681SAndroid Build Coastguard Worker using namespace llvm::objcarc;
29*9880d681SAndroid Build Coastguard Worker
operator <<(raw_ostream & OS,const ARCInstKind Class)30*9880d681SAndroid Build Coastguard Worker raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS,
31*9880d681SAndroid Build Coastguard Worker const ARCInstKind Class) {
32*9880d681SAndroid Build Coastguard Worker switch (Class) {
33*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Retain:
34*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::Retain";
35*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainRV:
36*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::RetainRV";
37*9880d681SAndroid Build Coastguard Worker case ARCInstKind::ClaimRV:
38*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::ClaimRV";
39*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainBlock:
40*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::RetainBlock";
41*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Release:
42*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::Release";
43*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Autorelease:
44*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::Autorelease";
45*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleaseRV:
46*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::AutoreleaseRV";
47*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPush:
48*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::AutoreleasepoolPush";
49*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPop:
50*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::AutoreleasepoolPop";
51*9880d681SAndroid Build Coastguard Worker case ARCInstKind::NoopCast:
52*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::NoopCast";
53*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutorelease:
54*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::FusedRetainAutorelease";
55*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutoreleaseRV:
56*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::FusedRetainAutoreleaseRV";
57*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeakRetained:
58*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::LoadWeakRetained";
59*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreWeak:
60*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::StoreWeak";
61*9880d681SAndroid Build Coastguard Worker case ARCInstKind::InitWeak:
62*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::InitWeak";
63*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeak:
64*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::LoadWeak";
65*9880d681SAndroid Build Coastguard Worker case ARCInstKind::MoveWeak:
66*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::MoveWeak";
67*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CopyWeak:
68*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::CopyWeak";
69*9880d681SAndroid Build Coastguard Worker case ARCInstKind::DestroyWeak:
70*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::DestroyWeak";
71*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreStrong:
72*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::StoreStrong";
73*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CallOrUser:
74*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::CallOrUser";
75*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Call:
76*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::Call";
77*9880d681SAndroid Build Coastguard Worker case ARCInstKind::User:
78*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::User";
79*9880d681SAndroid Build Coastguard Worker case ARCInstKind::IntrinsicUser:
80*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::IntrinsicUser";
81*9880d681SAndroid Build Coastguard Worker case ARCInstKind::None:
82*9880d681SAndroid Build Coastguard Worker return OS << "ARCInstKind::None";
83*9880d681SAndroid Build Coastguard Worker }
84*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unknown instruction class!");
85*9880d681SAndroid Build Coastguard Worker }
86*9880d681SAndroid Build Coastguard Worker
GetFunctionClass(const Function * F)87*9880d681SAndroid Build Coastguard Worker ARCInstKind llvm::objcarc::GetFunctionClass(const Function *F) {
88*9880d681SAndroid Build Coastguard Worker Function::const_arg_iterator AI = F->arg_begin(), AE = F->arg_end();
89*9880d681SAndroid Build Coastguard Worker
90*9880d681SAndroid Build Coastguard Worker // No (mandatory) arguments.
91*9880d681SAndroid Build Coastguard Worker if (AI == AE)
92*9880d681SAndroid Build Coastguard Worker return StringSwitch<ARCInstKind>(F->getName())
93*9880d681SAndroid Build Coastguard Worker .Case("objc_autoreleasePoolPush", ARCInstKind::AutoreleasepoolPush)
94*9880d681SAndroid Build Coastguard Worker .Case("clang.arc.use", ARCInstKind::IntrinsicUser)
95*9880d681SAndroid Build Coastguard Worker .Default(ARCInstKind::CallOrUser);
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker // One argument.
98*9880d681SAndroid Build Coastguard Worker const Argument *A0 = &*AI++;
99*9880d681SAndroid Build Coastguard Worker if (AI == AE)
100*9880d681SAndroid Build Coastguard Worker // Argument is a pointer.
101*9880d681SAndroid Build Coastguard Worker if (PointerType *PTy = dyn_cast<PointerType>(A0->getType())) {
102*9880d681SAndroid Build Coastguard Worker Type *ETy = PTy->getElementType();
103*9880d681SAndroid Build Coastguard Worker // Argument is i8*.
104*9880d681SAndroid Build Coastguard Worker if (ETy->isIntegerTy(8))
105*9880d681SAndroid Build Coastguard Worker return StringSwitch<ARCInstKind>(F->getName())
106*9880d681SAndroid Build Coastguard Worker .Case("objc_retain", ARCInstKind::Retain)
107*9880d681SAndroid Build Coastguard Worker .Case("objc_retainAutoreleasedReturnValue", ARCInstKind::RetainRV)
108*9880d681SAndroid Build Coastguard Worker .Case("objc_unsafeClaimAutoreleasedReturnValue",
109*9880d681SAndroid Build Coastguard Worker ARCInstKind::ClaimRV)
110*9880d681SAndroid Build Coastguard Worker .Case("objc_retainBlock", ARCInstKind::RetainBlock)
111*9880d681SAndroid Build Coastguard Worker .Case("objc_release", ARCInstKind::Release)
112*9880d681SAndroid Build Coastguard Worker .Case("objc_autorelease", ARCInstKind::Autorelease)
113*9880d681SAndroid Build Coastguard Worker .Case("objc_autoreleaseReturnValue", ARCInstKind::AutoreleaseRV)
114*9880d681SAndroid Build Coastguard Worker .Case("objc_autoreleasePoolPop", ARCInstKind::AutoreleasepoolPop)
115*9880d681SAndroid Build Coastguard Worker .Case("objc_retainedObject", ARCInstKind::NoopCast)
116*9880d681SAndroid Build Coastguard Worker .Case("objc_unretainedObject", ARCInstKind::NoopCast)
117*9880d681SAndroid Build Coastguard Worker .Case("objc_unretainedPointer", ARCInstKind::NoopCast)
118*9880d681SAndroid Build Coastguard Worker .Case("objc_retain_autorelease",
119*9880d681SAndroid Build Coastguard Worker ARCInstKind::FusedRetainAutorelease)
120*9880d681SAndroid Build Coastguard Worker .Case("objc_retainAutorelease", ARCInstKind::FusedRetainAutorelease)
121*9880d681SAndroid Build Coastguard Worker .Case("objc_retainAutoreleaseReturnValue",
122*9880d681SAndroid Build Coastguard Worker ARCInstKind::FusedRetainAutoreleaseRV)
123*9880d681SAndroid Build Coastguard Worker .Case("objc_sync_enter", ARCInstKind::User)
124*9880d681SAndroid Build Coastguard Worker .Case("objc_sync_exit", ARCInstKind::User)
125*9880d681SAndroid Build Coastguard Worker .Default(ARCInstKind::CallOrUser);
126*9880d681SAndroid Build Coastguard Worker
127*9880d681SAndroid Build Coastguard Worker // Argument is i8**
128*9880d681SAndroid Build Coastguard Worker if (PointerType *Pte = dyn_cast<PointerType>(ETy))
129*9880d681SAndroid Build Coastguard Worker if (Pte->getElementType()->isIntegerTy(8))
130*9880d681SAndroid Build Coastguard Worker return StringSwitch<ARCInstKind>(F->getName())
131*9880d681SAndroid Build Coastguard Worker .Case("objc_loadWeakRetained", ARCInstKind::LoadWeakRetained)
132*9880d681SAndroid Build Coastguard Worker .Case("objc_loadWeak", ARCInstKind::LoadWeak)
133*9880d681SAndroid Build Coastguard Worker .Case("objc_destroyWeak", ARCInstKind::DestroyWeak)
134*9880d681SAndroid Build Coastguard Worker .Default(ARCInstKind::CallOrUser);
135*9880d681SAndroid Build Coastguard Worker }
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker // Two arguments, first is i8**.
138*9880d681SAndroid Build Coastguard Worker const Argument *A1 = &*AI++;
139*9880d681SAndroid Build Coastguard Worker if (AI == AE)
140*9880d681SAndroid Build Coastguard Worker if (PointerType *PTy = dyn_cast<PointerType>(A0->getType()))
141*9880d681SAndroid Build Coastguard Worker if (PointerType *Pte = dyn_cast<PointerType>(PTy->getElementType()))
142*9880d681SAndroid Build Coastguard Worker if (Pte->getElementType()->isIntegerTy(8))
143*9880d681SAndroid Build Coastguard Worker if (PointerType *PTy1 = dyn_cast<PointerType>(A1->getType())) {
144*9880d681SAndroid Build Coastguard Worker Type *ETy1 = PTy1->getElementType();
145*9880d681SAndroid Build Coastguard Worker // Second argument is i8*
146*9880d681SAndroid Build Coastguard Worker if (ETy1->isIntegerTy(8))
147*9880d681SAndroid Build Coastguard Worker return StringSwitch<ARCInstKind>(F->getName())
148*9880d681SAndroid Build Coastguard Worker .Case("objc_storeWeak", ARCInstKind::StoreWeak)
149*9880d681SAndroid Build Coastguard Worker .Case("objc_initWeak", ARCInstKind::InitWeak)
150*9880d681SAndroid Build Coastguard Worker .Case("objc_storeStrong", ARCInstKind::StoreStrong)
151*9880d681SAndroid Build Coastguard Worker .Default(ARCInstKind::CallOrUser);
152*9880d681SAndroid Build Coastguard Worker // Second argument is i8**.
153*9880d681SAndroid Build Coastguard Worker if (PointerType *Pte1 = dyn_cast<PointerType>(ETy1))
154*9880d681SAndroid Build Coastguard Worker if (Pte1->getElementType()->isIntegerTy(8))
155*9880d681SAndroid Build Coastguard Worker return StringSwitch<ARCInstKind>(F->getName())
156*9880d681SAndroid Build Coastguard Worker .Case("objc_moveWeak", ARCInstKind::MoveWeak)
157*9880d681SAndroid Build Coastguard Worker .Case("objc_copyWeak", ARCInstKind::CopyWeak)
158*9880d681SAndroid Build Coastguard Worker // Ignore annotation calls. This is important to stop the
159*9880d681SAndroid Build Coastguard Worker // optimizer from treating annotations as uses which would
160*9880d681SAndroid Build Coastguard Worker // make the state of the pointers they are attempting to
161*9880d681SAndroid Build Coastguard Worker // elucidate to be incorrect.
162*9880d681SAndroid Build Coastguard Worker .Case("llvm.arc.annotation.topdown.bbstart",
163*9880d681SAndroid Build Coastguard Worker ARCInstKind::None)
164*9880d681SAndroid Build Coastguard Worker .Case("llvm.arc.annotation.topdown.bbend",
165*9880d681SAndroid Build Coastguard Worker ARCInstKind::None)
166*9880d681SAndroid Build Coastguard Worker .Case("llvm.arc.annotation.bottomup.bbstart",
167*9880d681SAndroid Build Coastguard Worker ARCInstKind::None)
168*9880d681SAndroid Build Coastguard Worker .Case("llvm.arc.annotation.bottomup.bbend",
169*9880d681SAndroid Build Coastguard Worker ARCInstKind::None)
170*9880d681SAndroid Build Coastguard Worker .Default(ARCInstKind::CallOrUser);
171*9880d681SAndroid Build Coastguard Worker }
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker // Anything else.
174*9880d681SAndroid Build Coastguard Worker return ARCInstKind::CallOrUser;
175*9880d681SAndroid Build Coastguard Worker }
176*9880d681SAndroid Build Coastguard Worker
177*9880d681SAndroid Build Coastguard Worker // A whitelist of intrinsics that we know do not use objc pointers or decrement
178*9880d681SAndroid Build Coastguard Worker // ref counts.
isInertIntrinsic(unsigned ID)179*9880d681SAndroid Build Coastguard Worker static bool isInertIntrinsic(unsigned ID) {
180*9880d681SAndroid Build Coastguard Worker // TODO: Make this into a covered switch.
181*9880d681SAndroid Build Coastguard Worker switch (ID) {
182*9880d681SAndroid Build Coastguard Worker case Intrinsic::returnaddress:
183*9880d681SAndroid Build Coastguard Worker case Intrinsic::frameaddress:
184*9880d681SAndroid Build Coastguard Worker case Intrinsic::stacksave:
185*9880d681SAndroid Build Coastguard Worker case Intrinsic::stackrestore:
186*9880d681SAndroid Build Coastguard Worker case Intrinsic::vastart:
187*9880d681SAndroid Build Coastguard Worker case Intrinsic::vacopy:
188*9880d681SAndroid Build Coastguard Worker case Intrinsic::vaend:
189*9880d681SAndroid Build Coastguard Worker case Intrinsic::objectsize:
190*9880d681SAndroid Build Coastguard Worker case Intrinsic::prefetch:
191*9880d681SAndroid Build Coastguard Worker case Intrinsic::stackprotector:
192*9880d681SAndroid Build Coastguard Worker case Intrinsic::eh_return_i32:
193*9880d681SAndroid Build Coastguard Worker case Intrinsic::eh_return_i64:
194*9880d681SAndroid Build Coastguard Worker case Intrinsic::eh_typeid_for:
195*9880d681SAndroid Build Coastguard Worker case Intrinsic::eh_dwarf_cfa:
196*9880d681SAndroid Build Coastguard Worker case Intrinsic::eh_sjlj_lsda:
197*9880d681SAndroid Build Coastguard Worker case Intrinsic::eh_sjlj_functioncontext:
198*9880d681SAndroid Build Coastguard Worker case Intrinsic::init_trampoline:
199*9880d681SAndroid Build Coastguard Worker case Intrinsic::adjust_trampoline:
200*9880d681SAndroid Build Coastguard Worker case Intrinsic::lifetime_start:
201*9880d681SAndroid Build Coastguard Worker case Intrinsic::lifetime_end:
202*9880d681SAndroid Build Coastguard Worker case Intrinsic::invariant_start:
203*9880d681SAndroid Build Coastguard Worker case Intrinsic::invariant_end:
204*9880d681SAndroid Build Coastguard Worker // Don't let dbg info affect our results.
205*9880d681SAndroid Build Coastguard Worker case Intrinsic::dbg_declare:
206*9880d681SAndroid Build Coastguard Worker case Intrinsic::dbg_value:
207*9880d681SAndroid Build Coastguard Worker // Short cut: Some intrinsics obviously don't use ObjC pointers.
208*9880d681SAndroid Build Coastguard Worker return true;
209*9880d681SAndroid Build Coastguard Worker default:
210*9880d681SAndroid Build Coastguard Worker return false;
211*9880d681SAndroid Build Coastguard Worker }
212*9880d681SAndroid Build Coastguard Worker }
213*9880d681SAndroid Build Coastguard Worker
214*9880d681SAndroid Build Coastguard Worker // A whitelist of intrinsics that we know do not use objc pointers or decrement
215*9880d681SAndroid Build Coastguard Worker // ref counts.
isUseOnlyIntrinsic(unsigned ID)216*9880d681SAndroid Build Coastguard Worker static bool isUseOnlyIntrinsic(unsigned ID) {
217*9880d681SAndroid Build Coastguard Worker // We are conservative and even though intrinsics are unlikely to touch
218*9880d681SAndroid Build Coastguard Worker // reference counts, we white list them for safety.
219*9880d681SAndroid Build Coastguard Worker //
220*9880d681SAndroid Build Coastguard Worker // TODO: Expand this into a covered switch. There is a lot more here.
221*9880d681SAndroid Build Coastguard Worker switch (ID) {
222*9880d681SAndroid Build Coastguard Worker case Intrinsic::memcpy:
223*9880d681SAndroid Build Coastguard Worker case Intrinsic::memmove:
224*9880d681SAndroid Build Coastguard Worker case Intrinsic::memset:
225*9880d681SAndroid Build Coastguard Worker return true;
226*9880d681SAndroid Build Coastguard Worker default:
227*9880d681SAndroid Build Coastguard Worker return false;
228*9880d681SAndroid Build Coastguard Worker }
229*9880d681SAndroid Build Coastguard Worker }
230*9880d681SAndroid Build Coastguard Worker
231*9880d681SAndroid Build Coastguard Worker /// \brief Determine what kind of construct V is.
GetARCInstKind(const Value * V)232*9880d681SAndroid Build Coastguard Worker ARCInstKind llvm::objcarc::GetARCInstKind(const Value *V) {
233*9880d681SAndroid Build Coastguard Worker if (const Instruction *I = dyn_cast<Instruction>(V)) {
234*9880d681SAndroid Build Coastguard Worker // Any instruction other than bitcast and gep with a pointer operand have a
235*9880d681SAndroid Build Coastguard Worker // use of an objc pointer. Bitcasts, GEPs, Selects, PHIs transfer a pointer
236*9880d681SAndroid Build Coastguard Worker // to a subsequent use, rather than using it themselves, in this sense.
237*9880d681SAndroid Build Coastguard Worker // As a short cut, several other opcodes are known to have no pointer
238*9880d681SAndroid Build Coastguard Worker // operands of interest. And ret is never followed by a release, so it's
239*9880d681SAndroid Build Coastguard Worker // not interesting to examine.
240*9880d681SAndroid Build Coastguard Worker switch (I->getOpcode()) {
241*9880d681SAndroid Build Coastguard Worker case Instruction::Call: {
242*9880d681SAndroid Build Coastguard Worker const CallInst *CI = cast<CallInst>(I);
243*9880d681SAndroid Build Coastguard Worker // See if we have a function that we know something about.
244*9880d681SAndroid Build Coastguard Worker if (const Function *F = CI->getCalledFunction()) {
245*9880d681SAndroid Build Coastguard Worker ARCInstKind Class = GetFunctionClass(F);
246*9880d681SAndroid Build Coastguard Worker if (Class != ARCInstKind::CallOrUser)
247*9880d681SAndroid Build Coastguard Worker return Class;
248*9880d681SAndroid Build Coastguard Worker Intrinsic::ID ID = F->getIntrinsicID();
249*9880d681SAndroid Build Coastguard Worker if (isInertIntrinsic(ID))
250*9880d681SAndroid Build Coastguard Worker return ARCInstKind::None;
251*9880d681SAndroid Build Coastguard Worker if (isUseOnlyIntrinsic(ID))
252*9880d681SAndroid Build Coastguard Worker return ARCInstKind::User;
253*9880d681SAndroid Build Coastguard Worker }
254*9880d681SAndroid Build Coastguard Worker
255*9880d681SAndroid Build Coastguard Worker // Otherwise, be conservative.
256*9880d681SAndroid Build Coastguard Worker return GetCallSiteClass(CI);
257*9880d681SAndroid Build Coastguard Worker }
258*9880d681SAndroid Build Coastguard Worker case Instruction::Invoke:
259*9880d681SAndroid Build Coastguard Worker // Otherwise, be conservative.
260*9880d681SAndroid Build Coastguard Worker return GetCallSiteClass(cast<InvokeInst>(I));
261*9880d681SAndroid Build Coastguard Worker case Instruction::BitCast:
262*9880d681SAndroid Build Coastguard Worker case Instruction::GetElementPtr:
263*9880d681SAndroid Build Coastguard Worker case Instruction::Select:
264*9880d681SAndroid Build Coastguard Worker case Instruction::PHI:
265*9880d681SAndroid Build Coastguard Worker case Instruction::Ret:
266*9880d681SAndroid Build Coastguard Worker case Instruction::Br:
267*9880d681SAndroid Build Coastguard Worker case Instruction::Switch:
268*9880d681SAndroid Build Coastguard Worker case Instruction::IndirectBr:
269*9880d681SAndroid Build Coastguard Worker case Instruction::Alloca:
270*9880d681SAndroid Build Coastguard Worker case Instruction::VAArg:
271*9880d681SAndroid Build Coastguard Worker case Instruction::Add:
272*9880d681SAndroid Build Coastguard Worker case Instruction::FAdd:
273*9880d681SAndroid Build Coastguard Worker case Instruction::Sub:
274*9880d681SAndroid Build Coastguard Worker case Instruction::FSub:
275*9880d681SAndroid Build Coastguard Worker case Instruction::Mul:
276*9880d681SAndroid Build Coastguard Worker case Instruction::FMul:
277*9880d681SAndroid Build Coastguard Worker case Instruction::SDiv:
278*9880d681SAndroid Build Coastguard Worker case Instruction::UDiv:
279*9880d681SAndroid Build Coastguard Worker case Instruction::FDiv:
280*9880d681SAndroid Build Coastguard Worker case Instruction::SRem:
281*9880d681SAndroid Build Coastguard Worker case Instruction::URem:
282*9880d681SAndroid Build Coastguard Worker case Instruction::FRem:
283*9880d681SAndroid Build Coastguard Worker case Instruction::Shl:
284*9880d681SAndroid Build Coastguard Worker case Instruction::LShr:
285*9880d681SAndroid Build Coastguard Worker case Instruction::AShr:
286*9880d681SAndroid Build Coastguard Worker case Instruction::And:
287*9880d681SAndroid Build Coastguard Worker case Instruction::Or:
288*9880d681SAndroid Build Coastguard Worker case Instruction::Xor:
289*9880d681SAndroid Build Coastguard Worker case Instruction::SExt:
290*9880d681SAndroid Build Coastguard Worker case Instruction::ZExt:
291*9880d681SAndroid Build Coastguard Worker case Instruction::Trunc:
292*9880d681SAndroid Build Coastguard Worker case Instruction::IntToPtr:
293*9880d681SAndroid Build Coastguard Worker case Instruction::FCmp:
294*9880d681SAndroid Build Coastguard Worker case Instruction::FPTrunc:
295*9880d681SAndroid Build Coastguard Worker case Instruction::FPExt:
296*9880d681SAndroid Build Coastguard Worker case Instruction::FPToUI:
297*9880d681SAndroid Build Coastguard Worker case Instruction::FPToSI:
298*9880d681SAndroid Build Coastguard Worker case Instruction::UIToFP:
299*9880d681SAndroid Build Coastguard Worker case Instruction::SIToFP:
300*9880d681SAndroid Build Coastguard Worker case Instruction::InsertElement:
301*9880d681SAndroid Build Coastguard Worker case Instruction::ExtractElement:
302*9880d681SAndroid Build Coastguard Worker case Instruction::ShuffleVector:
303*9880d681SAndroid Build Coastguard Worker case Instruction::ExtractValue:
304*9880d681SAndroid Build Coastguard Worker break;
305*9880d681SAndroid Build Coastguard Worker case Instruction::ICmp:
306*9880d681SAndroid Build Coastguard Worker // Comparing a pointer with null, or any other constant, isn't an
307*9880d681SAndroid Build Coastguard Worker // interesting use, because we don't care what the pointer points to, or
308*9880d681SAndroid Build Coastguard Worker // about the values of any other dynamic reference-counted pointers.
309*9880d681SAndroid Build Coastguard Worker if (IsPotentialRetainableObjPtr(I->getOperand(1)))
310*9880d681SAndroid Build Coastguard Worker return ARCInstKind::User;
311*9880d681SAndroid Build Coastguard Worker break;
312*9880d681SAndroid Build Coastguard Worker default:
313*9880d681SAndroid Build Coastguard Worker // For anything else, check all the operands.
314*9880d681SAndroid Build Coastguard Worker // Note that this includes both operands of a Store: while the first
315*9880d681SAndroid Build Coastguard Worker // operand isn't actually being dereferenced, it is being stored to
316*9880d681SAndroid Build Coastguard Worker // memory where we can no longer track who might read it and dereference
317*9880d681SAndroid Build Coastguard Worker // it, so we have to consider it potentially used.
318*9880d681SAndroid Build Coastguard Worker for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end();
319*9880d681SAndroid Build Coastguard Worker OI != OE; ++OI)
320*9880d681SAndroid Build Coastguard Worker if (IsPotentialRetainableObjPtr(*OI))
321*9880d681SAndroid Build Coastguard Worker return ARCInstKind::User;
322*9880d681SAndroid Build Coastguard Worker }
323*9880d681SAndroid Build Coastguard Worker }
324*9880d681SAndroid Build Coastguard Worker
325*9880d681SAndroid Build Coastguard Worker // Otherwise, it's totally inert for ARC purposes.
326*9880d681SAndroid Build Coastguard Worker return ARCInstKind::None;
327*9880d681SAndroid Build Coastguard Worker }
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker /// \brief Test if the given class is a kind of user.
IsUser(ARCInstKind Class)330*9880d681SAndroid Build Coastguard Worker bool llvm::objcarc::IsUser(ARCInstKind Class) {
331*9880d681SAndroid Build Coastguard Worker switch (Class) {
332*9880d681SAndroid Build Coastguard Worker case ARCInstKind::User:
333*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CallOrUser:
334*9880d681SAndroid Build Coastguard Worker case ARCInstKind::IntrinsicUser:
335*9880d681SAndroid Build Coastguard Worker return true;
336*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Retain:
337*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainRV:
338*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainBlock:
339*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Release:
340*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Autorelease:
341*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleaseRV:
342*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPush:
343*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPop:
344*9880d681SAndroid Build Coastguard Worker case ARCInstKind::NoopCast:
345*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutorelease:
346*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutoreleaseRV:
347*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeakRetained:
348*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreWeak:
349*9880d681SAndroid Build Coastguard Worker case ARCInstKind::InitWeak:
350*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeak:
351*9880d681SAndroid Build Coastguard Worker case ARCInstKind::MoveWeak:
352*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CopyWeak:
353*9880d681SAndroid Build Coastguard Worker case ARCInstKind::DestroyWeak:
354*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreStrong:
355*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Call:
356*9880d681SAndroid Build Coastguard Worker case ARCInstKind::None:
357*9880d681SAndroid Build Coastguard Worker case ARCInstKind::ClaimRV:
358*9880d681SAndroid Build Coastguard Worker return false;
359*9880d681SAndroid Build Coastguard Worker }
360*9880d681SAndroid Build Coastguard Worker llvm_unreachable("covered switch isn't covered?");
361*9880d681SAndroid Build Coastguard Worker }
362*9880d681SAndroid Build Coastguard Worker
363*9880d681SAndroid Build Coastguard Worker /// \brief Test if the given class is objc_retain or equivalent.
IsRetain(ARCInstKind Class)364*9880d681SAndroid Build Coastguard Worker bool llvm::objcarc::IsRetain(ARCInstKind Class) {
365*9880d681SAndroid Build Coastguard Worker switch (Class) {
366*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Retain:
367*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainRV:
368*9880d681SAndroid Build Coastguard Worker return true;
369*9880d681SAndroid Build Coastguard Worker // I believe we treat retain block as not a retain since it can copy its
370*9880d681SAndroid Build Coastguard Worker // block.
371*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainBlock:
372*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Release:
373*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Autorelease:
374*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleaseRV:
375*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPush:
376*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPop:
377*9880d681SAndroid Build Coastguard Worker case ARCInstKind::NoopCast:
378*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutorelease:
379*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutoreleaseRV:
380*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeakRetained:
381*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreWeak:
382*9880d681SAndroid Build Coastguard Worker case ARCInstKind::InitWeak:
383*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeak:
384*9880d681SAndroid Build Coastguard Worker case ARCInstKind::MoveWeak:
385*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CopyWeak:
386*9880d681SAndroid Build Coastguard Worker case ARCInstKind::DestroyWeak:
387*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreStrong:
388*9880d681SAndroid Build Coastguard Worker case ARCInstKind::IntrinsicUser:
389*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CallOrUser:
390*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Call:
391*9880d681SAndroid Build Coastguard Worker case ARCInstKind::User:
392*9880d681SAndroid Build Coastguard Worker case ARCInstKind::None:
393*9880d681SAndroid Build Coastguard Worker case ARCInstKind::ClaimRV:
394*9880d681SAndroid Build Coastguard Worker return false;
395*9880d681SAndroid Build Coastguard Worker }
396*9880d681SAndroid Build Coastguard Worker llvm_unreachable("covered switch isn't covered?");
397*9880d681SAndroid Build Coastguard Worker }
398*9880d681SAndroid Build Coastguard Worker
399*9880d681SAndroid Build Coastguard Worker /// \brief Test if the given class is objc_autorelease or equivalent.
IsAutorelease(ARCInstKind Class)400*9880d681SAndroid Build Coastguard Worker bool llvm::objcarc::IsAutorelease(ARCInstKind Class) {
401*9880d681SAndroid Build Coastguard Worker switch (Class) {
402*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Autorelease:
403*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleaseRV:
404*9880d681SAndroid Build Coastguard Worker return true;
405*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Retain:
406*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainRV:
407*9880d681SAndroid Build Coastguard Worker case ARCInstKind::ClaimRV:
408*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainBlock:
409*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Release:
410*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPush:
411*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPop:
412*9880d681SAndroid Build Coastguard Worker case ARCInstKind::NoopCast:
413*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutorelease:
414*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutoreleaseRV:
415*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeakRetained:
416*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreWeak:
417*9880d681SAndroid Build Coastguard Worker case ARCInstKind::InitWeak:
418*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeak:
419*9880d681SAndroid Build Coastguard Worker case ARCInstKind::MoveWeak:
420*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CopyWeak:
421*9880d681SAndroid Build Coastguard Worker case ARCInstKind::DestroyWeak:
422*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreStrong:
423*9880d681SAndroid Build Coastguard Worker case ARCInstKind::IntrinsicUser:
424*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CallOrUser:
425*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Call:
426*9880d681SAndroid Build Coastguard Worker case ARCInstKind::User:
427*9880d681SAndroid Build Coastguard Worker case ARCInstKind::None:
428*9880d681SAndroid Build Coastguard Worker return false;
429*9880d681SAndroid Build Coastguard Worker }
430*9880d681SAndroid Build Coastguard Worker llvm_unreachable("covered switch isn't covered?");
431*9880d681SAndroid Build Coastguard Worker }
432*9880d681SAndroid Build Coastguard Worker
433*9880d681SAndroid Build Coastguard Worker /// \brief Test if the given class represents instructions which return their
434*9880d681SAndroid Build Coastguard Worker /// argument verbatim.
IsForwarding(ARCInstKind Class)435*9880d681SAndroid Build Coastguard Worker bool llvm::objcarc::IsForwarding(ARCInstKind Class) {
436*9880d681SAndroid Build Coastguard Worker switch (Class) {
437*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Retain:
438*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainRV:
439*9880d681SAndroid Build Coastguard Worker case ARCInstKind::ClaimRV:
440*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Autorelease:
441*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleaseRV:
442*9880d681SAndroid Build Coastguard Worker case ARCInstKind::NoopCast:
443*9880d681SAndroid Build Coastguard Worker return true;
444*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainBlock:
445*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Release:
446*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPush:
447*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPop:
448*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutorelease:
449*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutoreleaseRV:
450*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeakRetained:
451*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreWeak:
452*9880d681SAndroid Build Coastguard Worker case ARCInstKind::InitWeak:
453*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeak:
454*9880d681SAndroid Build Coastguard Worker case ARCInstKind::MoveWeak:
455*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CopyWeak:
456*9880d681SAndroid Build Coastguard Worker case ARCInstKind::DestroyWeak:
457*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreStrong:
458*9880d681SAndroid Build Coastguard Worker case ARCInstKind::IntrinsicUser:
459*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CallOrUser:
460*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Call:
461*9880d681SAndroid Build Coastguard Worker case ARCInstKind::User:
462*9880d681SAndroid Build Coastguard Worker case ARCInstKind::None:
463*9880d681SAndroid Build Coastguard Worker return false;
464*9880d681SAndroid Build Coastguard Worker }
465*9880d681SAndroid Build Coastguard Worker llvm_unreachable("covered switch isn't covered?");
466*9880d681SAndroid Build Coastguard Worker }
467*9880d681SAndroid Build Coastguard Worker
468*9880d681SAndroid Build Coastguard Worker /// \brief Test if the given class represents instructions which do nothing if
469*9880d681SAndroid Build Coastguard Worker /// passed a null pointer.
IsNoopOnNull(ARCInstKind Class)470*9880d681SAndroid Build Coastguard Worker bool llvm::objcarc::IsNoopOnNull(ARCInstKind Class) {
471*9880d681SAndroid Build Coastguard Worker switch (Class) {
472*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Retain:
473*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainRV:
474*9880d681SAndroid Build Coastguard Worker case ARCInstKind::ClaimRV:
475*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Release:
476*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Autorelease:
477*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleaseRV:
478*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainBlock:
479*9880d681SAndroid Build Coastguard Worker return true;
480*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPush:
481*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPop:
482*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutorelease:
483*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutoreleaseRV:
484*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeakRetained:
485*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreWeak:
486*9880d681SAndroid Build Coastguard Worker case ARCInstKind::InitWeak:
487*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeak:
488*9880d681SAndroid Build Coastguard Worker case ARCInstKind::MoveWeak:
489*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CopyWeak:
490*9880d681SAndroid Build Coastguard Worker case ARCInstKind::DestroyWeak:
491*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreStrong:
492*9880d681SAndroid Build Coastguard Worker case ARCInstKind::IntrinsicUser:
493*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CallOrUser:
494*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Call:
495*9880d681SAndroid Build Coastguard Worker case ARCInstKind::User:
496*9880d681SAndroid Build Coastguard Worker case ARCInstKind::None:
497*9880d681SAndroid Build Coastguard Worker case ARCInstKind::NoopCast:
498*9880d681SAndroid Build Coastguard Worker return false;
499*9880d681SAndroid Build Coastguard Worker }
500*9880d681SAndroid Build Coastguard Worker llvm_unreachable("covered switch isn't covered?");
501*9880d681SAndroid Build Coastguard Worker }
502*9880d681SAndroid Build Coastguard Worker
503*9880d681SAndroid Build Coastguard Worker /// \brief Test if the given class represents instructions which are always safe
504*9880d681SAndroid Build Coastguard Worker /// to mark with the "tail" keyword.
IsAlwaysTail(ARCInstKind Class)505*9880d681SAndroid Build Coastguard Worker bool llvm::objcarc::IsAlwaysTail(ARCInstKind Class) {
506*9880d681SAndroid Build Coastguard Worker // ARCInstKind::RetainBlock may be given a stack argument.
507*9880d681SAndroid Build Coastguard Worker switch (Class) {
508*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Retain:
509*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainRV:
510*9880d681SAndroid Build Coastguard Worker case ARCInstKind::ClaimRV:
511*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleaseRV:
512*9880d681SAndroid Build Coastguard Worker return true;
513*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Release:
514*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Autorelease:
515*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainBlock:
516*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPush:
517*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPop:
518*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutorelease:
519*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutoreleaseRV:
520*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeakRetained:
521*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreWeak:
522*9880d681SAndroid Build Coastguard Worker case ARCInstKind::InitWeak:
523*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeak:
524*9880d681SAndroid Build Coastguard Worker case ARCInstKind::MoveWeak:
525*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CopyWeak:
526*9880d681SAndroid Build Coastguard Worker case ARCInstKind::DestroyWeak:
527*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreStrong:
528*9880d681SAndroid Build Coastguard Worker case ARCInstKind::IntrinsicUser:
529*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CallOrUser:
530*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Call:
531*9880d681SAndroid Build Coastguard Worker case ARCInstKind::User:
532*9880d681SAndroid Build Coastguard Worker case ARCInstKind::None:
533*9880d681SAndroid Build Coastguard Worker case ARCInstKind::NoopCast:
534*9880d681SAndroid Build Coastguard Worker return false;
535*9880d681SAndroid Build Coastguard Worker }
536*9880d681SAndroid Build Coastguard Worker llvm_unreachable("covered switch isn't covered?");
537*9880d681SAndroid Build Coastguard Worker }
538*9880d681SAndroid Build Coastguard Worker
539*9880d681SAndroid Build Coastguard Worker /// \brief Test if the given class represents instructions which are never safe
540*9880d681SAndroid Build Coastguard Worker /// to mark with the "tail" keyword.
IsNeverTail(ARCInstKind Class)541*9880d681SAndroid Build Coastguard Worker bool llvm::objcarc::IsNeverTail(ARCInstKind Class) {
542*9880d681SAndroid Build Coastguard Worker /// It is never safe to tail call objc_autorelease since by tail calling
543*9880d681SAndroid Build Coastguard Worker /// objc_autorelease: fast autoreleasing causing our object to be potentially
544*9880d681SAndroid Build Coastguard Worker /// reclaimed from the autorelease pool which violates the semantics of
545*9880d681SAndroid Build Coastguard Worker /// __autoreleasing types in ARC.
546*9880d681SAndroid Build Coastguard Worker switch (Class) {
547*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Autorelease:
548*9880d681SAndroid Build Coastguard Worker return true;
549*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Retain:
550*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainRV:
551*9880d681SAndroid Build Coastguard Worker case ARCInstKind::ClaimRV:
552*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleaseRV:
553*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Release:
554*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainBlock:
555*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPush:
556*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPop:
557*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutorelease:
558*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutoreleaseRV:
559*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeakRetained:
560*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreWeak:
561*9880d681SAndroid Build Coastguard Worker case ARCInstKind::InitWeak:
562*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeak:
563*9880d681SAndroid Build Coastguard Worker case ARCInstKind::MoveWeak:
564*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CopyWeak:
565*9880d681SAndroid Build Coastguard Worker case ARCInstKind::DestroyWeak:
566*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreStrong:
567*9880d681SAndroid Build Coastguard Worker case ARCInstKind::IntrinsicUser:
568*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CallOrUser:
569*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Call:
570*9880d681SAndroid Build Coastguard Worker case ARCInstKind::User:
571*9880d681SAndroid Build Coastguard Worker case ARCInstKind::None:
572*9880d681SAndroid Build Coastguard Worker case ARCInstKind::NoopCast:
573*9880d681SAndroid Build Coastguard Worker return false;
574*9880d681SAndroid Build Coastguard Worker }
575*9880d681SAndroid Build Coastguard Worker llvm_unreachable("covered switch isn't covered?");
576*9880d681SAndroid Build Coastguard Worker }
577*9880d681SAndroid Build Coastguard Worker
578*9880d681SAndroid Build Coastguard Worker /// \brief Test if the given class represents instructions which are always safe
579*9880d681SAndroid Build Coastguard Worker /// to mark with the nounwind attribute.
IsNoThrow(ARCInstKind Class)580*9880d681SAndroid Build Coastguard Worker bool llvm::objcarc::IsNoThrow(ARCInstKind Class) {
581*9880d681SAndroid Build Coastguard Worker // objc_retainBlock is not nounwind because it calls user copy constructors
582*9880d681SAndroid Build Coastguard Worker // which could theoretically throw.
583*9880d681SAndroid Build Coastguard Worker switch (Class) {
584*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Retain:
585*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainRV:
586*9880d681SAndroid Build Coastguard Worker case ARCInstKind::ClaimRV:
587*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Release:
588*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Autorelease:
589*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleaseRV:
590*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPush:
591*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPop:
592*9880d681SAndroid Build Coastguard Worker return true;
593*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainBlock:
594*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutorelease:
595*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutoreleaseRV:
596*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeakRetained:
597*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreWeak:
598*9880d681SAndroid Build Coastguard Worker case ARCInstKind::InitWeak:
599*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeak:
600*9880d681SAndroid Build Coastguard Worker case ARCInstKind::MoveWeak:
601*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CopyWeak:
602*9880d681SAndroid Build Coastguard Worker case ARCInstKind::DestroyWeak:
603*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreStrong:
604*9880d681SAndroid Build Coastguard Worker case ARCInstKind::IntrinsicUser:
605*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CallOrUser:
606*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Call:
607*9880d681SAndroid Build Coastguard Worker case ARCInstKind::User:
608*9880d681SAndroid Build Coastguard Worker case ARCInstKind::None:
609*9880d681SAndroid Build Coastguard Worker case ARCInstKind::NoopCast:
610*9880d681SAndroid Build Coastguard Worker return false;
611*9880d681SAndroid Build Coastguard Worker }
612*9880d681SAndroid Build Coastguard Worker llvm_unreachable("covered switch isn't covered?");
613*9880d681SAndroid Build Coastguard Worker }
614*9880d681SAndroid Build Coastguard Worker
615*9880d681SAndroid Build Coastguard Worker /// Test whether the given instruction can autorelease any pointer or cause an
616*9880d681SAndroid Build Coastguard Worker /// autoreleasepool pop.
617*9880d681SAndroid Build Coastguard Worker ///
618*9880d681SAndroid Build Coastguard Worker /// This means that it *could* interrupt the RV optimization.
CanInterruptRV(ARCInstKind Class)619*9880d681SAndroid Build Coastguard Worker bool llvm::objcarc::CanInterruptRV(ARCInstKind Class) {
620*9880d681SAndroid Build Coastguard Worker switch (Class) {
621*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPop:
622*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CallOrUser:
623*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Call:
624*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Autorelease:
625*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleaseRV:
626*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutorelease:
627*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutoreleaseRV:
628*9880d681SAndroid Build Coastguard Worker return true;
629*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Retain:
630*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainRV:
631*9880d681SAndroid Build Coastguard Worker case ARCInstKind::ClaimRV:
632*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Release:
633*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPush:
634*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainBlock:
635*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeakRetained:
636*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreWeak:
637*9880d681SAndroid Build Coastguard Worker case ARCInstKind::InitWeak:
638*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeak:
639*9880d681SAndroid Build Coastguard Worker case ARCInstKind::MoveWeak:
640*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CopyWeak:
641*9880d681SAndroid Build Coastguard Worker case ARCInstKind::DestroyWeak:
642*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreStrong:
643*9880d681SAndroid Build Coastguard Worker case ARCInstKind::IntrinsicUser:
644*9880d681SAndroid Build Coastguard Worker case ARCInstKind::User:
645*9880d681SAndroid Build Coastguard Worker case ARCInstKind::None:
646*9880d681SAndroid Build Coastguard Worker case ARCInstKind::NoopCast:
647*9880d681SAndroid Build Coastguard Worker return false;
648*9880d681SAndroid Build Coastguard Worker }
649*9880d681SAndroid Build Coastguard Worker llvm_unreachable("covered switch isn't covered?");
650*9880d681SAndroid Build Coastguard Worker }
651*9880d681SAndroid Build Coastguard Worker
CanDecrementRefCount(ARCInstKind Kind)652*9880d681SAndroid Build Coastguard Worker bool llvm::objcarc::CanDecrementRefCount(ARCInstKind Kind) {
653*9880d681SAndroid Build Coastguard Worker switch (Kind) {
654*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Retain:
655*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainRV:
656*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Autorelease:
657*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleaseRV:
658*9880d681SAndroid Build Coastguard Worker case ARCInstKind::NoopCast:
659*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutorelease:
660*9880d681SAndroid Build Coastguard Worker case ARCInstKind::FusedRetainAutoreleaseRV:
661*9880d681SAndroid Build Coastguard Worker case ARCInstKind::IntrinsicUser:
662*9880d681SAndroid Build Coastguard Worker case ARCInstKind::User:
663*9880d681SAndroid Build Coastguard Worker case ARCInstKind::None:
664*9880d681SAndroid Build Coastguard Worker return false;
665*9880d681SAndroid Build Coastguard Worker
666*9880d681SAndroid Build Coastguard Worker // The cases below are conservative.
667*9880d681SAndroid Build Coastguard Worker
668*9880d681SAndroid Build Coastguard Worker // RetainBlock can result in user defined copy constructors being called
669*9880d681SAndroid Build Coastguard Worker // implying releases may occur.
670*9880d681SAndroid Build Coastguard Worker case ARCInstKind::RetainBlock:
671*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Release:
672*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPush:
673*9880d681SAndroid Build Coastguard Worker case ARCInstKind::AutoreleasepoolPop:
674*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeakRetained:
675*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreWeak:
676*9880d681SAndroid Build Coastguard Worker case ARCInstKind::InitWeak:
677*9880d681SAndroid Build Coastguard Worker case ARCInstKind::LoadWeak:
678*9880d681SAndroid Build Coastguard Worker case ARCInstKind::MoveWeak:
679*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CopyWeak:
680*9880d681SAndroid Build Coastguard Worker case ARCInstKind::DestroyWeak:
681*9880d681SAndroid Build Coastguard Worker case ARCInstKind::StoreStrong:
682*9880d681SAndroid Build Coastguard Worker case ARCInstKind::CallOrUser:
683*9880d681SAndroid Build Coastguard Worker case ARCInstKind::Call:
684*9880d681SAndroid Build Coastguard Worker case ARCInstKind::ClaimRV:
685*9880d681SAndroid Build Coastguard Worker return true;
686*9880d681SAndroid Build Coastguard Worker }
687*9880d681SAndroid Build Coastguard Worker
688*9880d681SAndroid Build Coastguard Worker llvm_unreachable("covered switch isn't covered?");
689*9880d681SAndroid Build Coastguard Worker }
690