mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-26 05:46:06 +00:00
Split class ValueRange to a new file
When we apply parent patch : https://reviews.llvm.org/D129475 The prompt I get with the clang compiler is: ValueRange is imcomplete type,ValueRange is a forward declaration in the file TypeRange.h, and the file OperationSupport.h already includes the file TypeRange.h.The class TypeRange and the class ValueRange depend on each other. Reviewed By: rriddle, Mogball Differential Revision: https://reviews.llvm.org/D130332
This commit is contained in:
parent
85063090e9
commit
10a4f03335
@ -834,366 +834,6 @@ private:
|
||||
bool printValueUsersFlag : 1;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Operation Value-Iterators
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// OperandRange
|
||||
|
||||
/// This class implements the operand iterators for the Operation class.
|
||||
class OperandRange final : public llvm::detail::indexed_accessor_range_base<
|
||||
OperandRange, OpOperand *, Value, Value, Value> {
|
||||
public:
|
||||
using RangeBaseT::RangeBaseT;
|
||||
|
||||
/// Returns the types of the values within this range.
|
||||
using type_iterator = ValueTypeIterator<iterator>;
|
||||
using type_range = ValueTypeRange<OperandRange>;
|
||||
type_range getTypes() const { return {begin(), end()}; }
|
||||
auto getType() const { return getTypes(); }
|
||||
|
||||
/// Return the operand index of the first element of this range. The range
|
||||
/// must not be empty.
|
||||
unsigned getBeginOperandIndex() const;
|
||||
|
||||
/// Split this range into a set of contiguous subranges using the given
|
||||
/// elements attribute, which contains the sizes of the sub ranges.
|
||||
OperandRangeRange split(ElementsAttr segmentSizes) const;
|
||||
|
||||
private:
|
||||
/// See `llvm::detail::indexed_accessor_range_base` for details.
|
||||
static OpOperand *offset_base(OpOperand *object, ptrdiff_t index) {
|
||||
return object + index;
|
||||
}
|
||||
/// See `llvm::detail::indexed_accessor_range_base` for details.
|
||||
static Value dereference_iterator(OpOperand *object, ptrdiff_t index) {
|
||||
return object[index].get();
|
||||
}
|
||||
|
||||
/// Allow access to `offset_base` and `dereference_iterator`.
|
||||
friend RangeBaseT;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// OperandRangeRange
|
||||
|
||||
/// This class represents a contiguous range of operand ranges, e.g. from a
|
||||
/// VariadicOfVariadic operand group.
|
||||
class OperandRangeRange final
|
||||
: public llvm::indexed_accessor_range<
|
||||
OperandRangeRange, std::pair<OpOperand *, Attribute>, OperandRange,
|
||||
OperandRange, OperandRange> {
|
||||
using OwnerT = std::pair<OpOperand *, Attribute>;
|
||||
using RangeBaseT =
|
||||
llvm::indexed_accessor_range<OperandRangeRange, OwnerT, OperandRange,
|
||||
OperandRange, OperandRange>;
|
||||
|
||||
public:
|
||||
using RangeBaseT::RangeBaseT;
|
||||
|
||||
/// Returns the range of types of the values within this range.
|
||||
TypeRangeRange getTypes() const { return TypeRangeRange(*this); }
|
||||
auto getType() const { return getTypes(); }
|
||||
|
||||
/// Construct a range given a parent set of operands, and an I32 elements
|
||||
/// attribute containing the sizes of the sub ranges.
|
||||
OperandRangeRange(OperandRange operands, Attribute operandSegments);
|
||||
|
||||
/// Flatten all of the sub ranges into a single contiguous operand range.
|
||||
OperandRange join() const;
|
||||
|
||||
private:
|
||||
/// See `llvm::indexed_accessor_range` for details.
|
||||
static OperandRange dereference(const OwnerT &object, ptrdiff_t index);
|
||||
|
||||
/// Allow access to `dereference_iterator`.
|
||||
friend RangeBaseT;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MutableOperandRange
|
||||
|
||||
/// This class provides a mutable adaptor for a range of operands. It allows for
|
||||
/// setting, inserting, and erasing operands from the given range.
|
||||
class MutableOperandRange {
|
||||
public:
|
||||
/// A pair of a named attribute corresponding to an operand segment attribute,
|
||||
/// and the index within that attribute. The attribute should correspond to an
|
||||
/// i32 DenseElementsAttr.
|
||||
using OperandSegment = std::pair<unsigned, NamedAttribute>;
|
||||
|
||||
/// Construct a new mutable range from the given operand, operand start index,
|
||||
/// and range length. `operandSegments` is an optional set of operand segments
|
||||
/// to be updated when mutating the operand list.
|
||||
MutableOperandRange(Operation *owner, unsigned start, unsigned length,
|
||||
ArrayRef<OperandSegment> operandSegments = llvm::None);
|
||||
MutableOperandRange(Operation *owner);
|
||||
|
||||
/// Slice this range into a sub range, with the additional operand segment.
|
||||
MutableOperandRange
|
||||
slice(unsigned subStart, unsigned subLen,
|
||||
Optional<OperandSegment> segment = llvm::None) const;
|
||||
|
||||
/// Append the given values to the range.
|
||||
void append(ValueRange values);
|
||||
|
||||
/// Assign this range to the given values.
|
||||
void assign(ValueRange values);
|
||||
|
||||
/// Assign the range to the given value.
|
||||
void assign(Value value);
|
||||
|
||||
/// Erase the operands within the given sub-range.
|
||||
void erase(unsigned subStart, unsigned subLen = 1);
|
||||
|
||||
/// Clear this range and erase all of the operands.
|
||||
void clear();
|
||||
|
||||
/// Returns the current size of the range.
|
||||
unsigned size() const { return length; }
|
||||
|
||||
/// Returns if the current range is empty.
|
||||
bool empty() const { return size() == 0; }
|
||||
|
||||
/// Allow implicit conversion to an OperandRange.
|
||||
operator OperandRange() const;
|
||||
|
||||
/// Returns the owning operation.
|
||||
Operation *getOwner() const { return owner; }
|
||||
|
||||
/// Split this range into a set of contiguous subranges using the given
|
||||
/// elements attribute, which contains the sizes of the sub ranges.
|
||||
MutableOperandRangeRange split(NamedAttribute segmentSizes) const;
|
||||
|
||||
/// Returns the value at the given index.
|
||||
Value operator[](unsigned index) const {
|
||||
return operator OperandRange()[index];
|
||||
}
|
||||
|
||||
private:
|
||||
/// Update the length of this range to the one provided.
|
||||
void updateLength(unsigned newLength);
|
||||
|
||||
/// The owning operation of this range.
|
||||
Operation *owner;
|
||||
|
||||
/// The start index of the operand range within the owner operand list, and
|
||||
/// the length starting from `start`.
|
||||
unsigned start, length;
|
||||
|
||||
/// Optional set of operand segments that should be updated when mutating the
|
||||
/// length of this range.
|
||||
SmallVector<OperandSegment, 1> operandSegments;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MutableOperandRangeRange
|
||||
|
||||
/// This class represents a contiguous range of mutable operand ranges, e.g.
|
||||
/// from a VariadicOfVariadic operand group.
|
||||
class MutableOperandRangeRange final
|
||||
: public llvm::indexed_accessor_range<
|
||||
MutableOperandRangeRange,
|
||||
std::pair<MutableOperandRange, NamedAttribute>, MutableOperandRange,
|
||||
MutableOperandRange, MutableOperandRange> {
|
||||
using OwnerT = std::pair<MutableOperandRange, NamedAttribute>;
|
||||
using RangeBaseT =
|
||||
llvm::indexed_accessor_range<MutableOperandRangeRange, OwnerT,
|
||||
MutableOperandRange, MutableOperandRange,
|
||||
MutableOperandRange>;
|
||||
|
||||
public:
|
||||
using RangeBaseT::RangeBaseT;
|
||||
|
||||
/// Construct a range given a parent set of operands, and an I32 tensor
|
||||
/// elements attribute containing the sizes of the sub ranges.
|
||||
MutableOperandRangeRange(const MutableOperandRange &operands,
|
||||
NamedAttribute operandSegmentAttr);
|
||||
|
||||
/// Flatten all of the sub ranges into a single contiguous mutable operand
|
||||
/// range.
|
||||
MutableOperandRange join() const;
|
||||
|
||||
/// Allow implicit conversion to an OperandRangeRange.
|
||||
operator OperandRangeRange() const;
|
||||
|
||||
private:
|
||||
/// See `llvm::indexed_accessor_range` for details.
|
||||
static MutableOperandRange dereference(const OwnerT &object, ptrdiff_t index);
|
||||
|
||||
/// Allow access to `dereference_iterator`.
|
||||
friend RangeBaseT;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ResultRange
|
||||
|
||||
/// This class implements the result iterators for the Operation class.
|
||||
class ResultRange final
|
||||
: public llvm::detail::indexed_accessor_range_base<
|
||||
ResultRange, detail::OpResultImpl *, OpResult, OpResult, OpResult> {
|
||||
public:
|
||||
using RangeBaseT::RangeBaseT;
|
||||
ResultRange(OpResult result);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Types
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// Returns the types of the values within this range.
|
||||
using type_iterator = ValueTypeIterator<iterator>;
|
||||
using type_range = ValueTypeRange<ResultRange>;
|
||||
type_range getTypes() const { return {begin(), end()}; }
|
||||
auto getType() const { return getTypes(); }
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Uses
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
class UseIterator;
|
||||
using use_iterator = UseIterator;
|
||||
using use_range = iterator_range<use_iterator>;
|
||||
|
||||
/// Returns a range of all uses of results within this range, which is useful
|
||||
/// for iterating over all uses.
|
||||
use_range getUses() const;
|
||||
use_iterator use_begin() const;
|
||||
use_iterator use_end() const;
|
||||
|
||||
/// Returns true if no results in this range have uses.
|
||||
bool use_empty() const {
|
||||
return llvm::all_of(*this,
|
||||
[](OpResult result) { return result.use_empty(); });
|
||||
}
|
||||
|
||||
/// Replace all uses of results of this range with the provided 'values'. The
|
||||
/// size of `values` must match the size of this range.
|
||||
template <typename ValuesT>
|
||||
std::enable_if_t<!std::is_convertible<ValuesT, Operation *>::value>
|
||||
replaceAllUsesWith(ValuesT &&values) {
|
||||
assert(static_cast<size_t>(std::distance(values.begin(), values.end())) ==
|
||||
size() &&
|
||||
"expected 'values' to correspond 1-1 with the number of results");
|
||||
|
||||
for (auto it : llvm::zip(*this, values))
|
||||
std::get<0>(it).replaceAllUsesWith(std::get<1>(it));
|
||||
}
|
||||
|
||||
/// Replace all uses of results of this range with results of 'op'.
|
||||
void replaceAllUsesWith(Operation *op);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Users
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
using user_iterator = ValueUserIterator<use_iterator, OpOperand>;
|
||||
using user_range = iterator_range<user_iterator>;
|
||||
|
||||
/// Returns a range of all users.
|
||||
user_range getUsers();
|
||||
user_iterator user_begin();
|
||||
user_iterator user_end();
|
||||
|
||||
private:
|
||||
/// See `llvm::detail::indexed_accessor_range_base` for details.
|
||||
static detail::OpResultImpl *offset_base(detail::OpResultImpl *object,
|
||||
ptrdiff_t index) {
|
||||
return object->getNextResultAtOffset(index);
|
||||
}
|
||||
/// See `llvm::detail::indexed_accessor_range_base` for details.
|
||||
static OpResult dereference_iterator(detail::OpResultImpl *object,
|
||||
ptrdiff_t index) {
|
||||
return offset_base(object, index);
|
||||
}
|
||||
|
||||
/// Allow access to `offset_base` and `dereference_iterator`.
|
||||
friend RangeBaseT;
|
||||
};
|
||||
|
||||
/// This class implements a use iterator for a range of operation results.
|
||||
/// This iterates over all uses of all results within the given result range.
|
||||
class ResultRange::UseIterator final
|
||||
: public llvm::iterator_facade_base<UseIterator, std::forward_iterator_tag,
|
||||
OpOperand> {
|
||||
public:
|
||||
/// Initialize the UseIterator. Specify `end` to return iterator to last
|
||||
/// use, otherwise this is an iterator to the first use.
|
||||
explicit UseIterator(ResultRange results, bool end = false);
|
||||
|
||||
using llvm::iterator_facade_base<UseIterator, std::forward_iterator_tag,
|
||||
OpOperand>::operator++;
|
||||
UseIterator &operator++();
|
||||
OpOperand *operator->() const { return use.getOperand(); }
|
||||
OpOperand &operator*() const { return *use.getOperand(); }
|
||||
|
||||
bool operator==(const UseIterator &rhs) const { return use == rhs.use; }
|
||||
bool operator!=(const UseIterator &rhs) const { return !(*this == rhs); }
|
||||
|
||||
private:
|
||||
void skipOverResultsWithNoUsers();
|
||||
|
||||
/// The range of results being iterated over.
|
||||
ResultRange::iterator it, endIt;
|
||||
/// The use of the result.
|
||||
Value::use_iterator use;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ValueRange
|
||||
|
||||
/// This class provides an abstraction over the different types of ranges over
|
||||
/// Values. In many cases, this prevents the need to explicitly materialize a
|
||||
/// SmallVector/std::vector. This class should be used in places that are not
|
||||
/// suitable for a more derived type (e.g. ArrayRef) or a template range
|
||||
/// parameter.
|
||||
class ValueRange final
|
||||
: public llvm::detail::indexed_accessor_range_base<
|
||||
ValueRange,
|
||||
PointerUnion<const Value *, OpOperand *, detail::OpResultImpl *>,
|
||||
Value, Value, Value> {
|
||||
public:
|
||||
/// The type representing the owner of a ValueRange. This is either a list of
|
||||
/// values, operands, or results.
|
||||
using OwnerT =
|
||||
PointerUnion<const Value *, OpOperand *, detail::OpResultImpl *>;
|
||||
|
||||
using RangeBaseT::RangeBaseT;
|
||||
|
||||
template <typename Arg,
|
||||
typename = typename std::enable_if_t<
|
||||
std::is_constructible<ArrayRef<Value>, Arg>::value &&
|
||||
!std::is_convertible<Arg, Value>::value>>
|
||||
ValueRange(Arg &&arg) : ValueRange(ArrayRef<Value>(std::forward<Arg>(arg))) {}
|
||||
ValueRange(const Value &value) : ValueRange(&value, /*count=*/1) {}
|
||||
ValueRange(const std::initializer_list<Value> &values)
|
||||
: ValueRange(ArrayRef<Value>(values)) {}
|
||||
ValueRange(iterator_range<OperandRange::iterator> values)
|
||||
: ValueRange(OperandRange(values)) {}
|
||||
ValueRange(iterator_range<ResultRange::iterator> values)
|
||||
: ValueRange(ResultRange(values)) {}
|
||||
ValueRange(ArrayRef<BlockArgument> values)
|
||||
: ValueRange(ArrayRef<Value>(values.data(), values.size())) {}
|
||||
ValueRange(ArrayRef<Value> values = llvm::None);
|
||||
ValueRange(OperandRange values);
|
||||
ValueRange(ResultRange values);
|
||||
|
||||
/// Returns the types of the values within this range.
|
||||
using type_iterator = ValueTypeIterator<iterator>;
|
||||
using type_range = ValueTypeRange<ValueRange>;
|
||||
type_range getTypes() const { return {begin(), end()}; }
|
||||
auto getType() const { return getTypes(); }
|
||||
|
||||
private:
|
||||
/// See `llvm::detail::indexed_accessor_range_base` for details.
|
||||
static OwnerT offset_base(const OwnerT &owner, ptrdiff_t index);
|
||||
/// See `llvm::detail::indexed_accessor_range_base` for details.
|
||||
static Value dereference_iterator(const OwnerT &owner, ptrdiff_t index);
|
||||
|
||||
/// Allow access to `offset_base` and `dereference_iterator`.
|
||||
friend RangeBaseT;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Operation Equivalency
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -15,17 +15,11 @@
|
||||
|
||||
#include "mlir/IR/Types.h"
|
||||
#include "mlir/IR/Value.h"
|
||||
#include "mlir/IR/ValueRange.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/ADT/Sequence.h"
|
||||
|
||||
namespace mlir {
|
||||
class OperandRange;
|
||||
class ResultRange;
|
||||
class Type;
|
||||
class Value;
|
||||
class ValueRange;
|
||||
template <typename ValueRangeT>
|
||||
class ValueTypeRange;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// TypeRange
|
||||
|
394
mlir/include/mlir/IR/ValueRange.h
Normal file
394
mlir/include/mlir/IR/ValueRange.h
Normal file
@ -0,0 +1,394 @@
|
||||
//===- ValueRange.h - Indexed Value-Iterators Range Classes -----*- C++ -*-===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the ValueRange related classes.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef MLIR_IR_VALUERANGE_H
|
||||
#define MLIR_IR_VALUERANGE_H
|
||||
|
||||
#include "mlir/IR/Types.h"
|
||||
#include "mlir/IR/Value.h"
|
||||
#include "llvm/ADT/PointerUnion.h"
|
||||
#include "llvm/ADT/Sequence.h"
|
||||
|
||||
namespace mlir {
|
||||
class ValueRange;
|
||||
template <typename ValueRangeT>
|
||||
class ValueTypeRange;
|
||||
class ElementsAttr;
|
||||
class TypeRangeRange;
|
||||
template <typename ValueIteratorT>
|
||||
class ValueTypeIterator;
|
||||
class OperandRangeRange;
|
||||
class MutableOperandRangeRange;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Operation Value-Iterators
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// OperandRange
|
||||
|
||||
/// This class implements the operand iterators for the Operation class.
|
||||
class OperandRange final : public llvm::detail::indexed_accessor_range_base<
|
||||
OperandRange, OpOperand *, Value, Value, Value> {
|
||||
public:
|
||||
using RangeBaseT::RangeBaseT;
|
||||
|
||||
/// Returns the types of the values within this range.
|
||||
using type_iterator = ValueTypeIterator<iterator>;
|
||||
using type_range = ValueTypeRange<OperandRange>;
|
||||
type_range getTypes() const;
|
||||
type_range getType() const;
|
||||
|
||||
/// Return the operand index of the first element of this range. The range
|
||||
/// must not be empty.
|
||||
unsigned getBeginOperandIndex() const;
|
||||
|
||||
/// Split this range into a set of contiguous subranges using the given
|
||||
/// elements attribute, which contains the sizes of the sub ranges.
|
||||
OperandRangeRange split(ElementsAttr segmentSizes) const;
|
||||
|
||||
private:
|
||||
/// See `llvm::detail::indexed_accessor_range_base` for details.
|
||||
static OpOperand *offset_base(OpOperand *object, ptrdiff_t index) {
|
||||
return object + index;
|
||||
}
|
||||
/// See `llvm::detail::indexed_accessor_range_base` for details.
|
||||
static Value dereference_iterator(OpOperand *object, ptrdiff_t index) {
|
||||
return object[index].get();
|
||||
}
|
||||
|
||||
/// Allow access to `offset_base` and `dereference_iterator`.
|
||||
friend RangeBaseT;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// OperandRangeRange
|
||||
|
||||
/// This class represents a contiguous range of operand ranges, e.g. from a
|
||||
/// VariadicOfVariadic operand group.
|
||||
class OperandRangeRange final
|
||||
: public llvm::indexed_accessor_range<
|
||||
OperandRangeRange, std::pair<OpOperand *, Attribute>, OperandRange,
|
||||
OperandRange, OperandRange> {
|
||||
using OwnerT = std::pair<OpOperand *, Attribute>;
|
||||
using RangeBaseT =
|
||||
llvm::indexed_accessor_range<OperandRangeRange, OwnerT, OperandRange,
|
||||
OperandRange, OperandRange>;
|
||||
|
||||
public:
|
||||
using RangeBaseT::RangeBaseT;
|
||||
|
||||
/// Returns the range of types of the values within this range.
|
||||
TypeRangeRange getTypes() const;
|
||||
TypeRangeRange getType() const;
|
||||
|
||||
/// Construct a range given a parent set of operands, and an I32 elements
|
||||
/// attribute containing the sizes of the sub ranges.
|
||||
OperandRangeRange(OperandRange operands, Attribute operandSegments);
|
||||
|
||||
/// Flatten all of the sub ranges into a single contiguous operand range.
|
||||
OperandRange join() const;
|
||||
|
||||
private:
|
||||
/// See `llvm::indexed_accessor_range` for details.
|
||||
static OperandRange dereference(const OwnerT &object, ptrdiff_t index);
|
||||
|
||||
/// Allow access to `dereference_iterator`.
|
||||
friend RangeBaseT;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MutableOperandRange
|
||||
|
||||
/// This class provides a mutable adaptor for a range of operands. It allows for
|
||||
/// setting, inserting, and erasing operands from the given range.
|
||||
class MutableOperandRange {
|
||||
public:
|
||||
/// A pair of a named attribute corresponding to an operand segment attribute,
|
||||
/// and the index within that attribute. The attribute should correspond to an
|
||||
/// i32 DenseElementsAttr.
|
||||
using OperandSegment = std::pair<unsigned, NamedAttribute>;
|
||||
|
||||
/// Construct a new mutable range from the given operand, operand start index,
|
||||
/// and range length. `operandSegments` is an optional set of operand segments
|
||||
/// to be updated when mutating the operand list.
|
||||
MutableOperandRange(Operation *owner, unsigned start, unsigned length,
|
||||
ArrayRef<OperandSegment> operandSegments = llvm::None);
|
||||
MutableOperandRange(Operation *owner);
|
||||
|
||||
/// Slice this range into a sub range, with the additional operand segment.
|
||||
MutableOperandRange
|
||||
slice(unsigned subStart, unsigned subLen,
|
||||
Optional<OperandSegment> segment = llvm::None) const;
|
||||
|
||||
/// Append the given values to the range.
|
||||
void append(ValueRange values);
|
||||
|
||||
/// Assign this range to the given values.
|
||||
void assign(ValueRange values);
|
||||
|
||||
/// Assign the range to the given value.
|
||||
void assign(Value value);
|
||||
|
||||
/// Erase the operands within the given sub-range.
|
||||
void erase(unsigned subStart, unsigned subLen = 1);
|
||||
|
||||
/// Clear this range and erase all of the operands.
|
||||
void clear();
|
||||
|
||||
/// Returns the current size of the range.
|
||||
unsigned size() const { return length; }
|
||||
|
||||
/// Returns if the current range is empty.
|
||||
bool empty() const { return size() == 0; }
|
||||
|
||||
/// Allow implicit conversion to an OperandRange.
|
||||
operator OperandRange() const;
|
||||
|
||||
/// Returns the owning operation.
|
||||
Operation *getOwner() const { return owner; }
|
||||
|
||||
/// Split this range into a set of contiguous subranges using the given
|
||||
/// elements attribute, which contains the sizes of the sub ranges.
|
||||
MutableOperandRangeRange split(NamedAttribute segmentSizes) const;
|
||||
|
||||
/// Returns the value at the given index.
|
||||
Value operator[](unsigned index) const {
|
||||
return operator OperandRange()[index];
|
||||
}
|
||||
|
||||
private:
|
||||
/// Update the length of this range to the one provided.
|
||||
void updateLength(unsigned newLength);
|
||||
|
||||
/// The owning operation of this range.
|
||||
Operation *owner;
|
||||
|
||||
/// The start index of the operand range within the owner operand list, and
|
||||
/// the length starting from `start`.
|
||||
unsigned start, length;
|
||||
|
||||
/// Optional set of operand segments that should be updated when mutating the
|
||||
/// length of this range.
|
||||
SmallVector<OperandSegment, 1> operandSegments;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MutableOperandRangeRange
|
||||
|
||||
/// This class represents a contiguous range of mutable operand ranges, e.g.
|
||||
/// from a VariadicOfVariadic operand group.
|
||||
class MutableOperandRangeRange final
|
||||
: public llvm::indexed_accessor_range<
|
||||
MutableOperandRangeRange,
|
||||
std::pair<MutableOperandRange, NamedAttribute>, MutableOperandRange,
|
||||
MutableOperandRange, MutableOperandRange> {
|
||||
using OwnerT = std::pair<MutableOperandRange, NamedAttribute>;
|
||||
using RangeBaseT =
|
||||
llvm::indexed_accessor_range<MutableOperandRangeRange, OwnerT,
|
||||
MutableOperandRange, MutableOperandRange,
|
||||
MutableOperandRange>;
|
||||
|
||||
public:
|
||||
using RangeBaseT::RangeBaseT;
|
||||
|
||||
/// Construct a range given a parent set of operands, and an I32 tensor
|
||||
/// elements attribute containing the sizes of the sub ranges.
|
||||
MutableOperandRangeRange(const MutableOperandRange &operands,
|
||||
NamedAttribute operandSegmentAttr);
|
||||
|
||||
/// Flatten all of the sub ranges into a single contiguous mutable operand
|
||||
/// range.
|
||||
MutableOperandRange join() const;
|
||||
|
||||
/// Allow implicit conversion to an OperandRangeRange.
|
||||
operator OperandRangeRange() const;
|
||||
|
||||
private:
|
||||
/// See `llvm::indexed_accessor_range` for details.
|
||||
static MutableOperandRange dereference(const OwnerT &object, ptrdiff_t index);
|
||||
|
||||
/// Allow access to `dereference_iterator`.
|
||||
friend RangeBaseT;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ResultRange
|
||||
|
||||
/// This class implements the result iterators for the Operation class.
|
||||
class ResultRange final
|
||||
: public llvm::detail::indexed_accessor_range_base<
|
||||
ResultRange, detail::OpResultImpl *, OpResult, OpResult, OpResult> {
|
||||
public:
|
||||
using RangeBaseT::RangeBaseT;
|
||||
ResultRange(OpResult result);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Types
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// Returns the types of the values within this range.
|
||||
using type_iterator = ValueTypeIterator<iterator>;
|
||||
using type_range = ValueTypeRange<ResultRange>;
|
||||
type_range getTypes() const;
|
||||
type_range getType() const;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Uses
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
class UseIterator;
|
||||
using use_iterator = UseIterator;
|
||||
using use_range = iterator_range<use_iterator>;
|
||||
|
||||
/// Returns a range of all uses of results within this range, which is useful
|
||||
/// for iterating over all uses.
|
||||
use_range getUses() const;
|
||||
use_iterator use_begin() const;
|
||||
use_iterator use_end() const;
|
||||
|
||||
/// Returns true if no results in this range have uses.
|
||||
bool use_empty() const {
|
||||
return llvm::all_of(*this,
|
||||
[](OpResult result) { return result.use_empty(); });
|
||||
}
|
||||
|
||||
/// Replace all uses of results of this range with the provided 'values'. The
|
||||
/// size of `values` must match the size of this range.
|
||||
template <typename ValuesT>
|
||||
std::enable_if_t<!std::is_convertible<ValuesT, Operation *>::value>
|
||||
replaceAllUsesWith(ValuesT &&values) {
|
||||
assert(static_cast<size_t>(std::distance(values.begin(), values.end())) ==
|
||||
size() &&
|
||||
"expected 'values' to correspond 1-1 with the number of results");
|
||||
|
||||
for (auto it : llvm::zip(*this, values))
|
||||
std::get<0>(it).replaceAllUsesWith(std::get<1>(it));
|
||||
}
|
||||
|
||||
/// Replace all uses of results of this range with results of 'op'.
|
||||
void replaceAllUsesWith(Operation *op);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Users
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
||||
using user_iterator = ValueUserIterator<use_iterator, OpOperand>;
|
||||
using user_range = iterator_range<user_iterator>;
|
||||
|
||||
/// Returns a range of all users.
|
||||
user_range getUsers();
|
||||
user_iterator user_begin();
|
||||
user_iterator user_end();
|
||||
|
||||
private:
|
||||
/// See `llvm::detail::indexed_accessor_range_base` for details.
|
||||
static detail::OpResultImpl *offset_base(detail::OpResultImpl *object,
|
||||
ptrdiff_t index) {
|
||||
return object->getNextResultAtOffset(index);
|
||||
}
|
||||
/// See `llvm::detail::indexed_accessor_range_base` for details.
|
||||
static OpResult dereference_iterator(detail::OpResultImpl *object,
|
||||
ptrdiff_t index) {
|
||||
return offset_base(object, index);
|
||||
}
|
||||
|
||||
/// Allow access to `offset_base` and `dereference_iterator`.
|
||||
friend RangeBaseT;
|
||||
};
|
||||
|
||||
/// This class implements a use iterator for a range of operation results.
|
||||
/// This iterates over all uses of all results within the given result range.
|
||||
class ResultRange::UseIterator final
|
||||
: public llvm::iterator_facade_base<UseIterator, std::forward_iterator_tag,
|
||||
OpOperand> {
|
||||
public:
|
||||
/// Initialize the UseIterator. Specify `end` to return iterator to last
|
||||
/// use, otherwise this is an iterator to the first use.
|
||||
explicit UseIterator(ResultRange results, bool end = false);
|
||||
|
||||
using llvm::iterator_facade_base<UseIterator, std::forward_iterator_tag,
|
||||
OpOperand>::operator++;
|
||||
UseIterator &operator++();
|
||||
OpOperand *operator->() const { return use.getOperand(); }
|
||||
OpOperand &operator*() const { return *use.getOperand(); }
|
||||
|
||||
bool operator==(const UseIterator &rhs) const { return use == rhs.use; }
|
||||
bool operator!=(const UseIterator &rhs) const { return !(*this == rhs); }
|
||||
|
||||
private:
|
||||
void skipOverResultsWithNoUsers();
|
||||
|
||||
/// The range of results being iterated over.
|
||||
ResultRange::iterator it, endIt;
|
||||
/// The use of the result.
|
||||
Value::use_iterator use;
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ValueRange
|
||||
|
||||
/// This class provides an abstraction over the different types of ranges over
|
||||
/// Values. In many cases, this prevents the need to explicitly materialize a
|
||||
/// SmallVector/std::vector. This class should be used in places that are not
|
||||
/// suitable for a more derived type (e.g. ArrayRef) or a template range
|
||||
/// parameter.
|
||||
class ValueRange final
|
||||
: public llvm::detail::indexed_accessor_range_base<
|
||||
ValueRange,
|
||||
PointerUnion<const Value *, OpOperand *, detail::OpResultImpl *>,
|
||||
Value, Value, Value> {
|
||||
public:
|
||||
/// The type representing the owner of a ValueRange. This is either a list of
|
||||
/// values, operands, or results.
|
||||
using OwnerT =
|
||||
PointerUnion<const Value *, OpOperand *, detail::OpResultImpl *>;
|
||||
|
||||
using RangeBaseT::RangeBaseT;
|
||||
|
||||
template <typename Arg,
|
||||
typename = typename std::enable_if_t<
|
||||
std::is_constructible<ArrayRef<Value>, Arg>::value &&
|
||||
!std::is_convertible<Arg, Value>::value>>
|
||||
ValueRange(Arg &&arg) : ValueRange(ArrayRef<Value>(std::forward<Arg>(arg))) {}
|
||||
ValueRange(const Value &value) : ValueRange(&value, /*count=*/1) {}
|
||||
ValueRange(const std::initializer_list<Value> &values)
|
||||
: ValueRange(ArrayRef<Value>(values)) {}
|
||||
ValueRange(iterator_range<OperandRange::iterator> values)
|
||||
: ValueRange(OperandRange(values)) {}
|
||||
ValueRange(iterator_range<ResultRange::iterator> values)
|
||||
: ValueRange(ResultRange(values)) {}
|
||||
ValueRange(ArrayRef<BlockArgument> values)
|
||||
: ValueRange(ArrayRef<Value>(values.data(), values.size())) {}
|
||||
ValueRange(ArrayRef<Value> values = llvm::None);
|
||||
ValueRange(OperandRange values);
|
||||
ValueRange(ResultRange values);
|
||||
|
||||
/// Returns the types of the values within this range.
|
||||
using type_iterator = ValueTypeIterator<iterator>;
|
||||
using type_range = ValueTypeRange<ValueRange>;
|
||||
type_range getTypes() const;
|
||||
type_range getType() const;
|
||||
|
||||
private:
|
||||
/// See `llvm::detail::indexed_accessor_range_base` for details.
|
||||
static OwnerT offset_base(const OwnerT &owner, ptrdiff_t index);
|
||||
/// See `llvm::detail::indexed_accessor_range_base` for details.
|
||||
static Value dereference_iterator(const OwnerT &owner, ptrdiff_t index);
|
||||
|
||||
/// Allow access to `offset_base` and `dereference_iterator`.
|
||||
friend RangeBaseT;
|
||||
};
|
||||
|
||||
} // namespace mlir
|
||||
|
||||
#endif // MLIR_IR_VALUERANGE_H
|
@ -18,6 +18,7 @@
|
||||
#include "mlir/IR/BuiltinTypes.h"
|
||||
#include "mlir/IR/OpImplementation.h"
|
||||
#include "mlir/IR/PatternMatch.h"
|
||||
#include "mlir/IR/TypeRange.h"
|
||||
|
||||
using namespace mlir;
|
||||
|
||||
|
@ -31,6 +31,7 @@ add_mlir_library(MLIRIR
|
||||
TypeRange.cpp
|
||||
TypeUtilities.cpp
|
||||
Value.cpp
|
||||
ValueRange.cpp
|
||||
Verifier.cpp
|
||||
Visitors.cpp
|
||||
|
||||
|
46
mlir/lib/IR/ValueRange.cpp
Normal file
46
mlir/lib/IR/ValueRange.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
//===- ValueRange.cpp - Indexed Value-Iterators Range Classes -------------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "mlir/IR/ValueRange.h"
|
||||
#include "mlir/IR/TypeRange.h"
|
||||
|
||||
using namespace mlir;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// TypeRangeRange
|
||||
|
||||
TypeRangeRange OperandRangeRange::getTypes() const {
|
||||
return TypeRangeRange(*this);
|
||||
}
|
||||
|
||||
TypeRangeRange OperandRangeRange::getType() const { return getTypes(); }
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// OperandRange
|
||||
|
||||
OperandRange::type_range OperandRange::getTypes() const {
|
||||
return {begin(), end()};
|
||||
}
|
||||
|
||||
OperandRange::type_range OperandRange::getType() const { return getTypes(); }
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ResultRange
|
||||
|
||||
ResultRange::type_range ResultRange::getTypes() const {
|
||||
return {begin(), end()};
|
||||
}
|
||||
|
||||
ResultRange::type_range ResultRange::getType() const { return getTypes(); }
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// ValueRange
|
||||
|
||||
ValueRange::type_range ValueRange::getTypes() const { return {begin(), end()}; }
|
||||
|
||||
ValueRange::type_range ValueRange::getType() const { return getTypes(); }
|
Loading…
x
Reference in New Issue
Block a user