[Mlir-commits] [mlir] 10a4f03 - Split class ValueRange to a new file
Jeff Niu
llvmlistbot at llvm.org
Mon Jul 25 14:33:27 PDT 2022
Author: lipracer
Date: 2022-07-25T15:33:21-06:00
New Revision: 10a4f0333557b4807e339767dd4cd72a27538aef
URL: https://github.com/llvm/llvm-project/commit/10a4f0333557b4807e339767dd4cd72a27538aef
DIFF: https://github.com/llvm/llvm-project/commit/10a4f0333557b4807e339767dd4cd72a27538aef.diff
LOG: 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
Added:
mlir/include/mlir/IR/ValueRange.h
mlir/lib/IR/ValueRange.cpp
Modified:
mlir/include/mlir/IR/OperationSupport.h
mlir/include/mlir/IR/TypeRange.h
mlir/lib/IR/BuiltinDialect.cpp
mlir/lib/IR/CMakeLists.txt
Removed:
################################################################################
diff --git a/mlir/include/mlir/IR/OperationSupport.h b/mlir/include/mlir/IR/OperationSupport.h
index 825ba95bf080a..b42ef52cd3144 100644
--- a/mlir/include/mlir/IR/OperationSupport.h
+++ b/mlir/include/mlir/IR/OperationSupport.h
@@ -834,366 +834,6 @@ class OpPrintingFlags {
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, ptr
diff _t index) {
- return object + index;
- }
- /// See `llvm::detail::indexed_accessor_range_base` for details.
- static Value dereference_iterator(OpOperand *object, ptr
diff _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, ptr
diff _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, ptr
diff _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,
- ptr
diff _t index) {
- return object->getNextResultAtOffset(index);
- }
- /// See `llvm::detail::indexed_accessor_range_base` for details.
- static OpResult dereference_iterator(detail::OpResultImpl *object,
- ptr
diff _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
diff erent 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, ptr
diff _t index);
- /// See `llvm::detail::indexed_accessor_range_base` for details.
- static Value dereference_iterator(const OwnerT &owner, ptr
diff _t index);
-
- /// Allow access to `offset_base` and `dereference_iterator`.
- friend RangeBaseT;
-};
-
//===----------------------------------------------------------------------===//
// Operation Equivalency
//===----------------------------------------------------------------------===//
diff --git a/mlir/include/mlir/IR/TypeRange.h b/mlir/include/mlir/IR/TypeRange.h
index bca21ac3736c1..ba797d84a3ae8 100644
--- a/mlir/include/mlir/IR/TypeRange.h
+++ b/mlir/include/mlir/IR/TypeRange.h
@@ -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
diff --git a/mlir/include/mlir/IR/ValueRange.h b/mlir/include/mlir/IR/ValueRange.h
new file mode 100644
index 0000000000000..6fb35eae12762
--- /dev/null
+++ b/mlir/include/mlir/IR/ValueRange.h
@@ -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, ptr
diff _t index) {
+ return object + index;
+ }
+ /// See `llvm::detail::indexed_accessor_range_base` for details.
+ static Value dereference_iterator(OpOperand *object, ptr
diff _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, ptr
diff _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, ptr
diff _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,
+ ptr
diff _t index) {
+ return object->getNextResultAtOffset(index);
+ }
+ /// See `llvm::detail::indexed_accessor_range_base` for details.
+ static OpResult dereference_iterator(detail::OpResultImpl *object,
+ ptr
diff _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
diff erent 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, ptr
diff _t index);
+ /// See `llvm::detail::indexed_accessor_range_base` for details.
+ static Value dereference_iterator(const OwnerT &owner, ptr
diff _t index);
+
+ /// Allow access to `offset_base` and `dereference_iterator`.
+ friend RangeBaseT;
+};
+
+} // namespace mlir
+
+#endif // MLIR_IR_VALUERANGE_H
diff --git a/mlir/lib/IR/BuiltinDialect.cpp b/mlir/lib/IR/BuiltinDialect.cpp
index 679591efa5c67..662bcd811db4e 100644
--- a/mlir/lib/IR/BuiltinDialect.cpp
+++ b/mlir/lib/IR/BuiltinDialect.cpp
@@ -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;
diff --git a/mlir/lib/IR/CMakeLists.txt b/mlir/lib/IR/CMakeLists.txt
index 699ef7e2362e8..94f06467b7c07 100644
--- a/mlir/lib/IR/CMakeLists.txt
+++ b/mlir/lib/IR/CMakeLists.txt
@@ -31,6 +31,7 @@ add_mlir_library(MLIRIR
TypeRange.cpp
TypeUtilities.cpp
Value.cpp
+ ValueRange.cpp
Verifier.cpp
Visitors.cpp
diff --git a/mlir/lib/IR/ValueRange.cpp b/mlir/lib/IR/ValueRange.cpp
new file mode 100644
index 0000000000000..bd2e10098e61d
--- /dev/null
+++ b/mlir/lib/IR/ValueRange.cpp
@@ -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(); }
More information about the Mlir-commits
mailing list