LLVM  3.7.0
PtrState.h
Go to the documentation of this file.
1 //===--- PtrState.h - ARC State for a Ptr -------------------*- 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 // This file contains declarations for the ARC state associated with a ptr. It
11 // is only used by the ARC Sequence Dataflow computation. By separating this
12 // from the actual dataflow, it is easier to consider the mechanics of the ARC
13 // optimization separate from the actual predicates being used.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #ifndef LLVM_LIB_TRANSFORMS_OBJCARC_PTRSTATE_H
18 #define LLVM_LIB_TRANSFORMS_OBJCARC_PTRSTATE_H
19 
20 #include "ARCInstKind.h"
21 #include "llvm/ADT/SmallPtrSet.h"
22 #include "llvm/IR/Instruction.h"
23 #include "llvm/IR/Value.h"
25 #include "llvm/Support/Debug.h"
26 
27 namespace llvm {
28 namespace objcarc {
29 
30 class ARCMDKindCache;
31 class ProvenanceAnalysis;
32 
33 /// \enum Sequence
34 ///
35 /// \brief A sequence of states that a pointer may go through in which an
36 /// objc_retain and objc_release are actually needed.
37 enum Sequence {
39  S_Retain, ///< objc_retain(x).
40  S_CanRelease, ///< foo(x) -- x could possibly see a ref count decrement.
41  S_Use, ///< any use of x.
42  S_Stop, ///< like S_Release, but code motion is stopped.
43  S_Release, ///< objc_release(x).
44  S_MovableRelease ///< objc_release(x), !clang.imprecise_release.
45 };
46 
49 
50 /// \brief Unidirectional information about either a
51 /// retain-decrement-use-release sequence or release-use-decrement-retain
52 /// reverse sequence.
53 struct RRInfo {
54  /// After an objc_retain, the reference count of the referenced
55  /// object is known to be positive. Similarly, before an objc_release, the
56  /// reference count of the referenced object is known to be positive. If
57  /// there are retain-release pairs in code regions where the retain count
58  /// is known to be positive, they can be eliminated, regardless of any side
59  /// effects between them.
60  ///
61  /// Also, a retain+release pair nested within another retain+release
62  /// pair all on the known same pointer value can be eliminated, regardless
63  /// of any intervening side effects.
64  ///
65  /// KnownSafe is true when either of these conditions is satisfied.
66  bool KnownSafe;
67 
68  /// True of the objc_release calls are all marked with the "tail" keyword.
70 
71  /// If the Calls are objc_release calls and they all have a
72  /// clang.imprecise_release tag, this is the metadata tag.
74 
75  /// For a top-down sequence, the set of objc_retains or
76  /// objc_retainBlocks. For bottom-up, the set of objc_releases.
78 
79  /// The set of optimal insert positions for moving calls in the opposite
80  /// sequence.
82 
83  /// If this is true, we cannot perform code motion but can still remove
84  /// retain/release pairs.
86 
90 
91  void clear();
92 
93  /// Conservatively merge the two RRInfo. Returns true if a partial merge has
94  /// occurred, false otherwise.
95  bool Merge(const RRInfo &Other);
96 };
97 
98 /// \brief This class summarizes several per-pointer runtime properties which
99 /// are propogated through the flow graph.
100 class PtrState {
101 protected:
102  /// True if the reference count is known to be incremented.
104 
105  /// True if we've seen an opportunity for partial RR elimination, such as
106  /// pushing calls into a CFG triangle or into one side of a CFG diamond.
107  bool Partial;
108 
109  /// The current position in the sequence.
110  unsigned char Seq : 8;
111 
112  /// Unidirectional information about the current sequence.
114 
116 
117 public:
118  bool IsKnownSafe() const { return RRI.KnownSafe; }
119 
120  void SetKnownSafe(const bool NewValue) { RRI.KnownSafe = NewValue; }
121 
122  bool IsTailCallRelease() const { return RRI.IsTailCallRelease; }
123 
124  void SetTailCallRelease(const bool NewValue) {
125  RRI.IsTailCallRelease = NewValue;
126  }
127 
129  return RRI.ReleaseMetadata != nullptr;
130  }
131 
132  const MDNode *GetReleaseMetadata() const { return RRI.ReleaseMetadata; }
133 
134  void SetReleaseMetadata(MDNode *NewValue) { RRI.ReleaseMetadata = NewValue; }
135 
136  bool IsCFGHazardAfflicted() const { return RRI.CFGHazardAfflicted; }
137 
138  void SetCFGHazardAfflicted(const bool NewValue) {
139  RRI.CFGHazardAfflicted = NewValue;
140  }
141 
144 
146 
147  void SetSeq(Sequence NewSeq);
148 
149  Sequence GetSeq() const { return static_cast<Sequence>(Seq); }
150 
152 
153  void ResetSequenceProgress(Sequence NewSeq);
154  void Merge(const PtrState &Other, bool TopDown);
155 
156  void InsertCall(Instruction *I) { RRI.Calls.insert(I); }
157 
159 
161 
162  bool HasReverseInsertPts() const { return !RRI.ReverseInsertPts.empty(); }
163 
164  const RRInfo &GetRRInfo() const { return RRI; }
165 };
166 
169 
170  /// (Re-)Initialize this bottom up pointer returning true if we detected a
171  /// pointer with nested releases.
172  bool InitBottomUp(ARCMDKindCache &Cache, Instruction *I);
173 
174  /// Return true if this set of releases can be paired with a release. Modifies
175  /// state appropriately to reflect that the matching occured if it is
176  /// successful.
177  ///
178  /// It is assumed that one has already checked that the RCIdentity of the
179  /// retain and the RCIdentity of this ptr state are the same.
180  bool MatchWithRetain();
181 
182  void HandlePotentialUse(BasicBlock *BB, Instruction *Inst, const Value *Ptr,
183  ProvenanceAnalysis &PA, ARCInstKind Class);
184  bool HandlePotentialAlterRefCount(Instruction *Inst, const Value *Ptr,
185  ProvenanceAnalysis &PA, ARCInstKind Class);
186 };
187 
190 
191  /// (Re-)Initialize this bottom up pointer returning true if we detected a
192  /// pointer with nested releases.
194 
195  /// Return true if this set of retains can be paired with the given
196  /// release. Modifies state appropriately to reflect that the matching
197  /// occured.
199 
200  void HandlePotentialUse(Instruction *Inst, const Value *Ptr,
201  ProvenanceAnalysis &PA, ARCInstKind Class);
202 
203  bool HandlePotentialAlterRefCount(Instruction *Inst, const Value *Ptr,
204  ProvenanceAnalysis &PA, ARCInstKind Class);
205 };
206 
207 } // end namespace objcarc
208 } // end namespace llvm
209 
210 #endif
bool Merge(const RRInfo &Other)
Conservatively merge the two RRInfo.
Definition: PtrState.cpp:91
SmallPtrSet< Instruction *, 2 > Calls
For a top-down sequence, the set of objc_retains or objc_retainBlocks.
Definition: PtrState.h:77
void ClearReverseInsertPts()
Definition: PtrState.h:160
bool HandlePotentialAlterRefCount(Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, ARCInstKind Class)
Definition: PtrState.cpp:215
any use of x.
Definition: PtrState.h:41
bool MatchWithRelease(ARCMDKindCache &Cache, Instruction *Release)
Return true if this set of retains can be paired with the given release.
Definition: PtrState.cpp:321
Metadata node.
Definition: Metadata.h:740
void SetKnownSafe(const bool NewValue)
Definition: PtrState.h:120
bool HasReverseInsertPts() const
Definition: PtrState.h:162
SmallPtrSet< Instruction *, 2 > ReverseInsertPts
The set of optimal insert positions for moving calls in the opposite sequence.
Definition: PtrState.h:81
bool IsKnownSafe() const
Definition: PtrState.h:118
unsigned char Seq
The current position in the sequence.
Definition: PtrState.h:110
void InsertReverseInsertPt(Instruction *I)
Definition: PtrState.h:158
void InsertCall(Instruction *I)
Definition: PtrState.h:156
This class summarizes several per-pointer runtime properties which are propogated through the flow gr...
Definition: PtrState.h:100
#define false
Definition: ConvertUTF.c:65
ELFYAML::ELF_STO Other
Definition: ELFYAML.cpp:591
bool IsTailCallRelease
True of the objc_release calls are all marked with the "tail" keyword.
Definition: PtrState.h:69
bool InitBottomUp(ARCMDKindCache &Cache, Instruction *I)
(Re-)Initialize this bottom up pointer returning true if we detected a pointer with nested releases...
Definition: PtrState.cpp:165
void ClearKnownPositiveRefCount()
Definition: PtrState.cpp:121
void HandlePotentialUse(BasicBlock *BB, Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, ARCInstKind Class)
Definition: PtrState.cpp:243
const RRInfo & GetRRInfo() const
Definition: PtrState.h:164
Unidirectional information about either a retain-decrement-use-release sequence or release-use-decrem...
Definition: PtrState.h:53
raw_ostream & operator<<(raw_ostream &OS, const ARCInstKind Class)
Definition: ARCInstKind.cpp:28
const MDNode * GetReleaseMetadata() const
Definition: PtrState.h:132
Sequence GetSeq() const
Definition: PtrState.h:149
void HandlePotentialUse(Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, ARCInstKind Class)
Definition: PtrState.cpp:383
RRInfo RRI
Unidirectional information about the current sequence.
Definition: PtrState.h:113
LLVM Basic Block Representation.
Definition: BasicBlock.h:65
bool IsCFGHazardAfflicted() const
Definition: PtrState.h:136
bool KnownPositiveRefCount
True if the reference count is known to be incremented.
Definition: PtrState.h:103
void Merge(const PtrState &Other, bool TopDown)
Definition: PtrState.cpp:138
like S_Release, but code motion is stopped.
Definition: PtrState.h:42
#define LLVM_ATTRIBUTE_UNUSED
Definition: Compiler.h:142
A cache of MDKinds used by various ARC optimizations.
bool MatchWithRetain()
Return true if this set of releases can be paired with a release.
Definition: PtrState.cpp:191
bool IsTailCallRelease() const
Definition: PtrState.h:122
void ResetSequenceProgress(Sequence NewSeq)
Definition: PtrState.cpp:131
bool CFGHazardAfflicted
If this is true, we cannot perform code motion but can still remove retain/release pairs...
Definition: PtrState.h:85
objc_release(x), !clang.imprecise_release.
Definition: PtrState.h:44
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
Definition: SmallPtrSet.h:299
objc_release(x).
Definition: PtrState.h:43
void SetReleaseMetadata(MDNode *NewValue)
Definition: PtrState.h:134
bool Partial
True if we've seen an opportunity for partial RR elimination, such as pushing calls into a CFG triang...
Definition: PtrState.h:107
ARCInstKind
Equivalence classes of instructions in the ARC Model.
Definition: ARCInstKind.h:30
bool HandlePotentialAlterRefCount(Instruction *Inst, const Value *Ptr, ProvenanceAnalysis &PA, ARCInstKind Class)
Definition: PtrState.cpp:350
objc_retain(x).
Definition: PtrState.h:39
MDNode * ReleaseMetadata
If the Calls are objc_release calls and they all have a clang.imprecise_release tag, this is the metadata tag.
Definition: PtrState.h:73
void SetTailCallRelease(const bool NewValue)
Definition: PtrState.h:124
void ClearSequenceProgress()
Definition: PtrState.h:151
#define I(x, y, z)
Definition: MD5.cpp:54
Sequence
A sequence of states that a pointer may go through in which an objc_retain and objc_release are actua...
Definition: PtrState.h:37
void SetSeq(Sequence NewSeq)
Definition: PtrState.cpp:126
bool IsTrackingImpreciseReleases() const
Definition: PtrState.h:128
void SetCFGHazardAfflicted(const bool NewValue)
Definition: PtrState.h:138
const ARM::ArchExtKind Kind
LLVM Value Representation.
Definition: Value.h:69
foo(x) – x could possibly see a ref count decrement.
Definition: PtrState.h:40
bool KnownSafe
After an objc_retain, the reference count of the referenced object is known to be positive...
Definition: PtrState.h:66
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
This is similar to BasicAliasAnalysis, and it uses many of the same techniques, except it uses specia...
bool InitTopDown(ARCInstKind Kind, Instruction *I)
(Re-)Initialize this bottom up pointer returning true if we detected a pointer with nested releases...
Definition: PtrState.cpp:296
bool HasKnownPositiveRefCount() const
Definition: PtrState.h:145