Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:15

0001 //===- ObjCARCInstKind.h - ARC instruction equivalence classes --*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_ANALYSIS_OBJCARCINSTKIND_H
0010 #define LLVM_ANALYSIS_OBJCARCINSTKIND_H
0011 
0012 #include "llvm/IR/Instructions.h"
0013 
0014 namespace llvm {
0015 namespace objcarc {
0016 
0017 /// \enum ARCInstKind
0018 ///
0019 /// Equivalence classes of instructions in the ARC Model.
0020 ///
0021 /// Since we do not have "instructions" to represent ARC concepts in LLVM IR,
0022 /// we instead operate on equivalence classes of instructions.
0023 ///
0024 /// TODO: This should be split into two enums: a runtime entry point enum
0025 /// (possibly united with the ARCRuntimeEntrypoint class) and an enum that deals
0026 /// with effects of instructions in the ARC model (which would handle the notion
0027 /// of a User or CallOrUser).
0028 enum class ARCInstKind {
0029   Retain,                   ///< objc_retain
0030   RetainRV,                 ///< objc_retainAutoreleasedReturnValue
0031   UnsafeClaimRV,            ///< objc_unsafeClaimAutoreleasedReturnValue
0032   RetainBlock,              ///< objc_retainBlock
0033   Release,                  ///< objc_release
0034   Autorelease,              ///< objc_autorelease
0035   AutoreleaseRV,            ///< objc_autoreleaseReturnValue
0036   AutoreleasepoolPush,      ///< objc_autoreleasePoolPush
0037   AutoreleasepoolPop,       ///< objc_autoreleasePoolPop
0038   NoopCast,                 ///< objc_retainedObject, etc.
0039   FusedRetainAutorelease,   ///< objc_retainAutorelease
0040   FusedRetainAutoreleaseRV, ///< objc_retainAutoreleaseReturnValue
0041   LoadWeakRetained,         ///< objc_loadWeakRetained (primitive)
0042   StoreWeak,                ///< objc_storeWeak (primitive)
0043   InitWeak,                 ///< objc_initWeak (derived)
0044   LoadWeak,                 ///< objc_loadWeak (derived)
0045   MoveWeak,                 ///< objc_moveWeak (derived)
0046   CopyWeak,                 ///< objc_copyWeak (derived)
0047   DestroyWeak,              ///< objc_destroyWeak (derived)
0048   StoreStrong,              ///< objc_storeStrong (derived)
0049   IntrinsicUser,            ///< llvm.objc.clang.arc.use
0050   CallOrUser,               ///< could call objc_release and/or "use" pointers
0051   Call,                     ///< could call objc_release
0052   User,                     ///< could "use" a pointer
0053   None                      ///< anything that is inert from an ARC perspective.
0054 };
0055 
0056 raw_ostream &operator<<(raw_ostream &OS, const ARCInstKind Class);
0057 
0058 /// Test if the given class is a kind of user.
0059 bool IsUser(ARCInstKind Class);
0060 
0061 /// Test if the given class is objc_retain or equivalent.
0062 bool IsRetain(ARCInstKind Class);
0063 
0064 /// Test if the given class is objc_autorelease or equivalent.
0065 bool IsAutorelease(ARCInstKind Class);
0066 
0067 /// Test if the given class represents instructions which return their
0068 /// argument verbatim.
0069 bool IsForwarding(ARCInstKind Class);
0070 
0071 /// Test if the given class represents instructions which do nothing if
0072 /// passed a null pointer.
0073 bool IsNoopOnNull(ARCInstKind Class);
0074 
0075 /// Test if the given class represents instructions which do nothing if
0076 /// passed a global variable.
0077 bool IsNoopOnGlobal(ARCInstKind Class);
0078 
0079 /// Test if the given class represents instructions which are always safe
0080 /// to mark with the "tail" keyword.
0081 bool IsAlwaysTail(ARCInstKind Class);
0082 
0083 /// Test if the given class represents instructions which are never safe
0084 /// to mark with the "tail" keyword.
0085 bool IsNeverTail(ARCInstKind Class);
0086 
0087 /// Test if the given class represents instructions which are always safe
0088 /// to mark with the nounwind attribute.
0089 bool IsNoThrow(ARCInstKind Class);
0090 
0091 /// Test whether the given instruction can autorelease any pointer or cause an
0092 /// autoreleasepool pop.
0093 bool CanInterruptRV(ARCInstKind Class);
0094 
0095 /// Determine if F is one of the special known Functions.  If it isn't,
0096 /// return ARCInstKind::CallOrUser.
0097 ARCInstKind GetFunctionClass(const Function *F);
0098 
0099 /// Determine which objc runtime call instruction class V belongs to.
0100 ///
0101 /// This is similar to GetARCInstKind except that it only detects objc
0102 /// runtime calls. This allows it to be faster.
0103 ///
0104 inline ARCInstKind GetBasicARCInstKind(const Value *V) {
0105   if (const CallInst *CI = dyn_cast<CallInst>(V)) {
0106     if (const Function *F = CI->getCalledFunction())
0107       return GetFunctionClass(F);
0108     // Otherwise, be conservative.
0109     return ARCInstKind::CallOrUser;
0110   }
0111 
0112   // Otherwise, be conservative.
0113   return isa<InvokeInst>(V) ? ARCInstKind::CallOrUser : ARCInstKind::User;
0114 }
0115 
0116 /// Map V to its ARCInstKind equivalence class.
0117 ARCInstKind GetARCInstKind(const Value *V);
0118 
0119 /// Returns false if conservatively we can prove that any instruction mapped to
0120 /// this kind can not decrement ref counts. Returns true otherwise.
0121 bool CanDecrementRefCount(ARCInstKind Kind);
0122 
0123 } // end namespace objcarc
0124 } // end namespace llvm
0125 
0126 #endif