Fix build error.
[oota-llvm.git] / lib / Transforms / ObjCARC / PtrState.h
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"
21 #include "llvm/IR/Instruction.h"
22 #include "llvm/IR/Value.h"
23 #include "llvm/Support/raw_ostream.h"
24 #include "llvm/Support/Debug.h"
25
26 namespace llvm {
27 namespace objcarc {
28
29 /// \enum Sequence
30 ///
31 /// \brief A sequence of states that a pointer may go through in which an
32 /// objc_retain and objc_release are actually needed.
33 enum Sequence {
34   S_None,
35   S_Retain,        ///< objc_retain(x).
36   S_CanRelease,    ///< foo(x) -- x could possibly see a ref count decrement.
37   S_Use,           ///< any use of x.
38   S_Stop,          ///< like S_Release, but code motion is stopped.
39   S_Release,       ///< objc_release(x).
40   S_MovableRelease ///< objc_release(x), !clang.imprecise_release.
41 };
42
43 raw_ostream &operator<<(raw_ostream &OS,
44                         const Sequence S) LLVM_ATTRIBUTE_UNUSED;
45
46 /// \brief Unidirectional information about either a
47 /// retain-decrement-use-release sequence or release-use-decrement-retain
48 /// reverse sequence.
49 struct RRInfo {
50   /// After an objc_retain, the reference count of the referenced
51   /// object is known to be positive. Similarly, before an objc_release, the
52   /// reference count of the referenced object is known to be positive. If
53   /// there are retain-release pairs in code regions where the retain count
54   /// is known to be positive, they can be eliminated, regardless of any side
55   /// effects between them.
56   ///
57   /// Also, a retain+release pair nested within another retain+release
58   /// pair all on the known same pointer value can be eliminated, regardless
59   /// of any intervening side effects.
60   ///
61   /// KnownSafe is true when either of these conditions is satisfied.
62   bool KnownSafe;
63
64   /// True of the objc_release calls are all marked with the "tail" keyword.
65   bool IsTailCallRelease;
66
67   /// If the Calls are objc_release calls and they all have a
68   /// clang.imprecise_release tag, this is the metadata tag.
69   MDNode *ReleaseMetadata;
70
71   /// For a top-down sequence, the set of objc_retains or
72   /// objc_retainBlocks. For bottom-up, the set of objc_releases.
73   SmallPtrSet<Instruction *, 2> Calls;
74
75   /// The set of optimal insert positions for moving calls in the opposite
76   /// sequence.
77   SmallPtrSet<Instruction *, 2> ReverseInsertPts;
78
79   /// If this is true, we cannot perform code motion but can still remove
80   /// retain/release pairs.
81   bool CFGHazardAfflicted;
82
83   RRInfo()
84       : KnownSafe(false), IsTailCallRelease(false), ReleaseMetadata(nullptr),
85         CFGHazardAfflicted(false) {}
86
87   void clear();
88
89   /// Conservatively merge the two RRInfo. Returns true if a partial merge has
90   /// occurred, false otherwise.
91   bool Merge(const RRInfo &Other);
92 };
93
94 /// \brief This class summarizes several per-pointer runtime properties which
95 /// are propogated through the flow graph.
96 class PtrState {
97   /// True if the reference count is known to be incremented.
98   bool KnownPositiveRefCount;
99
100   /// True if we've seen an opportunity for partial RR elimination, such as
101   /// pushing calls into a CFG triangle or into one side of a CFG diamond.
102   bool Partial;
103
104   /// The current position in the sequence.
105   unsigned char Seq : 8;
106
107   /// Unidirectional information about the current sequence.
108   RRInfo RRI;
109
110 public:
111   PtrState() : KnownPositiveRefCount(false), Partial(false), Seq(S_None) {}
112
113   bool IsKnownSafe() const { return RRI.KnownSafe; }
114
115   void SetKnownSafe(const bool NewValue) { RRI.KnownSafe = NewValue; }
116
117   bool IsTailCallRelease() const { return RRI.IsTailCallRelease; }
118
119   void SetTailCallRelease(const bool NewValue) {
120     RRI.IsTailCallRelease = NewValue;
121   }
122
123   bool IsTrackingImpreciseReleases() const {
124     return RRI.ReleaseMetadata != nullptr;
125   }
126
127   const MDNode *GetReleaseMetadata() const { return RRI.ReleaseMetadata; }
128
129   void SetReleaseMetadata(MDNode *NewValue) { RRI.ReleaseMetadata = NewValue; }
130
131   bool IsCFGHazardAfflicted() const { return RRI.CFGHazardAfflicted; }
132
133   void SetCFGHazardAfflicted(const bool NewValue) {
134     RRI.CFGHazardAfflicted = NewValue;
135   }
136
137   void SetKnownPositiveRefCount();
138   void ClearKnownPositiveRefCount();
139
140   bool HasKnownPositiveRefCount() const { return KnownPositiveRefCount; }
141
142   void SetSeq(Sequence NewSeq);
143
144   Sequence GetSeq() const { return static_cast<Sequence>(Seq); }
145
146   void ClearSequenceProgress() { ResetSequenceProgress(S_None); }
147
148   void ResetSequenceProgress(Sequence NewSeq);
149   void Merge(const PtrState &Other, bool TopDown);
150
151   void InsertCall(Instruction *I) { RRI.Calls.insert(I); }
152
153   void InsertReverseInsertPt(Instruction *I) { RRI.ReverseInsertPts.insert(I); }
154
155   void ClearReverseInsertPts() { RRI.ReverseInsertPts.clear(); }
156
157   bool HasReverseInsertPts() const { return !RRI.ReverseInsertPts.empty(); }
158
159   const RRInfo &GetRRInfo() const { return RRI; }
160 };
161
162 } // end namespace objcarc
163 } // end namespace llvm
164
165 #endif