1//===- 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/Instructions.h"
14#include "llvm/IR/Function.h"
15
16namespace llvm {
17namespace objcarc {
18
19/// \enum ARCInstKind
20///
21/// \brief Equivalence classes of instructions in the ARC Model.
22///
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
60/// \brief Test if the given class is a kind of user.
61bool IsUser(ARCInstKind Class);
62
63/// \brief Test if the given class is objc_retain or equivalent.
64bool IsRetain(ARCInstKind Class);
65
66/// \brief Test if the given class is objc_autorelease or equivalent.
67bool IsAutorelease(ARCInstKind Class);
68
69/// \brief Test if the given class represents instructions which return their
70/// argument verbatim.
71bool IsForwarding(ARCInstKind Class);
72
73/// \brief Test if the given class represents instructions which do nothing if
74/// passed a null pointer.
75bool IsNoopOnNull(ARCInstKind Class);
76
77/// \brief Test if the given class represents instructions which are always safe
78/// to mark with the "tail" keyword.
79bool IsAlwaysTail(ARCInstKind Class);
80
81/// \brief Test if the given class represents instructions which are never safe
82/// to mark with the "tail" keyword.
83bool IsNeverTail(ARCInstKind Class);
84
85/// \brief Test if the given class represents instructions which are always safe
86/// 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
93/// \brief Determine if F is one of the special known Functions.  If it isn't,
94/// return ARCInstKind::CallOrUser.
95ARCInstKind GetFunctionClass(const Function *F);
96
97/// \brief Determine which objc runtime call instruction class V belongs to.
98///
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
125