[Mlir-commits] [mlir] aea3026 - [mlir] Move the Operation use iteration utilities to ResultRange
River Riddle
llvmlistbot at llvm.org
Wed Aug 25 02:38:03 PDT 2021
Author: River Riddle
Date: 2021-08-25T09:27:35Z
New Revision: aea3026ea7ffbdacf45e068e139ebf78deeade9d
URL: https://github.com/llvm/llvm-project/commit/aea3026ea7ffbdacf45e068e139ebf78deeade9d
DIFF: https://github.com/llvm/llvm-project/commit/aea3026ea7ffbdacf45e068e139ebf78deeade9d.diff
LOG: [mlir] Move the Operation use iteration utilities to ResultRange
This allows for iterating and interacting with the uses of a specific subset of
results as opposed to just the full range.
Differential Revision: https://reviews.llvm.org/D108586
Added:
Modified:
mlir/include/mlir/IR/Operation.h
mlir/include/mlir/IR/OperationSupport.h
mlir/lib/IR/Operation.cpp
mlir/lib/IR/OperationSupport.cpp
Removed:
################################################################################
diff --git a/mlir/include/mlir/IR/Operation.h b/mlir/include/mlir/IR/Operation.h
index 8b22695db3d1b..05f8e408cf880 100644
--- a/mlir/include/mlir/IR/Operation.h
+++ b/mlir/include/mlir/IR/Operation.h
@@ -532,52 +532,20 @@ class alignas(8) Operation final
result.dropAllUses();
}
- /// This class implements a use iterator for the Operation. This iterates over
- /// all uses of all results.
- class UseIterator final
- : public llvm::iterator_facade_base<
- UseIterator, std::forward_iterator_tag, OpOperand> {
- public:
- /// Initialize UseIterator for op, specify end to return iterator to last
- /// use.
- explicit UseIterator(Operation *op, 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 operation whose uses are being iterated over.
- Operation *op;
- /// The result of op who's uses are being iterated over.
- Operation::result_iterator res;
- /// The use of the result.
- Value::use_iterator use;
- };
- using use_iterator = UseIterator;
- using use_range = iterator_range<use_iterator>;
+ using use_iterator = result_range::use_iterator;
+ using use_range = result_range::use_range;
- use_iterator use_begin() { return use_iterator(this); }
- use_iterator use_end() { return use_iterator(this, /*end=*/true); }
+ use_iterator use_begin() { return getResults().use_begin(); }
+ use_iterator use_end() { return getResults().use_end(); }
/// Returns a range of all uses, which is useful for iterating over all uses.
- use_range getUses() { return {use_begin(), use_end()}; }
+ use_range getUses() { return getResults().getUses(); }
/// Returns true if this operation has exactly one use.
bool hasOneUse() { return llvm::hasSingleElement(getUses()); }
/// Returns true if this operation has no uses.
- bool use_empty() {
- return llvm::all_of(getOpResults(),
- [](OpResult result) { return result.use_empty(); });
- }
+ bool use_empty() { return getResults().use_empty(); }
/// Returns true if the results of this operation are used outside of the
/// given block.
diff --git a/mlir/include/mlir/IR/OperationSupport.h b/mlir/include/mlir/IR/OperationSupport.h
index 0af719c92d911..05273505946fa 100644
--- a/mlir/include/mlir/IR/OperationSupport.h
+++ b/mlir/include/mlir/IR/OperationSupport.h
@@ -903,12 +903,48 @@ class ResultRange final
public:
using RangeBaseT::RangeBaseT;
+ //===--------------------------------------------------------------------===//
+ // 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(); });
+ }
+
+ //===--------------------------------------------------------------------===//
+ // 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,
@@ -925,6 +961,34 @@ class ResultRange final
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
diff --git a/mlir/lib/IR/Operation.cpp b/mlir/lib/IR/Operation.cpp
index d5b8f1c2903e3..8e521d31f0b89 100644
--- a/mlir/lib/IR/Operation.cpp
+++ b/mlir/lib/IR/Operation.cpp
@@ -1314,38 +1314,3 @@ void impl::ensureRegionTerminator(
OpBuilder opBuilder(builder.getContext());
ensureRegionTerminator(region, opBuilder, loc, buildTerminatorOp);
}
-
-//===----------------------------------------------------------------------===//
-// UseIterator
-//===----------------------------------------------------------------------===//
-
-Operation::UseIterator::UseIterator(Operation *op, bool end)
- : op(op), res(end ? op->result_end() : op->result_begin()) {
- // Only initialize current use if there are results/can be uses.
- if (op->getNumResults())
- skipOverResultsWithNoUsers();
-}
-
-Operation::UseIterator &Operation::UseIterator::operator++() {
- // We increment over uses, if we reach the last use then move to next
- // result.
- if (use != (*res).use_end())
- ++use;
- if (use == (*res).use_end()) {
- ++res;
- skipOverResultsWithNoUsers();
- }
- return *this;
-}
-
-void Operation::UseIterator::skipOverResultsWithNoUsers() {
- while (res != op->result_end() && (*res).use_empty())
- ++res;
-
- // If we are at the last result, then set use to first use of
- // first result (sentinel value used for end).
- if (res == op->result_end())
- use = {};
- else
- use = (*res).use_begin();
-}
diff --git a/mlir/lib/IR/OperationSupport.cpp b/mlir/lib/IR/OperationSupport.cpp
index 5b472db8c3f4b..955898dc6b569 100644
--- a/mlir/lib/IR/OperationSupport.cpp
+++ b/mlir/lib/IR/OperationSupport.cpp
@@ -552,6 +552,59 @@ MutableOperandRange MutableOperandRangeRange::dereference(const OwnerT &object,
MutableOperandRange::OperandSegment(index, object.second));
}
+//===----------------------------------------------------------------------===//
+// ResultRange
+
+ResultRange::use_range ResultRange::getUses() const {
+ return {use_begin(), use_end()};
+}
+ResultRange::use_iterator ResultRange::use_begin() const {
+ return use_iterator(*this);
+}
+ResultRange::use_iterator ResultRange::use_end() const {
+ return use_iterator(*this, /*end=*/true);
+}
+ResultRange::user_range ResultRange::getUsers() {
+ return {user_begin(), user_end()};
+}
+ResultRange::user_iterator ResultRange::user_begin() {
+ return user_iterator(use_begin());
+}
+ResultRange::user_iterator ResultRange::user_end() {
+ return user_iterator(use_end());
+}
+
+ResultRange::UseIterator::UseIterator(ResultRange results, bool end)
+ : it(end ? results.end() : results.begin()), endIt(results.end()) {
+ // Only initialize current use if there are results/can be uses.
+ if (it != endIt)
+ skipOverResultsWithNoUsers();
+}
+
+ResultRange::UseIterator &ResultRange::UseIterator::operator++() {
+ // We increment over uses, if we reach the last use then move to next
+ // result.
+ if (use != (*it).use_end())
+ ++use;
+ if (use == (*it).use_end()) {
+ ++it;
+ skipOverResultsWithNoUsers();
+ }
+ return *this;
+}
+
+void ResultRange::UseIterator::skipOverResultsWithNoUsers() {
+ while (it != endIt && (*it).use_empty())
+ ++it;
+
+ // If we are at the last result, then set use to first use of
+ // first result (sentinel value used for end).
+ if (it == endIt)
+ use = {};
+ else
+ use = (*it).use_begin();
+}
+
//===----------------------------------------------------------------------===//
// ValueRange
More information about the Mlir-commits
mailing list