LLVM 19.0.0git
ObjCARCInstKind.cpp
Go to the documentation of this file.
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
23#include "llvm/IR/Intrinsics.h"
24
25using namespace llvm;
26using namespace llvm::objcarc;
27
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
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.
158static 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.
197static 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.
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()) {
227 if (Class != ARCInstKind::CallOrUser)
228 return Class;
229 Intrinsic::ID ID = F->getIntrinsicID();
230 if (isInertIntrinsic(ID))
231 return ARCInstKind::None;
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())
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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
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}
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file defines common analysis utilities used by the ObjC ARC Optimizer.
static bool isInertIntrinsic(unsigned ID)
static bool isUseOnlyIntrinsic(unsigned ID)
raw_pwrite_stream & OS
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1742
This class represents a function call, abstracting a target machine's calling convention.
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
LLVM Value Representation.
Definition: Value.h:74
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool IsPotentialRetainableObjPtr(const Value *Op)
Test whether the given value is possible a retainable object pointer.
bool IsUser(ARCInstKind Class)
Test if the given class is a kind of user.
raw_ostream & operator<<(raw_ostream &OS, const ARCInstKind Class)
bool IsRetain(ARCInstKind Class)
Test if the given class is objc_retain or equivalent.
bool IsNeverTail(ARCInstKind Class)
Test if the given class represents instructions which are never safe to mark with the "tail" keyword.
bool IsAlwaysTail(ARCInstKind Class)
Test if the given class represents instructions which are always safe to mark with the "tail" keyword...
ARCInstKind GetCallSiteClass(const CallBase &CB)
Helper for GetARCInstKind.
bool IsAutorelease(ARCInstKind Class)
Test if the given class is objc_autorelease or equivalent.
ARCInstKind
Equivalence classes of instructions in the ARC Model.
ARCInstKind GetFunctionClass(const Function *F)
Determine if F is one of the special known Functions.
bool IsForwarding(ARCInstKind Class)
Test if the given class represents instructions which return their argument verbatim.
ARCInstKind GetARCInstKind(const Value *V)
Map V to its ARCInstKind equivalence class.
bool CanInterruptRV(ARCInstKind Class)
Test whether the given instruction can autorelease any pointer or cause an autoreleasepool pop.
bool IsNoThrow(ARCInstKind Class)
Test if the given class represents instructions which are always safe to mark with the nounwind attri...
bool CanDecrementRefCount(ARCInstKind Kind)
Returns false if conservatively we can prove that any instruction mapped to this kind can not decreme...
bool IsNoopOnGlobal(ARCInstKind Class)
Test if the given class represents instructions which do nothing if passed a global variable.
bool IsNoopOnNull(ARCInstKind Class)
Test if the given class represents instructions which do nothing if passed a null pointer.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18