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 34namespace llvm { 35 36class Function; 37class LLVMContext; 38 39namespace objcarc { 40 41enum 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. 55class ARCRuntimeEntryPoints { 56public: 57 ARCRuntimeEntryPoints() = default; 58 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 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 103private: 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 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