//===- ARCInstKind.cpp - ObjC ARC Optimization ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \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/Analysis/ObjCARCAnalysisUtils.h" #include "llvm/IR/Intrinsics.h" usingnamespacellvm; usingnamespacellvm::objcarc; raw_ostream &llvm::objcarc::operator<<(raw_ostream &OS, const ARCInstKind Class) { … } ARCInstKind llvm::objcarc::GetFunctionClass(const Function *F) { … } // A list of intrinsics that we know do not use objc pointers or decrement // ref counts. static bool isInertIntrinsic(unsigned ID) { … } // A list of intrinsics that we know do not use objc pointers or decrement // ref counts. static bool isUseOnlyIntrinsic(unsigned ID) { … } /// Determine what kind of construct V is. ARCInstKind llvm::objcarc::GetARCInstKind(const Value *V) { … } /// Test if the given class is a kind of user. bool llvm::objcarc::IsUser(ARCInstKind Class) { … } /// Test if the given class is objc_retain or equivalent. bool llvm::objcarc::IsRetain(ARCInstKind Class) { … } /// Test if the given class is objc_autorelease or equivalent. bool llvm::objcarc::IsAutorelease(ARCInstKind Class) { … } /// Test if the given class represents instructions which return their /// argument verbatim. bool llvm::objcarc::IsForwarding(ARCInstKind Class) { … } /// Test if the given class represents instructions which do nothing if /// passed a null pointer. bool llvm::objcarc::IsNoopOnNull(ARCInstKind Class) { … } /// Test if the given class represents instructions which do nothing if /// passed a global variable. bool llvm::objcarc::IsNoopOnGlobal(ARCInstKind Class) { … } /// Test if the given class represents instructions which are always safe /// to mark with the "tail" keyword. bool llvm::objcarc::IsAlwaysTail(ARCInstKind Class) { … } /// Test if the given class represents instructions which are never safe /// to mark with the "tail" keyword. bool llvm::objcarc::IsNeverTail(ARCInstKind Class) { … } /// Test if the given class represents instructions which are always safe /// to mark with the nounwind attribute. bool llvm::objcarc::IsNoThrow(ARCInstKind Class) { … } /// 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) { … } bool llvm::objcarc::CanDecrementRefCount(ARCInstKind Kind) { … }