Home | History | Annotate | Line # | Download | only in ObjCARC
      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 
     30 namespace llvm {
     31 
     32 class Function;
     33 class Module;
     34 
     35 namespace objcarc {
     36 
     37 enum class ARCRuntimeEntryPointKind {
     38   AutoreleaseRV,
     39   Release,
     40   Retain,
     41   RetainBlock,
     42   Autorelease,
     43   StoreStrong,
     44   RetainRV,
     45   ClaimRV,
     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.
     52 class ARCRuntimeEntryPoints {
     53 public:
     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     ClaimRV = 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::ClaimRV:
     91       return getIntrinsicEntryPoint(
     92           ClaimRV, 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 
    104 private:
    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 *ClaimRV = 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