llvm/llvm/include/llvm/Analysis/ObjCARCInstKind.h

//===- ObjCARCInstKind.h - ARC instruction equivalence classes --*- 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
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_OBJCARCINSTKIND_H
#define LLVM_ANALYSIS_OBJCARCINSTKIND_H

#include "llvm/IR/Instructions.h"

namespace llvm {
namespace objcarc {

/// \enum ARCInstKind
///
/// Equivalence classes of instructions in the ARC Model.
///
/// Since we do not have "instructions" to represent ARC concepts in LLVM IR,
/// we instead operate on equivalence classes of instructions.
///
/// TODO: This should be split into two enums: a runtime entry point enum
/// (possibly united with the ARCRuntimeEntrypoint class) and an enum that deals
/// with effects of instructions in the ARC model (which would handle the notion
/// of a User or CallOrUser).
enum class ARCInstKind {};

raw_ostream &operator<<(raw_ostream &OS, const ARCInstKind Class);

/// Test if the given class is a kind of user.
bool IsUser(ARCInstKind Class);

/// Test if the given class is objc_retain or equivalent.
bool IsRetain(ARCInstKind Class);

/// Test if the given class is objc_autorelease or equivalent.
bool IsAutorelease(ARCInstKind Class);

/// Test if the given class represents instructions which return their
/// argument verbatim.
bool IsForwarding(ARCInstKind Class);

/// Test if the given class represents instructions which do nothing if
/// passed a null pointer.
bool IsNoopOnNull(ARCInstKind Class);

/// Test if the given class represents instructions which do nothing if
/// passed a global variable.
bool IsNoopOnGlobal(ARCInstKind Class);

/// Test if the given class represents instructions which are always safe
/// to mark with the "tail" keyword.
bool IsAlwaysTail(ARCInstKind Class);

/// Test if the given class represents instructions which are never safe
/// to mark with the "tail" keyword.
bool IsNeverTail(ARCInstKind Class);

/// Test if the given class represents instructions which are always safe
/// to mark with the nounwind attribute.
bool IsNoThrow(ARCInstKind Class);

/// Test whether the given instruction can autorelease any pointer or cause an
/// autoreleasepool pop.
bool CanInterruptRV(ARCInstKind Class);

/// Determine if F is one of the special known Functions.  If it isn't,
/// return ARCInstKind::CallOrUser.
ARCInstKind GetFunctionClass(const Function *F);

/// Determine which objc runtime call instruction class V belongs to.
///
/// This is similar to GetARCInstKind except that it only detects objc
/// runtime calls. This allows it to be faster.
///
inline ARCInstKind GetBasicARCInstKind(const Value *V) {}

/// Map V to its ARCInstKind equivalence class.
ARCInstKind GetARCInstKind(const Value *V);

/// Returns false if conservatively we can prove that any instruction mapped to
/// this kind can not decrement ref counts. Returns true otherwise.
bool CanDecrementRefCount(ARCInstKind Kind);

} // end namespace objcarc
} // end namespace llvm

#endif