[flang-commits] [mlir] [flang] Make MLIR Value more consistent in terms of `const` "correctness" (NFC) (PR #72765)

Mehdi Amini via flang-commits flang-commits at lists.llvm.org
Mon Nov 20 12:04:45 PST 2023


https://github.com/joker-eph updated https://github.com/llvm/llvm-project/pull/72765

>From 468a049277e138c98b8d1c0c85ec6c35d0e666b3 Mon Sep 17 00:00:00 2001
From: Mehdi Amini <joker.eph at gmail.com>
Date: Fri, 17 Nov 2023 22:38:27 -0800
Subject: [PATCH] Make MLIR Value more consistent in terms of `const`
 "correctness" (NFC)

MLIR can't really be const-correct (it would need a `ConstValue` class
alongside the `Value` class really, like `ArrayRef` and `MutableArrayRef`).
This is however making is more consistent: method that are directly modifying
the Value shouldn't be marked const.
---
 flang/lib/Optimizer/Dialect/FIRDialect.cpp    |  2 +-
 mlir/docs/Tutorials/Toy/Ch-4.md               |  2 +-
 mlir/examples/toy/Ch4/mlir/Dialect.cpp        |  3 +-
 mlir/examples/toy/Ch5/mlir/Dialect.cpp        |  3 +-
 mlir/examples/toy/Ch6/mlir/Dialect.cpp        |  3 +-
 mlir/examples/toy/Ch7/mlir/Dialect.cpp        |  3 +-
 mlir/include/mlir/IR/Value.h                  | 28 ++++++++++---------
 mlir/include/mlir/Transforms/InliningUtils.h  |  6 ++--
 .../ControlFlowToSPIRV/ControlFlowToSPIRV.cpp |  2 +-
 .../Func/Extensions/InlinerExtension.cpp      |  3 +-
 mlir/lib/Dialect/LLVMIR/IR/LLVMInlining.cpp   |  6 ++--
 mlir/lib/Dialect/Linalg/IR/LinalgDialect.cpp  |  3 +-
 mlir/lib/Dialect/SCF/IR/SCF.cpp               |  3 +-
 mlir/lib/Dialect/SPIRV/IR/SPIRVDialect.cpp    |  3 +-
 mlir/lib/IR/AsmPrinter.cpp                    | 13 +++++----
 mlir/lib/IR/Value.cpp                         |  7 ++---
 mlir/lib/Transforms/Utils/InliningUtils.cpp   |  5 ++--
 .../Dialect/Test/TestDialectInterfaces.cpp    |  3 +-
 18 files changed, 44 insertions(+), 54 deletions(-)

