xref: /freebsd/contrib/llvm-project/llvm/lib/Analysis/ObjCARCInstKind.cpp (revision 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623)
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/Analysis/ObjCARCAnalysisUtils.h"
23 #include "llvm/IR/Intrinsics.h"
24 
25 using namespace llvm;
26 using namespace llvm::objcarc;
27 
operator <<(raw_ostream & OS,const ARCInstKind Class)28 raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS,
29                                        const ARCInstKind Class) {
30   switch (Class) {
31   case ARCInstKind::Retain:
32     return OS << "ARCInstKind::Retain";
33   case ARCInstKind::RetainRV:
34     return OS << "ARCInstKind::RetainRV";
35   case ARCInstKind::UnsafeClaimRV:
36     return OS << "ARCInstKind::UnsafeClaimRV";
37   case ARCInstKind::RetainBlock:
38     return OS << "ARCInstKind::RetainBlock";
39   case ARCInstKind::Release:
40     return OS << "ARCInstKind::Release";
41   case ARCInstKind::Autorelease:
42     return OS << "ARCInstKind::Autorelease";
43   case ARCInstKind::AutoreleaseRV:
44     return OS << "ARCInstKind::AutoreleaseRV";
45   case ARCInstKind::AutoreleasepoolPush:
46     return OS << "ARCInstKind::AutoreleasepoolPush";
47   case ARCInstKind::AutoreleasepoolPop:
48     return OS << "ARCInstKind::AutoreleasepoolPop";
49   case ARCInstKind::NoopCast:
50     return OS << "ARCInstKind::NoopCast";
51   case ARCInstKind::FusedRetainAutorelease:
52     return OS << "ARCInstKind::FusedRetainAutorelease";
53   case ARCInstKind::FusedRetainAutoreleaseRV:
54     return OS << "ARCInstKind::FusedRetainAutoreleaseRV";
55   case ARCInstKind::LoadWeakRetained:
56     return OS << "ARCInstKind::LoadWeakRetained";
57   case ARCInstKind::StoreWeak:
58     return OS << "ARCInstKind::StoreWeak";
59   case ARCInstKind::InitWeak:
60     return OS << "ARCInstKind::InitWeak";
61   case ARCInstKind::LoadWeak:
62     return OS << "ARCInstKind::LoadWeak";
63   case ARCInstKind::MoveWeak:
64     return OS << "ARCInstKind::MoveWeak";
65   case ARCInstKind::CopyWeak:
66     return OS << "ARCInstKind::CopyWeak";
67   case ARCInstKind::DestroyWeak:
68     return OS << "ARCInstKind::DestroyWeak";
69   case ARCInstKind::StoreStrong:
70     return OS << "ARCInstKind::StoreStrong";
71   case ARCInstKind::CallOrUser:
72     return OS << "ARCInstKind::CallOrUser";
73   case ARCInstKind::Call:
74     return OS << "ARCInstKind::Call";
75   case ARCInstKind::User:
76     return OS << "ARCInstKind::User";
77   case ARCInstKind::IntrinsicUser:
78     return OS << "ARCInstKind::IntrinsicUser";
79   case ARCInstKind::None:
80     return OS << "ARCInstKind::None";
81   }
82   llvm_unreachable("Unknown instruction class!");
83 }
84 
GetFunctionClass(const Function * F)85 ARCInstKind llvm::objcarc::GetFunctionClass(const Function *F) {
86 
87   Intrinsic::ID ID = F->getIntrinsicID();
88   switch (ID) {
89   default:
90     return ARCInstKind::CallOrUser;
91   case Intrinsic::objc_autorelease:
92     return ARCInstKind::Autorelease;
93   case Intrinsic::objc_autoreleasePoolPop:
94     return ARCInstKind::AutoreleasepoolPop;
95   case Intrinsic::objc_autoreleasePoolPush:
96     return ARCInstKind::AutoreleasepoolPush;
97   case Intrinsic::objc_autoreleaseReturnValue:
98     return ARCInstKind::AutoreleaseRV;
99   case Intrinsic::objc_copyWeak:
100     return ARCInstKind::CopyWeak;
101   case Intrinsic::objc_destroyWeak:
102     return ARCInstKind::DestroyWeak;
103   case Intrinsic::objc_initWeak:
104     return ARCInstKind::InitWeak;
105   case Intrinsic::objc_loadWeak:
106     return ARCInstKind::LoadWeak;
107   case Intrinsic::objc_loadWeakRetained:
108     return ARCInstKind::LoadWeakRetained;
109   case Intrinsic::objc_moveWeak:
110     return ARCInstKind::MoveWeak;
111   case Intrinsic::objc_release:
112     return ARCInstKind::Release;
113   case Intrinsic::objc_retain:
114     return ARCInstKind::Retain;
115   case Intrinsic::objc_retainAutorelease:
116     return ARCInstKind::FusedRetainAutorelease;
117   case Intrinsic::objc_retainAutoreleaseReturnValue:
118     return ARCInstKind::FusedRetainAutoreleaseRV;
119   case Intrinsic::objc_retainAutoreleasedReturnValue:
120     return ARCInstKind::RetainRV;
121   case Intrinsic::objc_retainBlock:
122     return ARCInstKind::RetainBlock;
123   case Intrinsic::objc_storeStrong:
124     return ARCInstKind::StoreStrong;
125   case Intrinsic::objc_storeWeak:
126     return ARCInstKind::StoreWeak;
127   case Intrinsic::objc_clang_arc_use:
128     return ARCInstKind::IntrinsicUser;
129   case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue:
130     return ARCInstKind::UnsafeClaimRV;
131   case Intrinsic::objc_retainedObject:
132     return ARCInstKind::NoopCast;
133   case Intrinsic::objc_unretainedObject:
134     return ARCInstKind::NoopCast;
135   case Intrinsic::objc_unretainedPointer:
136     return ARCInstKind::NoopCast;
137   case Intrinsic::objc_retain_autorelease:
138     return ARCInstKind::FusedRetainAutorelease;
139   case Intrinsic::objc_sync_enter:
140     return ARCInstKind::User;
141   case Intrinsic::objc_sync_exit:
142     return ARCInstKind::User;
143   case Intrinsic::objc_clang_arc_noop_use:
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 (const Use &U : I->operands())
300         if (IsPotentialRetainableObjPtr(U))
301           return ARCInstKind::User;
302     }
303   }
304 
305   // Otherwise, it's totally inert for ARC purposes.
306   return ARCInstKind::None;
307 }
308 
309 /// Test if the given class is a kind of user.
IsUser(ARCInstKind Class)310 bool llvm::objcarc::IsUser(ARCInstKind Class) {
311   switch (Class) {
312   case ARCInstKind::User:
313   case ARCInstKind::CallOrUser:
314   case ARCInstKind::IntrinsicUser:
315     return true;
316   case ARCInstKind::Retain:
317   case ARCInstKind::RetainRV:
318   case ARCInstKind::RetainBlock:
319   case ARCInstKind::Release:
320   case ARCInstKind::Autorelease:
321   case ARCInstKind::AutoreleaseRV:
322   case ARCInstKind::AutoreleasepoolPush:
323   case ARCInstKind::AutoreleasepoolPop:
324   case ARCInstKind::NoopCast:
325   case ARCInstKind::FusedRetainAutorelease:
326   case ARCInstKind::FusedRetainAutoreleaseRV:
327   case ARCInstKind::LoadWeakRetained:
328   case ARCInstKind::StoreWeak:
329   case ARCInstKind::InitWeak:
330   case ARCInstKind::LoadWeak:
331   case ARCInstKind::MoveWeak:
332   case ARCInstKind::CopyWeak:
333   case ARCInstKind::DestroyWeak:
334   case ARCInstKind::StoreStrong:
335   case ARCInstKind::Call:
336   case ARCInstKind::None:
337   case ARCInstKind::UnsafeClaimRV:
338     return false;
339   }
340   llvm_unreachable("covered switch isn't covered?");
341 }
342 
343 /// Test if the given class is objc_retain or equivalent.
IsRetain(ARCInstKind Class)344 bool llvm::objcarc::IsRetain(ARCInstKind Class) {
345   switch (Class) {
346   case ARCInstKind::Retain:
347   case ARCInstKind::RetainRV:
348     return true;
349   // I believe we treat retain block as not a retain since it can copy its
350   // block.
351   case ARCInstKind::RetainBlock:
352   case ARCInstKind::Release:
353   case ARCInstKind::Autorelease:
354   case ARCInstKind::AutoreleaseRV:
355   case ARCInstKind::AutoreleasepoolPush:
356   case ARCInstKind::AutoreleasepoolPop:
357   case ARCInstKind::NoopCast:
358   case ARCInstKind::FusedRetainAutorelease:
359   case ARCInstKind::FusedRetainAutoreleaseRV:
360   case ARCInstKind::LoadWeakRetained:
361   case ARCInstKind::StoreWeak:
362   case ARCInstKind::InitWeak:
363   case ARCInstKind::LoadWeak:
364   case ARCInstKind::MoveWeak:
365   case ARCInstKind::CopyWeak:
366   case ARCInstKind::DestroyWeak:
367   case ARCInstKind::StoreStrong:
368   case ARCInstKind::IntrinsicUser:
369   case ARCInstKind::CallOrUser:
370   case ARCInstKind::Call:
371   case ARCInstKind::User:
372   case ARCInstKind::None:
373   case ARCInstKind::UnsafeClaimRV:
374     return false;
375   }
376   llvm_unreachable("covered switch isn't covered?");
377 }
378 
379 /// Test if the given class is objc_autorelease or equivalent.
IsAutorelease(ARCInstKind Class)380 bool llvm::objcarc::IsAutorelease(ARCInstKind Class) {
381   switch (Class) {
382   case ARCInstKind::Autorelease:
383   case ARCInstKind::AutoreleaseRV:
384     return true;
385   case ARCInstKind::Retain:
386   case ARCInstKind::RetainRV:
387   case ARCInstKind::UnsafeClaimRV:
388   case ARCInstKind::RetainBlock:
389   case ARCInstKind::Release:
390   case ARCInstKind::AutoreleasepoolPush:
391   case ARCInstKind::AutoreleasepoolPop:
392   case ARCInstKind::NoopCast:
393   case ARCInstKind::FusedRetainAutorelease:
394   case ARCInstKind::FusedRetainAutoreleaseRV:
395   case ARCInstKind::LoadWeakRetained:
396   case ARCInstKind::StoreWeak:
397   case ARCInstKind::InitWeak:
398   case ARCInstKind::LoadWeak:
399   case ARCInstKind::MoveWeak:
400   case ARCInstKind::CopyWeak:
401   case ARCInstKind::DestroyWeak:
402   case ARCInstKind::StoreStrong:
403   case ARCInstKind::IntrinsicUser:
404   case ARCInstKind::CallOrUser:
405   case ARCInstKind::Call:
406   case ARCInstKind::User:
407   case ARCInstKind::None:
408     return false;
409   }
410   llvm_unreachable("covered switch isn't covered?");
411 }
412 
413 /// Test if the given class represents instructions which return their
414 /// argument verbatim.
IsForwarding(ARCInstKind Class)415 bool llvm::objcarc::IsForwarding(ARCInstKind Class) {
416   switch (Class) {
417   case ARCInstKind::Retain:
418   case ARCInstKind::RetainRV:
419   case ARCInstKind::UnsafeClaimRV:
420   case ARCInstKind::Autorelease:
421   case ARCInstKind::AutoreleaseRV:
422   case ARCInstKind::NoopCast:
423     return true;
424   case ARCInstKind::RetainBlock:
425   case ARCInstKind::Release:
426   case ARCInstKind::AutoreleasepoolPush:
427   case ARCInstKind::AutoreleasepoolPop:
428   case ARCInstKind::FusedRetainAutorelease:
429   case ARCInstKind::FusedRetainAutoreleaseRV:
430   case ARCInstKind::LoadWeakRetained:
431   case ARCInstKind::StoreWeak:
432   case ARCInstKind::InitWeak:
433   case ARCInstKind::LoadWeak:
434   case ARCInstKind::MoveWeak:
435   case ARCInstKind::CopyWeak:
436   case ARCInstKind::DestroyWeak:
437   case ARCInstKind::StoreStrong:
438   case ARCInstKind::IntrinsicUser:
439   case ARCInstKind::CallOrUser:
440   case ARCInstKind::Call:
441   case ARCInstKind::User:
442   case ARCInstKind::None:
443     return false;
444   }
445   llvm_unreachable("covered switch isn't covered?");
446 }
447 
448 /// Test if the given class represents instructions which do nothing if
449 /// passed a null pointer.
IsNoopOnNull(ARCInstKind Class)450 bool llvm::objcarc::IsNoopOnNull(ARCInstKind Class) {
451   switch (Class) {
452   case ARCInstKind::Retain:
453   case ARCInstKind::RetainRV:
454   case ARCInstKind::UnsafeClaimRV:
455   case ARCInstKind::Release:
456   case ARCInstKind::Autorelease:
457   case ARCInstKind::AutoreleaseRV:
458   case ARCInstKind::RetainBlock:
459     return true;
460   case ARCInstKind::AutoreleasepoolPush:
461   case ARCInstKind::AutoreleasepoolPop:
462   case ARCInstKind::FusedRetainAutorelease:
463   case ARCInstKind::FusedRetainAutoreleaseRV:
464   case ARCInstKind::LoadWeakRetained:
465   case ARCInstKind::StoreWeak:
466   case ARCInstKind::InitWeak:
467   case ARCInstKind::LoadWeak:
468   case ARCInstKind::MoveWeak:
469   case ARCInstKind::CopyWeak:
470   case ARCInstKind::DestroyWeak:
471   case ARCInstKind::StoreStrong:
472   case ARCInstKind::IntrinsicUser:
473   case ARCInstKind::CallOrUser:
474   case ARCInstKind::Call:
475   case ARCInstKind::User:
476   case ARCInstKind::None:
477   case ARCInstKind::NoopCast:
478     return false;
479   }
480   llvm_unreachable("covered switch isn't covered?");
481 }
482 
483 /// Test if the given class represents instructions which do nothing if
484 /// passed a global variable.
IsNoopOnGlobal(ARCInstKind Class)485 bool llvm::objcarc::IsNoopOnGlobal(ARCInstKind Class) {
486   switch (Class) {
487   case ARCInstKind::Retain:
488   case ARCInstKind::RetainRV:
489   case ARCInstKind::UnsafeClaimRV:
490   case ARCInstKind::Release:
491   case ARCInstKind::Autorelease:
492   case ARCInstKind::AutoreleaseRV:
493   case ARCInstKind::RetainBlock:
494   case ARCInstKind::FusedRetainAutorelease:
495   case ARCInstKind::FusedRetainAutoreleaseRV:
496     return true;
497   case ARCInstKind::AutoreleasepoolPush:
498   case ARCInstKind::AutoreleasepoolPop:
499   case ARCInstKind::LoadWeakRetained:
500   case ARCInstKind::StoreWeak:
501   case ARCInstKind::InitWeak:
502   case ARCInstKind::LoadWeak:
503   case ARCInstKind::MoveWeak:
504   case ARCInstKind::CopyWeak:
505   case ARCInstKind::DestroyWeak:
506   case ARCInstKind::StoreStrong:
507   case ARCInstKind::IntrinsicUser:
508   case ARCInstKind::CallOrUser:
509   case ARCInstKind::Call:
510   case ARCInstKind::User:
511   case ARCInstKind::None:
512   case ARCInstKind::NoopCast:
513     return false;
514   }
515   llvm_unreachable("covered switch isn't covered?");
516 }
517 
518 /// Test if the given class represents instructions which are always safe
519 /// to mark with the "tail" keyword.
IsAlwaysTail(ARCInstKind Class)520 bool llvm::objcarc::IsAlwaysTail(ARCInstKind Class) {
521   // ARCInstKind::RetainBlock may be given a stack argument.
522   switch (Class) {
523   case ARCInstKind::Retain:
524   case ARCInstKind::RetainRV:
525   case ARCInstKind::UnsafeClaimRV:
526   case ARCInstKind::AutoreleaseRV:
527     return true;
528   case ARCInstKind::Release:
529   case ARCInstKind::Autorelease:
530   case ARCInstKind::RetainBlock:
531   case ARCInstKind::AutoreleasepoolPush:
532   case ARCInstKind::AutoreleasepoolPop:
533   case ARCInstKind::FusedRetainAutorelease:
534   case ARCInstKind::FusedRetainAutoreleaseRV:
535   case ARCInstKind::LoadWeakRetained:
536   case ARCInstKind::StoreWeak:
537   case ARCInstKind::InitWeak:
538   case ARCInstKind::LoadWeak:
539   case ARCInstKind::MoveWeak:
540   case ARCInstKind::CopyWeak:
541   case ARCInstKind::DestroyWeak:
542   case ARCInstKind::StoreStrong:
543   case ARCInstKind::IntrinsicUser:
544   case ARCInstKind::CallOrUser:
545   case ARCInstKind::Call:
546   case ARCInstKind::User:
547   case ARCInstKind::None:
548   case ARCInstKind::NoopCast:
549     return false;
550   }
551   llvm_unreachable("covered switch isn't covered?");
552 }
553 
554 /// Test if the given class represents instructions which are never safe
555 /// to mark with the "tail" keyword.
IsNeverTail(ARCInstKind Class)556 bool llvm::objcarc::IsNeverTail(ARCInstKind Class) {
557   /// It is never safe to tail call objc_autorelease since by tail calling
558   /// objc_autorelease: fast autoreleasing causing our object to be potentially
559   /// reclaimed from the autorelease pool which violates the semantics of
560   /// __autoreleasing types in ARC.
561   switch (Class) {
562   case ARCInstKind::Autorelease:
563     return true;
564   case ARCInstKind::Retain:
565   case ARCInstKind::RetainRV:
566   case ARCInstKind::UnsafeClaimRV:
567   case ARCInstKind::AutoreleaseRV:
568   case ARCInstKind::Release:
569   case ARCInstKind::RetainBlock:
570   case ARCInstKind::AutoreleasepoolPush:
571   case ARCInstKind::AutoreleasepoolPop:
572   case ARCInstKind::FusedRetainAutorelease:
573   case ARCInstKind::FusedRetainAutoreleaseRV:
574   case ARCInstKind::LoadWeakRetained:
575   case ARCInstKind::StoreWeak:
576   case ARCInstKind::InitWeak:
577   case ARCInstKind::LoadWeak:
578   case ARCInstKind::MoveWeak:
579   case ARCInstKind::CopyWeak:
580   case ARCInstKind::DestroyWeak:
581   case ARCInstKind::StoreStrong:
582   case ARCInstKind::IntrinsicUser:
583   case ARCInstKind::CallOrUser:
584   case ARCInstKind::Call:
585   case ARCInstKind::User:
586   case ARCInstKind::None:
587   case ARCInstKind::NoopCast:
588     return false;
589   }
590   llvm_unreachable("covered switch isn't covered?");
591 }
592 
593 /// Test if the given class represents instructions which are always safe
594 /// to mark with the nounwind attribute.
IsNoThrow(ARCInstKind Class)595 bool llvm::objcarc::IsNoThrow(ARCInstKind Class) {
596   // objc_retainBlock is not nounwind because it calls user copy constructors
597   // which could theoretically throw.
598   switch (Class) {
599   case ARCInstKind::Retain:
600   case ARCInstKind::RetainRV:
601   case ARCInstKind::UnsafeClaimRV:
602   case ARCInstKind::Release:
603   case ARCInstKind::Autorelease:
604   case ARCInstKind::AutoreleaseRV:
605   case ARCInstKind::AutoreleasepoolPush:
606   case ARCInstKind::AutoreleasepoolPop:
607     return true;
608   case ARCInstKind::RetainBlock:
609   case ARCInstKind::FusedRetainAutorelease:
610   case ARCInstKind::FusedRetainAutoreleaseRV:
611   case ARCInstKind::LoadWeakRetained:
612   case ARCInstKind::StoreWeak:
613   case ARCInstKind::InitWeak:
614   case ARCInstKind::LoadWeak:
615   case ARCInstKind::MoveWeak:
616   case ARCInstKind::CopyWeak:
617   case ARCInstKind::DestroyWeak:
618   case ARCInstKind::StoreStrong:
619   case ARCInstKind::IntrinsicUser:
620   case ARCInstKind::CallOrUser:
621   case ARCInstKind::Call:
622   case ARCInstKind::User:
623   case ARCInstKind::None:
624   case ARCInstKind::NoopCast:
625     return false;
626   }
627   llvm_unreachable("covered switch isn't covered?");
628 }
629 
630 /// Test whether the given instruction can autorelease any pointer or cause an
631 /// autoreleasepool pop.
632 ///
633 /// This means that it *could* interrupt the RV optimization.
CanInterruptRV(ARCInstKind Class)634 bool llvm::objcarc::CanInterruptRV(ARCInstKind Class) {
635   switch (Class) {
636   case ARCInstKind::AutoreleasepoolPop:
637   case ARCInstKind::CallOrUser:
638   case ARCInstKind::Call:
639   case ARCInstKind::Autorelease:
640   case ARCInstKind::AutoreleaseRV:
641   case ARCInstKind::FusedRetainAutorelease:
642   case ARCInstKind::FusedRetainAutoreleaseRV:
643     return true;
644   case ARCInstKind::Retain:
645   case ARCInstKind::RetainRV:
646   case ARCInstKind::UnsafeClaimRV:
647   case ARCInstKind::Release:
648   case ARCInstKind::AutoreleasepoolPush:
649   case ARCInstKind::RetainBlock:
650   case ARCInstKind::LoadWeakRetained:
651   case ARCInstKind::StoreWeak:
652   case ARCInstKind::InitWeak:
653   case ARCInstKind::LoadWeak:
654   case ARCInstKind::MoveWeak:
655   case ARCInstKind::CopyWeak:
656   case ARCInstKind::DestroyWeak:
657   case ARCInstKind::StoreStrong:
658   case ARCInstKind::IntrinsicUser:
659   case ARCInstKind::User:
660   case ARCInstKind::None:
661   case ARCInstKind::NoopCast:
662     return false;
663   }
664   llvm_unreachable("covered switch isn't covered?");
665 }
666 
CanDecrementRefCount(ARCInstKind Kind)667 bool llvm::objcarc::CanDecrementRefCount(ARCInstKind Kind) {
668   switch (Kind) {
669   case ARCInstKind::Retain:
670   case ARCInstKind::RetainRV:
671   case ARCInstKind::Autorelease:
672   case ARCInstKind::AutoreleaseRV:
673   case ARCInstKind::NoopCast:
674   case ARCInstKind::FusedRetainAutorelease:
675   case ARCInstKind::FusedRetainAutoreleaseRV:
676   case ARCInstKind::IntrinsicUser:
677   case ARCInstKind::User:
678   case ARCInstKind::None:
679     return false;
680 
681   // The cases below are conservative.
682 
683   // RetainBlock can result in user defined copy constructors being called
684   // implying releases may occur.
685   case ARCInstKind::RetainBlock:
686   case ARCInstKind::Release:
687   case ARCInstKind::AutoreleasepoolPush:
688   case ARCInstKind::AutoreleasepoolPop:
689   case ARCInstKind::LoadWeakRetained:
690   case ARCInstKind::StoreWeak:
691   case ARCInstKind::InitWeak:
692   case ARCInstKind::LoadWeak:
693   case ARCInstKind::MoveWeak:
694   case ARCInstKind::CopyWeak:
695   case ARCInstKind::DestroyWeak:
696   case ARCInstKind::StoreStrong:
697   case ARCInstKind::CallOrUser:
698   case ARCInstKind::Call:
699   case ARCInstKind::UnsafeClaimRV:
700     return true;
701   }
702 
703   llvm_unreachable("covered switch isn't covered?");
704 }
705