]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/include/llvm/Analysis/ObjCARCInstKind.h
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / include / llvm / Analysis / ObjCARCInstKind.h
1 //===- ObjCARCInstKind.h - ARC instruction equivalence classes --*- C++ -*-===//
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
9 #ifndef LLVM_ANALYSIS_OBJCARCINSTKIND_H
10 #define LLVM_ANALYSIS_OBJCARCINSTKIND_H
11
12 #include "llvm/IR/Function.h"
13 #include "llvm/IR/Intrinsics.h"
14 #include "llvm/IR/Instructions.h"
15
16 namespace llvm {
17 namespace objcarc {
18
19 /// \enum ARCInstKind
20 ///
21 /// Equivalence classes of instructions in the ARC Model.
22 ///
23 /// Since we do not have "instructions" to represent ARC concepts in LLVM IR,
24 /// we instead operate on equivalence classes of instructions.
25 ///
26 /// TODO: This should be split into two enums: a runtime entry point enum
27 /// (possibly united with the ARCRuntimeEntrypoint class) and an enum that deals
28 /// with effects of instructions in the ARC model (which would handle the notion
29 /// of a User or CallOrUser).
30 enum class ARCInstKind {
31   Retain,                   ///< objc_retain
32   RetainRV,                 ///< objc_retainAutoreleasedReturnValue
33   ClaimRV,                  ///< objc_unsafeClaimAutoreleasedReturnValue
34   RetainBlock,              ///< objc_retainBlock
35   Release,                  ///< objc_release
36   Autorelease,              ///< objc_autorelease
37   AutoreleaseRV,            ///< objc_autoreleaseReturnValue
38   AutoreleasepoolPush,      ///< objc_autoreleasePoolPush
39   AutoreleasepoolPop,       ///< objc_autoreleasePoolPop
40   NoopCast,                 ///< objc_retainedObject, etc.
41   FusedRetainAutorelease,   ///< objc_retainAutorelease
42   FusedRetainAutoreleaseRV, ///< objc_retainAutoreleaseReturnValue
43   LoadWeakRetained,         ///< objc_loadWeakRetained (primitive)
44   StoreWeak,                ///< objc_storeWeak (primitive)
45   InitWeak,                 ///< objc_initWeak (derived)
46   LoadWeak,                 ///< objc_loadWeak (derived)
47   MoveWeak,                 ///< objc_moveWeak (derived)
48   CopyWeak,                 ///< objc_copyWeak (derived)
49   DestroyWeak,              ///< objc_destroyWeak (derived)
50   StoreStrong,              ///< objc_storeStrong (derived)
51   IntrinsicUser,            ///< llvm.objc.clang.arc.use
52   CallOrUser,               ///< could call objc_release and/or "use" pointers
53   Call,                     ///< could call objc_release
54   User,                     ///< could "use" a pointer
55   None                      ///< anything that is inert from an ARC perspective.
56 };
57
58 raw_ostream &operator<<(raw_ostream &OS, const ARCInstKind Class);
59
60 /// Test if the given class is a kind of user.
61 bool IsUser(ARCInstKind Class);
62
63 /// Test if the given class is objc_retain or equivalent.
64 bool IsRetain(ARCInstKind Class);
65
66 /// Test if the given class is objc_autorelease or equivalent.
67 bool IsAutorelease(ARCInstKind Class);
68
69 /// Test if the given class represents instructions which return their
70 /// argument verbatim.
71 bool IsForwarding(ARCInstKind Class);
72
73 /// Test if the given class represents instructions which do nothing if
74 /// passed a null pointer.
75 bool IsNoopOnNull(ARCInstKind Class);
76
77 /// Test if the given class represents instructions which do nothing if
78 /// passed a global variable.
79 bool IsNoopOnGlobal(ARCInstKind Class);
80
81 /// Test if the given class represents instructions which are always safe
82 /// to mark with the "tail" keyword.
83 bool IsAlwaysTail(ARCInstKind Class);
84
85 /// Test if the given class represents instructions which are never safe
86 /// to mark with the "tail" keyword.
87 bool IsNeverTail(ARCInstKind Class);
88
89 /// Test if the given class represents instructions which are always safe
90 /// to mark with the nounwind attribute.
91 bool IsNoThrow(ARCInstKind Class);
92
93 /// Test whether the given instruction can autorelease any pointer or cause an
94 /// autoreleasepool pop.
95 bool CanInterruptRV(ARCInstKind Class);
96
97 /// Determine if F is one of the special known Functions.  If it isn't,
98 /// return ARCInstKind::CallOrUser.
99 ARCInstKind GetFunctionClass(const Function *F);
100
101 /// Determine which objc runtime call instruction class V belongs to.
102 ///
103 /// This is similar to GetARCInstKind except that it only detects objc
104 /// runtime calls. This allows it to be faster.
105 ///
106 inline ARCInstKind GetBasicARCInstKind(const Value *V) {
107   if (const CallInst *CI = dyn_cast<CallInst>(V)) {
108     if (const Function *F = CI->getCalledFunction())
109       return GetFunctionClass(F);
110     // Otherwise, be conservative.
111     return ARCInstKind::CallOrUser;
112   }
113
114   // Otherwise, be conservative.
115   return isa<InvokeInst>(V) ? ARCInstKind::CallOrUser : ARCInstKind::User;
116 }
117
118 /// Map V to its ARCInstKind equivalence class.
119 ARCInstKind GetARCInstKind(const Value *V);
120
121 /// Returns false if conservatively we can prove that any instruction mapped to
122 /// this kind can not decrement ref counts. Returns true otherwise.
123 bool CanDecrementRefCount(ARCInstKind Kind);
124
125 } // end namespace objcarc
126 } // end namespace llvm
127
128 #endif