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"
23template <
typename OperandType>
25template <
typename UseIteratorT,
typename OperandType>
48 assert(
this == *self);
63 *
this = std::move(other);
67 other.removeFromCurrent();
96 template <
typename UseListT>
98 back = &useList->firstUse;
102 useList->firstUse =
this;
126template <
typename DerivedT,
typename IRValueT>
138 *
this = std::move(other);
143 other.value =
nullptr;
153 return this == &other;
156 return !(*
this == other);
160 IRValueT
get()
const {
return value; }
163 void set(IRValueT newValue) {
172 bool is(IRValueT other)
const {
return value == other; }
186 void insertIntoCurrent() {
insertInto(DerivedT::getUseList(value)); }
194template <
typename OperandType>
198 assert(
use_empty() &&
"Cannot destroy a value that still has uses!");
210 template <
typename ValueT>
212 assert((!newValue ||
this != OperandType::getUseList(newValue)) &&
213 "cannot RAUW a value with itself");
223 assert((
size_t)std::distance(
getUses().begin(),
getUses().end()) ==
225 "indices vector expected to have a number of elements equal to the "
229 for (
size_t idx = 0; idx <
indices.size();
230 idx++,
ptr =
ptr->getNextOperandUsingThisValue())
233 initFirstUse(shuffled.front());
234 auto *current = firstUse;
235 for (
auto &next : llvm::drop_begin(shuffled)) {
236 current->linkTo(next);
239 current->linkTo(
nullptr);
257 return firstUse && firstUse->getNextOperandUsingThisValue() ==
nullptr;
281 OperandType *
getFirstUse()
const {
return (OperandType *)firstUse; }
290 detail::IROperandBase *firstUse =
nullptr;
293 friend detail::IROperandBase;
302template <
typename OperandType>
304 :
public llvm::iterator_facade_base<ValueUseIterator<OperandType>,
305 std::forward_iterator_tag,
318 std::forward_iterator_tag,
319 OperandType>::operator++;
321 assert(
current &&
"incrementing past end()!");
340template <
typename UseIteratorT,
typename OperandType>
342 :
public llvm::mapped_iterator_base<
343 ValueUserIterator<UseIteratorT, OperandType>, UseIteratorT,
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.
OperandType * getFirstUse() const
Return the first operand that is using this value, for use by custom use/def iterators.
ValueUseIterator< OperandType > use_iterator
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
iterator_range< use_iterator > use_range
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
iterator_range< user_iterator > user_range
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.
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 & operator=(IROperand &&other)
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)
ValueUseIterator & operator++()
OperandType * getOperand() const
Returns the current operands.
bool operator==(const ValueUseIterator &rhs) const
detail::IROperandBase * current
OperandType & operator*() const
Operation * getUser() const
Returns the operation that owns this use.
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 * nextUse
The next operand in the use-chain.
IROperandBase & operator=(IROperandBase &&other)
IROperandBase & operator=(const IROperandBase &use)=delete
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 * getNextOperandUsingThisValue()
Return the next operand on the use-list of the value we are referring to.
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.
void initChainWithUse(IROperandBase **self)
Initialize the use-def chain by setting the back address to self and nextUse to nullptr.
Include the generated interface declarations.