@@ -67,14 +67,106 @@ class AliasResult {
67
67
// / Returns if this result is a partial alias.
68
68
bool isPartial () const { return kind == PartialAlias; }
69
69
70
- // / Return the internal kind of this alias result .
71
- Kind getKind ( ) const { return kind; }
70
+ // / Print this alias result to the provided output stream .
71
+ void print (raw_ostream &os ) const ;
72
72
73
73
private:
74
74
// / The internal kind of the result.
75
75
Kind kind;
76
76
};
77
77
78
+ inline raw_ostream &operator <<(raw_ostream &os, const AliasResult &result) {
79
+ result.print (os);
80
+ return os;
81
+ }
82
+
83
+ // ===----------------------------------------------------------------------===//
84
+ // ModRefResult
85
+ // ===----------------------------------------------------------------------===//
86
+
87
+ // / The possible results of whether a memory access modifies or references
88
+ // / a memory location. The possible results are: no access at all, a
89
+ // / modification, a reference, or both a modification and a reference.
90
+ class LLVM_NODISCARD ModRefResult {
91
+ // / Note: This is a simplified version of the ModRefResult in
92
+ // / `llvm/Analysis/AliasAnalysis.h`, and namely removes the `Must` concept. If
93
+ // / this becomes useful/necessary we should add it here.
94
+ enum class Kind {
95
+ // / The access neither references nor modifies the value stored in memory.
96
+ NoModRef = 0 ,
97
+ // / The access may reference the value stored in memory.
98
+ Ref = 1 ,
99
+ // / The access may modify the value stored in memory.
100
+ Mod = 2 ,
101
+ // / The access may reference and may modify the value stored in memory.
102
+ ModRef = Ref | Mod,
103
+ };
104
+
105
+ public:
106
+ bool operator ==(const ModRefResult &rhs) const { return kind == rhs.kind ; }
107
+ bool operator !=(const ModRefResult &rhs) const { return !(*this == rhs); }
108
+
109
+ // / Return a new result that indicates that the memory access neither
110
+ // / references nor modifies the value stored in memory.
111
+ static ModRefResult getNoModRef () { return Kind::NoModRef; }
112
+
113
+ // / Return a new result that indicates that the memory access may reference
114
+ // / the value stored in memory.
115
+ static ModRefResult getRef () { return Kind::Ref; }
116
+
117
+ // / Return a new result that indicates that the memory access may modify the
118
+ // / value stored in memory.
119
+ static ModRefResult getMod () { return Kind::Mod; }
120
+
121
+ // / Return a new result that indicates that the memory access may reference
122
+ // / and may modify the value stored in memory.
123
+ static ModRefResult getModAndRef () { return Kind::ModRef; }
124
+
125
+ // / Returns if this result does not modify or reference memory.
126
+ LLVM_NODISCARD bool isNoModRef () const { return kind == Kind::NoModRef; }
127
+
128
+ // / Returns if this result modifies memory.
129
+ LLVM_NODISCARD bool isMod () const {
130
+ return static_cast <int >(kind) & static_cast <int >(Kind::Mod);
131
+ }
132
+
133
+ // / Returns if this result references memory.
134
+ LLVM_NODISCARD bool isRef () const {
135
+ return static_cast <int >(kind) & static_cast <int >(Kind::Ref);
136
+ }
137
+
138
+ // / Returns if this result modifies *or* references memory.
139
+ LLVM_NODISCARD bool isModOrRef () const { return kind != Kind::NoModRef; }
140
+
141
+ // / Returns if this result modifies *and* references memory.
142
+ LLVM_NODISCARD bool isModAndRef () const { return kind == Kind::ModRef; }
143
+
144
+ // / Merge this ModRef result with `other` and return the result.
145
+ ModRefResult merge (const ModRefResult &other) {
146
+ return ModRefResult (static_cast <Kind>(static_cast <int >(kind) |
147
+ static_cast <int >(other.kind )));
148
+ }
149
+ // / Intersect this ModRef result with `other` and return the result.
150
+ ModRefResult intersect (const ModRefResult &other) {
151
+ return ModRefResult (static_cast <Kind>(static_cast <int >(kind) &
152
+ static_cast <int >(other.kind )));
153
+ }
154
+
155
+ // / Print this ModRef result to the provided output stream.
156
+ void print (raw_ostream &os) const ;
157
+
158
+ private:
159
+ ModRefResult (Kind kind) : kind(kind) {}
160
+
161
+ // / The internal kind of the result.
162
+ Kind kind;
163
+ };
164
+
165
+ inline raw_ostream &operator <<(raw_ostream &os, const ModRefResult &result) {
166
+ result.print (os);
167
+ return os;
168
+ }
169
+
78
170
// ===----------------------------------------------------------------------===//
79
171
// AliasAnalysisTraits
80
172
// ===----------------------------------------------------------------------===//
@@ -92,6 +184,9 @@ struct AliasAnalysisTraits {
92
184
93
185
// / Given two values, return their aliasing behavior.
94
186
virtual AliasResult alias (Value lhs, Value rhs) = 0;
187
+
188
+ // / Return the modify-reference behavior of `op` on `location`.
189
+ virtual ModRefResult getModRef (Operation *op, Value location) = 0;
95
190
};
96
191
97
192
// / This class represents the `Model` of an alias analysis implementation
@@ -108,6 +203,11 @@ struct AliasAnalysisTraits {
108
203
return impl.alias (lhs, rhs);
109
204
}
110
205
206
+ // / Return the modify-reference behavior of `op` on `location`.
207
+ ModRefResult getModRef (Operation *op, Value location) final {
208
+ return impl.getModRef (op, location);
209
+ }
210
+
111
211
private:
112
212
ImplT impl;
113
213
};
@@ -147,7 +247,12 @@ class AliasAnalysis {
147
247
// / * AnalysisT(AnalysisT &&)
148
248
// / * AliasResult alias(Value lhs, Value rhs)
149
249
// / - This method returns an `AliasResult` that corresponds to the
150
- // / aliasing behavior between `lhs` and `rhs`.
250
+ // / aliasing behavior between `lhs` and `rhs`. The conservative "I don't
251
+ // / know" result of this method should be MayAlias.
252
+ // / * ModRefResult getModRef(Operation *op, Value location)
253
+ // / - This method returns a `ModRefResult` that corresponds to the
254
+ // / modify-reference behavior of `op` on the given `location`. The
255
+ // / conservative "I don't know" result of this method should be ModRef.
151
256
template <typename AnalysisT>
152
257
void addAnalysisImplementation (AnalysisT &&analysis) {
153
258
aliasImpls.push_back (
@@ -161,6 +266,13 @@ class AliasAnalysis {
161
266
// / Given two values, return their aliasing behavior.
162
267
AliasResult alias (Value lhs, Value rhs);
163
268
269
+ // ===--------------------------------------------------------------------===//
270
+ // ModRef Queries
271
+ // ===--------------------------------------------------------------------===//
272
+
273
+ // / Return the modify-reference behavior of `op` on `location`.
274
+ ModRefResult getModRef (Operation *op, Value location);
275
+
164
276
private:
165
277
// / A set of internal alias analysis implementations.
166
278
SmallVector<std::unique_ptr<Concept>, 4 > aliasImpls;
0 commit comments