[Mlir-commits] [mlir] 054ec47 - [mlir] NFC: move DiagnosedSilenceableFailure to Utils in Transform dialect

Alex Zinenko llvmlistbot at llvm.org
Fri Jan 6 04:23:51 PST 2023


Author: Alex Zinenko
Date: 2023-01-06T12:23:37Z
New Revision: 054ec47c91d6fe8bed219ff465547a31c1fbb0c2

URL: https://github.com/llvm/llvm-project/commit/054ec47c91d6fe8bed219ff465547a31c1fbb0c2
DIFF: https://github.com/llvm/llvm-project/commit/054ec47c91d6fe8bed219ff465547a31c1fbb0c2.diff

LOG: [mlir] NFC: move DiagnosedSilenceableFailure to Utils in Transform dialect

It was originally placed in TransformInterfaces for convenience, but it
is really a generic utility. It may also create an include cycle between
TransformTypes and TransformInterfaces if the latter needs to include
the former because the former uses the failure util.

Reviewed By: springerm

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

Added: 
    mlir/include/mlir/Dialect/Transform/Utils/DiagnosedSilenceableFailure.h
    mlir/lib/Dialect/Transform/Utils/DiagnosedSilenceableFailure.cpp

Modified: 
    mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h
    mlir/include/mlir/Dialect/Transform/IR/TransformOps.h
    mlir/include/mlir/Dialect/Transform/IR/TransformTypes.h
    mlir/include/mlir/Dialect/Transform/Utils/Utils.h
    mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
    mlir/lib/Dialect/Transform/IR/CMakeLists.txt
    mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp
    mlir/lib/Dialect/Transform/Utils/CMakeLists.txt
    mlir/lib/Dialect/Transform/Utils/Utils.cpp
    utils/bazel/llvm-project-overlay/mlir/BUILD.bazel

Removed: 
    


################################################################################
diff  --git a/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h b/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h
index 4cfc2e44ab96a..aa9a5b25e562f 100644
--- a/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h
+++ b/mlir/include/mlir/Dialect/Transform/IR/TransformInterfaces.h
@@ -9,271 +9,14 @@
 #ifndef MLIR_DIALECT_TRANSFORM_IR_TRANSFORMINTERFACES_H
 #define MLIR_DIALECT_TRANSFORM_IR_TRANSFORMINTERFACES_H
 
+#include "mlir/Dialect/Transform/IR/TransformTypes.h"
+#include "mlir/Dialect/Transform/Utils/DiagnosedSilenceableFailure.h"
 #include "mlir/IR/OpDefinition.h"
 
 #include "mlir/Interfaces/SideEffectInterfaces.h"
 #include "mlir/Support/LogicalResult.h"
