[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