xref: /freebsd-src/contrib/llvm-project/llvm/lib/Transforms/ObjCARC/ARCRuntimeEntryPoints.h (revision 04eeddc0aa8e0a417a16eaf9d7d095207f4a8623)
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