Line data Source code
1 : //===- ObjCARCInstKind.h - ARC instruction equivalence classes --*- C++ -*-===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 :
10 : #ifndef LLVM_ANALYSIS_OBJCARCINSTKIND_H
11 : #define LLVM_ANALYSIS_OBJCARCINSTKIND_H
12 :
13 : #include "llvm/IR/Function.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, ///< 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 are always safe
78 : /// to mark with the "tail" keyword.
79 : bool IsAlwaysTail(ARCInstKind Class);
80 :
81 : /// Test if the given class represents instructions which are never safe
82 : /// to mark with the "tail" keyword.
83 : bool IsNeverTail(ARCInstKind Class);
84 :
85 : /// Test if the given class represents instructions which are always safe
86 : /// to mark with the nounwind attribute.
87 : bool IsNoThrow(ARCInstKind Class);
88 :
89 : /// Test whether the given instruction can autorelease any pointer or cause an
90 : /// autoreleasepool pop.
91 : bool CanInterruptRV(ARCInstKind Class);
92 :
93 : /// Determine if F is one of the special known Functions. If it isn't,
94 : /// return ARCInstKind::CallOrUser.
95 : ARCInstKind GetFunctionClass(const Function *F);
96 :
97 : /// Determine which objc runtime call instruction class V belongs to.
98 : ///
99 : /// This is similar to GetARCInstKind except that it only detects objc
100 : /// runtime calls. This allows it to be faster.
101 : ///
102 19939 : inline ARCInstKind GetBasicARCInstKind(const Value *V) {
103 : if (const CallInst *CI = dyn_cast<CallInst>(V)) {
104 : if (const Function *F = CI->getCalledFunction())
105 5056 : return GetFunctionClass(F);
106 : // Otherwise, be conservative.
107 : return ARCInstKind::CallOrUser;
108 : }
109 :
110 : // Otherwise, be conservative.
111 : return isa<InvokeInst>(V) ? ARCInstKind::CallOrUser : ARCInstKind::User;
112 : }
113 :
114 : /// Map V to its ARCInstKind equivalence class.
115 : ARCInstKind GetARCInstKind(const Value *V);
116 :
117 : /// Returns false if conservatively we can prove that any instruction mapped to
118 : /// this kind can not decrement ref counts. Returns true otherwise.
119 : bool CanDecrementRefCount(ARCInstKind Kind);
120 :
121 : } // end namespace objcarc
122 : } // end namespace llvm
123 :
124 : #endif
|