MLIR: include/mlir/IR/UseDefLists.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13 #ifndef MLIR_IR_USEDEFLISTS_H
14 #define MLIR_IR_USEDEFLISTS_H
15
17 #include "llvm/ADT/PointerIntPair.h"
18 #include "llvm/ADT/iterator_range.h"
19
20 namespace mlir {
21
22 class Operation;
23 template
24 class ValueUseIterator;
25 template <typename UseIteratorT, typename OperandType>
26 class ValueUserIterator;
27
28
29
30
31
32 namespace detail {
33
34
36 public:
37
39
40
41
42
44
45
46
48 assert(this == *self);
51 }
52
53
58 }
59
60 protected:
63 *this = std::move(other);
64 }
67 other.removeFromCurrent();
68 other.back = nullptr;
70 back = nullptr;
71 return *this;
72 }
73
76
78
79
83 back = nullptr;
84 }
85
86
89 return;
93 }
94
95
96 template
98 back = &useList->firstUse;
99 nextUse = useList->firstUse;
102 useList->firstUse = this;
103 }
104
105
107
108
110
111 private:
112
114 };
115 }
116
117
118
119
120
121
122
123
124
125
126 template <typename DerivedT, typename IRValueT>
128 public:
132 insertIntoCurrent();
133 }
134
135
136
138 *this = std::move(other);
139 }
142 value = other.value;
143 other.value = nullptr;
144 if (value)
145 insertIntoCurrent();
146 return *this;
147 }
148
149
150
151
153 return this == &other;
154 }
156 return !(*this == other);
157 }
158
159
160 IRValueT get() const { return value; }
161
162
163 void set(IRValueT newValue) {
164
165
167 value = newValue;
168 insertIntoCurrent();
169 }
170
171
172 bool is(IRValueT other) const { return value == other; }
173
174
177 value = nullptr;
178 }
179
180 private:
181
182
183 IRValueT value = {};
184
185
186 void insertIntoCurrent() { insertInto(DerivedT::getUseList(value)); }
187 };
188
189
190
191
192
193
194 template
196 public:
198 assert(use_empty() && "Cannot destroy a value that still has uses!");
199 }
200
201
205 }
206
207
208
209
210 template
212 assert((!newValue || this != OperandType::getUseList(newValue)) &&
213 "cannot RAUW a value with itself");
216 }
217
218
219
220
221
223 assert((size_t)std::distance(getUses().begin(), getUses().end()) ==
224 indices.size() &&
225 "indices vector expected to have a number of elements equal to the "
226 "number of uses");
229 for (size_t idx = 0; idx < indices.size();
231 shuffled[indices[idx]] = ptr;
232
233 initFirstUse(shuffled.front());
234 auto *current = firstUse;
235 for (auto &next : llvm::drop_begin(shuffled)) {
236 current->linkTo(next);
237 current = next;
238 }
239 current->linkTo(nullptr);
240 }
241
242
243
244
245
248
251
252
254
255
258 }
259
260
261 bool use_empty() const { return firstUse == nullptr; }
262
263
264
265
266
269
272
273
275
276 protected:
278
279
280
281 OperandType *getFirstUse() const { return (OperandType *)firstUse; }
282
283 private:
284
286 firstUse = use;
288 }
289
290 detail::IROperandBase *firstUse = nullptr;
291
292
293 friend detail::IROperandBase;
294 };
295
296
297
298
299
300
301
302 template
304 : public llvm::iterator_facade_base<ValueUseIterator,
305 std::forward_iterator_tag,
306 OperandType> {
307 public:
309
310
312
313
316
317 using llvm::iterator_facade_base<ValueUseIterator,
318 std::forward_iterator_tag,
319 OperandType>::operator++;
321 assert(current && "incrementing past end()!");
323 return *this;
324 }
325
328 }
329
330 protected:
332 };
333
334
335
336
337
338
339
340 template <typename UseIteratorT, typename OperandType>
342 : public llvm::mapped_iterator_base<
343 ValueUserIterator<UseIteratorT, OperandType>, UseIteratorT,
344 Operation *> {
345 public:
346 using llvm::mapped_iterator_base<ValueUserIterator<UseIteratorT, OperandType>,
347 UseIteratorT,
348 Operation *>::mapped_iterator_base;
349
350
352
353
355 };
356
357 }
358
359 #endif
This class represents a single IR object that contains a use list.
bool hasOneUse() const
Returns true if this value has exactly one use.
use_range getUses() const
Returns a range of all uses, which is useful for iterating over all uses.
user_range getUsers() const
Returns a range of all users.
ValueUseIterator< OperandType > use_iterator
OperandType * getFirstUse() const
Return the first operand that is using this value, for use by custom use/def iterators.
void dropAllUses()
Drop all uses of this object from their respective owners.
user_iterator user_end() const
void shuffleUseList(ArrayRef< unsigned > indices)
Shuffle the use-list chain according to the provided indices vector, which need to represent a valid ...
use_iterator use_begin() const
ValueUserIterator< use_iterator, OperandType > user_iterator
IRObjectWithUseList()=default
bool use_empty() const
Returns true if this value has no uses.
user_iterator user_begin() const
void replaceAllUsesWith(ValueT &&newValue)
Replace all uses of 'this' value with the new value, updating anything in the IR that uses 'this' to ...
use_iterator use_end() const
A reference to a value, suitable for use as an operand of an operation.
IRValueT get() const
Return the current value being used by this operand.
void set(IRValueT newValue)
Set the current value being used by this operand.
IROperand & operator=(IROperand &&other)
bool operator==(const IROperand< DerivedT, IRValueT > &other) const
Two operands are equal if they have the same owner and the same operand number.
bool is(IRValueT other) const
Returns true if this operand contains the given value.
IROperand(IROperand &&other)
We support a move constructor so IROperand's can be in vectors, but this shouldn't be used by general...
IROperand(Operation *owner)
IROperand(Operation *owner, IRValueT value)
void drop()
Remove this use of the operand.
bool operator!=(const IROperand< DerivedT, IRValueT > &other) const
Operation is the basic unit of execution within MLIR.
An iterator class that allows for iterating over the uses of an IR operand type.
ValueUseIterator(detail::IROperandBase *use=nullptr)
bool operator==(const ValueUseIterator &rhs) const
detail::IROperandBase * current
Operation * getUser() const
Returns the operation that owns this use.
ValueUseIterator & operator++()
OperandType * getOperand() const
Returns the current operands.
OperandType & operator*() const
An iterator over the users of an IRObject.
Operation * operator->()
Provide access to the underlying operation.
Operation * mapElement(OperandType &value) const
Map the element to the iterator result type.
This class is the base for IROperand, and provides all of the non-templated facilities for operand us...
IROperandBase & operator=(const IROperandBase &use)=delete
IROperandBase * nextUse
The next operand in the use-chain.
IROperandBase ** back
This points to the previous link in the use-chain.
IROperandBase(const IROperandBase &use)=delete
Operands are not copyable or assignable.
void removeFromCurrent()
Remove this operand from the current use list.
IROperandBase(Operation *owner)
Operation * getOwner() const
Return the owner of this operand.
void linkTo(IROperandBase *next)
Link the current node to next.
void drop()
Remove this use of the operand.
IROperandBase(IROperandBase &&other)
void insertInto(UseListT *useList)
Insert this operand into the given use list.
IROperandBase & operator=(IROperandBase &&other)
void initChainWithUse(IROperandBase **self)
Initialize the use-def chain by setting the back address to self and nextUse to nullptr.
IROperandBase * getNextOperandUsingThisValue()
Return the next operand on the use-list of the value we are referring to.
Include the generated interface declarations.