13 #ifndef MLIR_IR_USEDEFLISTS_H
14 #define MLIR_IR_USEDEFLISTS_H
17 #include "llvm/ADT/PointerIntPair.h"
18 #include "llvm/ADT/iterator_range.h"
23 template <
typename OperandType>
24 class ValueUseIterator;
25 template <
typename UseIteratorT,
typename OperandType>
26 class ValueUserIterator;
48 assert(
this == *
self);
63 *
this = std::move(other);
67 other.removeFromCurrent();
96 template <
typename UseListT>
98 back = &useList->firstUse;
102 useList->firstUse =
this;
126 template <
typename DerivedT,
typename IRValueT>
138 *
this = std::move(other);
143 other.value =
nullptr;
150 IRValueT
get()
const {
return value; }
153 void set(IRValueT newValue) {
162 bool is(IRValueT other)
const {
return value == other; }
176 void insertIntoCurrent() {
insertInto(DerivedT::getUseList(value)); }
184 template <
typename OperandType>
188 assert(
use_empty() &&
"Cannot destroy a value that still has uses!");
200 template <
typename ValueT>
202 assert((!newValue ||
this != OperandType::getUseList(newValue)) &&
203 "cannot RAUW a value with itself");
213 assert((
size_t)std::distance(
getUses().begin(),
getUses().end()) ==
215 "indices vector expected to have a number of elements equal to the "
219 for (
size_t idx = 0; idx < indices.size();
221 shuffled[indices[idx]] = ptr;
223 initFirstUse(shuffled.front());
224 auto *current = firstUse;
225 for (
auto &next : llvm::drop_begin(shuffled)) {
229 current->linkTo(
nullptr);
271 OperandType *
getFirstUse()
const {
return (OperandType *)firstUse; }
280 detail::IROperandBase *firstUse =
nullptr;
283 friend detail::IROperandBase;
292 template <
typename OperandType>
294 :
public llvm::iterator_facade_base<ValueUseIterator<OperandType>,
295 std::forward_iterator_tag,
307 using llvm::iterator_facade_base<ValueUseIterator<OperandType>,
308 std::forward_iterator_tag,
309 OperandType>::operator++;
311 assert(
current &&
"incrementing past end()!");
330 template <
typename UseIteratorT,
typename OperandType>
332 :
public llvm::mapped_iterator_base<
333 ValueUserIterator<UseIteratorT, OperandType>, UseIteratorT,
336 using llvm::mapped_iterator_base<ValueUserIterator<UseIteratorT, OperandType>,
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 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.
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.
This header declares functions that assist transformations in the MemRef dialect.