diff options
| -rw-r--r-- | mlir/include/mlir/IR/Diagnostics.h | 230 | ||||
| -rw-r--r-- | mlir/include/mlir/IR/Function.h | 10 | ||||
| -rw-r--r-- | mlir/include/mlir/IR/MLIRContext.h | 7 | ||||
| -rw-r--r-- | mlir/include/mlir/IR/OpDefinition.h | 14 | ||||
| -rw-r--r-- | mlir/include/mlir/IR/Operation.h | 17 | ||||
| -rw-r--r-- | mlir/lib/FxpMathOps/Transforms/LowerUniformRealMath.cpp | 15 | ||||
| -rw-r--r-- | mlir/lib/IR/Diagnostics.cpp | 146 | ||||
| -rw-r--r-- | mlir/lib/IR/Dialect.cpp | 1 | ||||
| -rw-r--r-- | mlir/lib/IR/Function.cpp | 15 | ||||
| -rw-r--r-- | mlir/lib/IR/MLIRContext.cpp | 13 | ||||
| -rw-r--r-- | mlir/lib/IR/Operation.cpp | 47 | ||||
| -rw-r--r-- | mlir/lib/IR/StandardTypes.cpp | 1 | ||||
| -rw-r--r-- | mlir/lib/IR/Types.cpp | 1 | ||||
| -rw-r--r-- | mlir/lib/Parser/Lexer.cpp | 1 | ||||
| -rw-r--r-- | mlir/lib/Pass/Pass.cpp | 2 | ||||
| -rw-r--r-- | mlir/lib/Target/LLVMIR/ModuleTranslation.cpp | 6 |
16 files changed, 415 insertions, 111 deletions
diff --git a/mlir/include/mlir/IR/Diagnostics.h b/mlir/include/mlir/IR/Diagnostics.h index 45cb66a7126..ebb70bab287 100644 --- a/mlir/include/mlir/IR/Diagnostics.h +++ b/mlir/include/mlir/IR/Diagnostics.h @@ -22,11 +22,16 @@ #ifndef MLIR_IR_DIAGNOSTICS_H #define MLIR_IR_DIAGNOSTICS_H +#include "mlir/IR/Location.h" #include "mlir/Support/LLVM.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/Twine.h" #include <functional> namespace mlir { -class Location; +class DiagnosticEngine; +class LogicalResult; +class Type; namespace detail { struct DiagnosticEngineImpl; @@ -41,6 +46,217 @@ enum class DiagnosticSeverity { }; //===----------------------------------------------------------------------===// +// DiagnosticArgument +//===----------------------------------------------------------------------===// + +/// A variant type that holds a single argument for a diagnostic. +class DiagnosticArgument { +public: + /// Enum that represents the different kinds of diagnostic arguments + /// supported. + enum class DiagnosticArgumentKind { + Integer, + String, + Type, + Unsigned, + }; + + /// Outputs this argument to a stream. + void print(raw_ostream &os) const; + + /// Returns the kind of this argument. + DiagnosticArgumentKind getKind() const { return kind; } + + /// Returns this argument as a string. + StringRef getAsString() const { + assert(getKind() == DiagnosticArgumentKind::String); + return stringVal; + } + + /// Returns this argument as a signed integer. + int64_t getAsInteger() const { + assert(getKind() == DiagnosticArgumentKind::Integer); + return static_cast<int64_t>(opaqueVal); + } + + /// Returns this argument as a Type. + Type getAsType() const; + + /// Returns this argument as an unsigned integer. + uint64_t getAsUnsigned() const { + assert(getKind() == DiagnosticArgumentKind::Unsigned); + return static_cast<uint64_t>(opaqueVal); + } + +private: + friend class Diagnostic; + + // Construct from an int64_t. + explicit DiagnosticArgument(int64_t val) + : kind(DiagnosticArgumentKind::Integer), opaqueVal(val) {} + + // Construct from an uint64_t. + explicit DiagnosticArgument(uint64_t val) + : kind(DiagnosticArgumentKind::Unsigned), opaqueVal(val) {} + + // Construct from a string reference. + explicit DiagnosticArgument(StringRef val) + : kind(DiagnosticArgumentKind::String), stringVal(val) {} + + // Construct from a Type. + explicit DiagnosticArgument(Type val); + + /// The kind of this argument. + DiagnosticArgumentKind kind; + + /// The value of this argument. + union { + intptr_t opaqueVal; + StringRef stringVal; + }; +}; + +inline raw_ostream &operator<<(raw_ostream &os, const DiagnosticArgument &arg) { + arg.print(os); + return os; +} + +//===----------------------------------------------------------------------===// +// Diagnostic +//===----------------------------------------------------------------------===// + +/// This class contains all of the information necessary to report a diagnostic +/// to the DiagnosticEngine. It should generally not be constructed directly, +/// and instead used transitively via InFlightDiagnostic. +class Diagnostic { +public: + Diagnostic(Location loc, DiagnosticSeverity severity) + : loc(loc), severity(severity) {} + Diagnostic(Diagnostic &&) = default; + Diagnostic &operator=(Diagnostic &&) = default; + + /// Returns the severity of this diagnostic. + DiagnosticSeverity getSeverity() const { return severity; } + + /// Returns the source location for this diagnostic. + Location getLocation() const { return loc; } + + /// Returns the current list of diagnostic arguments. + MutableArrayRef<DiagnosticArgument> getArguments() { return arguments; } + ArrayRef<DiagnosticArgument> getArguments() const { return arguments; } + + /// Stream operator for inserting new diagnostic arguments. + template <typename Arg> + typename std::enable_if<!std::is_convertible<Arg, StringRef>::value, + Diagnostic &>::type + operator<<(Arg &&val) { + arguments.push_back(DiagnosticArgument(std::forward<Arg>(val))); + return *this; + } + Diagnostic &operator<<(const char *val) { + arguments.push_back(DiagnosticArgument(val)); + return *this; + } + Diagnostic &operator<<(const Twine &val) { + llvm::SmallString<0> str; + arguments.push_back(DiagnosticArgument(val.toStringRef(str))); + stringArguments.emplace_back(std::move(str), arguments.size()); + return *this; + } + + /// Outputs this diagnostic to a stream. + void print(raw_ostream &os) const; + + /// Converts the diagnostic to a string. + std::string str() const; + +private: + Diagnostic(const Diagnostic &rhs) = delete; + Diagnostic &operator=(const Diagnostic &rhs) = delete; + + /// The source location. + Location loc; + + /// The severity of this diagnostic. + DiagnosticSeverity severity; + + /// The current list of arguments. + SmallVector<DiagnosticArgument, 4> arguments; + + /// A list of string values used as arguments and the corresponding index of + /// those arguments. This is used to guarantee the liveness of non-constant + /// strings used in diagnostics. + std::vector<std::pair<llvm::SmallString<0>, unsigned>> stringArguments; +}; + +inline raw_ostream &operator<<(raw_ostream &os, const Diagnostic &diag) { + diag.print(os); + return os; +} + +//===----------------------------------------------------------------------===// +// InFlightDiagnostic +//===----------------------------------------------------------------------===// + +/// This class represents a diagnostic that is inflight and set to be reported. +/// This allows for last minute modifications of the diagnostic before it is +/// emitted by a DiagnosticEngine. +class InFlightDiagnostic { +public: + InFlightDiagnostic() = default; + InFlightDiagnostic(InFlightDiagnostic &&rhs) + : owner(rhs.owner), impl(std::move(rhs.impl)) { + // Reset the rhs diagnostic. + rhs.impl.reset(); + } + ~InFlightDiagnostic() { + if (isInFlight()) + report(); + } + + /// Stream operator for new diagnostic arguments. + template <typename Arg> InFlightDiagnostic &&operator<<(Arg &&arg) && { + appendArgument(std::forward<Arg>(arg)); + return std::move(*this); + } + template <typename Arg> InFlightDiagnostic &operator<<(Arg &&arg) & { + appendArgument(std::forward<Arg>(arg)); + return *this; + } + + /// Reports the diagnostic to the engine. + void report(); + + /// Allow an inflight diagnostic to be converted to 'failure', otherwise + /// 'success' if this is an empty diagnostic. + operator LogicalResult() const; + + /// Returns if the diagnostic is still in flight. + bool isInFlight() const { return impl.hasValue(); } + +private: + InFlightDiagnostic &operator=(const InFlightDiagnostic &) = delete; + InFlightDiagnostic &operator=(InFlightDiagnostic &&) = delete; + InFlightDiagnostic(DiagnosticEngine *owner, Diagnostic &&rhs) + : owner(owner), impl(std::move(rhs)) {} + + /// Add an argument to the internal diagnostic. + template <typename Arg> void appendArgument(Arg &&arg) { + assert(isInFlight() && "diagnostic not inflight"); + *impl << std::forward<Arg>(arg); + } + + // Allow access to the constructor. + friend DiagnosticEngine; + + /// The engine that this diagnostic is to report to. + DiagnosticEngine *owner; + + /// The raw diagnostic that is inflight to be reported. + llvm::Optional<Diagnostic> impl; +}; + +//===----------------------------------------------------------------------===// // DiagnosticEngine //===----------------------------------------------------------------------===// @@ -60,7 +276,7 @@ public: // // 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). + // notes will be dropped and errors will be emitted to errs. using HandlerTy = std::function<void(Location, StringRef, DiagnosticSeverity)>; @@ -74,10 +290,14 @@ public: /// Return the current diagnostic handler, or null if none is present. HandlerTy getHandler(); + /// Create a new inflight diagnostic with the given location and severity. + InFlightDiagnostic emit(Location loc, DiagnosticSeverity severity) { + return InFlightDiagnostic(this, Diagnostic(loc, severity)); + } + /// 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); + /// the default behavior if not. + void emit(const Diagnostic &diag); private: friend class MLIRContextImpl; diff --git a/mlir/include/mlir/IR/Function.h b/mlir/include/mlir/IR/Function.h index 4c57ff6b3fc..30eca05d6f3 100644 --- a/mlir/include/mlir/IR/Function.h +++ b/mlir/include/mlir/IR/Function.h @@ -250,18 +250,16 @@ public: void dump(); /// Emit an error about fatal conditions with this function, reporting up to - /// any diagnostic handlers that may be listening. This function always - /// returns failure. NOTE: This may terminate the containing application, - /// only use when the IR is in an inconsistent state. - LogicalResult emitError(const Twine &message); + /// any diagnostic handlers that may be listening. + InFlightDiagnostic emitError(const Twine &message); /// Emit a warning about this function, reporting up to any diagnostic /// handlers that may be listening. - void emitWarning(const Twine &message); + InFlightDiagnostic emitWarning(const Twine &message); /// Emit a remark about this function, reporting up to any diagnostic /// handlers that may be listening. - void emitRemark(const Twine &message); + InFlightDiagnostic emitRemark(const Twine &message); /// Displays the CFG in a window. This is for use from the debugger and /// depends on Graphviz to generate the graph. diff --git a/mlir/include/mlir/IR/MLIRContext.h b/mlir/include/mlir/IR/MLIRContext.h index d90035bc823..cdbfcf35470 100644 --- a/mlir/include/mlir/IR/MLIRContext.h +++ b/mlir/include/mlir/IR/MLIRContext.h @@ -27,6 +27,7 @@ namespace mlir { class AbstractOperation; class DiagnosticEngine; class Dialect; +class InFlightDiagnostic; class Location; class MLIRContextImpl; class StorageUniquer; @@ -60,11 +61,11 @@ public: // 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); + /// Emit an error message using the diagnostic engine. + InFlightDiagnostic emitError(Location location, const Twine &message); /// Emit a remark message using the diagnostic engine. - void emitRemark(Location location, const Twine &message); + InFlightDiagnostic emitRemark(Location location, const Twine &message); /// Returns the diagnostic engine for this context. DiagnosticEngine &getDiagEngine(); diff --git a/mlir/include/mlir/IR/OpDefinition.h b/mlir/include/mlir/IR/OpDefinition.h index 4430e242e76..636122aea71 100644 --- a/mlir/include/mlir/IR/OpDefinition.h +++ b/mlir/include/mlir/IR/OpDefinition.h @@ -104,26 +104,24 @@ public: void erase() { state->erase(); } /// Emit an error about fatal conditions with this operation, reporting up to - /// any diagnostic handlers that may be listening. This function always - /// returns failure. NOTE: This may terminate the containing application, - /// only use when the IR is in an inconsistent state. - LogicalResult emitError(const Twine &message); + /// any diagnostic handlers that may be listening. + InFlightDiagnostic emitError(const Twine &message); /// Emit an error with the op name prefixed, like "'dim' op " which is /// convenient for verifiers. This always returns failure. - LogicalResult emitOpError(const Twine &message); + InFlightDiagnostic emitOpError(const Twine &message); /// Emit a warning about this operation, reporting up to any diagnostic /// handlers that may be listening. - void emitWarning(const Twine &message); + InFlightDiagnostic emitWarning(const Twine &message); /// Emit a note about this operation, reporting up to any diagnostic /// handlers that may be listening. - void emitNote(const Twine &message); + InFlightDiagnostic emitNote(const Twine &message); /// Emit a remark about this operation, reporting up to any diagnostic /// handlers that may be listening. - void emitRemark(const Twine &message); + InFlightDiagnostic emitRemark(const Twine &message); // These are default implementations of customization hooks. public: diff --git a/mlir/include/mlir/IR/Operation.h b/mlir/include/mlir/IR/Operation.h index d9ab87670b6..23e147a3ae7 100644 --- a/mlir/include/mlir/IR/Operation.h +++ b/mlir/include/mlir/IR/Operation.h @@ -24,6 +24,7 @@ #include "mlir/IR/AffineMap.h" #include "mlir/IR/Block.h" +#include "mlir/IR/Diagnostics.h" #include "mlir/IR/OperationSupport.h" #include "llvm/ADT/Twine.h" #include "llvm/ADT/ilist.h" @@ -429,26 +430,24 @@ public: //===--------------------------------------------------------------------===// /// Emit an error with the op name prefixed, like "'dim' op " which is - /// convenient for verifiers. This function always returns failure. - LogicalResult emitOpError(const Twine &message); + /// convenient for verifiers. + InFlightDiagnostic emitOpError(const Twine &message); /// Emit an error about fatal conditions with this operation, reporting up to - /// any diagnostic handlers that may be listening. This function always - /// returns failure. NOTE: This may terminate the containing application, - /// only use when the IR is in an inconsistent state. - LogicalResult emitError(const Twine &message); + /// any diagnostic handlers that may be listening. + InFlightDiagnostic emitError(const Twine &message); /// Emit a warning about this operation, reporting up to any diagnostic /// handlers that may be listening. - void emitWarning(const Twine &message); + InFlightDiagnostic emitWarning(const Twine &message); /// Emit a note about this operation, reporting up to any diagnostic /// handlers that may be listening. - void emitNote(const Twine &message); + InFlightDiagnostic emitNote(const Twine &message); /// Emit a remark about this operation, reporting up to any diagnostic /// handlers that may be listening. - void emitRemark(const Twine &message); + InFlightDiagnostic emitRemark(const Twine &message); private: Operation(Location location, OperationName name, unsigned numResults, diff --git a/mlir/lib/FxpMathOps/Transforms/LowerUniformRealMath.cpp b/mlir/lib/FxpMathOps/Transforms/LowerUniformRealMath.cpp index 3e8a47a474b..96db87ca375 100644 --- a/mlir/lib/FxpMathOps/Transforms/LowerUniformRealMath.cpp +++ b/mlir/lib/FxpMathOps/Transforms/LowerUniformRealMath.cpp @@ -52,10 +52,10 @@ static Value *emitUniformPerLayerDequantize(Location loc, Value *input, // Pre-conditions. if (!elementType.isSigned()) { // TODO: Support unsigned storage type. - return rewriter.getContext()->getDiagEngine().emit( - loc, "unimplemented: dequantize signed uniform", - DiagnosticSeverity::Warning), - nullptr; + rewriter.getContext()->getDiagEngine().emit(loc, + DiagnosticSeverity::Warning) + << "unimplemented: dequantize signed uniform"; + return nullptr; } Type storageType = elementType.castToStorageType(input->getType()); @@ -94,10 +94,9 @@ emitUniformPerAxisDequantize(Location loc, Value *input, UniformQuantizedPerAxisType elementType, PatternRewriter &rewriter) { // TODO: Support per-axis dequantize. - return rewriter.getContext()->getDiagEngine().emit( - loc, "unimplemented: per-axis uniform dequantization", - DiagnosticSeverity::Warning), - nullptr; + rewriter.getContext()->getDiagEngine().emit(loc, DiagnosticSeverity::Warning) + << "unimplemented: per-axis uniform dequantization"; + return nullptr; } static Value *emitDequantize(Location loc, Value *input, diff --git a/mlir/lib/IR/Diagnostics.cpp b/mlir/lib/IR/Diagnostics.cpp index 0311fa16420..b266183bb8d 100644 --- a/mlir/lib/IR/Diagnostics.cpp +++ b/mlir/lib/IR/Diagnostics.cpp @@ -17,6 +17,7 @@ #include "mlir/IR/Diagnostics.h" #include "mlir/IR/Location.h" +#include "mlir/IR/Types.h" #include "llvm/ADT/Twine.h" #include "llvm/Support/Mutex.h" #include "llvm/Support/raw_ostream.h" @@ -24,9 +25,86 @@ using namespace mlir; using namespace mlir::detail; +//===----------------------------------------------------------------------===// +// DiagnosticArgument +//===----------------------------------------------------------------------===// + +// Construct from a Type. +DiagnosticArgument::DiagnosticArgument(Type val) + : kind(DiagnosticArgumentKind::Type), + opaqueVal(reinterpret_cast<intptr_t>(val.getAsOpaquePointer())) {} + +/// Returns this argument as a Type. +Type DiagnosticArgument::getAsType() const { + assert(getKind() == DiagnosticArgumentKind::Type); + return Type::getFromOpaquePointer(reinterpret_cast<const void *>(opaqueVal)); +} + +/// Outputs this argument to a stream. +void DiagnosticArgument::print(raw_ostream &os) const { + switch (kind) { + case DiagnosticArgumentKind::Integer: + os << getAsInteger(); + break; + case DiagnosticArgumentKind::String: + os << getAsString(); + break; + case DiagnosticArgumentKind::Type: + os << getAsType(); + break; + case DiagnosticArgumentKind::Unsigned: + os << getAsUnsigned(); + break; + } +} + +//===----------------------------------------------------------------------===// +// Diagnostic +//===----------------------------------------------------------------------===// + +/// Outputs this diagnostic to a stream. +void Diagnostic::print(raw_ostream &os) const { + for (auto &arg : getArguments()) + arg.print(os); +} + +/// Convert the diagnostic to a string. +std::string Diagnostic::str() const { + std::string str; + llvm::raw_string_ostream os(str); + print(os); + return os.str(); +} + +//===----------------------------------------------------------------------===// +// InFlightDiagnostic +//===----------------------------------------------------------------------===// + +/// Allow an inflight diagnostic to be converted to 'failure', otherwise +/// 'success' if this is an empty diagnostic. +InFlightDiagnostic::operator LogicalResult() const { + return failure(isInFlight()); +} + +/// Reports the diagnostic to the engine. +void InFlightDiagnostic::report() { + if (isInFlight()) { + owner->emit(*impl); + impl.reset(); + } +} + +//===----------------------------------------------------------------------===// +// DiagnosticEngineImpl +//===----------------------------------------------------------------------===// + namespace mlir { namespace detail { struct DiagnosticEngineImpl { + /// Emit a diagnostic using the registered issue handle if present, or with + /// the default behavior if not. + void emit(Location loc, StringRef msg, DiagnosticSeverity severity); + /// A mutex to ensure that diagnostics emission is thread-safe. llvm::sys::SmartMutex<true> mutex; @@ -37,42 +115,18 @@ struct DiagnosticEngineImpl { } // 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<true> lock(impl->mutex); - impl->handler = handler; -} - -/// Return the current diagnostic handler, or null if none is present. -auto DiagnosticEngine::getHandler() -> HandlerTy { - llvm::sys::SmartScopedLock<true> 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<true> lock(impl->mutex); +/// the default behavior if not. +void DiagnosticEngineImpl::emit(Location loc, StringRef msg, + DiagnosticSeverity severity) { + // Lock access to the handler. + llvm::sys::SmartScopedLock<true> lock(mutex); // If we had a handler registered, emit the diagnostic using it. - if (impl->handler) { + if (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. + // Check to see if we are emitting a diagnostic on a fused location. if (auto fusedLoc = loc.dyn_cast<FusedLoc>()) { auto fusedLocs = fusedLoc->getLocations(); @@ -85,7 +139,7 @@ void DiagnosticEngine::emit(Location loc, const Twine &msg, return; } - return impl->handler(loc, msg.str(), severity); + return handler(loc, msg, severity); } // Otherwise, if this is an error we emit it to stderr. @@ -101,3 +155,31 @@ void DiagnosticEngine::emit(Location loc, const Twine &msg, os << msg << '\n'; os.flush(); } + +//===----------------------------------------------------------------------===// +// DiagnosticEngine +//===----------------------------------------------------------------------===// + +DiagnosticEngine::DiagnosticEngine() : impl(new DiagnosticEngineImpl()) {} +DiagnosticEngine::~DiagnosticEngine() {} + +/// 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 DiagnosticEngine::setHandler(const HandlerTy &handler) { + llvm::sys::SmartScopedLock<true> lock(impl->mutex); + impl->handler = handler; +} + +/// Return the current diagnostic handler, or null if none is present. +auto DiagnosticEngine::getHandler() -> HandlerTy { + llvm::sys::SmartScopedLock<true> lock(impl->mutex); + return impl->handler; +} + +/// Emit a diagnostic using the registered issue handler if present, or with +/// the default behavior if not. +void DiagnosticEngine::emit(const Diagnostic &diag) { + impl->emit(diag.getLocation(), diag.str(), diag.getSeverity()); +} diff --git a/mlir/lib/IR/Dialect.cpp b/mlir/lib/IR/Dialect.cpp index e87358c4bd4..89ff1b50ed4 100644 --- a/mlir/lib/IR/Dialect.cpp +++ b/mlir/lib/IR/Dialect.cpp @@ -16,6 +16,7 @@ // ============================================================================= #include "mlir/IR/Dialect.h" +#include "mlir/IR/Diagnostics.h" #include "mlir/IR/DialectHooks.h" #include "mlir/IR/MLIRContext.h" #include "llvm/ADT/Twine.h" diff --git a/mlir/lib/IR/Function.cpp b/mlir/lib/IR/Function.cpp index e655e2ed774..66b296f2454 100644 --- a/mlir/lib/IR/Function.cpp +++ b/mlir/lib/IR/Function.cpp @@ -118,23 +118,24 @@ void Function::erase() { /// Emit a remark about this function, reporting up to any diagnostic /// handlers that may be listening. -void Function::emitRemark(const Twine &message) { - getContext()->emitRemark(getLoc(), message); +InFlightDiagnostic Function::emitRemark(const Twine &message) { + return getContext()->emitRemark(getLoc(), message); } /// Emit a warning about this function, reporting up to any diagnostic /// handlers that may be listening. -void Function::emitWarning(const Twine &message) { - getContext()->getDiagEngine().emit(getLoc(), message, - DiagnosticSeverity::Warning); +InFlightDiagnostic Function::emitWarning(const Twine &message) { + return getContext()->getDiagEngine().emit(getLoc(), + DiagnosticSeverity::Warning) + << message; } /// Emit an error about fatal conditions with this function, reporting up to /// any diagnostic handlers that may be listening. This function always /// returns failure. NOTE: This may terminate the containing application, only /// use when the IR is in an inconsistent state. -LogicalResult Function::emitError(const Twine &message) { - return getContext()->emitError(getLoc(), message), failure(); +InFlightDiagnostic Function::emitError(const Twine &message) { + return getContext()->emitError(getLoc(), message); } /// Clone the internal blocks from this function into dest and all attributes diff --git a/mlir/lib/IR/MLIRContext.cpp b/mlir/lib/IR/MLIRContext.cpp index 5161c27368c..6e3c7c9da5a 100644 --- a/mlir/lib/IR/MLIRContext.cpp +++ b/mlir/lib/IR/MLIRContext.cpp @@ -422,14 +422,17 @@ static ArrayRef<T> copyArrayRefInto(llvm::BumpPtrAllocator &allocator, // Diagnostic Handlers //===----------------------------------------------------------------------===// -bool MLIRContext::emitError(Location location, const llvm::Twine &message) { - getImpl().diagEngine.emit(location, message, DiagnosticSeverity::Error); - return true; +InFlightDiagnostic MLIRContext::emitError(Location location, + const llvm::Twine &message) { + return getImpl().diagEngine.emit(location, DiagnosticSeverity::Error) + << message; } /// Emit a remark message using the diagnostic engine. -void MLIRContext::emitRemark(Location location, const Twine &message) { - getImpl().diagEngine.emit(location, message, DiagnosticSeverity::Remark); +InFlightDiagnostic MLIRContext::emitRemark(Location location, + const Twine &message) { + return getImpl().diagEngine.emit(location, DiagnosticSeverity::Remark) + << message; } /// Returns the diagnostic engine for this context. diff --git a/mlir/lib/IR/Operation.cpp b/mlir/lib/IR/Operation.cpp index 1a0aaa526c1..da02c58d366 100644 --- a/mlir/lib/IR/Operation.cpp +++ b/mlir/lib/IR/Operation.cpp @@ -307,30 +307,29 @@ void Operation::walk(const std::function<void(Operation *)> &callback) { /// Emit a remark about this operation, reporting up to any diagnostic /// handlers that may be listening. -void Operation::emitRemark(const Twine &message) { - getContext()->emitRemark(getLoc(), message); +InFlightDiagnostic Operation::emitRemark(const Twine &message) { + return getContext()->emitRemark(getLoc(), message); } /// Emit a note about this operation, reporting up to any diagnostic /// handlers that may be listening. -void Operation::emitNote(const Twine &message) { - getContext()->getDiagEngine().emit(getLoc(), message, - DiagnosticSeverity::Note); +InFlightDiagnostic Operation::emitNote(const Twine &message) { + return getContext()->getDiagEngine().emit(getLoc(), DiagnosticSeverity::Note) + << message; } /// Emit a warning about this operation, reporting up to any diagnostic /// handlers that may be listening. -void Operation::emitWarning(const Twine &message) { - getContext()->getDiagEngine().emit(getLoc(), message, - DiagnosticSeverity::Warning); +InFlightDiagnostic Operation::emitWarning(const Twine &message) { + return getContext()->getDiagEngine().emit(getLoc(), + DiagnosticSeverity::Warning) + << message; } /// Emit an error about fatal conditions with this operation, reporting up to -/// any diagnostic handlers that may be listening. This function always -/// returns failure. NOTE: This may terminate the containing application, only -/// use when the IR is in an inconsistent state. -LogicalResult Operation::emitError(const Twine &message) { - return getContext()->emitError(getLoc(), message), failure(); +/// any diagnostic handlers that may be listening. +InFlightDiagnostic Operation::emitError(const Twine &message) { + return getContext()->emitError(getLoc(), message); } /// Given an operation 'other' that is within the same parent block, return @@ -551,7 +550,7 @@ LogicalResult Operation::fold(SmallVectorImpl<Value *> &results) { /// Emit an error with the op name prefixed, like "'dim' op " which is /// convenient for verifiers. -LogicalResult Operation::emitOpError(const Twine &message) { +InFlightDiagnostic Operation::emitOpError(const Twine &message) { return emitError(Twine('\'') + getName().getStringRef() + "' op " + message); } @@ -652,35 +651,33 @@ bool OpState::parse(OpAsmParser *parser, OperationState *result) { void OpState::print(OpAsmPrinter *p) { p->printGenericOp(getOperation()); } /// Emit an error about fatal conditions with this operation, reporting up to -/// any diagnostic handlers that may be listening. NOTE: This may terminate -/// the containing application, only use when the IR is in an inconsistent -/// state. -LogicalResult OpState::emitError(const Twine &message) { +/// any diagnostic handlers that may be listening. +InFlightDiagnostic OpState::emitError(const Twine &message) { return getOperation()->emitError(message); } /// Emit an error with the op name prefixed, like "'dim' op " which is /// convenient for verifiers. -LogicalResult OpState::emitOpError(const Twine &message) { +InFlightDiagnostic OpState::emitOpError(const Twine &message) { return getOperation()->emitOpError(message); } /// Emit a warning about this operation, reporting up to any diagnostic /// handlers that may be listening. -void OpState::emitWarning(const Twine &message) { - getOperation()->emitWarning(message); +InFlightDiagnostic OpState::emitWarning(const Twine &message) { + return getOperation()->emitWarning(message); } /// Emit a note about this operation, reporting up to any diagnostic /// handlers that may be listening. -void OpState::emitNote(const Twine &message) { - getOperation()->emitNote(message); +InFlightDiagnostic OpState::emitNote(const Twine &message) { + return getOperation()->emitNote(message); } /// Emit a remark about this operation, reporting up to any diagnostic /// handlers that may be listening. -void OpState::emitRemark(const Twine &message) { - getOperation()->emitRemark(message); +InFlightDiagnostic OpState::emitRemark(const Twine &message) { + return getOperation()->emitRemark(message); } //===----------------------------------------------------------------------===// diff --git a/mlir/lib/IR/StandardTypes.cpp b/mlir/lib/IR/StandardTypes.cpp index 1427f1f03c0..25a02332516 100644 --- a/mlir/lib/IR/StandardTypes.cpp +++ b/mlir/lib/IR/StandardTypes.cpp @@ -18,6 +18,7 @@ #include "mlir/IR/StandardTypes.h" #include "TypeDetail.h" #include "mlir/IR/AffineMap.h" +#include "mlir/IR/Diagnostics.h" #include "mlir/Support/STLExtras.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/Twine.h" diff --git a/mlir/lib/IR/Types.cpp b/mlir/lib/IR/Types.cpp index 701935439f6..dba33a97886 100644 --- a/mlir/lib/IR/Types.cpp +++ b/mlir/lib/IR/Types.cpp @@ -17,6 +17,7 @@ #include "mlir/IR/Types.h" #include "TypeDetail.h" +#include "mlir/IR/Diagnostics.h" #include "mlir/IR/Dialect.h" #include "llvm/ADT/Twine.h" diff --git a/mlir/lib/Parser/Lexer.cpp b/mlir/lib/Parser/Lexer.cpp index 8d3fa88419d..59a435e2266 100644 --- a/mlir/lib/Parser/Lexer.cpp +++ b/mlir/lib/Parser/Lexer.cpp @@ -20,6 +20,7 @@ //===----------------------------------------------------------------------===// #include "Lexer.h" +#include "mlir/IR/Diagnostics.h" #include "mlir/IR/Location.h" #include "mlir/IR/MLIRContext.h" #include "llvm/Support/SourceMgr.h" diff --git a/mlir/lib/Pass/Pass.cpp b/mlir/lib/Pass/Pass.cpp index b7d7ca74dba..2489115877d 100644 --- a/mlir/lib/Pass/Pass.cpp +++ b/mlir/lib/Pass/Pass.cpp @@ -222,7 +222,7 @@ struct ParallelDiagnosticHandler { // Emit the diagnostics back to the context. emitDiagnostics( [&](Location loc, StringRef message, DiagnosticSeverity kind) { - return context.getDiagEngine().emit(loc, message, kind); + return context.getDiagEngine().emit(loc, kind) << message; }); } diff --git a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp index 58bbc9c873b..8a9c649feb3 100644 --- a/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp +++ b/mlir/lib/Target/LLVMIR/ModuleTranslation.cpp @@ -339,10 +339,12 @@ bool ModuleTranslation::convertOneFunction(Function &func) { // NB: Attribute already verified to be boolean, so check if we can indeed // attach the attribute to this argument, based on its type. auto argTy = mlirArg->getType().dyn_cast<LLVM::LLVMType>(); - if (!argTy.getUnderlyingType()->isPointerTy()) - return argTy.getContext()->emitError( + if (!argTy.getUnderlyingType()->isPointerTy()) { + argTy.getContext()->emitError( func.getLoc(), "llvm.noalias attribute attached to LLVM non-pointer argument"); + return true; + } if (attr.getValue()) llvmArg.addAttr(llvm::Attribute::AttrKind::NoAlias); } |

