143 lines
4.7 KiB
C
143 lines
4.7 KiB
C
|
//===- ARCRuntimeEntryPoints.h - ObjC ARC Optimization ----------*- C++ -*-===//
|
||
|
//
|
||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
//
|
||
|
/// \file
|
||
|
/// This file contains a class ARCRuntimeEntryPoints for use in
|
||
|
/// creating/managing references to entry points to the arc objective c runtime.
|
||
|
///
|
||
|
/// WARNING: This file knows about certain library functions. It recognizes them
|
||
|
/// by name, and hardwires knowledge of their semantics.
|
||
|
///
|
||
|
/// WARNING: This file knows about how certain Objective-C library functions are
|
||
|
/// used. Naive LLVM IR transformations which would otherwise be
|
||
|
/// behavior-preserving may break these assumptions.
|
||
|
//
|
||
|
//===----------------------------------------------------------------------===//
|
||
|
|
||
|
#ifndef LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H
|
||
|
#define LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H
|
||
|
|
||
|
#include "llvm/IR/Attributes.h"
|
||
|
#include "llvm/IR/Intrinsics.h"
|
||
|
#include "llvm/Support/ErrorHandling.h"
|
||
|
#include <cassert>
|
||
|
|
||
|
namespace llvm {
|
||
|
|
||
|
class Function;
|
||
|
class Module;
|
||
|
|
||
|
namespace objcarc {
|
||
|
|
||
|
enum class ARCRuntimeEntryPointKind {
|
||
|
AutoreleaseRV,
|
||
|
Release,
|
||
|
Retain,
|
||
|
RetainBlock,
|
||
|
Autorelease,
|
||
|
StoreStrong,
|
||
|
RetainRV,
|
||
|
RetainAutorelease,
|
||
|
RetainAutoreleaseRV,
|
||
|
};
|
||
|
|
||
|
/// Declarations for ObjC runtime functions and constants. These are initialized
|
||
|
/// lazily to avoid cluttering up the Module with unused declarations.
|
||
|
class ARCRuntimeEntryPoints {
|
||
|
public:
|
||
|
ARCRuntimeEntryPoints() = default;
|
||
|
|
||
|
void init(Module *M) {
|
||
|
TheModule = M;
|
||
|
AutoreleaseRV = nullptr;
|
||
|
Release = nullptr;
|
||
|
Retain = nullptr;
|
||
|
RetainBlock = nullptr;
|
||
|
Autorelease = nullptr;
|
||
|
StoreStrong = nullptr;
|
||
|
RetainRV = nullptr;
|
||
|
RetainAutorelease = nullptr;
|
||
|
RetainAutoreleaseRV = nullptr;
|
||
|
}
|
||
|
|
||
|
Function *get(ARCRuntimeEntryPointKind kind) {
|
||
|
assert(TheModule != nullptr && "Not initialized.");
|
||
|
|
||
|
switch (kind) {
|
||
|
case ARCRuntimeEntryPointKind::AutoreleaseRV:
|
||
|
return getIntrinsicEntryPoint(AutoreleaseRV,
|
||
|
Intrinsic::objc_autoreleaseReturnValue);
|
||
|
case ARCRuntimeEntryPointKind::Release:
|
||
|
return getIntrinsicEntryPoint(Release, Intrinsic::objc_release);
|
||
|
case ARCRuntimeEntryPointKind::Retain:
|
||
|
return getIntrinsicEntryPoint(Retain, Intrinsic::objc_retain);
|
||
|
case ARCRuntimeEntryPointKind::RetainBlock:
|
||
|
return getIntrinsicEntryPoint(RetainBlock, Intrinsic::objc_retainBlock);
|
||
|
case ARCRuntimeEntryPointKind::Autorelease:
|
||
|
return getIntrinsicEntryPoint(Autorelease, Intrinsic::objc_autorelease);
|
||
|
case ARCRuntimeEntryPointKind::StoreStrong:
|
||
|
return getIntrinsicEntryPoint(StoreStrong, Intrinsic::objc_storeStrong);
|
||
|
case ARCRuntimeEntryPointKind::RetainRV:
|
||
|
return getIntrinsicEntryPoint(RetainRV,
|
||
|
Intrinsic::objc_retainAutoreleasedReturnValue);
|
||
|
case ARCRuntimeEntryPointKind::RetainAutorelease:
|
||
|
return getIntrinsicEntryPoint(RetainAutorelease,
|
||
|
Intrinsic::objc_retainAutorelease);
|
||
|
case ARCRuntimeEntryPointKind::RetainAutoreleaseRV:
|
||
|
return getIntrinsicEntryPoint(RetainAutoreleaseRV,
|
||
|
Intrinsic::objc_retainAutoreleaseReturnValue);
|
||
|
}
|
||
|
|
||
|
llvm_unreachable("Switch should be a covered switch.");
|
||
|
}
|
||
|
|
||
|
private:
|
||
|
/// Cached reference to the module which we will insert declarations into.
|
||
|
Module *TheModule = nullptr;
|
||
|
|
||
|
/// Declaration for ObjC runtime function objc_autoreleaseReturnValue.
|
||
|
Function *AutoreleaseRV = nullptr;
|
||
|
|
||
|
/// Declaration for ObjC runtime function objc_release.
|
||
|
Function *Release = nullptr;
|
||
|
|
||
|
/// Declaration for ObjC runtime function objc_retain.
|
||
|
Function *Retain = nullptr;
|
||
|
|
||
|
/// Declaration for ObjC runtime function objc_retainBlock.
|
||
|
Function *RetainBlock = nullptr;
|
||
|
|
||
|
/// Declaration for ObjC runtime function objc_autorelease.
|
||
|
Function *Autorelease = nullptr;
|
||
|
|
||
|
/// Declaration for objc_storeStrong().
|
||
|
Function *StoreStrong = nullptr;
|
||
|
|
||
|
/// Declaration for objc_retainAutoreleasedReturnValue().
|
||
|
Function *RetainRV = nullptr;
|
||
|
|
||
|
/// Declaration for objc_retainAutorelease().
|
||
|
Function *RetainAutorelease = nullptr;
|
||
|
|
||
|
/// Declaration for objc_retainAutoreleaseReturnValue().
|
||
|
Function *RetainAutoreleaseRV = nullptr;
|
||
|
|
||
|
Function *getIntrinsicEntryPoint(Function *&Decl, Intrinsic::ID IntID) {
|
||
|
if (Decl)
|
||
|
return Decl;
|
||
|
|
||
|
return Decl = Intrinsic::getDeclaration(TheModule, IntID);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
} // end namespace objcarc
|
||
|
|
||
|
} // end namespace llvm
|
||
|
|
||
|
#endif // LLVM_LIB_TRANSFORMS_OBJCARC_ARCRUNTIMEENTRYPOINTS_H
|