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 30namespace llvm { 31 32class Function; 33class Module; 34 35namespace objcarc { 36 37enum 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. 52class ARCRuntimeEntryPoints { 53public: 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 104private: 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