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