[Mlir-commits] [mlir] 94a4ca4 - [mlir] Add a TypeRange class that functions similar to ValueRange.

River Riddle llvmlistbot at llvm.org
Tue Feb 18 11:41:11 PST 2020


Author: River Riddle
Date: 2020-02-18T11:37:24-08:00
New Revision: 94a4ca4bf33b0c536bb22f09e035a2df24b0776f

URL: https://github.com/llvm/llvm-project/commit/94a4ca4bf33b0c536bb22f09e035a2df24b0776f
DIFF: https://github.com/llvm/llvm-project/commit/94a4ca4bf33b0c536bb22f09e035a2df24b0776f.diff

LOG: [mlir] Add a TypeRange class that functions similar to ValueRange.

Summary: This class wraps around the various different ways to construct a range of Type, without forcing the materialization of that range into a contiguous vector.

Differential Revision: https://reviews.llvm.org/D74646

Added: 
    

Modified: 
    mlir/include/mlir/IR/OpImplementation.h
    mlir/include/mlir/IR/Operation.h
    mlir/include/mlir/IR/OperationSupport.h
    mlir/lib/IR/OperationSupport.cpp

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/IR/OpImplementation.h b/mlir/include/mlir/IR/OpImplementation.h
index 4edf17e50a52..1df97e5f87d0 100644
--- a/mlir/include/mlir/IR/OpImplementation.h
+++ b/mlir/include/mlir/IR/OpImplementation.h
@@ -188,10 +188,9 @@ inline OpAsmPrinter &operator<<(OpAsmPrinter &p, bool value) {
   return p << (value ? StringRef("true") : "false");
 }
 
