10b57cec5SDimitry Andric //===- ARCRuntimeEntryPoints.h - ObjC ARC Optimization ----------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// This file contains a class ARCRuntimeEntryPoints for use in 110b57cec5SDimitry Andric /// creating/managing references to entry points to the arc objective c runtime. 120b57cec5SDimitry Andric /// 130b57cec5SDimitry Andric /// WARNING: This file knows about certain library functions. It recognizes them 140b57cec5SDimitry Andric /// by name, and hardwires knowledge of their semantics. 150b57cec5SDimitry Andric /// 160b57cec5SDimitry Andric /// WARNING: This file knows about how certain Objective-C library functions are 170b57cec5SDimitry Andric /// used. Naive LLVM IR transformations which would otherwise be 180b57cec5SDimitry Andric /// behavior-preserving may break these assumptions. 190b57cec5SDimitry Andric // 200b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric #ifndef LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H 230b57cec5SDimitry Andric #define LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric #include "llvm/IR/Attributes.h" 260b57cec5SDimitry Andric #include "llvm/IR/Intrinsics.h" 270b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h" 280b57cec5SDimitry Andric #include <cassert> 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric namespace llvm { 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric class Function; 335ffd83dbSDimitry Andric class Module; 340b57cec5SDimitry Andric 350b57cec5SDimitry Andric namespace objcarc { 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric enum class ARCRuntimeEntryPointKind { 380b57cec5SDimitry Andric AutoreleaseRV, 390b57cec5SDimitry Andric Release, 400b57cec5SDimitry Andric Retain, 410b57cec5SDimitry Andric RetainBlock, 420b57cec5SDimitry Andric Autorelease, 430b57cec5SDimitry Andric StoreStrong, 440b57cec5SDimitry Andric RetainRV, 45*04eeddc0SDimitry Andric UnsafeClaimRV, 460b57cec5SDimitry Andric RetainAutorelease, 470b57cec5SDimitry Andric RetainAutoreleaseRV, 480b57cec5SDimitry Andric }; 490b57cec5SDimitry Andric 500b57cec5SDimitry Andric /// Declarations for ObjC runtime functions and constants. These are initialized 510b57cec5SDimitry Andric /// lazily to avoid cluttering up the Module with unused declarations. 520b57cec5SDimitry Andric class ARCRuntimeEntryPoints { 530b57cec5SDimitry Andric public: 540b57cec5SDimitry Andric ARCRuntimeEntryPoints() = default; 550b57cec5SDimitry Andric init(Module * M)560b57cec5SDimitry Andric void init(Module *M) { 570b57cec5SDimitry Andric TheModule = M; 580b57cec5SDimitry Andric AutoreleaseRV = nullptr; 590b57cec5SDimitry Andric Release = nullptr; 600b57cec5SDimitry Andric Retain = nullptr; 610b57cec5SDimitry Andric RetainBlock = nullptr; 620b57cec5SDimitry Andric Autorelease = nullptr; 630b57cec5SDimitry Andric StoreStrong = nullptr; 640b57cec5SDimitry Andric RetainRV = nullptr; 65*04eeddc0SDimitry Andric UnsafeClaimRV = nullptr; 660b57cec5SDimitry Andric RetainAutorelease = nullptr; 670b57cec5SDimitry Andric RetainAutoreleaseRV = nullptr; 680b57cec5SDimitry Andric } 690b57cec5SDimitry Andric get(ARCRuntimeEntryPointKind kind)700b57cec5SDimitry Andric Function *get(ARCRuntimeEntryPointKind kind) { 710b57cec5SDimitry Andric assert(TheModule != nullptr && "Not initialized."); 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric switch (kind) { 740b57cec5SDimitry Andric case ARCRuntimeEntryPointKind::AutoreleaseRV: 750b57cec5SDimitry Andric return getIntrinsicEntryPoint(AutoreleaseRV, 760b57cec5SDimitry Andric Intrinsic::objc_autoreleaseReturnValue); 770b57cec5SDimitry Andric case ARCRuntimeEntryPointKind::Release: 780b57cec5SDimitry Andric return getIntrinsicEntryPoint(Release, Intrinsic::objc_release); 790b57cec5SDimitry Andric case ARCRuntimeEntryPointKind::Retain: 800b57cec5SDimitry Andric return getIntrinsicEntryPoint(Retain, Intrinsic::objc_retain); 810b57cec5SDimitry Andric case ARCRuntimeEntryPointKind::RetainBlock: 820b57cec5SDimitry Andric return getIntrinsicEntryPoint(RetainBlock, Intrinsic::objc_retainBlock); 830b57cec5SDimitry Andric case ARCRuntimeEntryPointKind::Autorelease: 840b57cec5SDimitry Andric return getIntrinsicEntryPoint(Autorelease, Intrinsic::objc_autorelease); 850b57cec5SDimitry Andric case ARCRuntimeEntryPointKind::StoreStrong: 860b57cec5SDimitry Andric return getIntrinsicEntryPoint(StoreStrong, Intrinsic::objc_storeStrong); 870b57cec5SDimitry Andric case ARCRuntimeEntryPointKind::RetainRV: 880b57cec5SDimitry Andric return getIntrinsicEntryPoint(RetainRV, 890b57cec5SDimitry Andric Intrinsic::objc_retainAutoreleasedReturnValue); 90*04eeddc0SDimitry Andric case ARCRuntimeEntryPointKind::UnsafeClaimRV: 91fe6060f1SDimitry Andric return getIntrinsicEntryPoint( 92*04eeddc0SDimitry Andric UnsafeClaimRV, Intrinsic::objc_unsafeClaimAutoreleasedReturnValue); 930b57cec5SDimitry Andric case ARCRuntimeEntryPointKind::RetainAutorelease: 940b57cec5SDimitry Andric return getIntrinsicEntryPoint(RetainAutorelease, 950b57cec5SDimitry Andric Intrinsic::objc_retainAutorelease); 960b57cec5SDimitry Andric case ARCRuntimeEntryPointKind::RetainAutoreleaseRV: 970b57cec5SDimitry Andric return getIntrinsicEntryPoint(RetainAutoreleaseRV, 980b57cec5SDimitry Andric Intrinsic::objc_retainAutoreleaseReturnValue); 990b57cec5SDimitry Andric } 1000b57cec5SDimitry Andric 1010b57cec5SDimitry Andric llvm_unreachable("Switch should be a covered switch."); 1020b57cec5SDimitry Andric } 1030b57cec5SDimitry Andric 1040b57cec5SDimitry Andric private: 1050b57cec5SDimitry Andric /// Cached reference to the module which we will insert declarations into. 1060b57cec5SDimitry Andric Module *TheModule = nullptr; 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric /// Declaration for ObjC runtime function objc_autoreleaseReturnValue. 1090b57cec5SDimitry Andric Function *AutoreleaseRV = nullptr; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric /// Declaration for ObjC runtime function objc_release. 1120b57cec5SDimitry Andric Function *Release = nullptr; 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric /// Declaration for ObjC runtime function objc_retain. 1150b57cec5SDimitry Andric Function *Retain = nullptr; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric /// Declaration for ObjC runtime function objc_retainBlock. 1180b57cec5SDimitry Andric Function *RetainBlock = nullptr; 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric /// Declaration for ObjC runtime function objc_autorelease. 1210b57cec5SDimitry Andric Function *Autorelease = nullptr; 1220b57cec5SDimitry Andric 1230b57cec5SDimitry Andric /// Declaration for objc_storeStrong(). 1240b57cec5SDimitry Andric Function *StoreStrong = nullptr; 1250b57cec5SDimitry Andric 1260b57cec5SDimitry Andric /// Declaration for objc_retainAutoreleasedReturnValue(). 1270b57cec5SDimitry Andric Function *RetainRV = nullptr; 1280b57cec5SDimitry Andric 129fe6060f1SDimitry Andric /// Declaration for objc_unsafeClaimAutoreleasedReturnValue(). 130*04eeddc0SDimitry Andric Function *UnsafeClaimRV = nullptr; 131fe6060f1SDimitry Andric 1320b57cec5SDimitry Andric /// Declaration for objc_retainAutorelease(). 1330b57cec5SDimitry Andric Function *RetainAutorelease = nullptr; 1340b57cec5SDimitry Andric 1350b57cec5SDimitry Andric /// Declaration for objc_retainAutoreleaseReturnValue(). 1360b57cec5SDimitry Andric Function *RetainAutoreleaseRV = nullptr; 1370b57cec5SDimitry Andric getIntrinsicEntryPoint(Function * & Decl,Intrinsic::ID IntID)1380b57cec5SDimitry Andric Function *getIntrinsicEntryPoint(Function *&Decl, Intrinsic::ID IntID) { 1390b57cec5SDimitry Andric if (Decl) 1400b57cec5SDimitry Andric return Decl; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric return Decl = Intrinsic::getDeclaration(TheModule, IntID); 1430b57cec5SDimitry Andric } 1440b57cec5SDimitry Andric }; 1450b57cec5SDimitry Andric 1460b57cec5SDimitry Andric } // end namespace objcarc 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric } // end namespace llvm 1490b57cec5SDimitry Andric 1500b57cec5SDimitry Andric #endif // LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H 151