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 UnsafeClaimRV, 46 RetainAutorelease, 47 RetainAutoreleaseRV, 48 }; 49 50 /// Declarations for ObjC runtime functions and constants. These are initialized 51 /// lazily to avoid cluttering up the Module with unused declarations. 52 class ARCRuntimeEntryPoints { 53 public: 54 ARCRuntimeEntryPoints() = default; 55 56 void init(Module *M) { 57 TheModule = M; 58 AutoreleaseRV = nullptr; 59 Release = nullptr; 60 Retain = nullptr; 61 RetainBlock = nullptr; 62 Autorelease = nullptr; 63 StoreStrong = nullptr; 64 RetainRV = nullptr; 65 UnsafeClaimRV = nullptr; 66 RetainAutorelease = nullptr; 67 RetainAutoreleaseRV = nullptr; 68 } 69 70 Function *get(ARCRuntimeEntryPointKind kind) { 71 assert(TheModule != nullptr && "Not initialized."); 72 73 switch (kind) { 74 case ARCRuntimeEntryPointKind::AutoreleaseRV: 75 return getIntrinsicEntryPoint(AutoreleaseRV, 76 Intrinsic::objc_autoreleaseReturnValue); 77 case ARCRuntimeEntryPointKind::Release: 78 return getIntrinsicEntryPoint(Release, Intrinsic::objc_release); 79 case ARCRuntimeEntryPointKind::Retain: 80 return getIntrinsicEntryPoint(Retain, Intrinsic::objc_retain); 81 case ARCRuntimeEntryPointKind::RetainBlock: 82 return getIntrinsicEntryPoint(RetainBlock, Intrinsic::objc_retainBlock); 83 case ARCRuntimeEntryPointKind::Autorelease: 84 return getIntrinsicEntryPoint(Autorelease, Intrinsic::objc_autorelease); 85 case ARCRuntimeEntryPointKind::StoreStrong: 86 return getIntrinsicEntryPoint(StoreStrong, Intrinsic::objc_storeStrong); 87 case ARCRuntimeEntryPointKind::RetainRV: 88 return getIntrinsicEntryPoint(RetainRV, 89 Intrinsic::objc_retainAutoreleasedReturnValue); 90 case ARCRuntimeEntryPointKind::UnsafeClaimRV: 91 return getIntrinsicEntryPoint( 92 UnsafeClaimRV, Intrinsic::objc_unsafeClaimAutoreleasedReturnValue); 93 case ARCRuntimeEntryPointKind::RetainAutorelease: 94 return getIntrinsicEntryPoint(RetainAutorelease, 95 Intrinsic::objc_retainAutorelease); 96 case ARCRuntimeEntryPointKind::RetainAutoreleaseRV: 97 return getIntrinsicEntryPoint(RetainAutoreleaseRV, 98 Intrinsic::objc_retainAutoreleaseReturnValue); 99 } 100 101 llvm_unreachable("Switch should be a covered switch."); 102 } 103 104 private: 105 /// Cached reference to the module which we will insert declarations into. 106 Module *TheModule = nullptr; 107 108 /// Declaration for ObjC runtime function objc_autoreleaseReturnValue. 109 Function *AutoreleaseRV = nullptr; 110 111 /// Declaration for ObjC runtime function objc_release. 112 Function *Release = nullptr; 113 114 /// Declaration for ObjC runtime function objc_retain. 115 Function *Retain = nullptr; 116 117 /// Declaration for ObjC runtime function objc_retainBlock. 118 Function *RetainBlock = nullptr; 119 120 /// Declaration for ObjC runtime function objc_autorelease. 121 Function *Autorelease = nullptr; 122 123 /// Declaration for objc_storeStrong(). 124 Function *StoreStrong = nullptr; 125 126 /// Declaration for objc_retainAutoreleasedReturnValue(). 127 Function *RetainRV = nullptr; 128 129 /// Declaration for objc_unsafeClaimAutoreleasedReturnValue(). 130 Function *UnsafeClaimRV = nullptr; 131 132 /// Declaration for objc_retainAutorelease(). 133 Function *RetainAutorelease = nullptr; 134 135 /// Declaration for objc_retainAutoreleaseReturnValue(). 136 Function *RetainAutoreleaseRV = nullptr; 137 138 Function *getIntrinsicEntryPoint(Function *&Decl, Intrinsic::ID IntID) { 139 if (Decl) 140 return Decl; 141 142 return Decl = Intrinsic::getDeclaration(TheModule, IntID); 143 } 144 }; 145 146 } // end namespace objcarc 147 148 } // end namespace llvm 149 150 #endif // LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H 151