-#include "llvm/ADT/ScopeExit.h"
 
 namespace mlir {
-
-/// The result of a transform IR operation application. This can have one of the
-/// three states:
-///   - success;
-///   - silenceable (recoverable) failure with yet-unreported diagnostic;
-///   - definite failure.
-/// Silenceable failure is intended to communicate information about
-/// transformations that did not apply but in a way that supports recovery,
-/// for example, they did not modify the payload IR or modified it in some
-/// predictable way. They are associated with a Diagnostic that provides more
-/// details on the failure. Silenceable failure can be discarded, turning the
-/// result into success, or "reported", emitting the diagnostic and turning the
-/// result into definite failure.
-/// Transform IR operations containing other operations are allowed to do either
-/// with the results of the nested transformations, but must propagate definite
-/// failures as their diagnostics have been already reported to the user.
-class [[nodiscard]] DiagnosedSilenceableFailure {
-public:
-  DiagnosedSilenceableFailure(const DiagnosedSilenceableFailure &) = delete;
-  DiagnosedSilenceableFailure &
-  operator=(const DiagnosedSilenceableFailure &) = delete;
-  DiagnosedSilenceableFailure(DiagnosedSilenceableFailure &&) = default;
-  DiagnosedSilenceableFailure &
-  operator=(DiagnosedSilenceableFailure &&) = default;
-
-  /// Constructs a DiagnosedSilenceableFailure in the success state.
-  static DiagnosedSilenceableFailure success() {
-    return DiagnosedSilenceableFailure(::mlir::success());
-  }
-
-  /// Constructs a DiagnosedSilenceableFailure in the failure state. Typically,
-  /// a diagnostic has been emitted before this.
-  static DiagnosedSilenceableFailure definiteFailure() {
-    return DiagnosedSilenceableFailure(::mlir::failure());
-  }
-
-  /// Constructs a DiagnosedSilenceableFailure in the silenceable failure state,
-  /// ready to emit the given diagnostic. This is considered a failure
-  /// regardless of the diagnostic severity.
-  static DiagnosedSilenceableFailure silenceableFailure(Diagnostic &&diag) {
-    return DiagnosedSilenceableFailure(std::forward<Diagnostic>(diag));
-  }
-  static DiagnosedSilenceableFailure
-  silenceableFailure(SmallVector<Diagnostic> &&diag) {
-    return DiagnosedSilenceableFailure(
-        std::forward<SmallVector<Diagnostic>>(diag));
-  }
-
-  /// Converts all kinds of failure into a LogicalResult failure, emitting the
-  /// diagnostic if necessary. Must not be called more than once.
-  LogicalResult checkAndReport() {
-#if LLVM_ENABLE_ABI_BREAKING_CHECKS
-    assert(!reported && "attempting to report a diagnostic more than once");
-    reported = true;
-#endif // LLVM_ENABLE_ABI_BREAKING_CHECKS
-    if (!diagnostics.empty()) {
-      for (auto &&diagnostic : diagnostics) {
-        diagnostic.getLocation().getContext()->getDiagEngine().emit(
-            std::move(diagnostic));
-      }
-      diagnostics.clear();
-      result = ::mlir::failure();
-    }
-    return result;
-  }
-
-  /// Returns `true` if this is a success.
-  bool succeeded() const {
-    return ::mlir::succeeded(result) && diagnostics.empty();
-  }
-
-  /// Returns `true` if this is a definite failure.
-  bool isDefiniteFailure() const {
-    return ::mlir::failed(result) && diagnostics.empty();
-  }
-
-  /// Returns `true` if this is a silenceable failure.
-  bool isSilenceableFailure() const { return !diagnostics.empty(); }
-
-  /// Returns the diagnostic message without emitting it. Expects this object
-  /// to be a silenceable failure.
-  std::string getMessage() const {
-    std::string res;
-    for (auto &diagnostic : diagnostics) {
-      res.append(diagnostic.str());
-      res.append("\n");
-    }
-    return res;
-  }
-
-  /// Returns a string representation of the failure mode (for error reporting).
-  std::string getStatusString() const {
-    if (succeeded())
-      return "success";
-    if (isSilenceableFailure())
-      return "silenceable failure";
-    return "definite failure";
-  }
-
-  /// Converts silenceable failure into LogicalResult success without reporting
-  /// the diagnostic, preserves the other states.
-  LogicalResult silence() {
-    if (!diagnostics.empty()) {
-      diagnostics.clear();
-      result = ::mlir::success();
-    }
-    return result;
-  }
-
-  /// Take the diagnostics and silence.
-  void takeDiagnostics(SmallVectorImpl<Diagnostic> &diags) {
-    assert(!diagnostics.empty() && "expected a diagnostic to be present");
-    diags.append(std::make_move_iterator(diagnostics.begin()),
-                 std::make_move_iterator(diagnostics.end()));
-  }
-
-  /// Streams the given values into the last diagnostic.
-  /// Expects this object to be a silenceable failure.
-  template <typename T>
-  DiagnosedSilenceableFailure &operator<<(T &&value) & {
-    assert(isSilenceableFailure() &&
-           "can only append output in silenceable failure state");
-    diagnostics.back() << std::forward<T>(value);
-    return *this;
-  }
-  template <typename T>
-  DiagnosedSilenceableFailure &&operator<<(T &&value) && {
-    return std::move(this->operator<<(std::forward<T>(value)));
-  }
-
-  /// Attaches a note to the last diagnostic.
-  /// Expects this object to be a silenceable failure.
-  Diagnostic &attachNote(Optional<Location> loc = std::nullopt) {
-    assert(isSilenceableFailure() &&
-           "can only attach notes to silenceable failures");
-    return diagnostics.back().attachNote(loc);
-  }
-
-private:
-  explicit DiagnosedSilenceableFailure(LogicalResult result) : result(result) {}
-  explicit DiagnosedSilenceableFailure(Diagnostic &&diagnostic)
-      : result(failure()) {
-    diagnostics.emplace_back(std::move(diagnostic));
-  }
-  explicit DiagnosedSilenceableFailure(SmallVector<Diagnostic> &&diagnostics)
-      : diagnostics(std::move(diagnostics)), result(failure()) {}
-
-  /// The diagnostics associated with this object. If non-empty, the object is
-  /// considered to be in the silenceable failure state regardless of the
-  /// `result` field.
-  SmallVector<Diagnostic, 1> diagnostics;
-
-  /// The "definite" logical state, either success or failure.
-  /// Ignored if the diagnostics message is present.
-  LogicalResult result;
-
-#if LLVM_ENABLE_ABI_BREAKING_CHECKS
-  /// Whether the associated diagnostics have been reported.
-  /// Diagnostics reporting consumes the diagnostics, so we need a mechanism to
-  /// 
diff erentiate reported diagnostics from a state where it was never
-  /// created.
-  bool reported = false;
-#endif // LLVM_ENABLE_ABI_BREAKING_CHECKS
-};
-
-class DiagnosedDefiniteFailure;
-
-DiagnosedDefiniteFailure emitDefiniteFailure(Location loc,
-                                             const Twine &message = {});
-
-/// A compatibility class connecting `InFlightDiagnostic` to
-/// `DiagnosedSilenceableFailure` while providing an interface similar to the
-/// former. Implicitly convertible to `DiagnosticSilenceableFailure` in definite
-/// failure state and to `LogicalResult` failure. Reports the error on
-/// conversion or on destruction. Instances of this class can be created by
-/// `emitDefiniteFailure()`.
-class DiagnosedDefiniteFailure {
-  friend DiagnosedDefiniteFailure emitDefiniteFailure(Location loc,
-                                                      const Twine &message);
-
-public:
-  /// Only move-constructible because it carries an in-flight diagnostic.
-  DiagnosedDefiniteFailure(DiagnosedDefiniteFailure &&) = default;
-
-  /// Forward the message to the diagnostic.
-  template <typename T>
-  DiagnosedDefiniteFailure &operator<<(T &&value) & {
-    diag << std::forward<T>(value);
-    return *this;
-  }
-  template <typename T>
-  DiagnosedDefiniteFailure &&operator<<(T &&value) && {
-    return std::move(this->operator<<(std::forward<T>(value)));
-  }
-
-  /// Attaches a note to the error.
-  Diagnostic &attachNote(Optional<Location> loc = std::nullopt) {
-    return diag.attachNote(loc);
-  }
-
-  /// Implicit conversion to DiagnosedSilenceableFailure in the definite failure
-  /// state. Reports the error.
-  operator DiagnosedSilenceableFailure() {
-    diag.report();
-    return DiagnosedSilenceableFailure::definiteFailure();
-  }
-
-  /// Implicit conversion to LogicalResult in the failure state. Reports the
-  /// error.
-  operator LogicalResult() {
-    diag.report();
-    return failure();
-  }
-
-private:
-  /// Constructs a definite failure at the given location with the given
-  /// message.
-  explicit DiagnosedDefiniteFailure(Location loc, const Twine &message)
-      : diag(emitError(loc, message)) {}
-
-  /// Copy-construction and any assignment is disallowed to prevent repeated
-  /// error reporting.
-  DiagnosedDefiniteFailure(const DiagnosedDefiniteFailure &) = delete;
-  DiagnosedDefiniteFailure &
-  operator=(const DiagnosedDefiniteFailure &) = delete;
-  DiagnosedDefiniteFailure &operator=(DiagnosedDefiniteFailure &&) = delete;
-
-  /// The error message.
-  InFlightDiagnostic diag;
-};
-
-/// Emits a definite failure with the given message. The returned object allows
-/// for last-minute modification to the error message, such as attaching notes
-/// and completing the message. It will be reported when the object is
-/// destructed or converted.
-inline DiagnosedDefiniteFailure emitDefiniteFailure(Location loc,
-                                                    const Twine &message) {
-  return DiagnosedDefiniteFailure(loc, message);
-}
-inline DiagnosedDefiniteFailure emitDefiniteFailure(Operation *op,
-                                                    const Twine &message = {}) {
-  return emitDefiniteFailure(op->getLoc(), message);
-}
-
-/// Emits a silenceable failure with the given message. A silenceable failure
-/// must be either suppressed or converted into a definite failure and reported
-/// to the user.
-inline DiagnosedSilenceableFailure
-emitSilenceableFailure(Location loc, const Twine &message = {}) {
-  Diagnostic diag(loc, DiagnosticSeverity::Error);
-  diag << message;
-  return DiagnosedSilenceableFailure::silenceableFailure(std::move(diag));
-}
-inline DiagnosedSilenceableFailure
-emitSilenceableFailure(Operation *op, const Twine &message = {}) {
-  return emitSilenceableFailure(op->getLoc(), message);
-}
-
 namespace transform {
 
 class TransformOpInterface;

diff  --git a/mlir/include/mlir/Dialect/Transform/IR/TransformOps.h b/mlir/include/mlir/Dialect/Transform/IR/TransformOps.h
index 822c24d28bc57..0a737d5313750 100644
--- a/mlir/include/mlir/Dialect/Transform/IR/TransformOps.h
+++ b/mlir/include/mlir/Dialect/Transform/IR/TransformOps.h
@@ -10,6 +10,7 @@
 #define MLIR_DIALECT_TRANSFORM_IR_TRANSFORMOPS_H
 
 #include "mlir/Dialect/PDL/IR/PDLTypes.h"
+#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
 #include "mlir/Dialect/Transform/IR/TransformTypes.h"
 #include "mlir/IR/OpDefinition.h"
 #include "mlir/IR/OpImplementation.h"

diff  --git a/mlir/include/mlir/Dialect/Transform/IR/TransformTypes.h b/mlir/include/mlir/Dialect/Transform/IR/TransformTypes.h
index a8b6ee0328e3c..bf0fc208829a7 100644
--- a/mlir/include/mlir/Dialect/Transform/IR/TransformTypes.h
+++ b/mlir/include/mlir/Dialect/Transform/IR/TransformTypes.h
@@ -9,7 +9,7 @@
 #ifndef MLIR_DIALECT_TRANSFORM_IR_TRANSFORMTYPES_H
 #define MLIR_DIALECT_TRANSFORM_IR_TRANSFORMTYPES_H
 
-#include "mlir/Dialect/Transform/IR/TransformInterfaces.h"
+#include "mlir/Dialect/Transform/Utils/DiagnosedSilenceableFailure.h"
 #include "mlir/IR/Types.h"
 #include "mlir/Support/LLVM.h"
 

diff  --git a/mlir/include/mlir/Dialect/Transform/Utils/DiagnosedSilenceableFailure.h b/mlir/include/mlir/Dialect/Transform/Utils/DiagnosedSilenceableFailure.h
new file mode 100644
index 0000000000000..fcb3524479b72
--- /dev/null
+++ b/mlir/include/mlir/Dialect/Transform/Utils/DiagnosedSilenceableFailure.h
@@ -0,0 +1,266 @@
+//===- DiagnosedSilenceableFailure.h - Tri-state result ----------- 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 declares the DiagnosedSilenceableFailure class allowing to store
+// a tri-state result (definite failure, recoverable failure, success) with an
+// optional associated list of diagnostics.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/IR/Diagnostics.h"
+#include "mlir/IR/Operation.h"
+
+#ifndef MLIR_DIALECT_TRANSFORM_UTILS_DIAGNOSEDSILENCEABLEFAILURE_H
+#define MLIR_DIALECT_TRANSFORM_UTILS_DIAGNOSEDSILENCEABLEFAILURE_H
+
+namespace mlir {
+/// The result of a transform IR operation application. This can have one of the
+/// three states:
+///   - success;
+///   - silenceable (recoverable) failure with yet-unreported diagnostic;
+///   - definite failure.
+/// Silenceable failure is intended to communicate information about
+/// transformations that did not apply but in a way that supports recovery,
+/// for example, they did not modify the payload IR or modified it in some
+/// predictable way. They are associated with a Diagnostic that provides more
+/// details on the failure. Silenceable failure can be discarded, turning the
+/// result into success, or "reported", emitting the diagnostic and turning the
+/// result into definite failure.
+/// Transform IR operations containing other operations are allowed to do either
+/// with the results of the nested transformations, but must propagate definite
+/// failures as their diagnostics have been already reported to the user.
+class [[nodiscard]] DiagnosedSilenceableFailure {
+public:
+  DiagnosedSilenceableFailure(const DiagnosedSilenceableFailure &) = delete;
+  DiagnosedSilenceableFailure &
+  operator=(const DiagnosedSilenceableFailure &) = delete;
+  DiagnosedSilenceableFailure(DiagnosedSilenceableFailure &&) = default;
+  DiagnosedSilenceableFailure &
+  operator=(DiagnosedSilenceableFailure &&) = default;
+
+  /// Constructs a DiagnosedSilenceableFailure in the success state.
+  static DiagnosedSilenceableFailure success() {
+    return DiagnosedSilenceableFailure(::mlir::success());
+  }
+
+  /// Constructs a DiagnosedSilenceableFailure in the failure state. Typically,
+  /// a diagnostic has been emitted before this.
+  static DiagnosedSilenceableFailure definiteFailure() {
+    return DiagnosedSilenceableFailure(::mlir::failure());
+  }
+
+  /// Constructs a DiagnosedSilenceableFailure in the silenceable failure state,
+  /// ready to emit the given diagnostic. This is considered a failure
+  /// regardless of the diagnostic severity.
+  static DiagnosedSilenceableFailure silenceableFailure(Diagnostic &&diag) {
+    return DiagnosedSilenceableFailure(std::forward<Diagnostic>(diag));
+  }
+  static DiagnosedSilenceableFailure
+  silenceableFailure(SmallVector<Diagnostic> &&diag) {
+    return DiagnosedSilenceableFailure(
+        std::forward<SmallVector<Diagnostic>>(diag));
+  }
+
+  /// Converts all kinds of failure into a LogicalResult failure, emitting the
+  /// diagnostic if necessary. Must not be called more than once.
+  LogicalResult checkAndReport();
+
+  /// Returns `true` if this is a success.
+  bool succeeded() const {
+    return ::mlir::succeeded(result) && diagnostics.empty();
+  }
+
+  /// Returns `true` if this is a definite failure.
+  bool isDefiniteFailure() const {
+    return ::mlir::failed(result) && diagnostics.empty();
+  }
+
+  /// Returns `true` if this is a silenceable failure.
+  bool isSilenceableFailure() const { return !diagnostics.empty(); }
+
+  /// Returns the diagnostic message without emitting it. Expects this object
+  /// to be a silenceable failure.
+  std::string getMessage() const {
+    std::string res;
+    for (auto &diagnostic : diagnostics) {
+      res.append(diagnostic.str());
+      res.append("\n");
+    }
+    return res;
+  }
+
+  /// Returns a string representation of the failure mode (for error reporting).
+  std::string getStatusString() const {
+    if (succeeded())
+      return "success";
+    if (isSilenceableFailure())
+      return "silenceable failure";
+    return "definite failure";
+  }
+
+  /// Converts silenceable failure into LogicalResult success without reporting
+  /// the diagnostic, preserves the other states.
+  LogicalResult silence() {
+    if (!diagnostics.empty()) {
+      diagnostics.clear();
+      result = ::mlir::success();
+    }
+    return result;
+  }
+
+  /// Take the diagnostics and silence.
+  void takeDiagnostics(SmallVectorImpl<Diagnostic> &diags) {
+    assert(!diagnostics.empty() && "expected a diagnostic to be present");
+    diags.append(std::make_move_iterator(diagnostics.begin()),
+                 std::make_move_iterator(diagnostics.end()));
+  }
+
+  /// Streams the given values into the last diagnostic.
+  /// Expects this object to be a silenceable failure.
+  template <typename T>
+  DiagnosedSilenceableFailure &operator<<(T &&value) & {
+    assert(isSilenceableFailure() &&
+           "can only append output in silenceable failure state");
+    diagnostics.back() << std::forward<T>(value);
+    return *this;
+  }
+  template <typename T>
+  DiagnosedSilenceableFailure &&operator<<(T &&value) && {
+    return std::move(this->operator<<(std::forward<T>(value)));
+  }
+
+  /// Attaches a note to the last diagnostic.
+  /// Expects this object to be a silenceable failure.
+  Diagnostic &attachNote(Optional<Location> loc = std::nullopt) {
+    assert(isSilenceableFailure() &&
+           "can only attach notes to silenceable failures");
+    return diagnostics.back().attachNote(loc);
+  }
+
+private:
+  explicit DiagnosedSilenceableFailure(LogicalResult result) : result(result) {}
+  explicit DiagnosedSilenceableFailure(Diagnostic &&diagnostic)
+      : result(failure()) {
+    diagnostics.emplace_back(std::move(diagnostic));
+  }
+  explicit DiagnosedSilenceableFailure(SmallVector<Diagnostic> &&diagnostics)
+      : diagnostics(std::move(diagnostics)), result(failure()) {}
+
+  /// The diagnostics associated with this object. If non-empty, the object is
+  /// considered to be in the silenceable failure state regardless of the
+  /// `result` field.
+  SmallVector<Diagnostic, 1> diagnostics;
+
+  /// The "definite" logical state, either success or failure.
+  /// Ignored if the diagnostics message is present.
+  LogicalResult result;
+
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+  /// Whether the associated diagnostics have been reported.
+  /// Diagnostics reporting consumes the diagnostics, so we need a mechanism to
+  /// 
diff erentiate reported diagnostics from a state where it was never
+  /// created.
+  bool reported = false;
+#endif // LLVM_ENABLE_ABI_BREAKING_CHECKS
+};
+
+class DiagnosedDefiniteFailure;
+
+DiagnosedDefiniteFailure emitDefiniteFailure(Location loc,
+                                             const Twine &message = {});
+
+/// A compatibility class connecting `InFlightDiagnostic` to
+/// `DiagnosedSilenceableFailure` while providing an interface similar to the
+/// former. Implicitly convertible to `DiagnosticSilenceableFailure` in definite
+/// failure state and to `LogicalResult` failure. Reports the error on
+/// conversion or on destruction. Instances of this class can be created by
+/// `emitDefiniteFailure()`.
+class DiagnosedDefiniteFailure {
+  friend DiagnosedDefiniteFailure emitDefiniteFailure(Location loc,
+                                                      const Twine &message);
+
+public:
+  /// Only move-constructible because it carries an in-flight diagnostic.
+  DiagnosedDefiniteFailure(DiagnosedDefiniteFailure &&) = default;
+
+  /// Forward the message to the diagnostic.
+  template <typename T>
+  DiagnosedDefiniteFailure &operator<<(T &&value) & {
+    diag << std::forward<T>(value);
+    return *this;
+  }
+  template <typename T>
+  DiagnosedDefiniteFailure &&operator<<(T &&value) && {
+    return std::move(this->operator<<(std::forward<T>(value)));
+  }
+
+  /// Attaches a note to the error.
+  Diagnostic &attachNote(Optional<Location> loc = std::nullopt) {
+    return diag.attachNote(loc);
+  }
+
+  /// Implicit conversion to DiagnosedSilenceableFailure in the definite failure
+  /// state. Reports the error.
+  operator DiagnosedSilenceableFailure() {
+    diag.report();
+    return DiagnosedSilenceableFailure::definiteFailure();
+  }
+
+  /// Implicit conversion to LogicalResult in the failure state. Reports the
+  /// error.
+  operator LogicalResult() {
+    diag.report();
+    return failure();
+  }
+
+private:
+  /// Constructs a definite failure at the given location with the given
+  /// message.
+  explicit DiagnosedDefiniteFailure(Location loc, const Twine &message)
+      : diag(emitError(loc, message)) {}
+
+  /// Copy-construction and any assignment is disallowed to prevent repeated
+  /// error reporting.
+  DiagnosedDefiniteFailure(const DiagnosedDefiniteFailure &) = delete;
+  DiagnosedDefiniteFailure &
+  operator=(const DiagnosedDefiniteFailure &) = delete;
+  DiagnosedDefiniteFailure &operator=(DiagnosedDefiniteFailure &&) = delete;
+
+  /// The error message.
+  InFlightDiagnostic diag;
+};
+
+/// Emits a definite failure with the given message. The returned object allows
+/// for last-minute modification to the error message, such as attaching notes
+/// and completing the message. It will be reported when the object is
+/// destructed or converted.
+inline DiagnosedDefiniteFailure emitDefiniteFailure(Location loc,
+                                                    const Twine &message) {
+  return DiagnosedDefiniteFailure(loc, message);
+}
+inline DiagnosedDefiniteFailure emitDefiniteFailure(Operation *op,
+                                                    const Twine &message = {}) {
+  return emitDefiniteFailure(op->getLoc(), message);
+}
+
+/// Emits a silenceable failure with the given message. A silenceable failure
+/// must be either suppressed or converted into a definite failure and reported
+/// to the user.
+inline DiagnosedSilenceableFailure
+emitSilenceableFailure(Location loc, const Twine &message = {}) {
+  Diagnostic diag(loc, DiagnosticSeverity::Error);
+  diag << message;
+  return DiagnosedSilenceableFailure::silenceableFailure(std::move(diag));
+}
+inline DiagnosedSilenceableFailure
+emitSilenceableFailure(Operation *op, const Twine &message = {}) {
+  return emitSilenceableFailure(op->getLoc(), message);
+}
+} // namespace mlir
+
+#endif // MLIR_DIALECT_TRANSFORM_UTILS_DIAGNOSEDSILENCEABLEFAILURE_H

diff  --git a/mlir/include/mlir/Dialect/Transform/Utils/Utils.h b/mlir/include/mlir/Dialect/Transform/Utils/Utils.h
index ced6f12aa69de..04a0b090e6b90 100644
--- a/mlir/include/mlir/Dialect/Transform/Utils/Utils.h
+++ b/mlir/include/mlir/Dialect/Transform/Utils/Utils.h
@@ -14,8 +14,6 @@
 #include "mlir/IR/ValueRange.h"
 #include "mlir/Support/LLVM.h"
 
-#include "llvm/ADT/SmallVector.h"
-
 namespace mlir {
 class OpAsmPrinter;
 

diff  --git a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
index 6702e9a057748..4f75d3daeac48 100644
--- a/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
+++ b/mlir/lib/Dialect/Linalg/TransformOps/LinalgTransformOps.cpp
@@ -26,6 +26,7 @@
 #include "mlir/IR/OpDefinition.h"
 #include "mlir/Interfaces/TilingInterface.h"
 #include "mlir/Transforms/GreedyPatternRewriteDriver.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Debug.h"
 

diff  --git a/mlir/lib/Dialect/Transform/IR/CMakeLists.txt b/mlir/lib/Dialect/Transform/IR/CMakeLists.txt
index fe4c8275e9adc..d219edd88c515 100644
--- a/mlir/lib/Dialect/Transform/IR/CMakeLists.txt
+++ b/mlir/lib/Dialect/Transform/IR/CMakeLists.txt
@@ -15,4 +15,5 @@ add_mlir_dialect_library(MLIRTransformDialect
   MLIRPDLInterpDialect
   MLIRRewrite
   MLIRSideEffectInterfaces
+  MLIRTransformDialectUtils
   )

diff  --git a/mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp b/mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp
index 46dc2aebdfc9c..dbfc8da338aa7 100644
--- a/mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp
+++ b/mlir/lib/Dialect/Transform/IR/TransformInterfaces.cpp
@@ -11,6 +11,7 @@
 #include "mlir/IR/Diagnostics.h"
 #include "mlir/IR/Operation.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/ScopeExit.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorHandling.h"
 

diff  --git a/mlir/lib/Dialect/Transform/Utils/CMakeLists.txt b/mlir/lib/Dialect/Transform/Utils/CMakeLists.txt
index eadcbab3069dd..64aa27482cfb6 100644
--- a/mlir/lib/Dialect/Transform/Utils/CMakeLists.txt
+++ b/mlir/lib/Dialect/Transform/Utils/CMakeLists.txt
@@ -1,10 +1,13 @@
 add_mlir_dialect_library(MLIRTransformDialectUtils
+  DiagnosedSilenceableFailure.cpp
   Utils.cpp
+
   ADDITIONAL_HEADER_DIRS
   ${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Transform
+
   LINK_LIBS PUBLIC
   MLIRDialectUtils
   MLIRIR
   MLIRSupport
-  MLIRTransformDialect
+  MLIRViewLikeInterface
 )

diff  --git a/mlir/lib/Dialect/Transform/Utils/DiagnosedSilenceableFailure.cpp b/mlir/lib/Dialect/Transform/Utils/DiagnosedSilenceableFailure.cpp
new file mode 100644
index 0000000000000..44cc561485799
--- /dev/null
+++ b/mlir/lib/Dialect/Transform/Utils/DiagnosedSilenceableFailure.cpp
@@ -0,0 +1,33 @@
+//===- DiagnosedSilenceableFailure.cpp - Tri-state result -----------------===//
+//
+// 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 DiagnosedSilenceableFailure class allowing to store
+// a tri-state result (definite failure, recoverable failure, success) with an
+// optional associated list of diagnostics.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/Transform/Utils/DiagnosedSilenceableFailure.h"
+
+using namespace mlir;
+
+LogicalResult mlir::DiagnosedSilenceableFailure::checkAndReport() {
+#if LLVM_ENABLE_ABI_BREAKING_CHECKS
+  assert(!reported && "attempting to report a diagnostic more than once");
+  reported = true;
+#endif // LLVM_ENABLE_ABI_BREAKING_CHECKS
+  if (!diagnostics.empty()) {
+    for (auto &&diagnostic : diagnostics) {
+      diagnostic.getLocation().getContext()->getDiagEngine().emit(
+          std::move(diagnostic));
+    }
+    diagnostics.clear();
+    result = ::mlir::failure();
+  }
+  return result;
+}

diff  --git a/mlir/lib/Dialect/Transform/Utils/Utils.cpp b/mlir/lib/Dialect/Transform/Utils/Utils.cpp
index 4af6dfd0a3d0c..8f67a8886fd33 100644
--- a/mlir/lib/Dialect/Transform/Utils/Utils.cpp
+++ b/mlir/lib/Dialect/Transform/Utils/Utils.cpp
@@ -8,20 +8,15 @@
 
 #include "mlir/Dialect/Transform/Utils/Utils.h"
 
-#include "mlir/Dialect/Transform/IR/TransformDialect.h"
-#include "mlir/Dialect/Transform/IR/TransformTypes.h"
-#include "mlir/Dialect/Utils/StaticValueUtils.h"
-#include "mlir/IR/Matchers.h"
 #include "mlir/IR/OpDefinition.h"
 #include "mlir/Interfaces/ViewLikeInterface.h"
 
 using namespace mlir;
 using namespace mlir::transform;
 
-void transform::printPackedOrDynamicIndexList(OpAsmPrinter &printer,
-                                              Operation *op, Value packed,
-                                              OperandRange values,
-                                              ArrayRef<int64_t> integers) {
+void mlir::transform::printPackedOrDynamicIndexList(
+    OpAsmPrinter &printer, Operation *op, Value packed, OperandRange values,
+    ArrayRef<int64_t> integers) {
   if (packed) {
     assert(values.empty() && integers.empty() && "expected no values/integers");
     printer << packed;
@@ -30,7 +25,7 @@ void transform::printPackedOrDynamicIndexList(OpAsmPrinter &printer,
   printDynamicIndexList(printer, op, values, integers);
 }
 
-ParseResult transform::parsePackedOrDynamicIndexList(
+ParseResult mlir::transform::parsePackedOrDynamicIndexList(
     OpAsmParser &parser, std::optional<OpAsmParser::UnresolvedOperand> &packed,
     SmallVectorImpl<OpAsmParser::UnresolvedOperand> &values,
     DenseI64ArrayAttr &integers) {

diff  --git a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
index 6dcba58a766ff..d5c1f89ed644e 100644
--- a/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/mlir/BUILD.bazel
@@ -9138,6 +9138,7 @@ cc_library(
         ":TransformDialectEnumsIncGen",
         ":TransformDialectIncGen",
         ":TransformDialectInterfacesIncGen",
+        ":TransformDialectUtils",
         ":TransformOpsIncGen",
         ":TransformTypesIncGen",
         "//llvm:Support",
@@ -9187,14 +9188,13 @@ cc_library(
 
 cc_library(
     name = "TransformDialectUtils",
-    srcs = ["lib/Dialect/Transform/Utils/Utils.cpp"],
-    hdrs = ["include/mlir/Dialect/Transform/Utils/Utils.h"],
+    srcs = glob(["lib/Dialect/Transform/Utils/*cpp"]),
+    hdrs = glob(["include/mlir/Dialect/Transform/Utils/*.h"]),
     includes = ["include"],
     deps = [
         ":DialectUtils",
         ":IR",
         ":Support",
-        ":TransformDialect",
         ":ViewLikeInterface",
         "//llvm:Support",
     ],


        


More information about the Mlir-commits mailing list