diff options
Diffstat (limited to 'gnu/llvm/lib/Analysis/ObjCARCInstKind.cpp')
| -rw-r--r-- | gnu/llvm/lib/Analysis/ObjCARCInstKind.cpp | 671 |
1 files changed, 0 insertions, 671 deletions
diff --git a/gnu/llvm/lib/Analysis/ObjCARCInstKind.cpp b/gnu/llvm/lib/Analysis/ObjCARCInstKind.cpp deleted file mode 100644 index 31c43271183..00000000000 --- a/gnu/llvm/lib/Analysis/ObjCARCInstKind.cpp +++ /dev/null @@ -1,671 +0,0 @@ -//===- ARCInstKind.cpp - ObjC ARC Optimization ----------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// \file -/// This file defines several utility functions used by various ARC -/// optimizations which are IMHO too big to be in a header file. -/// -/// WARNING: This file knows about certain library functions. It recognizes them -/// by name, and hardwires knowledge of their semantics. -/// -/// WARNING: This file knows about how certain Objective-C library functions are -/// used. Naive LLVM IR transformations which would otherwise be -/// behavior-preserving may break these assumptions. -/// -//===----------------------------------------------------------------------===// - -#include "llvm/Analysis/ObjCARCInstKind.h" -#include "llvm/ADT/StringSwitch.h" -#include "llvm/Analysis/ObjCARCAnalysisUtils.h" -#include "llvm/IR/Intrinsics.h" - -using namespace llvm; -using namespace llvm::objcarc; - -raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS, - const ARCInstKind Class) { - switch (Class) { - case ARCInstKind::Retain: - return OS << "ARCInstKind::Retain"; - case ARCInstKind::RetainRV: - return OS << "ARCInstKind::RetainRV"; - case ARCInstKind::ClaimRV: - return OS << "ARCInstKind::ClaimRV"; - case ARCInstKind::RetainBlock: - return OS << "ARCInstKind::RetainBlock"; - case ARCInstKind::Release: - return OS << "ARCInstKind::Release"; - case ARCInstKind::Autorelease: - return OS << "ARCInstKind::Autorelease"; - case ARCInstKind::AutoreleaseRV: - return OS << "ARCInstKind::AutoreleaseRV"; - case ARCInstKind::AutoreleasepoolPush: - return OS << "ARCInstKind::AutoreleasepoolPush"; - case ARCInstKind::AutoreleasepoolPop: - return OS << "ARCInstKind::AutoreleasepoolPop"; - case ARCInstKind::NoopCast: - return OS << "ARCInstKind::NoopCast"; - case ARCInstKind::FusedRetainAutorelease: - return OS << "ARCInstKind::FusedRetainAutorelease"; - case ARCInstKind::FusedRetainAutoreleaseRV: - return OS << "ARCInstKind::FusedRetainAutoreleaseRV"; - case ARCInstKind::LoadWeakRetained: - return OS << "ARCInstKind::LoadWeakRetained"; - case ARCInstKind::StoreWeak: - return OS << "ARCInstKind::StoreWeak"; - case ARCInstKind::InitWeak: - return OS << "ARCInstKind::InitWeak"; - case ARCInstKind::LoadWeak: - return OS << "ARCInstKind::LoadWeak"; - case ARCInstKind::MoveWeak: - return OS << "ARCInstKind::MoveWeak"; - case ARCInstKind::CopyWeak: - return OS << "ARCInstKind::CopyWeak"; - case ARCInstKind::DestroyWeak: - return OS << "ARCInstKind::DestroyWeak"; - case ARCInstKind::StoreStrong: - return OS << "ARCInstKind::StoreStrong"; - case ARCInstKind::CallOrUser: - return OS << "ARCInstKind::CallOrUser"; - case ARCInstKind::Call: - return OS << "ARCInstKind::Call"; - case ARCInstKind::User: - return OS << "ARCInstKind::User"; - case ARCInstKind::IntrinsicUser: - return OS << "ARCInstKind::IntrinsicUser"; - case ARCInstKind::None: - return OS << "ARCInstKind::None"; - } - llvm_unreachable("Unknown instruction class!"); -} - -ARCInstKind llvm::objcarc::GetFunctionClass(const Function *F) { - - Intrinsic::ID ID = F->getIntrinsicID(); - switch (ID) { - default: - return ARCInstKind::CallOrUser; - case Intrinsic::objc_autorelease: - return ARCInstKind::Autorelease; - case Intrinsic::objc_autoreleasePoolPop: - return ARCInstKind::AutoreleasepoolPop; - case Intrinsic::objc_autoreleasePoolPush: - return ARCInstKind::AutoreleasepoolPush; - case Intrinsic::objc_autoreleaseReturnValue: - return ARCInstKind::AutoreleaseRV; - case Intrinsic::objc_copyWeak: - return ARCInstKind::CopyWeak; - case Intrinsic::objc_destroyWeak: - return ARCInstKind::DestroyWeak; - case Intrinsic::objc_initWeak: - return ARCInstKind::InitWeak; - case Intrinsic::objc_loadWeak: - return ARCInstKind::LoadWeak; - case Intrinsic::objc_loadWeakRetained: - return ARCInstKind::LoadWeakRetained; - case Intrinsic::objc_moveWeak: - return ARCInstKind::MoveWeak; - case Intrinsic::objc_release: - return ARCInstKind::Release; - case Intrinsic::objc_retain: - return ARCInstKind::Retain; - case Intrinsic::objc_retainAutorelease: - return ARCInstKind::FusedRetainAutorelease; - case Intrinsic::objc_retainAutoreleaseReturnValue: - return ARCInstKind::FusedRetainAutoreleaseRV; - case Intrinsic::objc_retainAutoreleasedReturnValue: - return ARCInstKind::RetainRV; - case Intrinsic::objc_retainBlock: - return ARCInstKind::RetainBlock; - case Intrinsic::objc_storeStrong: - return ARCInstKind::StoreStrong; - case Intrinsic::objc_storeWeak: - return ARCInstKind::StoreWeak; - case Intrinsic::objc_clang_arc_use: - return ARCInstKind::IntrinsicUser; - case Intrinsic::objc_unsafeClaimAutoreleasedReturnValue: - return ARCInstKind::ClaimRV; - case Intrinsic::objc_retainedObject: - return ARCInstKind::NoopCast; - case Intrinsic::objc_unretainedObject: - return ARCInstKind::NoopCast; - case Intrinsic::objc_unretainedPointer: - return ARCInstKind::NoopCast; - case Intrinsic::objc_retain_autorelease: - return ARCInstKind::FusedRetainAutorelease; - case Intrinsic::objc_sync_enter: - return ARCInstKind::User; - case Intrinsic::objc_sync_exit: - return ARCInstKind::User; - case Intrinsic::objc_arc_annotation_topdown_bbstart: - case Intrinsic::objc_arc_annotation_topdown_bbend: - case Intrinsic::objc_arc_annotation_bottomup_bbstart: - case Intrinsic::objc_arc_annotation_bottomup_bbend: - // Ignore annotation calls. This is important to stop the - // optimizer from treating annotations as uses which would - // make the state of the pointers they are attempting to - // elucidate to be incorrect. - return ARCInstKind::None; - } -} - -// A whitelist of intrinsics that we know do not use objc pointers or decrement -// ref counts. -static bool isInertIntrinsic(unsigned ID) { - // TODO: Make this into a covered switch. - switch (ID) { - case Intrinsic::returnaddress: - case Intrinsic::addressofreturnaddress: - case Intrinsic::frameaddress: - case Intrinsic::stacksave: - case Intrinsic::stackrestore: - case Intrinsic::vastart: - case Intrinsic::vacopy: - case Intrinsic::vaend: - case Intrinsic::objectsize: - case Intrinsic::prefetch: - case Intrinsic::stackprotector: - case Intrinsic::eh_return_i32: - case Intrinsic::eh_return_i64: - case Intrinsic::eh_typeid_for: - case Intrinsic::eh_dwarf_cfa: - case Intrinsic::eh_sjlj_lsda: - case Intrinsic::eh_sjlj_functioncontext: - case Intrinsic::init_trampoline: - case Intrinsic::adjust_trampoline: - case Intrinsic::lifetime_start: - case Intrinsic::lifetime_end: - case Intrinsic::invariant_start: - case Intrinsic::invariant_end: - // Don't let dbg info affect our results. - case Intrinsic::dbg_declare: - case Intrinsic::dbg_value: - case Intrinsic::dbg_label: - // Short cut: Some intrinsics obviously don't use ObjC pointers. - return true; - default: - return false; - } -} - -// A whitelist of intrinsics that we know do not use objc pointers or decrement -// ref counts. -static bool isUseOnlyIntrinsic(unsigned ID) { - // We are conservative and even though intrinsics are unlikely to touch - // reference counts, we white list them for safety. - // - // TODO: Expand this into a covered switch. There is a lot more here. - switch (ID) { - case Intrinsic::memcpy: - case Intrinsic::memmove: - case Intrinsic::memset: - return true; - default: - return false; - } -} - -/// Determine what kind of construct V is. -ARCInstKind llvm::objcarc::GetARCInstKind(const Value *V) { - if (const Instruction *I = dyn_cast<Instruction>(V)) { - // Any instruction other than bitcast and gep with a pointer operand have a - // use of an objc pointer. Bitcasts, GEPs, Selects, PHIs transfer a pointer - // to a subsequent use, rather than using it themselves, in this sense. - // As a short cut, several other opcodes are known to have no pointer - // operands of interest. And ret is never followed by a release, so it's - // not interesting to examine. - switch (I->getOpcode()) { - case Instruction::Call: { - const CallInst *CI = cast<CallInst>(I); - // See if we have a function that we know something about. - if (const Function *F = CI->getCalledFunction()) { - ARCInstKind Class = GetFunctionClass(F); - if (Class != ARCInstKind::CallOrUser) - return Class; - Intrinsic::ID ID = F->getIntrinsicID(); - if (isInertIntrinsic(ID)) - return ARCInstKind::None; - if (isUseOnlyIntrinsic(ID)) - return ARCInstKind::User; - } - - // Otherwise, be conservative. - return GetCallSiteClass(CI); - } - case Instruction::Invoke: - // Otherwise, be conservative. - return GetCallSiteClass(cast<InvokeInst>(I)); - case Instruction::BitCast: - case Instruction::GetElementPtr: - case Instruction::Select: - case Instruction::PHI: - case Instruction::Ret: - case Instruction::Br: - case Instruction::Switch: - case Instruction::IndirectBr: - case Instruction::Alloca: - case Instruction::VAArg: - case Instruction::Add: - case Instruction::FAdd: - case Instruction::Sub: - case Instruction::FSub: - case Instruction::Mul: - case Instruction::FMul: - case Instruction::SDiv: - case Instruction::UDiv: - case Instruction::FDiv: - case Instruction::SRem: - case Instruction::URem: - case Instruction::FRem: - case Instruction::Shl: - case Instruction::LShr: - case Instruction::AShr: - case Instruction::And: - case Instruction::Or: - case Instruction::Xor: - case Instruction::SExt: - case Instruction::ZExt: - case Instruction::Trunc: - case Instruction::IntToPtr: - case Instruction::FCmp: - case Instruction::FPTrunc: - case Instruction::FPExt: - case Instruction::FPToUI: - case Instruction::FPToSI: - case Instruction::UIToFP: - case Instruction::SIToFP: - case Instruction::InsertElement: - case Instruction::ExtractElement: - case Instruction::ShuffleVector: - case Instruction::ExtractValue: - break; - case Instruction::ICmp: - // Comparing a pointer with null, or any other constant, isn't an - // interesting use, because we don't care what the pointer points to, or - // about the values of any other dynamic reference-counted pointers. - if (IsPotentialRetainableObjPtr(I->getOperand(1))) - return ARCInstKind::User; - break; - default: - // For anything else, check all the operands. - // Note that this includes both operands of a Store: while the first - // operand isn't actually being dereferenced, it is being stored to - // memory where we can no longer track who might read it and dereference - // it, so we have to consider it potentially used. - for (User::const_op_iterator OI = I->op_begin(), OE = I->op_end(); - OI != OE; ++OI) - if (IsPotentialRetainableObjPtr(*OI)) - return ARCInstKind::User; - } - } - - // Otherwise, it's totally inert for ARC purposes. - return ARCInstKind::None; -} - -/// Test if the given class is a kind of user. -bool llvm::objcarc::IsUser(ARCInstKind Class) { - switch (Class) { - case ARCInstKind::User: - case ARCInstKind::CallOrUser: - case ARCInstKind::IntrinsicUser: - return true; - case ARCInstKind::Retain: - case ARCInstKind::RetainRV: - case ARCInstKind::RetainBlock: - case ARCInstKind::Release: - case ARCInstKind::Autorelease: - case ARCInstKind::AutoreleaseRV: - case ARCInstKind::AutoreleasepoolPush: - case ARCInstKind::AutoreleasepoolPop: - case ARCInstKind::NoopCast: - case ARCInstKind::FusedRetainAutorelease: - case ARCInstKind::FusedRetainAutoreleaseRV: - case ARCInstKind::LoadWeakRetained: - case ARCInstKind::StoreWeak: - case ARCInstKind::InitWeak: - case ARCInstKind::LoadWeak: - case ARCInstKind::MoveWeak: - case ARCInstKind::CopyWeak: - case ARCInstKind::DestroyWeak: - case ARCInstKind::StoreStrong: - case ARCInstKind::Call: - case ARCInstKind::None: - case ARCInstKind::ClaimRV: - return false; - } - llvm_unreachable("covered switch isn't covered?"); -} - -/// Test if the given class is objc_retain or equivalent. -bool llvm::objcarc::IsRetain(ARCInstKind Class) { - switch (Class) { - case ARCInstKind::Retain: - case ARCInstKind::RetainRV: - return true; - // I believe we treat retain block as not a retain since it can copy its - // block. - case ARCInstKind::RetainBlock: - case ARCInstKind::Release: - case ARCInstKind::Autorelease: - case ARCInstKind::AutoreleaseRV: - case ARCInstKind::AutoreleasepoolPush: - case ARCInstKind::AutoreleasepoolPop: - case ARCInstKind::NoopCast: - case ARCInstKind::FusedRetainAutorelease: - case ARCInstKind::FusedRetainAutoreleaseRV: - case ARCInstKind::LoadWeakRetained: - case ARCInstKind::StoreWeak: - case ARCInstKind::InitWeak: - case ARCInstKind::LoadWeak: - case ARCInstKind::MoveWeak: - case ARCInstKind::CopyWeak: - case ARCInstKind::DestroyWeak: - case ARCInstKind::StoreStrong: - case ARCInstKind::IntrinsicUser: - case ARCInstKind::CallOrUser: - case ARCInstKind::Call: - case ARCInstKind::User: - case ARCInstKind::None: - case ARCInstKind::ClaimRV: - return false; - } - llvm_unreachable("covered switch isn't covered?"); -} - -/// Test if the given class is objc_autorelease or equivalent. -bool llvm::objcarc::IsAutorelease(ARCInstKind Class) { - switch (Class) { - case ARCInstKind::Autorelease: - case ARCInstKind::AutoreleaseRV: - return true; - case ARCInstKind::Retain: - case ARCInstKind::RetainRV: - case ARCInstKind::ClaimRV: - case ARCInstKind::RetainBlock: - case ARCInstKind::Release: - case ARCInstKind::AutoreleasepoolPush: - case ARCInstKind::AutoreleasepoolPop: - case ARCInstKind::NoopCast: - case ARCInstKind::FusedRetainAutorelease: - case ARCInstKind::FusedRetainAutoreleaseRV: - case ARCInstKind::LoadWeakRetained: - case ARCInstKind::StoreWeak: - case ARCInstKind::InitWeak: - case ARCInstKind::LoadWeak: - case ARCInstKind::MoveWeak: - case ARCInstKind::CopyWeak: - case ARCInstKind::DestroyWeak: - case ARCInstKind::StoreStrong: - case ARCInstKind::IntrinsicUser: - case ARCInstKind::CallOrUser: - case ARCInstKind::Call: - case ARCInstKind::User: - case ARCInstKind::None: - return false; - } - llvm_unreachable("covered switch isn't covered?"); -} - -/// Test if the given class represents instructions which return their -/// argument verbatim. -bool llvm::objcarc::IsForwarding(ARCInstKind Class) { - switch (Class) { - case ARCInstKind::Retain: - case ARCInstKind::RetainRV: - case ARCInstKind::ClaimRV: - case ARCInstKind::Autorelease: - case ARCInstKind::AutoreleaseRV: - case ARCInstKind::NoopCast: - return true; - case ARCInstKind::RetainBlock: - case ARCInstKind::Release: - case ARCInstKind::AutoreleasepoolPush: - case ARCInstKind::AutoreleasepoolPop: - case ARCInstKind::FusedRetainAutorelease: - case ARCInstKind::FusedRetainAutoreleaseRV: - case ARCInstKind::LoadWeakRetained: - case ARCInstKind::StoreWeak: - case ARCInstKind::InitWeak: - case ARCInstKind::LoadWeak: - case ARCInstKind::MoveWeak: - case ARCInstKind::CopyWeak: - case ARCInstKind::DestroyWeak: - case ARCInstKind::StoreStrong: - case ARCInstKind::IntrinsicUser: - case ARCInstKind::CallOrUser: - case ARCInstKind::Call: - case ARCInstKind::User: - case ARCInstKind::None: - return false; - } - llvm_unreachable("covered switch isn't covered?"); -} - -/// Test if the given class represents instructions which do nothing if -/// passed a null pointer. -bool llvm::objcarc::IsNoopOnNull(ARCInstKind Class) { - switch (Class) { - case ARCInstKind::Retain: - case ARCInstKind::RetainRV: - case ARCInstKind::ClaimRV: - case ARCInstKind::Release: - case ARCInstKind::Autorelease: - case ARCInstKind::AutoreleaseRV: - case ARCInstKind::RetainBlock: - return true; - case ARCInstKind::AutoreleasepoolPush: - case ARCInstKind::AutoreleasepoolPop: - case ARCInstKind::FusedRetainAutorelease: - case ARCInstKind::FusedRetainAutoreleaseRV: - case ARCInstKind::LoadWeakRetained: - case ARCInstKind::StoreWeak: - case ARCInstKind::InitWeak: - case ARCInstKind::LoadWeak: - case ARCInstKind::MoveWeak: - case ARCInstKind::CopyWeak: - case ARCInstKind::DestroyWeak: - case ARCInstKind::StoreStrong: - case ARCInstKind::IntrinsicUser: - case ARCInstKind::CallOrUser: - case ARCInstKind::Call: - case ARCInstKind::User: - case ARCInstKind::None: - case ARCInstKind::NoopCast: - return false; - } - llvm_unreachable("covered switch isn't covered?"); -} - -/// Test if the given class represents instructions which are always safe -/// to mark with the "tail" keyword. -bool llvm::objcarc::IsAlwaysTail(ARCInstKind Class) { - // ARCInstKind::RetainBlock may be given a stack argument. - switch (Class) { - case ARCInstKind::Retain: - case ARCInstKind::RetainRV: - case ARCInstKind::ClaimRV: - case ARCInstKind::AutoreleaseRV: - return true; - case ARCInstKind::Release: - case ARCInstKind::Autorelease: - case ARCInstKind::RetainBlock: - case ARCInstKind::AutoreleasepoolPush: - case ARCInstKind::AutoreleasepoolPop: - case ARCInstKind::FusedRetainAutorelease: - case ARCInstKind::FusedRetainAutoreleaseRV: - case ARCInstKind::LoadWeakRetained: - case ARCInstKind::StoreWeak: - case ARCInstKind::InitWeak: - case ARCInstKind::LoadWeak: - case ARCInstKind::MoveWeak: - case ARCInstKind::CopyWeak: - case ARCInstKind::DestroyWeak: - case ARCInstKind::StoreStrong: - case ARCInstKind::IntrinsicUser: - case ARCInstKind::CallOrUser: - case ARCInstKind::Call: - case ARCInstKind::User: - case ARCInstKind::None: - case ARCInstKind::NoopCast: - return false; - } - llvm_unreachable("covered switch isn't covered?"); -} - -/// Test if the given class represents instructions which are never safe -/// to mark with the "tail" keyword. -bool llvm::objcarc::IsNeverTail(ARCInstKind Class) { - /// It is never safe to tail call objc_autorelease since by tail calling - /// objc_autorelease: fast autoreleasing causing our object to be potentially - /// reclaimed from the autorelease pool which violates the semantics of - /// __autoreleasing types in ARC. - switch (Class) { - case ARCInstKind::Autorelease: - return true; - case ARCInstKind::Retain: - case ARCInstKind::RetainRV: - case ARCInstKind::ClaimRV: - case ARCInstKind::AutoreleaseRV: - case ARCInstKind::Release: - case ARCInstKind::RetainBlock: - case ARCInstKind::AutoreleasepoolPush: - case ARCInstKind::AutoreleasepoolPop: - case ARCInstKind::FusedRetainAutorelease: - case ARCInstKind::FusedRetainAutoreleaseRV: - case ARCInstKind::LoadWeakRetained: - case ARCInstKind::StoreWeak: - case ARCInstKind::InitWeak: - case ARCInstKind::LoadWeak: - case ARCInstKind::MoveWeak: - case ARCInstKind::CopyWeak: - case ARCInstKind::DestroyWeak: - case ARCInstKind::StoreStrong: - case ARCInstKind::IntrinsicUser: - case ARCInstKind::CallOrUser: - case ARCInstKind::Call: - case ARCInstKind::User: - case ARCInstKind::None: - case ARCInstKind::NoopCast: - return false; - } - llvm_unreachable("covered switch isn't covered?"); -} - -/// Test if the given class represents instructions which are always safe -/// to mark with the nounwind attribute. -bool llvm::objcarc::IsNoThrow(ARCInstKind Class) { - // objc_retainBlock is not nounwind because it calls user copy constructors - // which could theoretically throw. - switch (Class) { - case ARCInstKind::Retain: - case ARCInstKind::RetainRV: - case ARCInstKind::ClaimRV: - case ARCInstKind::Release: - case ARCInstKind::Autorelease: - case ARCInstKind::AutoreleaseRV: - case ARCInstKind::AutoreleasepoolPush: - case ARCInstKind::AutoreleasepoolPop: - return true; - case ARCInstKind::RetainBlock: - case ARCInstKind::FusedRetainAutorelease: - case ARCInstKind::FusedRetainAutoreleaseRV: - case ARCInstKind::LoadWeakRetained: - case ARCInstKind::StoreWeak: - case ARCInstKind::InitWeak: - case ARCInstKind::LoadWeak: - case ARCInstKind::MoveWeak: - case ARCInstKind::CopyWeak: - case ARCInstKind::DestroyWeak: - case ARCInstKind::StoreStrong: - case ARCInstKind::IntrinsicUser: - case ARCInstKind::CallOrUser: - case ARCInstKind::Call: - case ARCInstKind::User: - case ARCInstKind::None: - case ARCInstKind::NoopCast: - return false; - } - llvm_unreachable("covered switch isn't covered?"); -} - -/// Test whether the given instruction can autorelease any pointer or cause an -/// autoreleasepool pop. -/// -/// This means that it *could* interrupt the RV optimization. -bool llvm::objcarc::CanInterruptRV(ARCInstKind Class) { - switch (Class) { - case ARCInstKind::AutoreleasepoolPop: - case ARCInstKind::CallOrUser: - case ARCInstKind::Call: - case ARCInstKind::Autorelease: - case ARCInstKind::AutoreleaseRV: - case ARCInstKind::FusedRetainAutorelease: - case ARCInstKind::FusedRetainAutoreleaseRV: - return true; - case ARCInstKind::Retain: - case ARCInstKind::RetainRV: - case ARCInstKind::ClaimRV: - case ARCInstKind::Release: - case ARCInstKind::AutoreleasepoolPush: - case ARCInstKind::RetainBlock: - case ARCInstKind::LoadWeakRetained: - case ARCInstKind::StoreWeak: - case ARCInstKind::InitWeak: - case ARCInstKind::LoadWeak: - case ARCInstKind::MoveWeak: - case ARCInstKind::CopyWeak: - case ARCInstKind::DestroyWeak: - case ARCInstKind::StoreStrong: - case ARCInstKind::IntrinsicUser: - case ARCInstKind::User: - case ARCInstKind::None: - case ARCInstKind::NoopCast: - return false; - } - llvm_unreachable("covered switch isn't covered?"); -} - -bool llvm::objcarc::CanDecrementRefCount(ARCInstKind Kind) { - switch (Kind) { - case ARCInstKind::Retain: - case ARCInstKind::RetainRV: - case ARCInstKind::Autorelease: - case ARCInstKind::AutoreleaseRV: - case ARCInstKind::NoopCast: - case ARCInstKind::FusedRetainAutorelease: - case ARCInstKind::FusedRetainAutoreleaseRV: - case ARCInstKind::IntrinsicUser: - case ARCInstKind::User: - case ARCInstKind::None: - return false; - - // The cases below are conservative. - - // RetainBlock can result in user defined copy constructors being called - // implying releases may occur. - case ARCInstKind::RetainBlock: - case ARCInstKind::Release: - case ARCInstKind::AutoreleasepoolPush: - case ARCInstKind::AutoreleasepoolPop: - case ARCInstKind::LoadWeakRetained: - case ARCInstKind::StoreWeak: - case ARCInstKind::InitWeak: - case ARCInstKind::LoadWeak: - case ARCInstKind::MoveWeak: - case ARCInstKind::CopyWeak: - case ARCInstKind::DestroyWeak: - case ARCInstKind::StoreStrong: - case ARCInstKind::CallOrUser: - case ARCInstKind::Call: - case ARCInstKind::ClaimRV: - return true; - } - - llvm_unreachable("covered switch isn't covered?"); -} |
