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