From eaf7f6b67136352f7cf837b59e6c92b4a73dd4cf Mon Sep 17 00:00:00 2001 From: River Riddle Date: Wed, 1 May 2019 11:14:15 -0700 Subject: [PATCH] Start sketching out a new diagnostics infrastructure. Create a new class 'DiagnosticEngine' and move the diagnostic handler support and final diagnostic emission from the MLIRContext to it. -- PiperOrigin-RevId: 246163897 --- mlir/include/mlir/IR/Diagnostics.h | 90 ++++++++++++++++++ mlir/include/mlir/IR/MLIRContext.h | 42 ++------- .../FxpMathOps/Transforms/LowerUniformRealMath.cpp | 13 +-- mlir/lib/IR/Diagnostics.cpp | 103 +++++++++++++++++++++ mlir/lib/IR/Function.cpp | 9 +- mlir/lib/IR/MLIRContext.cpp | 77 +++------------ mlir/lib/IR/Operation.cpp | 9 +- mlir/lib/Pass/Pass.cpp | 44 ++++----- .../Vectorization/VectorizerTestPass.cpp | 5 +- mlir/tools/mlir-opt/mlir-opt.cpp | 56 +++++------ 10 files changed, 279 insertions(+), 169 deletions(-) create mode 100644 mlir/include/mlir/IR/Diagnostics.h create mode 100644 mlir/lib/IR/Diagnostics.cpp diff --git a/mlir/include/mlir/IR/Diagnostics.h b/mlir/include/mlir/IR/Diagnostics.h new file mode 100644 index 0000000..b4f002f --- /dev/null +++ b/mlir/include/mlir/IR/Diagnostics.h @@ -0,0 +1,90 @@ +//===- Diagnostics.h - MLIR Diagnostics -------------------------*- C++ -*-===// +// +// Copyright 2019 The MLIR Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= +// +// This file defines utilities for emitting diagnostics. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_IR_DIAGNOSTICS_H +#define MLIR_IR_DIAGNOSTICS_H + +#include "mlir/Support/LLVM.h" +#include + +namespace mlir { +class Location; + +namespace detail { +struct DiagnosticEngineImpl; +} // end namespace detail + +/// Defines the different supported severity of a diagnostic. +enum class DiagnosticSeverity { + Note, + Warning, + Error, +}; + +//===----------------------------------------------------------------------===// +// DiagnosticEngine +//===----------------------------------------------------------------------===// + +/// This class is the main interface for diagnostics. The DiagnosticEngine +/// manages the registration of diagnostic handlers as well as the core API for +/// diagnostic emission. This class should not be constructed directly, but +/// instead interfaced with via an MLIRContext instance. +class DiagnosticEngine { +public: + ~DiagnosticEngine(); + + // Diagnostic handler registration and use. MLIR supports the ability for the + // IR to carry arbitrary metadata about operation location information. If a + // problem is detected by the compiler, it can invoke the emitError / + // emitWarning / emitNote method on an Operation and have it get reported + // through this interface. + // + // Tools using MLIR are encouraged to register error handlers and define a + // schema for their location information. If they don't, then warnings and + // notes will be dropped and errors will terminate the process with exit(1). + + using HandlerTy = + std::function; + + /// Set the diagnostic handler for this engine. The handler is passed + /// location information if present (nullptr if not) along with a message and + /// a severity that indicates whether this is an error, warning, etc. Note + /// that this replaces any existing handler. + void setHandler(const HandlerTy &handler); + + /// Return the current diagnostic handler, or null if none is present. + HandlerTy getHandler(); + + /// Emit a diagnostic using the registered issue handle if present, or with + /// the default behavior if not. The MLIR compiler should not generally + /// interact with this, it should use methods on Operation instead. + void emit(Location loc, const Twine &msg, DiagnosticSeverity severity); + +private: + friend class MLIRContextImpl; + DiagnosticEngine(); + + /// The internal implementation of the DiagnosticEngine. + std::unique_ptr impl; +}; +} // namespace mlir + +#endif diff --git a/mlir/include/mlir/IR/MLIRContext.h b/mlir/include/mlir/IR/MLIRContext.h index 4b2343a..553c17c 100644 --- a/mlir/include/mlir/IR/MLIRContext.h +++ b/mlir/include/mlir/IR/MLIRContext.h @@ -25,6 +25,7 @@ namespace mlir { class AbstractOperation; +class DiagnosticEngine; class Dialect; class Location; class MLIRContextImpl; @@ -55,45 +56,16 @@ public: /// directly. std::vector getRegisteredOperations(); - /// This is the interpretation of a diagnostic that is emitted to the - /// diagnostic handler below. - enum class DiagnosticKind { Note, Warning, Error }; - - // Diagnostic handler registration and use. MLIR supports the ability for the - // IR to carry arbitrary metadata about operation location information. If an - // problem is detected by the compiler, it can invoke the emitError / - // emitWarning / emitNote method on an Operation and have it get reported - // through this interface. - // - // Tools using MLIR are encouraged to register error handlers and define a - // schema for their location information. If they don't, then warnings and - // notes will be dropped and errors will terminate the process with exit(1). - - using DiagnosticHandlerTy = std::function; - - /// Register a diagnostic handler with this LLVM context. The handler is - /// passed location information if present (nullptr if not) along with a - /// message and a boolean that indicates whether this is an error or warning. - void registerDiagnosticHandler(const DiagnosticHandlerTy &handler); - - /// Return the current diagnostic handler, or null if none is present. - DiagnosticHandlerTy getDiagnosticHandler(); - - /// Emit a diagnostic using the registered issue handle if present, or with - /// the default behavior if not. The MLIR compiler should not generally - /// interact with this, it should use methods on Operation instead. - void emitDiagnostic(Location location, const Twine &message, - DiagnosticKind kind); - - /// Emit an error message using the registered issue handle if present, or to - /// the standard error stream otherwise and return true. - bool emitError(Location location, const Twine &message); - // This is effectively private given that only MLIRContext.cpp can see the // MLIRContextImpl type. MLIRContextImpl &getImpl() { return *impl.get(); } + /// Emit an error message using the diagnostic engine and return true. + bool emitError(Location location, const Twine &message); + + /// Returns the diagnostic engine for this context. + DiagnosticEngine &getDiagEngine(); + /// Returns the storage uniquer used for constructing type storage instances. /// This should not be used directly. StorageUniquer &getTypeUniquer(); diff --git a/mlir/lib/FxpMathOps/Transforms/LowerUniformRealMath.cpp b/mlir/lib/FxpMathOps/Transforms/LowerUniformRealMath.cpp index ecd66ef..2ee39c9 100644 --- a/mlir/lib/FxpMathOps/Transforms/LowerUniformRealMath.cpp +++ b/mlir/lib/FxpMathOps/Transforms/LowerUniformRealMath.cpp @@ -19,6 +19,7 @@ #include "mlir/FxpMathOps/FxpMathOps.h" #include "mlir/FxpMathOps/Passes.h" +#include "mlir/IR/Diagnostics.h" #include "mlir/IR/PatternMatch.h" #include "mlir/Pass/Pass.h" #include "mlir/StandardOps/Ops.h" @@ -51,9 +52,9 @@ static Value *emitUniformPerLayerDequantize(Location loc, Value *input, // Pre-conditions. if (!elementType.isSigned()) { // TODO: Support unsigned storage type. - return rewriter.getContext()->emitDiagnostic( + return rewriter.getContext()->getDiagEngine().emit( loc, "unimplemented: dequantize signed uniform", - MLIRContext::DiagnosticKind::Warning), + DiagnosticSeverity::Warning), nullptr; } @@ -93,13 +94,9 @@ emitUniformPerAxisDequantize(Location loc, Value *input, UniformQuantizedPerAxisType elementType, PatternRewriter &rewriter) { // TODO: Support per-axis dequantize. - return rewriter.getContext()->emitDiagnostic( + return rewriter.getContext()->getDiagEngine().emit( loc, "unimplemented: per-axis uniform dequantization", - MLIRContext::DiagnosticKind::Warning), - nullptr; - - return input->getDefiningOp()->emitWarning( - "unimplemented: per-axis uniform dequantization"), + DiagnosticSeverity::Warning), nullptr; } diff --git a/mlir/lib/IR/Diagnostics.cpp b/mlir/lib/IR/Diagnostics.cpp new file mode 100644 index 0000000..0311fa1 --- /dev/null +++ b/mlir/lib/IR/Diagnostics.cpp @@ -0,0 +1,103 @@ +//===- Diagnostics.cpp - MLIR Diagnostics ---------------------------------===// +// +// Copyright 2019 The MLIR Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ============================================================================= + +#include "mlir/IR/Diagnostics.h" +#include "mlir/IR/Location.h" +#include "llvm/ADT/Twine.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Support/raw_ostream.h" + +using namespace mlir; +using namespace mlir::detail; + +namespace mlir { +namespace detail { +struct DiagnosticEngineImpl { + /// A mutex to ensure that diagnostics emission is thread-safe. + llvm::sys::SmartMutex mutex; + + /// This is the handler to use to report diagnostics, or null if not + /// registered. + DiagnosticEngine::HandlerTy handler; +}; +} // namespace detail +} // namespace mlir + +//===----------------------------------------------------------------------===// +// DiagnosticEngine +//===----------------------------------------------------------------------===// + +DiagnosticEngine::DiagnosticEngine() : impl(new DiagnosticEngineImpl()) {} +DiagnosticEngine::~DiagnosticEngine() {} + +/// Register a diagnostic handler with this engine. The handler is +/// passed location information if present (nullptr if not) along with a +/// message and a severity that indicates whether this is an error, warning, +/// etc. +void DiagnosticEngine::setHandler(const HandlerTy &handler) { + llvm::sys::SmartScopedLock lock(impl->mutex); + impl->handler = handler; +} + +/// Return the current diagnostic handler, or null if none is present. +auto DiagnosticEngine::getHandler() -> HandlerTy { + llvm::sys::SmartScopedLock lock(impl->mutex); + return impl->handler; +} + +/// Emit a diagnostic using the registered issue handle if present, or with +/// the default behavior if not. The MLIR compiler should not generally +/// interact with this, it should use methods on Operation instead. +void DiagnosticEngine::emit(Location loc, const Twine &msg, + DiagnosticSeverity severity) { + /// Lock access to the diagnostic engine. + llvm::sys::SmartScopedLock lock(impl->mutex); + + // If we had a handler registered, emit the diagnostic using it. + if (impl->handler) { + // TODO(b/131756158) FusedLoc should be handled by the diagnostic handler + // instead of here. + // Check to see if we are emitting a diagnostic on a fused + // location. + if (auto fusedLoc = loc.dyn_cast()) { + auto fusedLocs = fusedLoc->getLocations(); + + // Emit the original diagnostic with the first location in the fused list. + emit(fusedLocs.front(), msg, severity); + + // Emit the rest of the locations as notes. + for (Location subLoc : fusedLocs.drop_front()) + emit(subLoc, "fused from here", DiagnosticSeverity::Note); + return; + } + + return impl->handler(loc, msg.str(), severity); + } + + // Otherwise, if this is an error we emit it to stderr. + if (severity != DiagnosticSeverity::Error) + return; + + auto &os = llvm::errs(); + if (!loc.isa()) + os << loc << ": "; + os << "error: "; + + // The default behavior for errors is to emit them to stderr. + os << msg << '\n'; + os.flush(); +} diff --git a/mlir/lib/IR/Function.cpp b/mlir/lib/IR/Function.cpp index 94fee35..98bafa2 100644 --- a/mlir/lib/IR/Function.cpp +++ b/mlir/lib/IR/Function.cpp @@ -18,6 +18,7 @@ #include "mlir/IR/Function.h" #include "mlir/IR/Attributes.h" #include "mlir/IR/BlockAndValueMapping.h" +#include "mlir/IR/Diagnostics.h" #include "mlir/IR/MLIRContext.h" #include "mlir/IR/Module.h" #include "mlir/IR/Types.h" @@ -118,15 +119,15 @@ void Function::erase() { /// Emit a note about this operation, reporting up to any diagnostic /// handlers that may be listening. void Function::emitNote(const Twine &message) { - getContext()->emitDiagnostic(getLoc(), message, - MLIRContext::DiagnosticKind::Note); + getContext()->getDiagEngine().emit(getLoc(), message, + DiagnosticSeverity::Note); } /// Emit a warning about this operation, reporting up to any diagnostic /// handlers that may be listening. void Function::emitWarning(const Twine &message) { - getContext()->emitDiagnostic(getLoc(), message, - MLIRContext::DiagnosticKind::Warning); + getContext()->getDiagEngine().emit(getLoc(), message, + DiagnosticSeverity::Warning); } /// Emit an error about fatal conditions with this operation, reporting up to diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp index 9760599..ca39983 100644 --- a/mlir/lib/IR/MLIRContext.cpp +++ b/mlir/lib/IR/MLIRContext.cpp @@ -26,6 +26,7 @@ #include "mlir/IR/AffineExpr.h" #include "mlir/IR/AffineMap.h" #include "mlir/IR/Attributes.h" +#include "mlir/IR/Diagnostics.h" #include "mlir/IR/Dialect.h" #include "mlir/IR/Function.h" #include "mlir/IR/Identifier.h" @@ -302,17 +303,18 @@ public: llvm::sys::SmartRWMutex identifierMutex; //===--------------------------------------------------------------------===// + // Diagnostics + //===--------------------------------------------------------------------===// + DiagnosticEngine diagEngine; + + //===--------------------------------------------------------------------===// // Other //===--------------------------------------------------------------------===// /// A general purpose mutex to lock access to parts of the context that do not - /// have a more specific mutex, e.g. registry operations, diagnostics, etc. + /// have a more specific mutex, e.g. registry operations. llvm::sys::SmartRWMutex contextMutex; - /// This is the handler to use to report diagnostics, or null if not - /// registered. - MLIRContext::DiagnosticHandlerTy diagnosticHandler; - /// This is a list of dialects that are created referring to this context. /// The MLIRContext owns the objects. std::vector> dialects; @@ -420,71 +422,14 @@ static ArrayRef copyArrayRefInto(llvm::BumpPtrAllocator &allocator, // Diagnostic Handlers //===----------------------------------------------------------------------===// -/// Register an issue handler with this MLIR context. The issue handler is -/// passed location information along with a message and a DiagnosticKind enum -/// value that indicates the type of the diagnostic (e.g., Warning, Error). -void MLIRContext::registerDiagnosticHandler( - const DiagnosticHandlerTy &handler) { - // Lock access to the context diagnostic handler. - llvm::sys::SmartScopedWriter contextLock(getImpl().contextMutex); - getImpl().diagnosticHandler = handler; -} - -/// Return the current diagnostic handler, or null if none is present. -auto MLIRContext::getDiagnosticHandler() -> DiagnosticHandlerTy { - // Lock access to the context diagnostic handler. - llvm::sys::SmartScopedReader contextLock(getImpl().contextMutex); - return getImpl().diagnosticHandler; -} - -/// This emits a diagnostic using the registered issue handle if present, or -/// with the default behavior if not. The MLIR compiler should not generally -/// interact with this, it should use methods on Operation instead. -void MLIRContext::emitDiagnostic(Location location, const llvm::Twine &message, - DiagnosticKind kind) { - // Check to see if we are emitting a diagnostic on a fused location. - if (auto fusedLoc = location.dyn_cast()) { - auto fusedLocs = fusedLoc->getLocations(); - - // Emit the original diagnostic with the first location in the fused list. - emitDiagnostic(fusedLocs.front(), message, kind); - - // Emit the rest of the locations as notes. - for (unsigned i = 1, e = fusedLocs.size(); i != e; ++i) - emitDiagnostic(fusedLocs[i], "fused from here", DiagnosticKind::Note); - return; - } - - // Lock access to the context so that no other threads emit diagnostics at - // the same time. - llvm::sys::SmartScopedWriter contextLock(getImpl().contextMutex); - - // If we had a handler registered, emit the diagnostic using it. - auto handler = getImpl().diagnosticHandler; - if (handler) - return handler(location, message.str(), kind); - - // The default behavior for notes and warnings is to ignore them. - if (kind != DiagnosticKind::Error) - return; - - auto &os = llvm::errs(); - - if (!location.isa()) - os << location << ": "; - - os << "error: "; - - // The default behavior for errors is to emit them to stderr. - os << message.str() << '\n'; - os.flush(); -} - bool MLIRContext::emitError(Location location, const llvm::Twine &message) { - emitDiagnostic(location, message, DiagnosticKind::Error); + getImpl().diagEngine.emit(location, message, DiagnosticSeverity::Error); return true; } +/// Returns the diagnostic engine for this context. +DiagnosticEngine &MLIRContext::getDiagEngine() { return getImpl().diagEngine; } + //===----------------------------------------------------------------------===// // Dialect and Operation Registration //===----------------------------------------------------------------------===// diff --git a/mlir/lib/IR/Operation.cpp b/mlir/lib/IR/Operation.cpp index 174d7d5..2a65971 100644 --- a/mlir/lib/IR/Operation.cpp +++ b/mlir/lib/IR/Operation.cpp @@ -17,6 +17,7 @@ #include "mlir/IR/Operation.h" #include "mlir/IR/BlockAndValueMapping.h" +#include "mlir/IR/Diagnostics.h" #include "mlir/IR/Dialect.h" #include "mlir/IR/Function.h" #include "mlir/IR/MLIRContext.h" @@ -307,15 +308,15 @@ void Operation::walk(const std::function &callback) { /// Emit a note about this operation, reporting up to any diagnostic /// handlers that may be listening. void Operation::emitNote(const Twine &message) { - getContext()->emitDiagnostic(getLoc(), message, - MLIRContext::DiagnosticKind::Note); + getContext()->getDiagEngine().emit(getLoc(), message, + DiagnosticSeverity::Note); } /// Emit a warning about this operation, reporting up to any diagnostic /// handlers that may be listening. void Operation::emitWarning(const Twine &message) { - getContext()->emitDiagnostic(getLoc(), message, - MLIRContext::DiagnosticKind::Warning); + getContext()->getDiagEngine().emit(getLoc(), message, + DiagnosticSeverity::Warning); } /// Emit an error about fatal conditions with this operation, reporting up to diff --git a/mlir/lib/Pass/Pass.cpp b/mlir/lib/Pass/Pass.cpp index da88130..2d79f56 100644 --- a/mlir/lib/Pass/Pass.cpp +++ b/mlir/lib/Pass/Pass.cpp @@ -21,6 +21,7 @@ #include "mlir/Pass/Pass.h" #include "PassDetail.h" +#include "mlir/IR/Diagnostics.h" #include "mlir/IR/Module.h" #include "mlir/Pass/PassManager.h" #include "llvm/Support/CommandLine.h" @@ -183,7 +184,7 @@ namespace { struct ParallelDiagnosticHandler { struct ThreadDiagnostic { ThreadDiagnostic(size_t id, Location loc, StringRef msg, - MLIRContext::DiagnosticKind kind) + DiagnosticSeverity kind) : id(id), loc(loc), msg(msg), kind(kind) {} bool operator<(const ThreadDiagnostic &rhs) const { return id < rhs.id; } @@ -195,24 +196,24 @@ struct ParallelDiagnosticHandler { /// Information for the diagnostic. Location loc; std::string msg; - MLIRContext::DiagnosticKind kind; + DiagnosticSeverity kind; }; ParallelDiagnosticHandler(MLIRContext &ctx) - : prevHandler(ctx.getDiagnosticHandler()), context(ctx) { - ctx.registerDiagnosticHandler([this](Location loc, StringRef message, - MLIRContext::DiagnosticKind kind) { - uint64_t tid = llvm::get_threadid(); - llvm::sys::SmartScopedLock lock(mutex); - - // Append a new diagnostic. - diagnostics.emplace_back(threadToFuncID[tid], loc, message, kind); - }); + : prevHandler(ctx.getDiagEngine().getHandler()), context(ctx) { + ctx.getDiagEngine().setHandler( + [this](Location loc, StringRef message, DiagnosticSeverity kind) { + uint64_t tid = llvm::get_threadid(); + llvm::sys::SmartScopedLock lock(mutex); + + // Append a new diagnostic. + diagnostics.emplace_back(threadToFuncID[tid], loc, message, kind); + }); } ~ParallelDiagnosticHandler() { // Restore the previous diagnostic handler. - context.registerDiagnosticHandler(prevHandler); + context.getDiagEngine().setHandler(prevHandler); // Early exit if there are no diagnostics, this is the common case. if (diagnostics.empty()) @@ -220,15 +221,14 @@ struct ParallelDiagnosticHandler { // Emit the diagnostics back to the context. emitDiagnostics( - [&](Location loc, StringRef message, MLIRContext::DiagnosticKind kind) { - return context.emitDiagnostic(loc, message, kind); + [&](Location loc, StringRef message, DiagnosticSeverity kind) { + return context.getDiagEngine().emit(loc, message, kind); }); } /// Utility method to emit any held diagnostics. void emitDiagnostics( - std::function - emitFn) { + std::function emitFn) { // Stable sort all of the diagnostics that were emitted. This creates a // deterministic ordering for the diagnostics based upon which function they // were emitted for. @@ -247,7 +247,7 @@ struct ParallelDiagnosticHandler { } /// The previous context diagnostic handler. - MLIRContext::DiagnosticHandlerTy prevHandler; + DiagnosticEngine::HandlerTy prevHandler; /// A smart mutex to lock access to the internal state. llvm::sys::SmartMutex mutex; @@ -277,21 +277,21 @@ struct PrettyStackTraceParallelDiagnosticEntry os << "In-Flight Diagnostics:\n"; parallelHandler.emitDiagnostics( - [&](Location loc, StringRef message, MLIRContext::DiagnosticKind kind) { + [&](Location loc, StringRef message, DiagnosticSeverity severity) { os.indent(4); // Print each diagnostic with the format: // ": : " if (!loc.isa()) os << loc << ": "; - switch (kind) { - case MLIRContext::DiagnosticKind::Error: + switch (severity) { + case DiagnosticSeverity::Error: os << "error: "; break; - case MLIRContext::DiagnosticKind::Warning: + case DiagnosticSeverity::Warning: os << "warning: "; break; - case MLIRContext::DiagnosticKind::Note: + case DiagnosticSeverity::Note: os << "note: "; break; } diff --git a/mlir/lib/Transforms/Vectorization/VectorizerTestPass.cpp b/mlir/lib/Transforms/Vectorization/VectorizerTestPass.cpp index 1998740..d080d65 100644 --- a/mlir/lib/Transforms/Vectorization/VectorizerTestPass.cpp +++ b/mlir/lib/Transforms/Vectorization/VectorizerTestPass.cpp @@ -25,6 +25,7 @@ #include "mlir/Analysis/SliceAnalysis.h" #include "mlir/Analysis/VectorAnalysis.h" #include "mlir/IR/Builders.h" +#include "mlir/IR/Diagnostics.h" #include "mlir/IR/StandardTypes.h" #include "mlir/Pass/Pass.h" #include "mlir/Support/Functional.h" @@ -296,8 +297,8 @@ void VectorizerTestPass::runOnFunction() { testNormalizeMaps(); if (!outs.str().empty()) { - getContext().emitDiagnostic(UnknownLoc::get(&getContext()), outs.str(), - MLIRContext::DiagnosticKind::Note); + getContext().getDiagEngine().emit(UnknownLoc::get(&getContext()), + outs.str(), DiagnosticSeverity::Note); } } diff --git a/mlir/tools/mlir-opt/mlir-opt.cpp b/mlir/tools/mlir-opt/mlir-opt.cpp index 4f40588..71d01b2 100644 --- a/mlir/tools/mlir-opt/mlir-opt.cpp +++ b/mlir/tools/mlir-opt/mlir-opt.cpp @@ -23,6 +23,7 @@ #include "mlir/Analysis/Passes.h" #include "mlir/IR/Attributes.h" +#include "mlir/IR/Diagnostics.h" #include "mlir/IR/Function.h" #include "mlir/IR/Location.h" #include "mlir/IR/MLIRContext.h" @@ -151,25 +152,25 @@ static OptResult performActions(SourceMgr &sourceMgr, MLIRContext *context) { } /// Given a diagnostic kind, return a human readable string for it. -static StringRef getDiagnosticKindString(MLIRContext::DiagnosticKind kind) { +static StringRef getDiagnosticKindString(DiagnosticSeverity kind) { switch (kind) { - case MLIRContext::DiagnosticKind::Note: + case DiagnosticSeverity::Note: return "note"; - case MLIRContext::DiagnosticKind::Warning: + case DiagnosticSeverity::Warning: return "warning"; - case MLIRContext::DiagnosticKind::Error: + case DiagnosticSeverity::Error: return "error"; } } /// Given a diagnostic kind, returns the LLVM DiagKind. -static llvm::SourceMgr::DiagKind getDiagKind(MLIRContext::DiagnosticKind kind) { +static llvm::SourceMgr::DiagKind getDiagKind(DiagnosticSeverity kind) { switch (kind) { - case MLIRContext::DiagnosticKind::Note: + case DiagnosticSeverity::Note: return llvm::SourceMgr::DK_Note; - case MLIRContext::DiagnosticKind::Warning: + case DiagnosticSeverity::Warning: return llvm::SourceMgr::DK_Warning; - case MLIRContext::DiagnosticKind::Error: + case DiagnosticSeverity::Error: return llvm::SourceMgr::DK_Error; } } @@ -188,20 +189,19 @@ static OptResult processFile(std::unique_ptr ownedBuffer) { // If we are in verify mode then we have a lot of work to do, otherwise just // perform the actions without worrying about it. if (!verifyDiagnostics) { - // Register a simple diagnostic handler that prints out info with context. - context.registerDiagnosticHandler([&](Location location, StringRef message, - MLIRContext::DiagnosticKind kind) { - unsigned line = 1, column = 1; - SMLoc loc; - if (auto fileLoc = location.dyn_cast()) { - line = fileLoc->getLine(); - column = fileLoc->getColumn(); - loc = getLocFromLineAndCol(buffer, line, column); - } - - sourceMgr.PrintMessage(loc, getDiagKind(kind), message); - }); + context.getDiagEngine().setHandler( + [&](Location location, StringRef message, DiagnosticSeverity kind) { + unsigned line = 1, column = 1; + SMLoc loc; + if (auto fileLoc = location.dyn_cast()) { + line = fileLoc->getLine(); + column = fileLoc->getColumn(); + loc = getLocFromLineAndCol(buffer, line, column); + } + + sourceMgr.PrintMessage(loc, getDiagKind(kind), message); + }); // Run the test actions. return performActions(sourceMgr, &context); @@ -214,7 +214,7 @@ static OptResult processFile(std::unique_ptr ownedBuffer) { // Record the expected diagnostic's position, substring and whether it was // seen. struct ExpectedDiag { - MLIRContext::DiagnosticKind kind; + DiagnosticSeverity kind; unsigned lineNo; StringRef substring; SMLoc fileLoc; @@ -224,7 +224,7 @@ static OptResult processFile(std::unique_ptr ownedBuffer) { // Error checker that verifies reported error was expected. auto checker = [&](Location location, StringRef message, - MLIRContext::DiagnosticKind kind) { + DiagnosticSeverity kind) { unsigned line = 1, column = 1; if (auto fileLoc = location.dyn_cast()) { line = fileLoc->getLine(); @@ -279,14 +279,14 @@ static OptResult processFile(std::unique_ptr ownedBuffer) { // Point to the start of expected-*. SMLoc expectedStart = SMLoc::getFromPointer(matches[0].data()); - MLIRContext::DiagnosticKind kind; + DiagnosticSeverity kind; if (matches[1] == "error") - kind = MLIRContext::DiagnosticKind::Error; + kind = DiagnosticSeverity::Error; else if (matches[1] == "warning") - kind = MLIRContext::DiagnosticKind::Warning; + kind = DiagnosticSeverity::Warning; else { assert(matches[1] == "note"); - kind = MLIRContext::DiagnosticKind::Note; + kind = DiagnosticSeverity::Note; } ExpectedDiag record{kind, lineNo + 1, matches[3], expectedStart, false}; @@ -306,7 +306,7 @@ static OptResult processFile(std::unique_ptr ownedBuffer) { } // Finally, register the error handler to capture them. - context.registerDiagnosticHandler(checker); + context.getDiagEngine().setHandler(checker); // Do any processing requested by command line flags. We don't care whether // these actions succeed or fail, we only care what diagnostics they produce -- 2.7.4