diff --git a/flang/lib/Optimizer/Dialect/FIRDialect.cpp b/flang/lib/Optimizer/Dialect/FIRDialect.cpp
index 997a6c90ada314a..d0176731c292d32 100644
--- a/flang/lib/Optimizer/Dialect/FIRDialect.cpp
+++ b/flang/lib/Optimizer/Dialect/FIRDialect.cpp
@@ -41,7 +41,7 @@ struct FIRInlinerInterface : public mlir::DialectInlinerInterface {
   /// previously returned by the call operation with the operands of the
   /// return.
   void handleTerminator(mlir::Operation *op,
-                        llvm::ArrayRef<mlir::Value> valuesToRepl) const final {
+                        mlir::ValueRange valuesToRepl) const final {
     auto returnOp = llvm::cast<mlir::func::ReturnOp>(op);
     assert(returnOp.getNumOperands() == valuesToRepl.size());
     for (const auto &it : llvm::enumerate(returnOp.getOperands()))
diff --git a/mlir/docs/Tutorials/Toy/Ch-4.md b/mlir/docs/Tutorials/Toy/Ch-4.md
index b9369fec1909682..ae10dc4a0113d76 100644
--- a/mlir/docs/Tutorials/Toy/Ch-4.md
+++ b/mlir/docs/Tutorials/Toy/Ch-4.md
@@ -91,7 +91,7 @@ struct ToyInlinerInterface : public DialectInlinerInterface {
   /// previously returned by the call operation with the operands of the
   /// return.
   void handleTerminator(Operation *op,
-                        ArrayRef<Value> valuesToRepl) const final {
+                        MutableArrayRef<Value> valuesToRepl) const final {
     // Only "toy.return" needs to be handled here.
     auto returnOp = cast<ReturnOp>(op);
 
diff --git a/mlir/examples/toy/Ch4/mlir/Dialect.cpp b/mlir/examples/toy/Ch4/mlir/Dialect.cpp
index cc0ea5c4a63750b..86a0e1df95c17a6 100644
--- a/mlir/examples/toy/Ch4/mlir/Dialect.cpp
+++ b/mlir/examples/toy/Ch4/mlir/Dialect.cpp
@@ -74,8 +74,7 @@ struct ToyInlinerInterface : public DialectInlinerInterface {
 
   /// Handle the given inlined terminator(toy.return) by replacing it with a new
   /// operation as necessary.
-  void handleTerminator(Operation *op,
-                        ArrayRef<Value> valuesToRepl) const final {
+  void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
     // Only "toy.return" needs to be handled here.
     auto returnOp = cast<ReturnOp>(op);
 
diff --git a/mlir/examples/toy/Ch5/mlir/Dialect.cpp b/mlir/examples/toy/Ch5/mlir/Dialect.cpp
index 74adfeb64cce5ee..c587dd27dc2b9e7 100644
--- a/mlir/examples/toy/Ch5/mlir/Dialect.cpp
+++ b/mlir/examples/toy/Ch5/mlir/Dialect.cpp
@@ -74,8 +74,7 @@ struct ToyInlinerInterface : public DialectInlinerInterface {
 
   /// Handle the given inlined terminator(toy.return) by replacing it with a new
   /// operation as necessary.
-  void handleTerminator(Operation *op,
-                        ArrayRef<Value> valuesToRepl) const final {
+  void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
     // Only "toy.return" needs to be handled here.
     auto returnOp = cast<ReturnOp>(op);
 
diff --git a/mlir/examples/toy/Ch6/mlir/Dialect.cpp b/mlir/examples/toy/Ch6/mlir/Dialect.cpp
index 74adfeb64cce5ee..c587dd27dc2b9e7 100644
--- a/mlir/examples/toy/Ch6/mlir/Dialect.cpp
+++ b/mlir/examples/toy/Ch6/mlir/Dialect.cpp
@@ -74,8 +74,7 @@ struct ToyInlinerInterface : public DialectInlinerInterface {
 
   /// Handle the given inlined terminator(toy.return) by replacing it with a new
   /// operation as necessary.
-  void handleTerminator(Operation *op,
-                        ArrayRef<Value> valuesToRepl) const final {
+  void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
     // Only "toy.return" needs to be handled here.
     auto returnOp = cast<ReturnOp>(op);
 
diff --git a/mlir/examples/toy/Ch7/mlir/Dialect.cpp b/mlir/examples/toy/Ch7/mlir/Dialect.cpp
index f17173f007645f1..b268b1ef157f9a0 100644
--- a/mlir/examples/toy/Ch7/mlir/Dialect.cpp
+++ b/mlir/examples/toy/Ch7/mlir/Dialect.cpp
@@ -80,8 +80,7 @@ struct ToyInlinerInterface : public DialectInlinerInterface {
 
   /// Handle the given inlined terminator(toy.return) by replacing it with a new
   /// operation as necessary.
-  void handleTerminator(Operation *op,
-                        ArrayRef<Value> valuesToRepl) const final {
+  void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
     // Only "toy.return" needs to be handled here.
     auto returnOp = cast<ReturnOp>(op);
 
diff --git a/mlir/include/mlir/IR/Value.h b/mlir/include/mlir/IR/Value.h
index dbcc10d4f4df80e..1c5bf09c1aeb87a 100644
--- a/mlir/include/mlir/IR/Value.h
+++ b/mlir/include/mlir/IR/Value.h
@@ -90,6 +90,9 @@ class alignas(8) ValueImpl : public IRObjectWithUseList<OpOperand> {
 /// class has value-type semantics and is just a simple wrapper around a
 /// ValueImpl that is either owner by a block(in the case of a BlockArgument) or
 /// an Operation(in the case of an OpResult).
+/// As most IR construct, this isn't const-correct, but we keep method
+/// consistent and as such method that immediately modify this Value aren't
+/// marked `const` (include modifying the Value use-list).
 class Value {
 public:
   constexpr Value(detail::ValueImpl *impl = nullptr) : impl(impl) {}
@@ -158,26 +161,25 @@ class Value {
   //===--------------------------------------------------------------------===//
 
   /// Drop all uses of this object from their respective owners.
-  void dropAllUses() const { return impl->dropAllUses(); }
+  void dropAllUses() { return impl->dropAllUses(); }
 
   /// Replace all uses of 'this' value with the new value, updating anything in
   /// the IR that uses 'this' to use the other value instead.  When this returns
   /// there are zero uses of 'this'.
-  void replaceAllUsesWith(Value newValue) const {
+  void replaceAllUsesWith(Value newValue) {
     impl->replaceAllUsesWith(newValue);
   }
 
   /// Replace all uses of 'this' value with 'newValue', updating anything in the
   /// IR that uses 'this' to use the other value instead except if the user is
   /// listed in 'exceptions' .
-  void
-  replaceAllUsesExcept(Value newValue,
-                       const SmallPtrSetImpl<Operation *> &exceptions) const;
+  void replaceAllUsesExcept(Value newValue,
+                            const SmallPtrSetImpl<Operation *> &exceptions);
 
   /// Replace all uses of 'this' value with 'newValue', updating anything in the
   /// IR that uses 'this' to use the other value instead except if the user is
   /// 'exceptedUser'.
-  void replaceAllUsesExcept(Value newValue, Operation *exceptedUser) const;
+  void replaceAllUsesExcept(Value newValue, Operation *exceptedUser);
 
   /// Replace all uses of 'this' value with 'newValue' if the given callback
   /// returns true.
@@ -185,7 +187,7 @@ class Value {
                          function_ref<bool(OpOperand &)> shouldReplace);
 
   /// Returns true if the value is used outside of the given block.
-  bool isUsedOutsideOfBlock(Block *block);
+  bool isUsedOutsideOfBlock(Block *block) const;
 
   /// Shuffle the use list order according to the provided indices. It is
   /// responsibility of the caller to make sure that the indices map the current
@@ -224,14 +226,14 @@ class Value {
   //===--------------------------------------------------------------------===//
   // Utilities
 
-  void print(raw_ostream &os);
-  void print(raw_ostream &os, const OpPrintingFlags &flags);
-  void print(raw_ostream &os, AsmState &state);
-  void dump();
+  void print(raw_ostream &os) const;
+  void print(raw_ostream &os, const OpPrintingFlags &flags) const;
+  void print(raw_ostream &os, AsmState &state) const;
+  void dump() const;
 
   /// Print this value as if it were an operand.
-  void printAsOperand(raw_ostream &os, AsmState &state);
-  void printAsOperand(raw_ostream &os, const OpPrintingFlags &flags);
+  void printAsOperand(raw_ostream &os, AsmState &state) const;
+  void printAsOperand(raw_ostream &os, const OpPrintingFlags &flags) const;
 
   /// Methods for supporting PointerLikeTypeTraits.
   void *getAsOpaquePointer() const { return impl; }
diff --git a/mlir/include/mlir/Transforms/InliningUtils.h b/mlir/include/mlir/Transforms/InliningUtils.h
index a602c4e208f1801..88fc033a6ab7be5 100644
--- a/mlir/include/mlir/Transforms/InliningUtils.h
+++ b/mlir/include/mlir/Transforms/InliningUtils.h
@@ -17,6 +17,7 @@
 #include "mlir/IR/DialectInterface.h"
 #include "mlir/IR/Location.h"
 #include "mlir/IR/Region.h"
+#include "mlir/IR/ValueRange.h"
 #include <optional>
 
 namespace mlir {
@@ -116,7 +117,7 @@ class DialectInlinerInterface
   /// operation). The given 'op' will be removed by the caller, after this
   /// function has been called.
   virtual void handleTerminator(Operation *op,
-                                ArrayRef<Value> valuesToReplace) const {
+                                ValueRange valuesToReplace) const {
     llvm_unreachable(
         "must implement handleTerminator in the case of one inlined block");
   }
@@ -211,8 +212,7 @@ class InlinerInterface
   //===--------------------------------------------------------------------===//
 
   virtual void handleTerminator(Operation *op, Block *newDest) const;
-  virtual void handleTerminator(Operation *op,
-                                ArrayRef<Value> valuesToRepl) const;
+  virtual void handleTerminator(Operation *op, ValueRange valuesToRepl) const;
 
   virtual Value handleArgument(OpBuilder &builder, Operation *call,
                                Operation *callable, Value argument,
diff --git a/mlir/lib/Conversion/ControlFlowToSPIRV/ControlFlowToSPIRV.cpp b/mlir/lib/Conversion/ControlFlowToSPIRV/ControlFlowToSPIRV.cpp
index 8907756d33845a0..995eecfc3e9c36e 100644
--- a/mlir/lib/Conversion/ControlFlowToSPIRV/ControlFlowToSPIRV.cpp
+++ b/mlir/lib/Conversion/ControlFlowToSPIRV/ControlFlowToSPIRV.cpp
@@ -34,7 +34,7 @@ static LogicalResult legalizeBlockArguments(Block &block, Operation *op,
                                             const TypeConverter &converter) {
   auto builder = OpBuilder::atBlockBegin(&block);
   for (unsigned i = 0; i < block.getNumArguments(); ++i) {
-    const auto arg = block.getArgument(i);
+    BlockArgument arg = block.getArgument(i);
     if (converter.isLegal(arg.getType()))
       continue;
     Type ty = arg.getType();
diff --git a/mlir/lib/Dialect/Func/Extensions/InlinerExtension.cpp b/mlir/lib/Dialect/Func/Extensions/InlinerExtension.cpp
index 125cc3ca649fbb3..719a74a29a62214 100644
--- a/mlir/lib/Dialect/Func/Extensions/InlinerExtension.cpp
+++ b/mlir/lib/Dialect/Func/Extensions/InlinerExtension.cpp
@@ -63,8 +63,7 @@ struct FuncInlinerInterface : public DialectInlinerInterface {
 
   /// Handle the given inlined terminator by replacing it with a new operation
   /// as necessary.
-  void handleTerminator(Operation *op,
-                        ArrayRef<Value> valuesToRepl) const final {
+  void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
     // Only return needs to be handled here.
     auto returnOp = cast<ReturnOp>(op);
 
diff --git a/mlir/lib/Dialect/LLVMIR/IR/LLVMInlining.cpp b/mlir/lib/Dialect/LLVMIR/IR/LLVMInlining.cpp
index 6063abdba7b9a1f..2abb9b0e3986872 100644
--- a/mlir/lib/Dialect/LLVMIR/IR/LLVMInlining.cpp
+++ b/mlir/lib/Dialect/LLVMIR/IR/LLVMInlining.cpp
@@ -737,15 +737,13 @@ struct LLVMInlinerInterface : public DialectInlinerInterface {
   /// Handle the given inlined return by replacing the uses of the call with the
   /// operands of the return. This overload is called when the inlined region
   /// only contains one block.
-  void handleTerminator(Operation *op,
-                        ArrayRef<Value> valuesToRepl) const final {
+  void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
     // Return will be the only terminator present.
     auto returnOp = cast<LLVM::ReturnOp>(op);
 
     // Replace the values directly with the return operands.
     assert(returnOp.getNumOperands() == valuesToRepl.size());
-    for (const auto &[dst, src] :
-         llvm::zip(valuesToRepl, returnOp.getOperands()))
+    for (auto [dst, src] : llvm::zip(valuesToRepl, returnOp.getOperands()))
       dst.replaceAllUsesWith(src);
   }
 
diff --git a/mlir/lib/Dialect/Linalg/IR/LinalgDialect.cpp b/mlir/lib/Dialect/Linalg/IR/LinalgDialect.cpp
index 30196e207d4a0ad..5069d43e7db95f8 100644
--- a/mlir/lib/Dialect/Linalg/IR/LinalgDialect.cpp
+++ b/mlir/lib/Dialect/Linalg/IR/LinalgDialect.cpp
@@ -53,8 +53,7 @@ struct LinalgInlinerInterface : public DialectInlinerInterface {
   }
   // Handle the given inlined terminator by replacing it with a new operation
   // as necessary. Required when the region has only one block.
-  void handleTerminator(Operation *op,
-                        ArrayRef<Value> valuesToRepl) const final {}
+  void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {}
 };
 
 } // namespace
diff --git a/mlir/lib/Dialect/SCF/IR/SCF.cpp b/mlir/lib/Dialect/SCF/IR/SCF.cpp
index 646284f8a9db435..3b55704c4ea07fa 100644
--- a/mlir/lib/Dialect/SCF/IR/SCF.cpp
+++ b/mlir/lib/Dialect/SCF/IR/SCF.cpp
@@ -50,8 +50,7 @@ struct SCFInlinerInterface : public DialectInlinerInterface {
   }
   // Handle the given inlined terminator by replacing it with a new operation
   // as necessary. Required when the region has only one block.
-  void handleTerminator(Operation *op,
-                        ArrayRef<Value> valuesToRepl) const final {
+  void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
     auto retValOp = dyn_cast<scf::YieldOp>(op);
     if (!retValOp)
       return;
diff --git a/mlir/lib/Dialect/SPIRV/IR/SPIRVDialect.cpp b/mlir/lib/Dialect/SPIRV/IR/SPIRVDialect.cpp
index 2de849dc4465e37..8a68decc5878c8e 100644
--- a/mlir/lib/Dialect/SPIRV/IR/SPIRVDialect.cpp
+++ b/mlir/lib/Dialect/SPIRV/IR/SPIRVDialect.cpp
@@ -101,8 +101,7 @@ struct SPIRVInlinerInterface : public DialectInlinerInterface {
 
   /// Handle the given inlined terminator by replacing it with a new operation
   /// as necessary.
-  void handleTerminator(Operation *op,
-                        ArrayRef<Value> valuesToRepl) const final {
+  void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
     // Only spirv.ReturnValue needs to be handled here.
     auto retValOp = dyn_cast<spirv::ReturnValueOp>(op);
     if (!retValOp)
diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp
index 6a67fc707b4976b..4b76dcf7f8a9f7c 100644
--- a/mlir/lib/IR/AsmPrinter.cpp
+++ b/mlir/lib/IR/AsmPrinter.cpp
@@ -3781,8 +3781,8 @@ void IntegerSet::print(raw_ostream &os) const {
   AsmPrinter::Impl(os, state.getImpl()).printIntegerSet(*this);
 }
 
-void Value::print(raw_ostream &os) { print(os, OpPrintingFlags()); }
-void Value::print(raw_ostream &os, const OpPrintingFlags &flags) {
+void Value::print(raw_ostream &os) const { print(os, OpPrintingFlags()); }
+void Value::print(raw_ostream &os, const OpPrintingFlags &flags) const {
   if (!impl) {
     os << "<<NULL VALUE>>";
     return;
@@ -3795,7 +3795,7 @@ void Value::print(raw_ostream &os, const OpPrintingFlags &flags) {
   os << "<block argument> of type '" << arg.getType()
      << "' at index: " << arg.getArgNumber();
 }
-void Value::print(raw_ostream &os, AsmState &state) {
+void Value::print(raw_ostream &os, AsmState &state) const {
   if (!impl) {
     os << "<<NULL VALUE>>";
     return;
@@ -3810,12 +3810,12 @@ void Value::print(raw_ostream &os, AsmState &state) {
      << "' at index: " << arg.getArgNumber();
 }
 
-void Value::dump() {
+void Value::dump() const {
   print(llvm::errs());
   llvm::errs() << "\n";
 }
 
-void Value::printAsOperand(raw_ostream &os, AsmState &state) {
+void Value::printAsOperand(raw_ostream &os, AsmState &state) const {
   // TODO: This doesn't necessarily capture all potential cases.
   // Currently, region arguments can be shadowed when printing the main
   // operation. If the IR hasn't been printed, this will produce the old SSA
@@ -3840,7 +3840,8 @@ static Operation *findParent(Operation *op, bool shouldUseLocalScope) {
   return op;
 }
 
-void Value::printAsOperand(raw_ostream &os, const OpPrintingFlags &flags) {
+void Value::printAsOperand(raw_ostream &os,
+                           const OpPrintingFlags &flags) const {
   Operation *op;
   if (auto result = llvm::dyn_cast<OpResult>(*this)) {
     op = result.getOwner();
diff --git a/mlir/lib/IR/Value.cpp b/mlir/lib/IR/Value.cpp
index 6b5195da5e47ba2..178765353cc1058 100644
--- a/mlir/lib/IR/Value.cpp
+++ b/mlir/lib/IR/Value.cpp
@@ -59,7 +59,7 @@ Block *Value::getParentBlock() {
 /// the IR that uses 'this' to use the other value instead except if the user is
 /// listed in 'exceptions' .
 void Value::replaceAllUsesExcept(
-    Value newValue, const SmallPtrSetImpl<Operation *> &exceptions) const {
+    Value newValue, const SmallPtrSetImpl<Operation *> &exceptions) {
   for (OpOperand &use : llvm::make_early_inc_range(getUses())) {
     if (exceptions.count(use.getOwner()) == 0)
       use.set(newValue);
@@ -69,8 +69,7 @@ void Value::replaceAllUsesExcept(
 /// Replace all uses of 'this' value with 'newValue', updating anything in the
 /// IR that uses 'this' to use the other value instead except if the user is
 /// 'exceptedUser'.
-void Value::replaceAllUsesExcept(Value newValue,
-                                 Operation *exceptedUser) const {
+void Value::replaceAllUsesExcept(Value newValue, Operation *exceptedUser) {
   for (OpOperand &use : llvm::make_early_inc_range(getUses())) {
     if (use.getOwner() != exceptedUser)
       use.set(newValue);
@@ -87,7 +86,7 @@ void Value::replaceUsesWithIf(Value newValue,
 }
 
 /// Returns true if the value is used outside of the given block.
-bool Value::isUsedOutsideOfBlock(Block *block) {
+bool Value::isUsedOutsideOfBlock(Block *block) const {
   return llvm::any_of(getUsers(), [block](Operation *user) {
     return user->getBlock() != block;
   });
diff --git a/mlir/lib/Transforms/Utils/InliningUtils.cpp b/mlir/lib/Transforms/Utils/InliningUtils.cpp
index 00c5405079def0e..ba146920fae2e99 100644
--- a/mlir/lib/Transforms/Utils/InliningUtils.cpp
+++ b/mlir/lib/Transforms/Utils/InliningUtils.cpp
@@ -97,7 +97,7 @@ void InlinerInterface::handleTerminator(Operation *op, Block *newDest) const {
 /// Handle the given inlined terminator by replacing it with a new operation
 /// as necessary.
 void InlinerInterface::handleTerminator(Operation *op,
-                                        ArrayRef<Value> valuesToRepl) const {
+                                        ValueRange valuesToRepl) const {
   auto *handler = getInterfaceFor(op);
   assert(handler && "expected valid dialect handler");
   handler->handleTerminator(op, valuesToRepl);
@@ -289,8 +289,7 @@ inlineRegionImpl(InlinerInterface &interface, Region *src, Block *inlineBlock,
                        firstBlockTerminator->getOperands());
 
     // Have the interface handle the terminator of this block.
-    interface.handleTerminator(firstBlockTerminator,
-                               llvm::to_vector<6>(resultsToReplace));
+    interface.handleTerminator(firstBlockTerminator, resultsToReplace);
     firstBlockTerminator->erase();
 
     // Merge the post insert block into the cloned entry block.
diff --git a/mlir/test/lib/Dialect/Test/TestDialectInterfaces.cpp b/mlir/test/lib/Dialect/Test/TestDialectInterfaces.cpp
index ab7d2486db9aec7..80ddcdc8ea69f7c 100644
--- a/mlir/test/lib/Dialect/Test/TestDialectInterfaces.cpp
+++ b/mlir/test/lib/Dialect/Test/TestDialectInterfaces.cpp
@@ -314,8 +314,7 @@ struct TestInlinerInterface : public DialectInlinerInterface {
 
   /// Handle the given inlined terminator by replacing it with a new operation
   /// as necessary.
-  void handleTerminator(Operation *op,
-                        ArrayRef<Value> valuesToRepl) const final {
+  void handleTerminator(Operation *op, ValueRange valuesToRepl) const final {
     // Only handle "test.return" here.
     auto returnOp = dyn_cast<TestReturnOp>(op);
     if (!returnOp)



More information about the flang-commits mailing list