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;
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)); }
194 template <
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();
231 shuffled[indices[idx]] = ptr;
233 initFirstUse(shuffled.front());
234 auto *current = firstUse;
235 for (
auto &next : llvm::drop_begin(shuffled)) {
239 current->linkTo(
nullptr);
281 OperandType *
getFirstUse()
const {
return (OperandType *)firstUse; }
290 detail::IROperandBase *firstUse =
nullptr;
293 friend detail::IROperandBase;
302 template <
typename OperandType>
304 :
public llvm::iterator_facade_base<ValueUseIterator<OperandType>,
305 std::forward_iterator_tag,
317 using llvm::iterator_facade_base<ValueUseIterator<OperandType>,
318 std::forward_iterator_tag,
319 OperandType>::operator++;
321 assert(
current &&
"incrementing past end()!");
340 template <
typename UseIteratorT,
typename OperandType>
342 :
public llvm::mapped_iterator_base<
343 ValueUserIterator<UseIteratorT, OperandType>, UseIteratorT,
346 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 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.