-template <typename IteratorT>
-inline OpAsmPrinter &
-operator<<(OpAsmPrinter &p,
-           const iterator_range<ValueTypeIterator<IteratorT>> &types) {
+template <typename ValueRangeT>
+inline OpAsmPrinter &operator<<(OpAsmPrinter &p,
+                                const ValueTypeRange<ValueRangeT> &types) {
   interleaveComma(types, p);
   return p;
 }

diff  --git a/mlir/include/mlir/IR/Operation.h b/mlir/include/mlir/IR/Operation.h
index 28e726edd874..8339f5e26943 100644
--- a/mlir/include/mlir/IR/Operation.h
+++ b/mlir/include/mlir/IR/Operation.h
@@ -232,7 +232,7 @@ class Operation final
 
   // Support operand type iteration.
   using operand_type_iterator = operand_range::type_iterator;
-  using operand_type_range = iterator_range<operand_type_iterator>;
+  using operand_type_range = operand_range::type_range;
   operand_type_iterator operand_type_begin() { return operand_begin(); }
   operand_type_iterator operand_type_end() { return operand_end(); }
   operand_type_range getOperandTypes() { return getOperands().getTypes(); }
@@ -260,7 +260,7 @@ class Operation final
 
   /// Support result type iteration.
   using result_type_iterator = result_range::type_iterator;
-  using result_type_range = ArrayRef<Type>;
+  using result_type_range = result_range::type_range;
   result_type_iterator result_type_begin() { return getResultTypes().begin(); }
   result_type_iterator result_type_end() { return getResultTypes().end(); }
   result_type_range getResultTypes();

diff  --git a/mlir/include/mlir/IR/OperationSupport.h b/mlir/include/mlir/IR/OperationSupport.h
index 9b41567a300b..a9a6ff46242c 100644
--- a/mlir/include/mlir/IR/OperationSupport.h
+++ b/mlir/include/mlir/IR/OperationSupport.h
@@ -32,14 +32,17 @@ struct OperationState;
 class OpAsmParser;
 class OpAsmParserResult;
 class OpAsmPrinter;
+class OperandRange;
 class OpFoldResult;
 class ParseResult;
 class Pattern;
 class Region;
+class ResultRange;
 class RewritePattern;
 class Type;
 class Value;
 class ValueRange;
+template <typename ValueRangeT> class ValueTypeRange;
 
 /// This is an adaptor from a list of values to named operands of OpTy.  In a
 /// generic operation context, e.g., in dialect conversions, an ordered array of
@@ -535,6 +538,46 @@ class OpPrintingFlags {
 // Operation Value-Iterators
 //===----------------------------------------------------------------------===//
 
+//===----------------------------------------------------------------------===//
+// TypeRange
+
+/// This class provides an abstraction over the various 
diff erent ranges of
+/// value types. 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 TypeRange
+    : public detail::indexed_accessor_range_base<
+          TypeRange,
+          llvm::PointerUnion<const Value *, const Type *, OpOperand *>, Type,
+          Type, Type> {
+public:
+  using RangeBaseT::RangeBaseT;
+  TypeRange(ArrayRef<Type> types = llvm::None);
+  explicit TypeRange(OperandRange values);
+  explicit TypeRange(ResultRange values);
+  explicit TypeRange(ValueRange values);
+  template <typename ValueRangeT>
+  TypeRange(ValueTypeRange<ValueRangeT> values)
+      : TypeRange(ValueRangeT(values.begin().getCurrent(),
+                              values.end().getCurrent())) {}
+
+private:
+  /// The owner of the range is either:
+  /// * A pointer to the first element of an array of values.
+  /// * A pointer to the first element of an array of types.
+  /// * A pointer to the first element of an array of operands.
+  using OwnerT = llvm::PointerUnion<const Value *, const Type *, OpOperand *>;
+
+  /// See `detail::indexed_accessor_range_base` for details.
+  static OwnerT offset_base(OwnerT object, ptr
diff _t index);
+  /// See `detail::indexed_accessor_range_base` for details.
+  static Type dereference_iterator(OwnerT object, ptr
diff _t index);
+
+  /// Allow access to `offset_base` and `dereference_iterator`.
+  friend RangeBaseT;
+};
+
 //===----------------------------------------------------------------------===//
 // ValueTypeRange
 
@@ -555,6 +598,18 @@ class ValueTypeIterator final
       : llvm::mapped_iterator<ValueIteratorT, Type (*)(Value)>(it, &unwrap) {}
 };
 
+/// This class implements iteration on the types of a given range of values.
+template <typename ValueRangeT>
+class ValueTypeRange final
+    : public llvm::iterator_range<
+          ValueTypeIterator<typename ValueRangeT::iterator>> {
+public:
+  using llvm::iterator_range<
+      ValueTypeIterator<typename ValueRangeT::iterator>>::iterator_range;
+  template <typename Container>
+  ValueTypeRange(Container &&c) : ValueTypeRange(c.begin(), c.end()) {}
+};
+
 //===----------------------------------------------------------------------===//
 // OperandRange
 
@@ -568,7 +623,8 @@ class OperandRange final
 
   /// Returns the types of the values within this range.
   using type_iterator = ValueTypeIterator<iterator>;
-  iterator_range<type_iterator> getTypes() const { return {begin(), end()}; }
+  using type_range = ValueTypeRange<OperandRange>;
+  type_range getTypes() const { return {begin(), end()}; }
 
 private:
   /// See `detail::indexed_accessor_range_base` for details.
@@ -598,7 +654,8 @@ class ResultRange final
 
   /// Returns the types of the values within this range.
   using type_iterator = ArrayRef<Type>::iterator;
-  ArrayRef<Type> getTypes() const;
+  using type_range = ArrayRef<Type>;
+  type_range getTypes() const;
 
 private:
   /// See `indexed_accessor_range` for details.
@@ -666,7 +723,8 @@ class ValueRange final
 
   /// Returns the types of the values within this range.
   using type_iterator = ValueTypeIterator<iterator>;
-  iterator_range<type_iterator> getTypes() const { return {begin(), end()}; }
+  using type_range = ValueTypeRange<ValueRange>;
+  type_range getTypes() const { return {begin(), end()}; }
 
 private:
   using OwnerT = detail::ValueRangeOwner;

diff  --git a/mlir/lib/IR/OperationSupport.cpp b/mlir/lib/IR/OperationSupport.cpp
index 609a6dca6b27..107fc483b96d 100644
--- a/mlir/lib/IR/OperationSupport.cpp
+++ b/mlir/lib/IR/OperationSupport.cpp
@@ -140,6 +140,43 @@ void detail::OperandStorage::grow(ResizableStorage &resizeUtil,
 // Operation Value-Iterators
 //===----------------------------------------------------------------------===//
 
+//===----------------------------------------------------------------------===//
+// TypeRange
+
+TypeRange::TypeRange(ArrayRef<Type> types)
+    : TypeRange(types.data(), types.size()) {}
+TypeRange::TypeRange(OperandRange values)
+    : TypeRange(values.begin().getBase(), values.size()) {}
+TypeRange::TypeRange(ResultRange values)
+    : TypeRange(values.getBase()->getResultTypes().slice(values.getStartIndex(),
+                                                         values.size())) {}
+TypeRange::TypeRange(ValueRange values) : TypeRange(OwnerT(), values.size()) {
+  detail::ValueRangeOwner owner = values.begin().getBase();
+  if (auto *op = reinterpret_cast<Operation *>(owner.ptr.dyn_cast<void *>()))
+    this->base = &op->getResultTypes()[owner.startIndex];
+  else if (auto *operand = owner.ptr.dyn_cast<OpOperand *>())
+    this->base = operand;
+  else
+    this->base = owner.ptr.get<const Value *>();
+}
+
+/// See `detail::indexed_accessor_range_base` for details.
+TypeRange::OwnerT TypeRange::offset_base(OwnerT object, ptr
diff _t index) {
+  if (auto *value = object.dyn_cast<const Value *>())
+    return {value + index};
+  if (auto *operand = object.dyn_cast<OpOperand *>())
+    return {operand + index};
+  return {object.dyn_cast<const Type *>() + index};
+}
+/// See `detail::indexed_accessor_range_base` for details.
+Type TypeRange::dereference_iterator(OwnerT object, ptr
diff _t index) {
+  if (auto *value = object.dyn_cast<const Value *>())
+    return (value + index)->getType();
+  if (auto *operand = object.dyn_cast<OpOperand *>())
+    return (operand + index)->get().getType();
+  return object.dyn_cast<const Type *>()[index];
+}
+
 //===----------------------------------------------------------------------===//
 // OperandRange
 


        


More information about the Mlir-commits mailing list