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