175 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8//9/// \file10/// This file contains a class ARCRuntimeEntryPoints for use in11/// creating/managing references to entry points to the arc objective c runtime.12///13/// WARNING: This file knows about certain library functions. It recognizes them14/// by name, and hardwires knowledge of their semantics.15///16/// WARNING: This file knows about how certain Objective-C library functions are17/// used. Naive LLVM IR transformations which would otherwise be18/// behavior-preserving may break these assumptions.19//20//===----------------------------------------------------------------------===//21 22#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H23#define LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H24 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 ClaimRV,46 UnsafeClaimRV,47 RetainAutorelease,48 RetainAutoreleaseRV,49 AutoreleasePoolPush,50 AutoreleasePoolPop,51};52 53/// Declarations for ObjC runtime functions and constants. These are initialized54/// 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 ClaimRV = nullptr;69 UnsafeClaimRV = nullptr;70 RetainAutorelease = nullptr;71 RetainAutoreleaseRV = nullptr;72 AutoreleasePoolPush = nullptr;73 AutoreleasePoolPop = nullptr;74 }75 76 Function *get(ARCRuntimeEntryPointKind kind) {77 assert(TheModule != nullptr && "Not initialized.");78 79 switch (kind) {80 case ARCRuntimeEntryPointKind::AutoreleaseRV:81 return getIntrinsicEntryPoint(AutoreleaseRV,82 Intrinsic::objc_autoreleaseReturnValue);83 case ARCRuntimeEntryPointKind::Release:84 return getIntrinsicEntryPoint(Release, Intrinsic::objc_release);85 case ARCRuntimeEntryPointKind::Retain:86 return getIntrinsicEntryPoint(Retain, Intrinsic::objc_retain);87 case ARCRuntimeEntryPointKind::RetainBlock:88 return getIntrinsicEntryPoint(RetainBlock, Intrinsic::objc_retainBlock);89 case ARCRuntimeEntryPointKind::Autorelease:90 return getIntrinsicEntryPoint(Autorelease, Intrinsic::objc_autorelease);91 case ARCRuntimeEntryPointKind::StoreStrong:92 return getIntrinsicEntryPoint(StoreStrong, Intrinsic::objc_storeStrong);93 case ARCRuntimeEntryPointKind::RetainRV:94 return getIntrinsicEntryPoint(RetainRV,95 Intrinsic::objc_retainAutoreleasedReturnValue);96 case ARCRuntimeEntryPointKind::ClaimRV:97 return getIntrinsicEntryPoint(98 ClaimRV, Intrinsic::objc_claimAutoreleasedReturnValue);99 case ARCRuntimeEntryPointKind::UnsafeClaimRV:100 return getIntrinsicEntryPoint(101 UnsafeClaimRV, Intrinsic::objc_unsafeClaimAutoreleasedReturnValue);102 case ARCRuntimeEntryPointKind::RetainAutorelease:103 return getIntrinsicEntryPoint(RetainAutorelease,104 Intrinsic::objc_retainAutorelease);105 case ARCRuntimeEntryPointKind::RetainAutoreleaseRV:106 return getIntrinsicEntryPoint(RetainAutoreleaseRV,107 Intrinsic::objc_retainAutoreleaseReturnValue);108 case ARCRuntimeEntryPointKind::AutoreleasePoolPush:109 return getIntrinsicEntryPoint(AutoreleasePoolPush,110 Intrinsic::objc_autoreleasePoolPush);111 case ARCRuntimeEntryPointKind::AutoreleasePoolPop:112 return getIntrinsicEntryPoint(AutoreleasePoolPop,113 Intrinsic::objc_autoreleasePoolPop);114 }115 116 llvm_unreachable("Switch should be a covered switch.");117 }118 119private:120 /// Cached reference to the module which we will insert declarations into.121 Module *TheModule = nullptr;122 123 /// Declaration for ObjC runtime function objc_autoreleaseReturnValue.124 Function *AutoreleaseRV = nullptr;125 126 /// Declaration for ObjC runtime function objc_release.127 Function *Release = nullptr;128 129 /// Declaration for ObjC runtime function objc_retain.130 Function *Retain = nullptr;131 132 /// Declaration for ObjC runtime function objc_retainBlock.133 Function *RetainBlock = nullptr;134 135 /// Declaration for ObjC runtime function objc_autorelease.136 Function *Autorelease = nullptr;137 138 /// Declaration for objc_storeStrong().139 Function *StoreStrong = nullptr;140 141 /// Declaration for objc_retainAutoreleasedReturnValue().142 Function *RetainRV = nullptr;143 144 /// Declaration for objc_claimAutoreleasedReturnValue().145 Function *ClaimRV = nullptr;146 147 /// Declaration for objc_unsafeClaimAutoreleasedReturnValue().148 Function *UnsafeClaimRV = nullptr;149 150 /// Declaration for objc_retainAutorelease().151 Function *RetainAutorelease = nullptr;152 153 /// Declaration for objc_retainAutoreleaseReturnValue().154 Function *RetainAutoreleaseRV = nullptr;155 156 /// Declaration for objc_autoreleasePoolPush().157 Function *AutoreleasePoolPush = nullptr;158 159 /// Declaration for objc_autoreleasePoolPop().160 Function *AutoreleasePoolPop = nullptr;161 162 Function *getIntrinsicEntryPoint(Function *&Decl, Intrinsic::ID IntID) {163 if (Decl)164 return Decl;165 166 return Decl = Intrinsic::getOrInsertDeclaration(TheModule, IntID);167 }168};169 170} // end namespace objcarc171 172} // end namespace llvm173 174#endif // LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H175