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