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