123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- #pragma once
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-parameter"
- #endif
- //===- 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 {
- Retain, ///< objc_retain
- RetainRV, ///< objc_retainAutoreleasedReturnValue
- ClaimRV, ///< objc_unsafeClaimAutoreleasedReturnValue
- RetainBlock, ///< objc_retainBlock
- Release, ///< objc_release
- Autorelease, ///< objc_autorelease
- AutoreleaseRV, ///< objc_autoreleaseReturnValue
- AutoreleasepoolPush, ///< objc_autoreleasePoolPush
- AutoreleasepoolPop, ///< objc_autoreleasePoolPop
- NoopCast, ///< objc_retainedObject, etc.
- FusedRetainAutorelease, ///< objc_retainAutorelease
- FusedRetainAutoreleaseRV, ///< objc_retainAutoreleaseReturnValue
- LoadWeakRetained, ///< objc_loadWeakRetained (primitive)
- StoreWeak, ///< objc_storeWeak (primitive)
- InitWeak, ///< objc_initWeak (derived)
- LoadWeak, ///< objc_loadWeak (derived)
- MoveWeak, ///< objc_moveWeak (derived)
- CopyWeak, ///< objc_copyWeak (derived)
- DestroyWeak, ///< objc_destroyWeak (derived)
- StoreStrong, ///< objc_storeStrong (derived)
- IntrinsicUser, ///< llvm.objc.clang.arc.use
- CallOrUser, ///< could call objc_release and/or "use" pointers
- Call, ///< could call objc_release
- User, ///< could "use" a pointer
- None ///< anything that is inert from an ARC perspective.
- };
- 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) {
- if (const CallInst *CI = dyn_cast<CallInst>(V)) {
- if (const Function *F = CI->getCalledFunction())
- return GetFunctionClass(F);
- // Otherwise, be conservative.
- return ARCInstKind::CallOrUser;
- }
- // Otherwise, be conservative.
- return isa<InvokeInst>(V) ? ARCInstKind::CallOrUser : ARCInstKind::User;
- }
- /// 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
- #ifdef __GNUC__
- #pragma GCC diagnostic pop
- #endif
|