10b57cec5SDimitry Andric //===- ARCInstKind.cpp - ObjC ARC Optimization ----------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric /// \file
90b57cec5SDimitry Andric /// This file defines several utility functions used by various ARC
100b57cec5SDimitry Andric /// optimizations which are IMHO too big to be in a header file.
110b57cec5SDimitry Andric ///
120b57cec5SDimitry Andric /// WARNING: This file knows about certain library functions. It recognizes them
130b57cec5SDimitry Andric /// by name, and hardwires knowledge of their semantics.
140b57cec5SDimitry Andric ///
150b57cec5SDimitry Andric /// WARNING: This file knows about how certain Objective-C library functions are
160b57cec5SDimitry Andric /// used. Naive LLVM IR transformations which would otherwise be
170b57cec5SDimitry Andric /// behavior-preserving may break these assumptions.
180b57cec5SDimitry Andric ///
190b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
200b57cec5SDimitry Andric
210b57cec5SDimitry Andric #include "llvm/Analysis/ObjCARCInstKind.h"
220b57cec5SDimitry Andric #include "llvm/Analysis/ObjCARCAnalysisUtils.h"
230b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h"
240b57cec5SDimitry Andric
250b57cec5SDimitry Andric using namespace llvm;
260b57cec5SDimitry Andric using namespace llvm::objcarc;
270b57cec5SDimitry Andric
operator <<(raw_ostream & OS,const ARCInstKind Class)280b57cec5SDimitry Andric raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS,
290b57cec5SDimitry Andric const ARCInstKind Class) {
300b57cec5SDimitry Andric switch (Class) {
310b57cec5SDimitry Andric case ARCInstKind::Retain:
320b57cec5SDimitry Andric return OS << "ARCInstKind::Retain";
330b57cec5SDimitry Andric case ARCInstKind::RetainRV:
340b57cec5SDimitry Andric return OS << "ARCInstKind::RetainRV";
35*04eeddc0SDimitry Andric case ARCInstKind::UnsafeClaimRV:
36*04eeddc0SDimitry Andric return OS << "ARCInstKind::UnsafeClaimRV";
370b57cec5SDimitry Andric case ARCInstKind::RetainBlock:
380b57cec5SDimitry Andric return OS << "ARCInstKind::RetainBlock";
390b57cec5SDimitry Andric case ARCInstKind::Release:
400b57cec5SDimitry Andric return OS << "ARCInstKind::Release";
410b57cec5SDimitry Andric case ARCInstKind::Autorelease:
420b57cec5SDimitry Andric return OS << "ARCInstKind::Autorelease";
430b57cec5SDimitry Andric case ARCInstKind::AutoreleaseRV:
440b57cec5SDimitry Andric return OS << "ARCInstKind::AutoreleaseRV";
450b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPush:
460b57cec5SDimitry Andric return OS << "ARCInstKind::AutoreleasepoolPush";
470b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPop:
480b57cec5SDimitry Andric return OS << "ARCInstKind::AutoreleasepoolPop";
490b57cec5SDimitry Andric case ARCInstKind::NoopCast:
500b57cec5SDimitry Andric return OS << "ARCInstKind::NoopCast";
510b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutorelease:
520b57cec5SDimitry Andric return OS << "ARCInstKind::FusedRetainAutorelease";
530b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutoreleaseRV:
540b57cec5SDimitry Andric return OS << "ARCInstKind::FusedRetainAutoreleaseRV";
550b57cec5SDimitry Andric case ARCInstKind::LoadWeakRetained:
560b57cec5SDimitry Andric return OS << "ARCInstKind::LoadWeakRetained";
570b57cec5SDimitry Andric case ARCInstKind::StoreWeak:
580b57cec5SDimitry Andric return OS << "ARCInstKind::StoreWeak";
590b57cec5SDimitry Andric case ARCInstKind::InitWeak:
600b57cec5SDimitry Andric return OS << "ARCInstKind::InitWeak";
610b57cec5SDimitry Andric case ARCInstKind::LoadWeak:
620b57cec5SDimitry Andric return OS << "ARCInstKind::LoadWeak";
630b57cec5SDimitry Andric case ARCInstKind::MoveWeak:
640b57cec5SDimitry Andric return OS << "ARCInstKind::MoveWeak";
650b57cec5SDimitry Andric case ARCInstKind::CopyWeak:
660b57cec5SDimitry Andric return OS << "ARCInstKind::CopyWeak";
670b57cec5SDimitry Andric case ARCInstKind::DestroyWeak:
680b57cec5SDimitry Andric return OS << "ARCInstKind::DestroyWeak";
690b57cec5SDimitry Andric case ARCInstKind::StoreStrong:
700b57cec5SDimitry Andric return OS << "ARCInstKind::StoreStrong";
710b57cec5SDimitry Andric case ARCInstKind::CallOrUser:
720b57cec5SDimitry Andric return OS << "ARCInstKind::CallOrUser";
730b57cec5SDimitry Andric case ARCInstKind::Call:
740b57cec5SDimitry Andric return OS << "ARCInstKind::Call";
750b57cec5SDimitry Andric case ARCInstKind::User:
760b57cec5SDimitry Andric return OS << "ARCInstKind::User";
770b57cec5SDimitry Andric case ARCInstKind::IntrinsicUser:
780b57cec5SDimitry Andric return OS << "ARCInstKind::IntrinsicUser";
790b57cec5SDimitry Andric case ARCInstKind::None:
800b57cec5SDimitry Andric return OS << "ARCInstKind::None";
810b57cec5SDimitry Andric }
820b57cec5SDimitry Andric llvm_unreachable("Unknown instruction class!");
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric
GetFunctionClass(const Function * F)850b57cec5SDimitry Andric ARCInstKind llvm::objcarc::GetFunctionClass(const Function *F) {
860b57cec5SDimitry Andric
870b57cec5SDimitry Andric Intrinsic::ID ID = F->getIntrinsicID();
880b57cec5SDimitry Andric switch (ID) {
890b57cec5SDimitry Andric default:
900b57cec5SDimitry Andric return ARCInstKind::CallOrUser;
910b57cec5SDimitry Andric case Intrinsic::objc_autorelease:
920b57cec5SDimitry Andric return ARCInstKind::Autorelease;
930b57cec5SDimitry Andric case Intrinsic::objc_autoreleasePoolPop:
940b57cec5SDimitry Andric return ARCInstKind::AutoreleasepoolPop;
950b57cec5SDimitry Andric case Intrinsic::objc_autoreleasePoolPush:
960b57cec5SDimitry Andric return ARCInstKind::AutoreleasepoolPush;
970b57cec5SDimitry Andric case Intrinsic::objc_autoreleaseReturnValue:
980b57cec5SDimitry Andric return ARCInstKind::AutoreleaseRV;
990b57cec5SDimitry Andric case Intrinsic::objc_copyWeak:
1000b57cec5SDimitry Andric return ARCInstKind::CopyWeak;
1010b57cec5SDimitry Andric case Intrinsic::objc_destroyWeak:
1020b57cec5SDimitry Andric return ARCInstKind::DestroyWeak;
1030b57cec5SDimitry Andric case Intrinsic::objc_initWeak:
1040b57cec5SDimitry Andric return ARCInstKind::InitWeak;
1050b57cec5SDimitry Andric case Intrinsic::objc_loadWeak:
1060b57cec5SDimitry Andric return ARCInstKind::LoadWeak;
1070b57cec5SDimitry Andric case Intrinsic::objc_loadWeakRetained:
1080b57cec5SDimitry Andric return ARCInstKind::LoadWeakRetained;
1090b57cec5SDimitry Andric case Intrinsic::objc_moveWeak:
1100b57cec5SDimitry Andric return ARCInstKind::MoveWeak;
1110b57cec5SDimitry Andric case Intrinsic::objc_release:
1120b57cec5SDimitry Andric return ARCInstKind::Release;
1130b57cec5SDimitry Andric case Intrinsic::objc_retain:
1140b57cec5SDimitry Andric return ARCInstKind::Retain;
1150b57cec5SDimitry Andric case Intrinsic::objc_retainAutorelease:
1160b57cec5SDimitry Andric return ARCInstKind::FusedRetainAutorelease;
1170b57cec5SDimitry Andric case Intrinsic::objc_retainAutoreleaseReturnValue:
1180b57cec5SDimitry Andric return ARCInstKind::FusedRetainAutoreleaseRV;
1190b57cec5SDimitry Andric case Intrinsic::objc_retainAutoreleasedReturnValue:
1200b57cec5SDimitry Andric return ARCInstKind::RetainRV;
1210b57cec5SDimitry Andric case Intrinsic::objc_retainBlock:
1220b57cec5SDimitry Andric return ARCInstKind::RetainBlock;
1230b57cec5SDimitry Andric case Intrinsic::objc_storeStrong:
1240b57cec5SDimitry Andric return ARCInstKind::StoreStrong;
1250b57cec5SDimitry Andric case Intrinsic::objc_storeWeak:
1260b57cec5SDimitry Andric return ARCInstKind::StoreWeak;
1270b57cec5SDimitry Andric case Intrinsic::objc_clang_arc_use:
1280b57cec5SDimitry Andric return ARCInstKind::IntrinsicUser;
1290b57cec5SDimitry Andric case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue:
130*04eeddc0SDimitry Andric return ARCInstKind::UnsafeClaimRV;
1310b57cec5SDimitry Andric case Intrinsic::objc_retainedObject:
1320b57cec5SDimitry Andric return ARCInstKind::NoopCast;
1330b57cec5SDimitry Andric case Intrinsic::objc_unretainedObject:
1340b57cec5SDimitry Andric return ARCInstKind::NoopCast;
1350b57cec5SDimitry Andric case Intrinsic::objc_unretainedPointer:
1360b57cec5SDimitry Andric return ARCInstKind::NoopCast;
1370b57cec5SDimitry Andric case Intrinsic::objc_retain_autorelease:
1380b57cec5SDimitry Andric return ARCInstKind::FusedRetainAutorelease;
1390b57cec5SDimitry Andric case Intrinsic::objc_sync_enter:
1400b57cec5SDimitry Andric return ARCInstKind::User;
1410b57cec5SDimitry Andric case Intrinsic::objc_sync_exit:
1420b57cec5SDimitry Andric return ARCInstKind::User;
143fe6060f1SDimitry Andric case Intrinsic::objc_clang_arc_noop_use:
1440b57cec5SDimitry Andric case Intrinsic::objc_arc_annotation_topdown_bbstart:
1450b57cec5SDimitry Andric case Intrinsic::objc_arc_annotation_topdown_bbend:
1460b57cec5SDimitry Andric case Intrinsic::objc_arc_annotation_bottomup_bbstart:
1470b57cec5SDimitry Andric case Intrinsic::objc_arc_annotation_bottomup_bbend:
1480b57cec5SDimitry Andric // Ignore annotation calls. This is important to stop the
1490b57cec5SDimitry Andric // optimizer from treating annotations as uses which would
1500b57cec5SDimitry Andric // make the state of the pointers they are attempting to
1510b57cec5SDimitry Andric // elucidate to be incorrect.
1520b57cec5SDimitry Andric return ARCInstKind::None;
1530b57cec5SDimitry Andric }
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric
1565ffd83dbSDimitry Andric // A list of intrinsics that we know do not use objc pointers or decrement
1570b57cec5SDimitry Andric // ref counts.
isInertIntrinsic(unsigned ID)1580b57cec5SDimitry Andric static bool isInertIntrinsic(unsigned ID) {
1590b57cec5SDimitry Andric // TODO: Make this into a covered switch.
1600b57cec5SDimitry Andric switch (ID) {
1610b57cec5SDimitry Andric case Intrinsic::returnaddress:
1620b57cec5SDimitry Andric case Intrinsic::addressofreturnaddress:
1630b57cec5SDimitry Andric case Intrinsic::frameaddress:
1640b57cec5SDimitry Andric case Intrinsic::stacksave:
1650b57cec5SDimitry Andric case Intrinsic::stackrestore:
1660b57cec5SDimitry Andric case Intrinsic::vastart:
1670b57cec5SDimitry Andric case Intrinsic::vacopy:
1680b57cec5SDimitry Andric case Intrinsic::vaend:
1690b57cec5SDimitry Andric case Intrinsic::objectsize:
1700b57cec5SDimitry Andric case Intrinsic::prefetch:
1710b57cec5SDimitry Andric case Intrinsic::stackprotector:
1720b57cec5SDimitry Andric case Intrinsic::eh_return_i32:
1730b57cec5SDimitry Andric case Intrinsic::eh_return_i64:
1740b57cec5SDimitry Andric case Intrinsic::eh_typeid_for:
1750b57cec5SDimitry Andric case Intrinsic::eh_dwarf_cfa:
1760b57cec5SDimitry Andric case Intrinsic::eh_sjlj_lsda:
1770b57cec5SDimitry Andric case Intrinsic::eh_sjlj_functioncontext:
1780b57cec5SDimitry Andric case Intrinsic::init_trampoline:
1790b57cec5SDimitry Andric case Intrinsic::adjust_trampoline:
1800b57cec5SDimitry Andric case Intrinsic::lifetime_start:
1810b57cec5SDimitry Andric case Intrinsic::lifetime_end:
1820b57cec5SDimitry Andric case Intrinsic::invariant_start:
1830b57cec5SDimitry Andric case Intrinsic::invariant_end:
1840b57cec5SDimitry Andric // Don't let dbg info affect our results.
1850b57cec5SDimitry Andric case Intrinsic::dbg_declare:
1860b57cec5SDimitry Andric case Intrinsic::dbg_value:
1870b57cec5SDimitry Andric case Intrinsic::dbg_label:
1880b57cec5SDimitry Andric // Short cut: Some intrinsics obviously don't use ObjC pointers.
1890b57cec5SDimitry Andric return true;
1900b57cec5SDimitry Andric default:
1910b57cec5SDimitry Andric return false;
1920b57cec5SDimitry Andric }
1930b57cec5SDimitry Andric }
1940b57cec5SDimitry Andric
1955ffd83dbSDimitry Andric // A list of intrinsics that we know do not use objc pointers or decrement
1960b57cec5SDimitry Andric // ref counts.
isUseOnlyIntrinsic(unsigned ID)1970b57cec5SDimitry Andric static bool isUseOnlyIntrinsic(unsigned ID) {
1980b57cec5SDimitry Andric // We are conservative and even though intrinsics are unlikely to touch
1990b57cec5SDimitry Andric // reference counts, we white list them for safety.
2000b57cec5SDimitry Andric //
2010b57cec5SDimitry Andric // TODO: Expand this into a covered switch. There is a lot more here.
2020b57cec5SDimitry Andric switch (ID) {
2030b57cec5SDimitry Andric case Intrinsic::memcpy:
2040b57cec5SDimitry Andric case Intrinsic::memmove:
2050b57cec5SDimitry Andric case Intrinsic::memset:
2060b57cec5SDimitry Andric return true;
2070b57cec5SDimitry Andric default:
2080b57cec5SDimitry Andric return false;
2090b57cec5SDimitry Andric }
2100b57cec5SDimitry Andric }
2110b57cec5SDimitry Andric
2120b57cec5SDimitry Andric /// Determine what kind of construct V is.
GetARCInstKind(const Value * V)2130b57cec5SDimitry Andric ARCInstKind llvm::objcarc::GetARCInstKind(const Value *V) {
2140b57cec5SDimitry Andric if (const Instruction *I = dyn_cast<Instruction>(V)) {
2150b57cec5SDimitry Andric // Any instruction other than bitcast and gep with a pointer operand have a
2160b57cec5SDimitry Andric // use of an objc pointer. Bitcasts, GEPs, Selects, PHIs transfer a pointer
2170b57cec5SDimitry Andric // to a subsequent use, rather than using it themselves, in this sense.
2180b57cec5SDimitry Andric // As a short cut, several other opcodes are known to have no pointer
2190b57cec5SDimitry Andric // operands of interest. And ret is never followed by a release, so it's
2200b57cec5SDimitry Andric // not interesting to examine.
2210b57cec5SDimitry Andric switch (I->getOpcode()) {
2220b57cec5SDimitry Andric case Instruction::Call: {
2230b57cec5SDimitry Andric const CallInst *CI = cast<CallInst>(I);
2240b57cec5SDimitry Andric // See if we have a function that we know something about.
2250b57cec5SDimitry Andric if (const Function *F = CI->getCalledFunction()) {
2260b57cec5SDimitry Andric ARCInstKind Class = GetFunctionClass(F);
2270b57cec5SDimitry Andric if (Class != ARCInstKind::CallOrUser)
2280b57cec5SDimitry Andric return Class;
2290b57cec5SDimitry Andric Intrinsic::ID ID = F->getIntrinsicID();
2300b57cec5SDimitry Andric if (isInertIntrinsic(ID))
2310b57cec5SDimitry Andric return ARCInstKind::None;
2320b57cec5SDimitry Andric if (isUseOnlyIntrinsic(ID))
2330b57cec5SDimitry Andric return ARCInstKind::User;
2340b57cec5SDimitry Andric }
2350b57cec5SDimitry Andric
2360b57cec5SDimitry Andric // Otherwise, be conservative.
2375ffd83dbSDimitry Andric return GetCallSiteClass(*CI);
2380b57cec5SDimitry Andric }
2390b57cec5SDimitry Andric case Instruction::Invoke:
2400b57cec5SDimitry Andric // Otherwise, be conservative.
2415ffd83dbSDimitry Andric return GetCallSiteClass(cast<InvokeInst>(*I));
2420b57cec5SDimitry Andric case Instruction::BitCast:
2430b57cec5SDimitry Andric case Instruction::GetElementPtr:
2440b57cec5SDimitry Andric case Instruction::Select:
2450b57cec5SDimitry Andric case Instruction::PHI:
2460b57cec5SDimitry Andric case Instruction::Ret:
2470b57cec5SDimitry Andric case Instruction::Br:
2480b57cec5SDimitry Andric case Instruction::Switch:
2490b57cec5SDimitry Andric case Instruction::IndirectBr:
2500b57cec5SDimitry Andric case Instruction::Alloca:
2510b57cec5SDimitry Andric case Instruction::VAArg:
2520b57cec5SDimitry Andric case Instruction::Add:
2530b57cec5SDimitry Andric case Instruction::FAdd:
2540b57cec5SDimitry Andric case Instruction::Sub:
2550b57cec5SDimitry Andric case Instruction::FSub:
2560b57cec5SDimitry Andric case Instruction::Mul:
2570b57cec5SDimitry Andric case Instruction::FMul:
2580b57cec5SDimitry Andric case Instruction::SDiv:
2590b57cec5SDimitry Andric case Instruction::UDiv:
2600b57cec5SDimitry Andric case Instruction::FDiv:
2610b57cec5SDimitry Andric case Instruction::SRem:
2620b57cec5SDimitry Andric case Instruction::URem:
2630b57cec5SDimitry Andric case Instruction::FRem:
2640b57cec5SDimitry Andric case Instruction::Shl:
2650b57cec5SDimitry Andric case Instruction::LShr:
2660b57cec5SDimitry Andric case Instruction::AShr:
2670b57cec5SDimitry Andric case Instruction::And:
2680b57cec5SDimitry Andric case Instruction::Or:
2690b57cec5SDimitry Andric case Instruction::Xor:
2700b57cec5SDimitry Andric case Instruction::SExt:
2710b57cec5SDimitry Andric case Instruction::ZExt:
2720b57cec5SDimitry Andric case Instruction::Trunc:
2730b57cec5SDimitry Andric case Instruction::IntToPtr:
2740b57cec5SDimitry Andric case Instruction::FCmp:
2750b57cec5SDimitry Andric case Instruction::FPTrunc:
2760b57cec5SDimitry Andric case Instruction::FPExt:
2770b57cec5SDimitry Andric case Instruction::FPToUI:
2780b57cec5SDimitry Andric case Instruction::FPToSI:
2790b57cec5SDimitry Andric case Instruction::UIToFP:
2800b57cec5SDimitry Andric case Instruction::SIToFP:
2810b57cec5SDimitry Andric case Instruction::InsertElement:
2820b57cec5SDimitry Andric case Instruction::ExtractElement:
2830b57cec5SDimitry Andric case Instruction::ShuffleVector:
2840b57cec5SDimitry Andric case Instruction::ExtractValue:
2850b57cec5SDimitry Andric break;
2860b57cec5SDimitry Andric case Instruction::ICmp:
2870b57cec5SDimitry Andric // Comparing a pointer with null, or any other constant, isn't an
2880b57cec5SDimitry Andric // interesting use, because we don't care what the pointer points to, or
2890b57cec5SDimitry Andric // about the values of any other dynamic reference-counted pointers.
2900b57cec5SDimitry Andric if (IsPotentialRetainableObjPtr(I->getOperand(1)))
2910b57cec5SDimitry Andric return ARCInstKind::User;
2920b57cec5SDimitry Andric break;
2930b57cec5SDimitry Andric default:
2940b57cec5SDimitry Andric // For anything else, check all the operands.
2950b57cec5SDimitry Andric // Note that this includes both operands of a Store: while the first
2960b57cec5SDimitry Andric // operand isn't actually being dereferenced, it is being stored to
2970b57cec5SDimitry Andric // memory where we can no longer track who might read it and dereference
2980b57cec5SDimitry Andric // it, so we have to consider it potentially used.
299349cc55cSDimitry Andric for (const Use &U : I->operands())
300349cc55cSDimitry Andric if (IsPotentialRetainableObjPtr(U))
3010b57cec5SDimitry Andric return ARCInstKind::User;
3020b57cec5SDimitry Andric }
3030b57cec5SDimitry Andric }
3040b57cec5SDimitry Andric
3050b57cec5SDimitry Andric // Otherwise, it's totally inert for ARC purposes.
3060b57cec5SDimitry Andric return ARCInstKind::None;
3070b57cec5SDimitry Andric }
3080b57cec5SDimitry Andric
3090b57cec5SDimitry Andric /// Test if the given class is a kind of user.
IsUser(ARCInstKind Class)3100b57cec5SDimitry Andric bool llvm::objcarc::IsUser(ARCInstKind Class) {
3110b57cec5SDimitry Andric switch (Class) {
3120b57cec5SDimitry Andric case ARCInstKind::User:
3130b57cec5SDimitry Andric case ARCInstKind::CallOrUser:
3140b57cec5SDimitry Andric case ARCInstKind::IntrinsicUser:
3150b57cec5SDimitry Andric return true;
3160b57cec5SDimitry Andric case ARCInstKind::Retain:
3170b57cec5SDimitry Andric case ARCInstKind::RetainRV:
3180b57cec5SDimitry Andric case ARCInstKind::RetainBlock:
3190b57cec5SDimitry Andric case ARCInstKind::Release:
3200b57cec5SDimitry Andric case ARCInstKind::Autorelease:
3210b57cec5SDimitry Andric case ARCInstKind::AutoreleaseRV:
3220b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPush:
3230b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPop:
3240b57cec5SDimitry Andric case ARCInstKind::NoopCast:
3250b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutorelease:
3260b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutoreleaseRV:
3270b57cec5SDimitry Andric case ARCInstKind::LoadWeakRetained:
3280b57cec5SDimitry Andric case ARCInstKind::StoreWeak:
3290b57cec5SDimitry Andric case ARCInstKind::InitWeak:
3300b57cec5SDimitry Andric case ARCInstKind::LoadWeak:
3310b57cec5SDimitry Andric case ARCInstKind::MoveWeak:
3320b57cec5SDimitry Andric case ARCInstKind::CopyWeak:
3330b57cec5SDimitry Andric case ARCInstKind::DestroyWeak:
3340b57cec5SDimitry Andric case ARCInstKind::StoreStrong:
3350b57cec5SDimitry Andric case ARCInstKind::Call:
3360b57cec5SDimitry Andric case ARCInstKind::None:
337*04eeddc0SDimitry Andric case ARCInstKind::UnsafeClaimRV:
3380b57cec5SDimitry Andric return false;
3390b57cec5SDimitry Andric }
3400b57cec5SDimitry Andric llvm_unreachable("covered switch isn't covered?");
3410b57cec5SDimitry Andric }
3420b57cec5SDimitry Andric
3430b57cec5SDimitry Andric /// Test if the given class is objc_retain or equivalent.
IsRetain(ARCInstKind Class)3440b57cec5SDimitry Andric bool llvm::objcarc::IsRetain(ARCInstKind Class) {
3450b57cec5SDimitry Andric switch (Class) {
3460b57cec5SDimitry Andric case ARCInstKind::Retain:
3470b57cec5SDimitry Andric case ARCInstKind::RetainRV:
3480b57cec5SDimitry Andric return true;
3490b57cec5SDimitry Andric // I believe we treat retain block as not a retain since it can copy its
3500b57cec5SDimitry Andric // block.
3510b57cec5SDimitry Andric case ARCInstKind::RetainBlock:
3520b57cec5SDimitry Andric case ARCInstKind::Release:
3530b57cec5SDimitry Andric case ARCInstKind::Autorelease:
3540b57cec5SDimitry Andric case ARCInstKind::AutoreleaseRV:
3550b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPush:
3560b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPop:
3570b57cec5SDimitry Andric case ARCInstKind::NoopCast:
3580b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutorelease:
3590b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutoreleaseRV:
3600b57cec5SDimitry Andric case ARCInstKind::LoadWeakRetained:
3610b57cec5SDimitry Andric case ARCInstKind::StoreWeak:
3620b57cec5SDimitry Andric case ARCInstKind::InitWeak:
3630b57cec5SDimitry Andric case ARCInstKind::LoadWeak:
3640b57cec5SDimitry Andric case ARCInstKind::MoveWeak:
3650b57cec5SDimitry Andric case ARCInstKind::CopyWeak:
3660b57cec5SDimitry Andric case ARCInstKind::DestroyWeak:
3670b57cec5SDimitry Andric case ARCInstKind::StoreStrong:
3680b57cec5SDimitry Andric case ARCInstKind::IntrinsicUser:
3690b57cec5SDimitry Andric case ARCInstKind::CallOrUser:
3700b57cec5SDimitry Andric case ARCInstKind::Call:
3710b57cec5SDimitry Andric case ARCInstKind::User:
3720b57cec5SDimitry Andric case ARCInstKind::None:
373*04eeddc0SDimitry Andric case ARCInstKind::UnsafeClaimRV:
3740b57cec5SDimitry Andric return false;
3750b57cec5SDimitry Andric }
3760b57cec5SDimitry Andric llvm_unreachable("covered switch isn't covered?");
3770b57cec5SDimitry Andric }
3780b57cec5SDimitry Andric
3790b57cec5SDimitry Andric /// Test if the given class is objc_autorelease or equivalent.
IsAutorelease(ARCInstKind Class)3800b57cec5SDimitry Andric bool llvm::objcarc::IsAutorelease(ARCInstKind Class) {
3810b57cec5SDimitry Andric switch (Class) {
3820b57cec5SDimitry Andric case ARCInstKind::Autorelease:
3830b57cec5SDimitry Andric case ARCInstKind::AutoreleaseRV:
3840b57cec5SDimitry Andric return true;
3850b57cec5SDimitry Andric case ARCInstKind::Retain:
3860b57cec5SDimitry Andric case ARCInstKind::RetainRV:
387*04eeddc0SDimitry Andric case ARCInstKind::UnsafeClaimRV:
3880b57cec5SDimitry Andric case ARCInstKind::RetainBlock:
3890b57cec5SDimitry Andric case ARCInstKind::Release:
3900b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPush:
3910b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPop:
3920b57cec5SDimitry Andric case ARCInstKind::NoopCast:
3930b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutorelease:
3940b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutoreleaseRV:
3950b57cec5SDimitry Andric case ARCInstKind::LoadWeakRetained:
3960b57cec5SDimitry Andric case ARCInstKind::StoreWeak:
3970b57cec5SDimitry Andric case ARCInstKind::InitWeak:
3980b57cec5SDimitry Andric case ARCInstKind::LoadWeak:
3990b57cec5SDimitry Andric case ARCInstKind::MoveWeak:
4000b57cec5SDimitry Andric case ARCInstKind::CopyWeak:
4010b57cec5SDimitry Andric case ARCInstKind::DestroyWeak:
4020b57cec5SDimitry Andric case ARCInstKind::StoreStrong:
4030b57cec5SDimitry Andric case ARCInstKind::IntrinsicUser:
4040b57cec5SDimitry Andric case ARCInstKind::CallOrUser:
4050b57cec5SDimitry Andric case ARCInstKind::Call:
4060b57cec5SDimitry Andric case ARCInstKind::User:
4070b57cec5SDimitry Andric case ARCInstKind::None:
4080b57cec5SDimitry Andric return false;
4090b57cec5SDimitry Andric }
4100b57cec5SDimitry Andric llvm_unreachable("covered switch isn't covered?");
4110b57cec5SDimitry Andric }
4120b57cec5SDimitry Andric
4130b57cec5SDimitry Andric /// Test if the given class represents instructions which return their
4140b57cec5SDimitry Andric /// argument verbatim.
IsForwarding(ARCInstKind Class)4150b57cec5SDimitry Andric bool llvm::objcarc::IsForwarding(ARCInstKind Class) {
4160b57cec5SDimitry Andric switch (Class) {
4170b57cec5SDimitry Andric case ARCInstKind::Retain:
4180b57cec5SDimitry Andric case ARCInstKind::RetainRV:
419*04eeddc0SDimitry Andric case ARCInstKind::UnsafeClaimRV:
4200b57cec5SDimitry Andric case ARCInstKind::Autorelease:
4210b57cec5SDimitry Andric case ARCInstKind::AutoreleaseRV:
4220b57cec5SDimitry Andric case ARCInstKind::NoopCast:
4230b57cec5SDimitry Andric return true;
4240b57cec5SDimitry Andric case ARCInstKind::RetainBlock:
4250b57cec5SDimitry Andric case ARCInstKind::Release:
4260b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPush:
4270b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPop:
4280b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutorelease:
4290b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutoreleaseRV:
4300b57cec5SDimitry Andric case ARCInstKind::LoadWeakRetained:
4310b57cec5SDimitry Andric case ARCInstKind::StoreWeak:
4320b57cec5SDimitry Andric case ARCInstKind::InitWeak:
4330b57cec5SDimitry Andric case ARCInstKind::LoadWeak:
4340b57cec5SDimitry Andric case ARCInstKind::MoveWeak:
4350b57cec5SDimitry Andric case ARCInstKind::CopyWeak:
4360b57cec5SDimitry Andric case ARCInstKind::DestroyWeak:
4370b57cec5SDimitry Andric case ARCInstKind::StoreStrong:
4380b57cec5SDimitry Andric case ARCInstKind::IntrinsicUser:
4390b57cec5SDimitry Andric case ARCInstKind::CallOrUser:
4400b57cec5SDimitry Andric case ARCInstKind::Call:
4410b57cec5SDimitry Andric case ARCInstKind::User:
4420b57cec5SDimitry Andric case ARCInstKind::None:
4430b57cec5SDimitry Andric return false;
4440b57cec5SDimitry Andric }
4450b57cec5SDimitry Andric llvm_unreachable("covered switch isn't covered?");
4460b57cec5SDimitry Andric }
4470b57cec5SDimitry Andric
4480b57cec5SDimitry Andric /// Test if the given class represents instructions which do nothing if
4490b57cec5SDimitry Andric /// passed a null pointer.
IsNoopOnNull(ARCInstKind Class)4500b57cec5SDimitry Andric bool llvm::objcarc::IsNoopOnNull(ARCInstKind Class) {
4510b57cec5SDimitry Andric switch (Class) {
4520b57cec5SDimitry Andric case ARCInstKind::Retain:
4530b57cec5SDimitry Andric case ARCInstKind::RetainRV:
454*04eeddc0SDimitry Andric case ARCInstKind::UnsafeClaimRV:
4550b57cec5SDimitry Andric case ARCInstKind::Release:
4560b57cec5SDimitry Andric case ARCInstKind::Autorelease:
4570b57cec5SDimitry Andric case ARCInstKind::AutoreleaseRV:
4580b57cec5SDimitry Andric case ARCInstKind::RetainBlock:
4590b57cec5SDimitry Andric return true;
4600b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPush:
4610b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPop:
4620b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutorelease:
4630b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutoreleaseRV:
4640b57cec5SDimitry Andric case ARCInstKind::LoadWeakRetained:
4650b57cec5SDimitry Andric case ARCInstKind::StoreWeak:
4660b57cec5SDimitry Andric case ARCInstKind::InitWeak:
4670b57cec5SDimitry Andric case ARCInstKind::LoadWeak:
4680b57cec5SDimitry Andric case ARCInstKind::MoveWeak:
4690b57cec5SDimitry Andric case ARCInstKind::CopyWeak:
4700b57cec5SDimitry Andric case ARCInstKind::DestroyWeak:
4710b57cec5SDimitry Andric case ARCInstKind::StoreStrong:
4720b57cec5SDimitry Andric case ARCInstKind::IntrinsicUser:
4730b57cec5SDimitry Andric case ARCInstKind::CallOrUser:
4740b57cec5SDimitry Andric case ARCInstKind::Call:
4750b57cec5SDimitry Andric case ARCInstKind::User:
4760b57cec5SDimitry Andric case ARCInstKind::None:
4770b57cec5SDimitry Andric case ARCInstKind::NoopCast:
4780b57cec5SDimitry Andric return false;
4790b57cec5SDimitry Andric }
4800b57cec5SDimitry Andric llvm_unreachable("covered switch isn't covered?");
4810b57cec5SDimitry Andric }
4820b57cec5SDimitry Andric
4830b57cec5SDimitry Andric /// Test if the given class represents instructions which do nothing if
4840b57cec5SDimitry Andric /// passed a global variable.
IsNoopOnGlobal(ARCInstKind Class)4850b57cec5SDimitry Andric bool llvm::objcarc::IsNoopOnGlobal(ARCInstKind Class) {
4860b57cec5SDimitry Andric switch (Class) {
4870b57cec5SDimitry Andric case ARCInstKind::Retain:
4880b57cec5SDimitry Andric case ARCInstKind::RetainRV:
489*04eeddc0SDimitry Andric case ARCInstKind::UnsafeClaimRV:
4900b57cec5SDimitry Andric case ARCInstKind::Release:
4910b57cec5SDimitry Andric case ARCInstKind::Autorelease:
4920b57cec5SDimitry Andric case ARCInstKind::AutoreleaseRV:
4930b57cec5SDimitry Andric case ARCInstKind::RetainBlock:
4940b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutorelease:
4950b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutoreleaseRV:
4960b57cec5SDimitry Andric return true;
4970b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPush:
4980b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPop:
4990b57cec5SDimitry Andric case ARCInstKind::LoadWeakRetained:
5000b57cec5SDimitry Andric case ARCInstKind::StoreWeak:
5010b57cec5SDimitry Andric case ARCInstKind::InitWeak:
5020b57cec5SDimitry Andric case ARCInstKind::LoadWeak:
5030b57cec5SDimitry Andric case ARCInstKind::MoveWeak:
5040b57cec5SDimitry Andric case ARCInstKind::CopyWeak:
5050b57cec5SDimitry Andric case ARCInstKind::DestroyWeak:
5060b57cec5SDimitry Andric case ARCInstKind::StoreStrong:
5070b57cec5SDimitry Andric case ARCInstKind::IntrinsicUser:
5080b57cec5SDimitry Andric case ARCInstKind::CallOrUser:
5090b57cec5SDimitry Andric case ARCInstKind::Call:
5100b57cec5SDimitry Andric case ARCInstKind::User:
5110b57cec5SDimitry Andric case ARCInstKind::None:
5120b57cec5SDimitry Andric case ARCInstKind::NoopCast:
5130b57cec5SDimitry Andric return false;
5140b57cec5SDimitry Andric }
5150b57cec5SDimitry Andric llvm_unreachable("covered switch isn't covered?");
5160b57cec5SDimitry Andric }
5170b57cec5SDimitry Andric
5180b57cec5SDimitry Andric /// Test if the given class represents instructions which are always safe
5190b57cec5SDimitry Andric /// to mark with the "tail" keyword.
IsAlwaysTail(ARCInstKind Class)5200b57cec5SDimitry Andric bool llvm::objcarc::IsAlwaysTail(ARCInstKind Class) {
5210b57cec5SDimitry Andric // ARCInstKind::RetainBlock may be given a stack argument.
5220b57cec5SDimitry Andric switch (Class) {
5230b57cec5SDimitry Andric case ARCInstKind::Retain:
5240b57cec5SDimitry Andric case ARCInstKind::RetainRV:
525*04eeddc0SDimitry Andric case ARCInstKind::UnsafeClaimRV:
5260b57cec5SDimitry Andric case ARCInstKind::AutoreleaseRV:
5270b57cec5SDimitry Andric return true;
5280b57cec5SDimitry Andric case ARCInstKind::Release:
5290b57cec5SDimitry Andric case ARCInstKind::Autorelease:
5300b57cec5SDimitry Andric case ARCInstKind::RetainBlock:
5310b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPush:
5320b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPop:
5330b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutorelease:
5340b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutoreleaseRV:
5350b57cec5SDimitry Andric case ARCInstKind::LoadWeakRetained:
5360b57cec5SDimitry Andric case ARCInstKind::StoreWeak:
5370b57cec5SDimitry Andric case ARCInstKind::InitWeak:
5380b57cec5SDimitry Andric case ARCInstKind::LoadWeak:
5390b57cec5SDimitry Andric case ARCInstKind::MoveWeak:
5400b57cec5SDimitry Andric case ARCInstKind::CopyWeak:
5410b57cec5SDimitry Andric case ARCInstKind::DestroyWeak:
5420b57cec5SDimitry Andric case ARCInstKind::StoreStrong:
5430b57cec5SDimitry Andric case ARCInstKind::IntrinsicUser:
5440b57cec5SDimitry Andric case ARCInstKind::CallOrUser:
5450b57cec5SDimitry Andric case ARCInstKind::Call:
5460b57cec5SDimitry Andric case ARCInstKind::User:
5470b57cec5SDimitry Andric case ARCInstKind::None:
5480b57cec5SDimitry Andric case ARCInstKind::NoopCast:
5490b57cec5SDimitry Andric return false;
5500b57cec5SDimitry Andric }
5510b57cec5SDimitry Andric llvm_unreachable("covered switch isn't covered?");
5520b57cec5SDimitry Andric }
5530b57cec5SDimitry Andric
5540b57cec5SDimitry Andric /// Test if the given class represents instructions which are never safe
5550b57cec5SDimitry Andric /// to mark with the "tail" keyword.
IsNeverTail(ARCInstKind Class)5560b57cec5SDimitry Andric bool llvm::objcarc::IsNeverTail(ARCInstKind Class) {
5570b57cec5SDimitry Andric /// It is never safe to tail call objc_autorelease since by tail calling
5580b57cec5SDimitry Andric /// objc_autorelease: fast autoreleasing causing our object to be potentially
5590b57cec5SDimitry Andric /// reclaimed from the autorelease pool which violates the semantics of
5600b57cec5SDimitry Andric /// __autoreleasing types in ARC.
5610b57cec5SDimitry Andric switch (Class) {
5620b57cec5SDimitry Andric case ARCInstKind::Autorelease:
5630b57cec5SDimitry Andric return true;
5640b57cec5SDimitry Andric case ARCInstKind::Retain:
5650b57cec5SDimitry Andric case ARCInstKind::RetainRV:
566*04eeddc0SDimitry Andric case ARCInstKind::UnsafeClaimRV:
5670b57cec5SDimitry Andric case ARCInstKind::AutoreleaseRV:
5680b57cec5SDimitry Andric case ARCInstKind::Release:
5690b57cec5SDimitry Andric case ARCInstKind::RetainBlock:
5700b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPush:
5710b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPop:
5720b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutorelease:
5730b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutoreleaseRV:
5740b57cec5SDimitry Andric case ARCInstKind::LoadWeakRetained:
5750b57cec5SDimitry Andric case ARCInstKind::StoreWeak:
5760b57cec5SDimitry Andric case ARCInstKind::InitWeak:
5770b57cec5SDimitry Andric case ARCInstKind::LoadWeak:
5780b57cec5SDimitry Andric case ARCInstKind::MoveWeak:
5790b57cec5SDimitry Andric case ARCInstKind::CopyWeak:
5800b57cec5SDimitry Andric case ARCInstKind::DestroyWeak:
5810b57cec5SDimitry Andric case ARCInstKind::StoreStrong:
5820b57cec5SDimitry Andric case ARCInstKind::IntrinsicUser:
5830b57cec5SDimitry Andric case ARCInstKind::CallOrUser:
5840b57cec5SDimitry Andric case ARCInstKind::Call:
5850b57cec5SDimitry Andric case ARCInstKind::User:
5860b57cec5SDimitry Andric case ARCInstKind::None:
5870b57cec5SDimitry Andric case ARCInstKind::NoopCast:
5880b57cec5SDimitry Andric return false;
5890b57cec5SDimitry Andric }
5900b57cec5SDimitry Andric llvm_unreachable("covered switch isn't covered?");
5910b57cec5SDimitry Andric }
5920b57cec5SDimitry Andric
5930b57cec5SDimitry Andric /// Test if the given class represents instructions which are always safe
5940b57cec5SDimitry Andric /// to mark with the nounwind attribute.
IsNoThrow(ARCInstKind Class)5950b57cec5SDimitry Andric bool llvm::objcarc::IsNoThrow(ARCInstKind Class) {
5960b57cec5SDimitry Andric // objc_retainBlock is not nounwind because it calls user copy constructors
5970b57cec5SDimitry Andric // which could theoretically throw.
5980b57cec5SDimitry Andric switch (Class) {
5990b57cec5SDimitry Andric case ARCInstKind::Retain:
6000b57cec5SDimitry Andric case ARCInstKind::RetainRV:
601*04eeddc0SDimitry Andric case ARCInstKind::UnsafeClaimRV:
6020b57cec5SDimitry Andric case ARCInstKind::Release:
6030b57cec5SDimitry Andric case ARCInstKind::Autorelease:
6040b57cec5SDimitry Andric case ARCInstKind::AutoreleaseRV:
6050b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPush:
6060b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPop:
6070b57cec5SDimitry Andric return true;
6080b57cec5SDimitry Andric case ARCInstKind::RetainBlock:
6090b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutorelease:
6100b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutoreleaseRV:
6110b57cec5SDimitry Andric case ARCInstKind::LoadWeakRetained:
6120b57cec5SDimitry Andric case ARCInstKind::StoreWeak:
6130b57cec5SDimitry Andric case ARCInstKind::InitWeak:
6140b57cec5SDimitry Andric case ARCInstKind::LoadWeak:
6150b57cec5SDimitry Andric case ARCInstKind::MoveWeak:
6160b57cec5SDimitry Andric case ARCInstKind::CopyWeak:
6170b57cec5SDimitry Andric case ARCInstKind::DestroyWeak:
6180b57cec5SDimitry Andric case ARCInstKind::StoreStrong:
6190b57cec5SDimitry Andric case ARCInstKind::IntrinsicUser:
6200b57cec5SDimitry Andric case ARCInstKind::CallOrUser:
6210b57cec5SDimitry Andric case ARCInstKind::Call:
6220b57cec5SDimitry Andric case ARCInstKind::User:
6230b57cec5SDimitry Andric case ARCInstKind::None:
6240b57cec5SDimitry Andric case ARCInstKind::NoopCast:
6250b57cec5SDimitry Andric return false;
6260b57cec5SDimitry Andric }
6270b57cec5SDimitry Andric llvm_unreachable("covered switch isn't covered?");
6280b57cec5SDimitry Andric }
6290b57cec5SDimitry Andric
6300b57cec5SDimitry Andric /// Test whether the given instruction can autorelease any pointer or cause an
6310b57cec5SDimitry Andric /// autoreleasepool pop.
6320b57cec5SDimitry Andric ///
6330b57cec5SDimitry Andric /// This means that it *could* interrupt the RV optimization.
CanInterruptRV(ARCInstKind Class)6340b57cec5SDimitry Andric bool llvm::objcarc::CanInterruptRV(ARCInstKind Class) {
6350b57cec5SDimitry Andric switch (Class) {
6360b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPop:
6370b57cec5SDimitry Andric case ARCInstKind::CallOrUser:
6380b57cec5SDimitry Andric case ARCInstKind::Call:
6390b57cec5SDimitry Andric case ARCInstKind::Autorelease:
6400b57cec5SDimitry Andric case ARCInstKind::AutoreleaseRV:
6410b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutorelease:
6420b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutoreleaseRV:
6430b57cec5SDimitry Andric return true;
6440b57cec5SDimitry Andric case ARCInstKind::Retain:
6450b57cec5SDimitry Andric case ARCInstKind::RetainRV:
646*04eeddc0SDimitry Andric case ARCInstKind::UnsafeClaimRV:
6470b57cec5SDimitry Andric case ARCInstKind::Release:
6480b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPush:
6490b57cec5SDimitry Andric case ARCInstKind::RetainBlock:
6500b57cec5SDimitry Andric case ARCInstKind::LoadWeakRetained:
6510b57cec5SDimitry Andric case ARCInstKind::StoreWeak:
6520b57cec5SDimitry Andric case ARCInstKind::InitWeak:
6530b57cec5SDimitry Andric case ARCInstKind::LoadWeak:
6540b57cec5SDimitry Andric case ARCInstKind::MoveWeak:
6550b57cec5SDimitry Andric case ARCInstKind::CopyWeak:
6560b57cec5SDimitry Andric case ARCInstKind::DestroyWeak:
6570b57cec5SDimitry Andric case ARCInstKind::StoreStrong:
6580b57cec5SDimitry Andric case ARCInstKind::IntrinsicUser:
6590b57cec5SDimitry Andric case ARCInstKind::User:
6600b57cec5SDimitry Andric case ARCInstKind::None:
6610b57cec5SDimitry Andric case ARCInstKind::NoopCast:
6620b57cec5SDimitry Andric return false;
6630b57cec5SDimitry Andric }
6640b57cec5SDimitry Andric llvm_unreachable("covered switch isn't covered?");
6650b57cec5SDimitry Andric }
6660b57cec5SDimitry Andric
CanDecrementRefCount(ARCInstKind Kind)6670b57cec5SDimitry Andric bool llvm::objcarc::CanDecrementRefCount(ARCInstKind Kind) {
6680b57cec5SDimitry Andric switch (Kind) {
6690b57cec5SDimitry Andric case ARCInstKind::Retain:
6700b57cec5SDimitry Andric case ARCInstKind::RetainRV:
6710b57cec5SDimitry Andric case ARCInstKind::Autorelease:
6720b57cec5SDimitry Andric case ARCInstKind::AutoreleaseRV:
6730b57cec5SDimitry Andric case ARCInstKind::NoopCast:
6740b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutorelease:
6750b57cec5SDimitry Andric case ARCInstKind::FusedRetainAutoreleaseRV:
6760b57cec5SDimitry Andric case ARCInstKind::IntrinsicUser:
6770b57cec5SDimitry Andric case ARCInstKind::User:
6780b57cec5SDimitry Andric case ARCInstKind::None:
6790b57cec5SDimitry Andric return false;
6800b57cec5SDimitry Andric
6810b57cec5SDimitry Andric // The cases below are conservative.
6820b57cec5SDimitry Andric
6830b57cec5SDimitry Andric // RetainBlock can result in user defined copy constructors being called
6840b57cec5SDimitry Andric // implying releases may occur.
6850b57cec5SDimitry Andric case ARCInstKind::RetainBlock:
6860b57cec5SDimitry Andric case ARCInstKind::Release:
6870b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPush:
6880b57cec5SDimitry Andric case ARCInstKind::AutoreleasepoolPop:
6890b57cec5SDimitry Andric case ARCInstKind::LoadWeakRetained:
6900b57cec5SDimitry Andric case ARCInstKind::StoreWeak:
6910b57cec5SDimitry Andric case ARCInstKind::InitWeak:
6920b57cec5SDimitry Andric case ARCInstKind::LoadWeak:
6930b57cec5SDimitry Andric case ARCInstKind::MoveWeak:
6940b57cec5SDimitry Andric case ARCInstKind::CopyWeak:
6950b57cec5SDimitry Andric case ARCInstKind::DestroyWeak:
6960b57cec5SDimitry Andric case ARCInstKind::StoreStrong:
6970b57cec5SDimitry Andric case ARCInstKind::CallOrUser:
6980b57cec5SDimitry Andric case ARCInstKind::Call:
699*04eeddc0SDimitry Andric case ARCInstKind::UnsafeClaimRV:
7000b57cec5SDimitry Andric return true;
7010b57cec5SDimitry Andric }
7020b57cec5SDimitry Andric
7030b57cec5SDimitry Andric llvm_unreachable("covered switch isn't covered?");
7040b57cec5SDimitry Andric }
705