1 | //===- ARCRuntimeEntryPoints.h - ObjC ARC Optimization ----------*- 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 | /// \file |
10 | /// This file contains a class ARCRuntimeEntryPoints for use in |
11 | /// creating/managing references to entry points to the arc objective c runtime. |
12 | /// |
13 | /// WARNING: This file knows about certain library functions. It recognizes them |
14 | /// by name, and hardwires knowledge of their semantics. |
15 | /// |
16 | /// WARNING: This file knows about how certain Objective-C library functions are |
17 | /// used. Naive LLVM IR transformations which would otherwise be |
18 | /// behavior-preserving may break these assumptions. |
19 | // |
20 | //===----------------------------------------------------------------------===// |
21 | |
22 | #ifndef LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H |
23 | #define LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H |
24 | |
25 | #include "llvm/IR/Attributes.h" |
26 | #include "llvm/IR/Intrinsics.h" |
27 | #include "llvm/Support/ErrorHandling.h" |
28 | #include <cassert> |
29 | |
30 | namespace llvm { |
31 | |
32 | class Function; |
33 | class Module; |
34 | |
35 | namespace objcarc { |
36 | |
37 | enum class ARCRuntimeEntryPointKind { |
38 | AutoreleaseRV, |
39 | Release, |
40 | Retain, |
41 | RetainBlock, |
42 | Autorelease, |
43 | StoreStrong, |
44 | RetainRV, |
45 | ClaimRV, |
46 | UnsafeClaimRV, |
47 | RetainAutorelease, |
48 | RetainAutoreleaseRV, |
49 | }; |
50 | |
51 | /// Declarations for ObjC runtime functions and constants. These are initialized |
52 | /// lazily to avoid cluttering up the Module with unused declarations. |
53 | class ARCRuntimeEntryPoints { |
54 | public: |
55 | ARCRuntimeEntryPoints() = default; |
56 | |
57 | void init(Module *M) { |
58 | TheModule = M; |
59 | AutoreleaseRV = nullptr; |
60 | Release = nullptr; |
61 | Retain = nullptr; |
62 | RetainBlock = nullptr; |
63 | Autorelease = nullptr; |
64 | StoreStrong = nullptr; |
65 | RetainRV = nullptr; |
66 | ClaimRV = nullptr; |
67 | UnsafeClaimRV = nullptr; |
68 | RetainAutorelease = nullptr; |
69 | RetainAutoreleaseRV = nullptr; |
70 | } |
71 | |
72 | Function *get(ARCRuntimeEntryPointKind kind) { |
73 | assert(TheModule != nullptr && "Not initialized." ); |
74 | |
75 | switch (kind) { |
76 | case ARCRuntimeEntryPointKind::AutoreleaseRV: |
77 | return getIntrinsicEntryPoint(Decl&: AutoreleaseRV, |
78 | IntID: Intrinsic::objc_autoreleaseReturnValue); |
79 | case ARCRuntimeEntryPointKind::Release: |
80 | return getIntrinsicEntryPoint(Decl&: Release, IntID: Intrinsic::objc_release); |
81 | case ARCRuntimeEntryPointKind::Retain: |
82 | return getIntrinsicEntryPoint(Decl&: Retain, IntID: Intrinsic::objc_retain); |
83 | case ARCRuntimeEntryPointKind::RetainBlock: |
84 | return getIntrinsicEntryPoint(Decl&: RetainBlock, IntID: Intrinsic::objc_retainBlock); |
85 | case ARCRuntimeEntryPointKind::Autorelease: |
86 | return getIntrinsicEntryPoint(Decl&: Autorelease, IntID: Intrinsic::objc_autorelease); |
87 | case ARCRuntimeEntryPointKind::StoreStrong: |
88 | return getIntrinsicEntryPoint(Decl&: StoreStrong, IntID: Intrinsic::objc_storeStrong); |
89 | case ARCRuntimeEntryPointKind::RetainRV: |
90 | return getIntrinsicEntryPoint(Decl&: RetainRV, |
91 | IntID: Intrinsic::objc_retainAutoreleasedReturnValue); |
92 | case ARCRuntimeEntryPointKind::ClaimRV: |
93 | return getIntrinsicEntryPoint( |
94 | Decl&: ClaimRV, IntID: Intrinsic::objc_claimAutoreleasedReturnValue); |
95 | case ARCRuntimeEntryPointKind::UnsafeClaimRV: |
96 | return getIntrinsicEntryPoint( |
97 | Decl&: UnsafeClaimRV, IntID: Intrinsic::objc_unsafeClaimAutoreleasedReturnValue); |
98 | case ARCRuntimeEntryPointKind::RetainAutorelease: |
99 | return getIntrinsicEntryPoint(Decl&: RetainAutorelease, |
100 | IntID: Intrinsic::objc_retainAutorelease); |
101 | case ARCRuntimeEntryPointKind::RetainAutoreleaseRV: |
102 | return getIntrinsicEntryPoint(Decl&: RetainAutoreleaseRV, |
103 | IntID: Intrinsic::objc_retainAutoreleaseReturnValue); |
104 | } |
105 | |
106 | llvm_unreachable("Switch should be a covered switch." ); |
107 | } |
108 | |
109 | private: |
110 | /// Cached reference to the module which we will insert declarations into. |
111 | Module *TheModule = nullptr; |
112 | |
113 | /// Declaration for ObjC runtime function objc_autoreleaseReturnValue. |
114 | Function *AutoreleaseRV = nullptr; |
115 | |
116 | /// Declaration for ObjC runtime function objc_release. |
117 | Function *Release = nullptr; |
118 | |
119 | /// Declaration for ObjC runtime function objc_retain. |
120 | Function *Retain = nullptr; |
121 | |
122 | /// Declaration for ObjC runtime function objc_retainBlock. |
123 | Function *RetainBlock = nullptr; |
124 | |
125 | /// Declaration for ObjC runtime function objc_autorelease. |
126 | Function *Autorelease = nullptr; |
127 | |
128 | /// Declaration for objc_storeStrong(). |
129 | Function *StoreStrong = nullptr; |
130 | |
131 | /// Declaration for objc_retainAutoreleasedReturnValue(). |
132 | Function *RetainRV = nullptr; |
133 | |
134 | /// Declaration for objc_claimAutoreleasedReturnValue(). |
135 | Function *ClaimRV = nullptr; |
136 | |
137 | /// Declaration for objc_unsafeClaimAutoreleasedReturnValue(). |
138 | Function *UnsafeClaimRV = nullptr; |
139 | |
140 | /// Declaration for objc_retainAutorelease(). |
141 | Function *RetainAutorelease = nullptr; |
142 | |
143 | /// Declaration for objc_retainAutoreleaseReturnValue(). |
144 | Function *RetainAutoreleaseRV = nullptr; |
145 | |
146 | Function *getIntrinsicEntryPoint(Function *&Decl, Intrinsic::ID IntID) { |
147 | if (Decl) |
148 | return Decl; |
149 | |
150 | return Decl = Intrinsic::getOrInsertDeclaration(M: TheModule, id: IntID); |
151 | } |
152 | }; |
153 | |
154 | } // end namespace objcarc |
155 | |
156 | } // end namespace llvm |
157 | |
158 | #endif // LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H |
159 | |