blob: 0b92d8b4835601aaf798fbc4075d0174eb84a785 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- ObjCARCInstKind.h - ARC instruction equivalence classes --*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef LLVM_ANALYSIS_OBJCARCINSTKIND_H
11#define LLVM_ANALYSIS_OBJCARCINSTKIND_H
12
13#include "llvm/IR/Function.h"
14#include "llvm/IR/Instructions.h"
15
16namespace llvm {
17namespace objcarc {
18
19/// \enum ARCInstKind
20///
Andrew Scullcdfcccc2018-10-05 20:58:37 +010021/// Equivalence classes of instructions in the ARC Model.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010022///
23/// Since we do not have "instructions" to represent ARC concepts in LLVM IR,
24/// we instead operate on equivalence classes of instructions.
25///
26/// TODO: This should be split into two enums: a runtime entry point enum
27/// (possibly united with the ARCRuntimeEntrypoint class) and an enum that deals
28/// with effects of instructions in the ARC model (which would handle the notion
29/// of a User or CallOrUser).
30enum class ARCInstKind {
31 Retain, ///< objc_retain
32 RetainRV, ///< objc_retainAutoreleasedReturnValue
33 ClaimRV, ///< objc_unsafeClaimAutoreleasedReturnValue
34 RetainBlock, ///< objc_retainBlock
35 Release, ///< objc_release
36 Autorelease, ///< objc_autorelease
37 AutoreleaseRV, ///< objc_autoreleaseReturnValue
38 AutoreleasepoolPush, ///< objc_autoreleasePoolPush
39 AutoreleasepoolPop, ///< objc_autoreleasePoolPop
40 NoopCast, ///< objc_retainedObject, etc.
41 FusedRetainAutorelease, ///< objc_retainAutorelease
42 FusedRetainAutoreleaseRV, ///< objc_retainAutoreleaseReturnValue
43 LoadWeakRetained, ///< objc_loadWeakRetained (primitive)
44 StoreWeak, ///< objc_storeWeak (primitive)
45 InitWeak, ///< objc_initWeak (derived)
46 LoadWeak, ///< objc_loadWeak (derived)
47 MoveWeak, ///< objc_moveWeak (derived)
48 CopyWeak, ///< objc_copyWeak (derived)
49 DestroyWeak, ///< objc_destroyWeak (derived)
50 StoreStrong, ///< objc_storeStrong (derived)
51 IntrinsicUser, ///< clang.arc.use
52 CallOrUser, ///< could call objc_release and/or "use" pointers
53 Call, ///< could call objc_release
54 User, ///< could "use" a pointer
55 None ///< anything that is inert from an ARC perspective.
56};
57
58raw_ostream &operator<<(raw_ostream &OS, const ARCInstKind Class);
59
Andrew Scullcdfcccc2018-10-05 20:58:37 +010060/// Test if the given class is a kind of user.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010061bool IsUser(ARCInstKind Class);
62
Andrew Scullcdfcccc2018-10-05 20:58:37 +010063/// Test if the given class is objc_retain or equivalent.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010064bool IsRetain(ARCInstKind Class);
65
Andrew Scullcdfcccc2018-10-05 20:58:37 +010066/// Test if the given class is objc_autorelease or equivalent.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010067bool IsAutorelease(ARCInstKind Class);
68
Andrew Scullcdfcccc2018-10-05 20:58:37 +010069/// Test if the given class represents instructions which return their
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010070/// argument verbatim.
71bool IsForwarding(ARCInstKind Class);
72
Andrew Scullcdfcccc2018-10-05 20:58:37 +010073/// Test if the given class represents instructions which do nothing if
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010074/// passed a null pointer.
75bool IsNoopOnNull(ARCInstKind Class);
76
Andrew Scullcdfcccc2018-10-05 20:58:37 +010077/// Test if the given class represents instructions which are always safe
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010078/// to mark with the "tail" keyword.
79bool IsAlwaysTail(ARCInstKind Class);
80
Andrew Scullcdfcccc2018-10-05 20:58:37 +010081/// Test if the given class represents instructions which are never safe
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010082/// to mark with the "tail" keyword.
83bool IsNeverTail(ARCInstKind Class);
84
Andrew Scullcdfcccc2018-10-05 20:58:37 +010085/// Test if the given class represents instructions which are always safe
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010086/// to mark with the nounwind attribute.
87bool IsNoThrow(ARCInstKind Class);
88
89/// Test whether the given instruction can autorelease any pointer or cause an
90/// autoreleasepool pop.
91bool CanInterruptRV(ARCInstKind Class);
92
Andrew Scullcdfcccc2018-10-05 20:58:37 +010093/// Determine if F is one of the special known Functions. If it isn't,
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010094/// return ARCInstKind::CallOrUser.
95ARCInstKind GetFunctionClass(const Function *F);
96
Andrew Scullcdfcccc2018-10-05 20:58:37 +010097/// Determine which objc runtime call instruction class V belongs to.
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010098///
99/// This is similar to GetARCInstKind except that it only detects objc
100/// runtime calls. This allows it to be faster.
101///
102inline ARCInstKind GetBasicARCInstKind(const Value *V) {
103 if (const CallInst *CI = dyn_cast<CallInst>(V)) {
104 if (const Function *F = CI->getCalledFunction())
105 return GetFunctionClass(F);
106 // Otherwise, be conservative.
107 return ARCInstKind::CallOrUser;
108 }
109
110 // Otherwise, be conservative.
111 return isa<InvokeInst>(V) ? ARCInstKind::CallOrUser : ARCInstKind::User;
112}
113
114/// Map V to its ARCInstKind equivalence class.
115ARCInstKind GetARCInstKind(const Value *V);
116
117/// Returns false if conservatively we can prove that any instruction mapped to
118/// this kind can not decrement ref counts. Returns true otherwise.
119bool CanDecrementRefCount(ARCInstKind Kind);
120
121} // end namespace objcarc
122} // end namespace llvm
123
124#endif