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