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 
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::ClaimRV:
36     return OS << "ARCInstKind::ClaimRV";
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 
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::ClaimRV;
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_arc_annotation_topdown_bbstart:
144   case Intrinsic::objc_arc_annotation_topdown_bbend:
145   case Intrinsic::objc_arc_annotation_bottomup_bbstart:
146   case Intrinsic::objc_arc_annotation_bottomup_bbend:
147     // Ignore annotation calls. This is important to stop the
148     // optimizer from treating annotations as uses which would
149     // make the state of the pointers they are attempting to
150     // elucidate to be incorrect.
151     return ARCInstKind::None;
152   }
153 }
154 
155 // A list of intrinsics that we know do not use objc pointers or decrement
156 // ref counts.
157 static bool isInertIntrinsic(unsigned ID) {
158   // TODO: Make this into a covered switch.
159   switch (ID) {
160   case Intrinsic::returnaddress:
161   case Intrinsic::addressofreturnaddress:
162   case Intrinsic::frameaddress:
163   case Intrinsic::stacksave:
164   case Intrinsic::stackrestore:
165   case Intrinsic::vastart:
166   case Intrinsic::vacopy:
167   case Intrinsic::vaend:
168   case Intrinsic::objectsize:
169   case Intrinsic::prefetch:
170   case Intrinsic::stackprotector:
171   case Intrinsic::eh_return_i32:
172   case Intrinsic::eh_return_i64:
173   case Intrinsic::eh_typeid_for:
174   case Intrinsic::eh_dwarf_cfa:
175   case Intrinsic::eh_sjlj_lsda:
176   case Intrinsic::eh_sjlj_functioncontext:
177   case Intrinsic::init_trampoline:
178   case Intrinsic::adjust_trampoline:
179   case Intrinsic::lifetime_start:
180   case Intrinsic::lifetime_end:
181   case Intrinsic::invariant_start:
182   case Intrinsic::invariant_end:
183   // Don't let dbg info affect our results.
184   case Intrinsic::dbg_declare:
185   case Intrinsic::dbg_value:
186   case Intrinsic::dbg_label:
187     // Short cut: Some intrinsics obviously don't use ObjC pointers.
188     return true;
189   default:
190     return false;
191   }
192 }
193 
194 // A list of intrinsics that we know do not use objc pointers or decrement
195 // ref counts.
196 static bool isUseOnlyIntrinsic(unsigned ID) {
197   // We are conservative and even though intrinsics are unlikely to touch
198   // reference counts, we white list them for safety.
199   //
200   // TODO: Expand this into a covered switch. There is a lot more here.
201   switch (ID) {
202   case Intrinsic::memcpy:
203   case Intrinsic::memmove:
204   case Intrinsic::memset:
205     return true;
206   default:
207     return false;
208   }
209 }
210 
211 /// Determine what kind of construct V is.
212 ARCInstKind llvm::objcarc::GetARCInstKind(const Value *V) {
213   if (const Instruction *I = dyn_cast<Instruction>(V)) {
214     // Any instruction other than bitcast and gep with a pointer operand have a
215     // use of an objc pointer. Bitcasts, GEPs, Selects, PHIs transfer a pointer
216     // to a subsequent use, rather than using it themselves, in this sense.
217     // As a short cut, several other opcodes are known to have no pointer
218     // operands of interest. And ret is never followed by a release, so it's
219     // not interesting to examine.
220     switch (I->getOpcode()) {
221     case Instruction::Call: {
222       const CallInst *CI = cast<CallInst>(I);
223       // See if we have a function that we know something about.
224       if (const Function *F = CI->getCalledFunction()) {
225         ARCInstKind Class = GetFunctionClass(F);
226         if (Class != ARCInstKind::CallOrUser)
227           return Class;
228         Intrinsic::ID ID = F->getIntrinsicID();
229         if (isInertIntrinsic(ID))
230           return ARCInstKind::None;
231         if (isUseOnlyIntrinsic(ID))
232           return ARCInstKind::User;
233       }
234 
235       // Otherwise, be conservative.
236       return GetCallSiteClass(*CI);
237     }
238     case Instruction::Invoke:
239       // Otherwise, be conservative.
240       return GetCallSiteClass(cast<InvokeInst>(*I));
241     case Instruction::BitCast:
242     case Instruction::GetElementPtr:
243     case Instruction::Select:
244     case Instruction::PHI:
245     case Instruction::Ret:
246     case Instruction::Br:
247     case Instruction::Switch:
248     case Instruction::IndirectBr:
249     case Instruction::Alloca:
250     case Instruction::VAArg:
251     case Instruction::Add:
252     case Instruction::FAdd:
253     case Instruction::Sub:
254     case Instruction::FSub:
255     case Instruction::Mul:
256     case Instruction::FMul:
257     case Instruction::SDiv:
258     case Instruction::UDiv:
259     case Instruction::FDiv:
260     case Instruction::SRem:
261     case Instruction::URem:
262     case Instruction::FRem:
263     case Instruction::Shl:
264     case Instruction::LShr:
265     case Instruction::AShr:
266     case Instruction::And:
267     case Instruction::Or:
268     case Instruction::Xor:
269     case Instruction::SExt:
270     case Instruction::ZExt:
271     case Instruction::Trunc:
272     case Instruction::IntToPtr:
273     case Instruction::FCmp:
274     case Instruction::FPTrunc:
275     case Instruction::FPExt:
276     case Instruction::FPToUI:
277     case Instruction::FPToSI:
278     case Instruction::UIToFP:
279     case Instruction::SIToFP:
280     case Instruction::InsertElement:
281     case Instruction::ExtractElement:
282     case Instruction::ShuffleVector:
283     case Instruction::ExtractValue:
284       break;
285     case Instruction::ICmp:
286       // Comparing a pointer with null, or any other constant, isn't an
287       // interesting use, because we don't care what the pointer points to, or
288       // about the values of any other dynamic reference-counted pointers.
289       if (IsPotentialRetainableObjPtr(I->getOperand(1)))
290         return ARCInstKind::User;
291       break;
292     default:
293       // For anything else, check all the operands.
294       // Note that this includes both operands of a Store: while the first
295       // operand isn't actually being dereferenced, it is being stored to
296       // memory where we can no longer track who might read it and dereference
297       // it, so we have to consider it potentially used.
298       for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end();
299            OI != OE; ++OI)
300         if (IsPotentialRetainableObjPtr(*OI))
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.
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::ClaimRV:
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.
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::ClaimRV:
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.
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::ClaimRV:
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.
415 bool llvm::objcarc::IsForwarding(ARCInstKind Class) {
416   switch (Class) {
417   case ARCInstKind::Retain:
418   case ARCInstKind::RetainRV:
419   case ARCInstKind::ClaimRV:
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.
450 bool llvm::objcarc::IsNoopOnNull(ARCInstKind Class) {
451   switch (Class) {
452   case ARCInstKind::Retain:
453   case ARCInstKind::RetainRV:
454   case ARCInstKind::ClaimRV:
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.
485 bool llvm::objcarc::IsNoopOnGlobal(ARCInstKind Class) {
486   switch (Class) {
487   case ARCInstKind::Retain:
488   case ARCInstKind::RetainRV:
489   case ARCInstKind::ClaimRV:
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.
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::ClaimRV:
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.
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::ClaimRV:
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.
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::ClaimRV:
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.
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::ClaimRV:
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 
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::ClaimRV:
700     return true;
701   }
702 
703   llvm_unreachable("covered switch isn't covered?");
704 }
705