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