diff --git a/mlir/cmake/modules/AddMLIR.cmake b/mlir/cmake/modules/AddMLIR.cmake index ff4269ed7acd2..c35308d57eadd 100644 --- a/mlir/cmake/modules/AddMLIR.cmake +++ b/mlir/cmake/modules/AddMLIR.cmake @@ -203,6 +203,14 @@ function(add_mlir_interface interface) add_dependencies(mlir-generic-headers MLIR${interface}IncGen) endfunction() +# Declare a dialect in the include directory +function(add_mlir_type_interface interface) + set(LLVM_TARGET_DEFINITIONS ${interface}.td) + mlir_tablegen(${interface}.h.inc -gen-type-interface-decls) + mlir_tablegen(${interface}.cpp.inc -gen-type-interface-defs) + add_public_tablegen_target(MLIR${interface}IncGen) + add_dependencies(mlir-generic-headers MLIR${interface}IncGen) +endfunction() # Generate Documentation function(add_mlir_doc doc_filename output_file output_directory command) diff --git a/mlir/include/mlir/IR/BuiltinTypes.h b/mlir/include/mlir/IR/BuiltinTypes.h index 86ec5c43970b1..d30cba29c9814 100644 --- a/mlir/include/mlir/IR/BuiltinTypes.h +++ b/mlir/include/mlir/IR/BuiltinTypes.h @@ -167,6 +167,8 @@ class BaseMemRefType : public Type, // Tablegen Type Declarations //===----------------------------------------------------------------------===// +#include "mlir/IR/QuantStorageTypeInterface.h" + #define GET_TYPEDEF_CLASSES #include "mlir/IR/BuiltinTypes.h.inc" diff --git a/mlir/include/mlir/IR/BuiltinTypes.td b/mlir/include/mlir/IR/BuiltinTypes.td index a0c8acea91dc5..c7e9ee2a4c95f 100644 --- a/mlir/include/mlir/IR/BuiltinTypes.td +++ b/mlir/include/mlir/IR/BuiltinTypes.td @@ -17,6 +17,7 @@ include "mlir/IR/AttrTypeBase.td" include "mlir/IR/BuiltinDialect.td" include "mlir/IR/BuiltinTypeInterfaces.td" +include "mlir/IR/QuantStorageTypeInterface.td" include "mlir/IR/CommonTypeConstraints.td" // TODO: Currently the types defined in this file are prefixed with `Builtin_`. @@ -100,7 +101,8 @@ class Builtin_CachedFloatType { +def Builtin_Float8E5M2 : Builtin_FloatType<"Float8E5M2", "f8E5M2", + ["QuantStorageTypeInterface"]> { let summary = "8-bit floating point with 2 bit mantissa"; let description = [{ An 8-bit floating point type with 1 sign bit, 5 bits exponent and 2 bits @@ -116,6 +118,33 @@ def Builtin_Float8E5M2 : Builtin_FloatType<"Float8E5M2", "f8E5M2"> { Described in: https://arxiv.org/abs/2209.05433 }]; + + let extraClassDeclaration = [{ + /// QuantStorageTypeInterface method implementations + bool isStorageSigned() const { return true; } + /// Get the bit width of this 8-bit floating point type. + unsigned getStorageWidth() const { return 8; } + + /// Get default maximum value for this 8-bit floating point type. + int64_t getDefaultMaximum() const { return 57344; } + /// Get default minimum value for this 8-bit floating point type. + int64_t getDefaultMinimum() const { return -getDefaultMaximum(); } + + /// Get the storage type as a string. + std::string getStorageType() const { return "f8E5M2"; } + + /// Check if this 8-bit floating point type uses packed representation. + bool isPacked() const { return false; } + + /// Get the logical bit width per value for this 8-bit floating point type. + unsigned getLogicalBitWidth() const { return 8; } + + /// Get the number of logical elements that fit in one byte for this 8-bit floating point type. + unsigned getElementsPerByte() const { return 1; } + + /// Get the preferred alignment in bytes for this 8-bit floating point type. + std::optional getPreferredAlignmentBytes() const { return std::nullopt; } + }]; } //===----------------------------------------------------------------------===// @@ -142,7 +171,8 @@ def Builtin_Float8E4M3 : Builtin_FloatType<"Float8E4M3", "f8E4M3"> { // Float8E4M3FNType //===----------------------------------------------------------------------===// -def Builtin_Float8E4M3FN : Builtin_FloatType<"Float8E4M3FN", "f8E4M3FN"> { +def Builtin_Float8E4M3FN : Builtin_FloatType<"Float8E4M3FN", "f8E4M3FN", + ["QuantStorageTypeInterface"]> { let summary = "8-bit floating point with 3 bit mantissa"; let description = [{ An 8-bit floating point type with 1 sign bit, 4 bits exponent and 3 bits @@ -159,6 +189,33 @@ def Builtin_Float8E4M3FN : Builtin_FloatType<"Float8E4M3FN", "f8E4M3FN"> { Described in: https://arxiv.org/abs/2209.05433 }]; + + let extraClassDeclaration = [{ + /// QuantStorageTypeInterface method implementations + bool isStorageSigned() const { return true; } + /// Get the bit width of this 8-bit floating point type. + unsigned getStorageWidth() const { return 8; } + + /// Get default maximum value for this 8-bit floating point type. + int64_t getDefaultMaximum() const { return 448; } + /// Get default minimum value for this 8-bit floating point type. + int64_t getDefaultMinimum() const { return -getDefaultMaximum(); } + + /// Get the storage type as a string. + std::string getStorageType() const { return "f8E4M3FN"; } + + /// Check if this 8-bit floating point type uses packed representation. + bool isPacked() const { return false; } + + /// Get the logical bit width per value for this 8-bit floating point type. + unsigned getLogicalBitWidth() const { return 8; } + + /// Get the number of logical elements that fit in one byte for this 8-bit floating point type. + unsigned getElementsPerByte() const { return 1; } + + /// Get the preferred alignment in bytes for this 8-bit floating point type. + std::optional getPreferredAlignmentBytes() const { return std::nullopt; } + }]; } //===----------------------------------------------------------------------===// @@ -497,7 +554,7 @@ def Builtin_Index : Builtin_Type<"Index", "index", //===----------------------------------------------------------------------===// def Builtin_Integer : Builtin_Type<"Integer", "integer", - [VectorElementTypeInterface]> { + [VectorElementTypeInterface, QuantStorageTypeInterface]> { let summary = "Integer type with arbitrary precision up to a fixed limit"; let description = [{ Syntax: @@ -554,6 +611,44 @@ def Builtin_Integer : Builtin_Type<"Integer", "integer", /// Integer representation maximal bitwidth. /// Note: This is aligned with the maximum width of llvm::IntegerType. static constexpr unsigned kMaxWidth = (1 << 24) - 1; + + /// QuantStorageTypeInterface method implementations + /// Return true if this is a signed or signless integer type. + bool isStorageSigned() const { return !isUnsigned(); } + /// Get the bit width of this integer type. + unsigned getStorageWidth() const { return getWidth(); } + + /// Get default maximum value for this integer type. + int64_t getDefaultMaximum() const { + if (isStorageSigned()) { + return llvm::maxIntN(getStorageWidth()); + } + return llvm::maxUIntN(getStorageWidth()); + } + /// Get default minimum value for this integer type. + int64_t getDefaultMinimum() const { + if (isStorageSigned()) { + return llvm::minIntN(getStorageWidth()); + } + return 0; + } + + /// Get the storage type as a string. + std::string getStorageType() const { + return (isStorageSigned() ? "i" : "u") + std::to_string(getWidth()); + } + + /// Check if this integer type uses packed representation. + bool isPacked() const { return false; } + + /// Get the logical bit width per value for this integer type. + unsigned getLogicalBitWidth() const { return getWidth(); } + + /// Get the number of logical elements that fit in one byte for this integer type. + unsigned getElementsPerByte() const { return 1; } + + /// Get the preferred alignment in bytes for this integer type. + std::optional getPreferredAlignmentBytes() const { return std::nullopt; } }]; } diff --git a/mlir/include/mlir/IR/CMakeLists.txt b/mlir/include/mlir/IR/CMakeLists.txt index 846547ff131e3..1e4ca1b8328c6 100644 --- a/mlir/include/mlir/IR/CMakeLists.txt +++ b/mlir/include/mlir/IR/CMakeLists.txt @@ -1,6 +1,8 @@ add_mlir_interface(SymbolInterfaces) add_mlir_interface(RegionKindInterface) +add_mlir_type_interface(QuantStorageTypeInterface) + set(LLVM_TARGET_DEFINITIONS OpAsmInterface.td) mlir_tablegen(OpAsmAttrInterface.h.inc -gen-attr-interface-decls) mlir_tablegen(OpAsmAttrInterface.cpp.inc -gen-attr-interface-defs) diff --git a/mlir/include/mlir/IR/QuantStorageTypeInterface.h b/mlir/include/mlir/IR/QuantStorageTypeInterface.h new file mode 100644 index 0000000000000..dce430efdbc89 --- /dev/null +++ b/mlir/include/mlir/IR/QuantStorageTypeInterface.h @@ -0,0 +1,22 @@ +//===- QuantStorageTypeInterface.h - Quantzation Interfaces --------*- 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 +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_IR_QuantStorageTypeInterface_H +#define MLIR_IR_QuantStorageTypeInterface_H + +#include "mlir/IR/Types.h" + +// Forward declarations for the types we need in the implementation +namespace mlir { +class IntegerType; +} // namespace mlir + +#include "mlir/IR/QuantStorageTypeInterface.h.inc" + +#endif // MLIR_IR_QuantStorageTypeInterface_H diff --git a/mlir/include/mlir/IR/QuantStorageTypeInterface.td b/mlir/include/mlir/IR/QuantStorageTypeInterface.td new file mode 100644 index 0000000000000..b09c6e79df840 --- /dev/null +++ b/mlir/include/mlir/IR/QuantStorageTypeInterface.td @@ -0,0 +1,69 @@ +#ifndef MLIR_IR_QUANTSTORAGETYPEINTERFACE +#define MLIR_IR_QUANTSTORAGETYPEINTERFACE + +include "mlir/IR/OpBase.td" + +def QuantStorageTypeInterface : TypeInterface<"QuantStorageTypeInterface"> { + let description = [{ + Interface for types that can be used as storage types in Quant dialect. + This interface provides methods to determine storage characteristics for quantization purposes, + including packing behavior, and alignment requirements. + }]; + let cppNamespace = "::mlir"; + + let methods = [ + InterfaceMethod<[{ + Check if the storage type is signed. + Returns true if the type represents signed values, false for unsigned. + }], + "bool", "isStorageSigned", (ins)>, + + InterfaceMethod<[{ + Get the bit width of this type. + Returns the number of bits used to store values of this type. + }], + "unsigned", "getStorageWidth", (ins)>, + + InterfaceMethod<[{ + Get default minimum value for this type. + }], + "int64_t", "getDefaultMinimum", (ins)>, + + InterfaceMethod<[{ + Get default maximum value for this type. + }], + "int64_t", "getDefaultMaximum", (ins)>, + + InterfaceMethod<[{ + Get the storage type as a string. + }], + "std::string", "getStorageType", (ins)>, + + InterfaceMethod<[{ + Check if the storage type uses packed representation. + Returns true if multiple values are packed into one byte (e.g., sub-byte types), + false if value uses full byte. + }], + "bool", "isPacked", (ins)>, + + InterfaceMethod<[{ + Get the logical bit width per value. + For packed sub-byte types, this may differ from getStorageWidth(). + }], + "unsigned", "getLogicalBitWidth", (ins)>, + + InterfaceMethod<[{ + Get the number of logical elements that fit in one byte. + For packed sub-byte types, this returns how many values can be stored per byte. + }], + "unsigned", "getElementsPerByte", (ins)>, + + InterfaceMethod<[{ + Returns the preferred alignment for this type, in bytes. + }], + "std::optional", "getPreferredAlignmentBytes", (ins)> + ]; + +} + +#endif // MLIR_IR_QUANTSTORAGETYPEINTERFACE diff --git a/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp b/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp index b2227792f32ca..b27cb790b9052 100644 --- a/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp +++ b/mlir/lib/Dialect/Quant/IR/QuantTypes.cpp @@ -9,6 +9,7 @@ #include "mlir/Dialect/Quant/IR/QuantTypes.h" #include "TypeDetail.h" #include "mlir/Dialect/Quant/IR/Quant.h" +#include "mlir/IR/QuantStorageTypeInterface.h" #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/MLIRContext.h" @@ -46,32 +47,27 @@ QuantizedType::verifyInvariants(function_ref emitError, unsigned flags, Type storageType, Type expressedType, int64_t storageTypeMin, int64_t storageTypeMax) { - // Verify that the storage type is integral. - // This restriction may be lifted at some point in favor of using bf16 - // or f16 as exact representations on hardware where that is advantageous. - auto intStorageType = llvm::dyn_cast(storageType); - if (!intStorageType) - return emitError() << "storage type must be integral"; - unsigned integralWidth = intStorageType.getWidth(); - - // Verify storage width. - if (integralWidth == 0 || integralWidth > MaxStorageBits) - return emitError() << "illegal storage type size: " << integralWidth; - - // Verify storageTypeMin and storageTypeMax. - bool isSigned = - (flags & QuantizationFlags::Signed) == QuantizationFlags::Signed; - int64_t defaultIntegerMin = - getDefaultMinimumForInteger(isSigned, integralWidth); - int64_t defaultIntegerMax = - getDefaultMaximumForInteger(isSigned, integralWidth); - if (storageTypeMax - storageTypeMin <= 0 || - storageTypeMin < defaultIntegerMin || - storageTypeMax > defaultIntegerMax) { - return emitError() << "illegal storage min and storage max: (" - << storageTypeMin << ":" << storageTypeMax << ")"; + if (auto quantStorageTypeInterface = + llvm::dyn_cast(storageType)) { + unsigned integralWidth = quantStorageTypeInterface.getStorageWidth(); + + // Verify storage width. + if (integralWidth == 0 || integralWidth > MaxStorageBits) + return emitError() << "illegal storage type size: " << integralWidth; + + int64_t defaultMin = quantStorageTypeInterface.getDefaultMinimum(); + int64_t defaultMax = quantStorageTypeInterface.getDefaultMaximum(); + + if (storageTypeMax - storageTypeMin <= 0 || storageTypeMin < defaultMin || + storageTypeMax > defaultMax) { + return emitError() << "illegal storage min and storage max: (" + << storageTypeMin << ":" << storageTypeMax << ")"; + } + + return success(); } - return success(); + + return emitError() << "storage type must implement QuantStorageTypeInterface"; } Type QuantizedType::getStorageType() const { @@ -87,20 +83,22 @@ int64_t QuantizedType::getStorageTypeMax() const { } bool QuantizedType::hasStorageTypeBounds() const { - unsigned int integralWidth = getStorageTypeIntegralWidth(); - bool isSignedInteger = isSigned(); - int64_t defaultIntegerMin = - getDefaultMinimumForInteger(isSignedInteger, integralWidth); - int64_t defaultIntegerMax = - getDefaultMaximumForInteger(isSignedInteger, integralWidth); - return defaultIntegerMin != getStorageTypeMin() || - defaultIntegerMax != getStorageTypeMax(); + Type storageType = static_cast(impl)->storageType; + auto quantStorageTypeInterface = + llvm::dyn_cast(storageType); + + int64_t defaultMin = quantStorageTypeInterface.getDefaultMinimum(); + int64_t defaultMax = quantStorageTypeInterface.getDefaultMaximum(); + + return defaultMin != getStorageTypeMin() || defaultMax != getStorageTypeMax(); } unsigned QuantizedType::getStorageTypeIntegralWidth() const { - // NOTE: If ever supporting non-integral storage types, some other scheme - // for determining the width will be needed. - return static_cast(impl)->storageType.getIntOrFloatBitWidth(); + Type storageType = static_cast(impl)->storageType; + auto quantStorageTypeInterface = + llvm::dyn_cast(storageType); + + return quantStorageTypeInterface.getStorageWidth(); } Type QuantizedType::getExpressedType() const { diff --git a/mlir/lib/Dialect/Quant/IR/TypeParser.cpp b/mlir/lib/Dialect/Quant/IR/TypeParser.cpp index 9a18cff24e62a..f86df4eacd21f 100644 --- a/mlir/lib/Dialect/Quant/IR/TypeParser.cpp +++ b/mlir/lib/Dialect/Quant/IR/TypeParser.cpp @@ -10,15 +10,16 @@ #include "mlir/Dialect/Quant/IR/QuantTypes.h" #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/DialectImplementation.h" +#include "mlir/IR/QuantStorageTypeInterface.h" #include "mlir/IR/Types.h" #include "llvm/ADT/APFloat.h" using namespace mlir; using namespace quant; -static IntegerType parseStorageType(DialectAsmParser &parser, bool &isSigned) { +static Type parseStorageType(DialectAsmParser &parser, bool &isSigned) { auto typeLoc = parser.getCurrentLocation(); - IntegerType type; + Type type; // Parse storage type (alpha_ident, integer_literal). StringRef identifier; @@ -27,20 +28,28 @@ static IntegerType parseStorageType(DialectAsmParser &parser, bool &isSigned) { if (result.has_value()) { if (!succeeded(*result)) return nullptr; - isSigned = !type.isUnsigned(); - storageTypeWidth = type.getWidth(); - } else if (succeeded(parser.parseKeyword(&identifier))) { - // Otherwise, this must be an unsigned integer (`u` integer-literal). - if (!identifier.consume_front("u")) { - parser.emitError(typeLoc, "illegal storage type prefix"); + + if (auto quantStorageTypeInterface = + llvm::dyn_cast(type)) { + isSigned = quantStorageTypeInterface.isStorageSigned(); + storageTypeWidth = quantStorageTypeInterface.getStorageWidth(); + } else { + parser.emitError(typeLoc, "illegal quantized storage type alias"); return nullptr; } - if (identifier.getAsInteger(10, storageTypeWidth)) { - parser.emitError(typeLoc, "expected storage type width"); + } else if (succeeded(parser.parseKeyword(&identifier))) { + // Otherwise, this must be an unsigned integer (`u` integer-literal) + if (identifier.consume_front("u")) { + if (identifier.getAsInteger(10, storageTypeWidth)) { + parser.emitError(typeLoc, "expected storage type width"); + return nullptr; + } + isSigned = false; + type = parser.getBuilder().getIntegerType(storageTypeWidth); + } else { + parser.emitError(typeLoc, "illegal quantized storage type alias"); return nullptr; } - isSigned = false; - type = parser.getBuilder().getIntegerType(storageTypeWidth); } else { return nullptr; } @@ -55,17 +64,18 @@ static IntegerType parseStorageType(DialectAsmParser &parser, bool &isSigned) { return type; } -static ParseResult parseStorageRange(DialectAsmParser &parser, - IntegerType storageType, bool isSigned, +static ParseResult parseStorageRange(DialectAsmParser &parser, Type storageType, int64_t &storageTypeMin, int64_t &storageTypeMax) { - int64_t defaultIntegerMin = QuantizedType::getDefaultMinimumForInteger( - isSigned, storageType.getWidth()); - int64_t defaultIntegerMax = QuantizedType::getDefaultMaximumForInteger( - isSigned, storageType.getWidth()); + auto quantStorageTypeInterface = + llvm::dyn_cast(storageType); + + int64_t defaultMin = quantStorageTypeInterface.getDefaultMinimum(); + int64_t defaultMax = quantStorageTypeInterface.getDefaultMaximum(); + if (failed(parser.parseOptionalLess())) { - storageTypeMin = defaultIntegerMin; - storageTypeMax = defaultIntegerMax; + storageTypeMin = defaultMin; + storageTypeMax = defaultMax; return success(); } @@ -75,11 +85,11 @@ static ParseResult parseStorageRange(DialectAsmParser &parser, parser.getCurrentLocation(&maxLoc) || parser.parseInteger(storageTypeMax) || parser.parseGreater()) return failure(); - if (storageTypeMin < defaultIntegerMin) { + if (storageTypeMin < defaultMin) { return parser.emitError(minLoc, "illegal storage type minimum: ") << storageTypeMin; } - if (storageTypeMax > defaultIntegerMax) { + if (storageTypeMax > defaultMax) { return parser.emitError(maxLoc, "illegal storage type maximum: ") << storageTypeMax; } @@ -113,7 +123,7 @@ static FloatType parseExpressedTypeAndRange(DialectAsmParser &parser, /// storage-type ::= (`i` | `u`) integer-literal /// expressed-type-spec ::= `:` `f` integer-literal static Type parseAnyType(DialectAsmParser &parser) { - IntegerType storageType; + Type storageType; FloatType expressedType; unsigned typeFlags = 0; int64_t storageTypeMin; @@ -134,8 +144,7 @@ static Type parseAnyType(DialectAsmParser &parser) { } // Storage type range. - if (parseStorageRange(parser, storageType, isSigned, storageTypeMin, - storageTypeMax)) { + if (parseStorageRange(parser, storageType, storageTypeMin, storageTypeMax)) { return nullptr; } @@ -322,7 +331,7 @@ parseQuantParamListUntilRBrace(DialectAsmParser &parser, Type expressedType, /// scale-zero-tensor (`,` scale-zero-tensor)* /// `}` static Type parseUniformType(DialectAsmParser &parser) { - IntegerType storageType; + Type storageType; FloatType expressedType; unsigned typeFlags = 0; int64_t storageTypeMin; @@ -350,8 +359,7 @@ static Type parseUniformType(DialectAsmParser &parser) { } // Storage type range. - if (parseStorageRange(parser, storageType, isSigned, storageTypeMin, - storageTypeMax)) { + if (parseStorageRange(parser, storageType, storageTypeMin, storageTypeMax)) { return nullptr; } @@ -486,13 +494,10 @@ Type QuantDialect::parseType(DialectAsmParser &parser) const { static void printStorageType(QuantizedType type, DialectAsmPrinter &out) { // storage type - unsigned storageWidth = type.getStorageTypeIntegralWidth(); - bool isSigned = type.isSigned(); - if (isSigned) { - out << "i" << storageWidth; - } else { - out << "u" << storageWidth; - } + auto quantStorageTypeInterface = + llvm::dyn_cast(type.getStorageType()); + + out << quantStorageTypeInterface.getStorageType(); // storageTypeMin and storageTypeMax if not default. if (type.hasStorageTypeBounds()) { diff --git a/mlir/lib/IR/CMakeLists.txt b/mlir/lib/IR/CMakeLists.txt index 3ef69cea18f0a..9e0d283854b38 100644 --- a/mlir/lib/IR/CMakeLists.txt +++ b/mlir/lib/IR/CMakeLists.txt @@ -31,6 +31,7 @@ add_mlir_library(MLIRIR OperationSupport.cpp PatternLoggingListener.cpp PatternMatch.cpp + QuantStorageTypeInterface.cpp Region.cpp RegionKindInterface.cpp SymbolTable.cpp @@ -62,12 +63,12 @@ add_mlir_library(MLIRIR MLIRCastInterfacesIncGen MLIRDataLayoutInterfacesIncGen MLIROpAsmInterfaceIncGen + MLIRQuantStorageTypeInterfaceIncGen MLIRRegionKindInterfaceIncGen MLIRSideEffectInterfacesIncGen MLIRSymbolInterfacesIncGen MLIRTensorEncodingIncGen - + LINK_LIBS PUBLIC MLIRSupport ) - diff --git a/mlir/lib/IR/QuantStorageTypeInterface.cpp b/mlir/lib/IR/QuantStorageTypeInterface.cpp new file mode 100644 index 0000000000000..bcc2dc1f3337c --- /dev/null +++ b/mlir/lib/IR/QuantStorageTypeInterface.cpp @@ -0,0 +1,23 @@ +//===- QuantStorageTypeInterface.cpp +//------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "mlir/Dialect/Quant/IR/Quant.h" +#include "mlir/Dialect/Quant/IR/QuantTypes.h" +#include "mlir/IR/BuiltinTypes.h" +#include "mlir/IR/Diagnostics.h" +#include "llvm/ADT/Sequence.h" + +using namespace mlir; +using namespace mlir::detail; + +//===----------------------------------------------------------------------===// +/// Tablegen Interface Definitions +//===----------------------------------------------------------------------===// + +#include "mlir/IR/QuantStorageTypeInterface.cpp.inc"