20#include <mlir/IR/DialectImplementation.h>
22#include <llvm/ADT/TypeSwitch.h>
29#define GET_TYPEDEF_CLASSES
31#define GET_ATTRDEF_CLASSES
39enum class FeltAttrEncoding : uint8_t {
44struct FeltDialectBytecodeInterface
48 Attribute readAttribute(DialectBytecodeReader &reader)
const final {
50 if (failed(reader.readVarInt(encoding))) {
53 if (encoding > std::numeric_limits<uint8_t>::max()) {
54 reader.emitError(
"unknown felt attribute encoding: ") << encoding;
58 switch (
static_cast<FeltAttrEncoding
>(encoding)) {
59 case FeltAttrEncoding::FeltConst: {
62 if (failed(value) || failed(reader.readType(type))) {
65 return llzk::felt::FeltConstAttr::get(getContext(), *value, type);
67 case FeltAttrEncoding::FieldSpec: {
69 if (failed(reader.readAttribute(fieldName))) {
78 auto fieldSpec = llzk::felt::FieldSpecAttr::getChecked([&reader]() {
79 return reader.emitError();
80 }, getContext(), fieldName, *prime);
85 return llzk::InFlightDiagnosticWrapper(reader.emitError());
93 reader.emitError(
"unknown felt attribute encoding: ") << encoding;
97 LogicalResult writeAttribute(Attribute attr, DialectBytecodeWriter &writer)
const final {
98 if (
auto feltConst = dyn_cast<llzk::felt::FeltConstAttr>(attr)) {
99 writer.writeVarInt(
static_cast<uint64_t
>(FeltAttrEncoding::FeltConst));
101 writer.writeType(feltConst.getType());
104 if (
auto fieldSpec = dyn_cast<llzk::felt::FieldSpecAttr>(attr)) {
105 writer.writeVarInt(
static_cast<uint64_t
>(FeltAttrEncoding::FieldSpec));
106 writer.writeAttribute(fieldSpec.getFieldName());
125Attribute FieldSpecAttr::parse(AsmParser &odsParser, Type) {
126 Builder odsBuilder(odsParser.getContext());
127 llvm::SMLoc odsLoc = odsParser.getCurrentLocation();
128 FailureOr<StringAttr> fieldNameAttrRes;
129 FailureOr<llzk::DynamicAPIntValue> primeRes;
132 if (odsParser.parseLess()) {
137 fieldNameAttrRes = FieldParser<StringAttr>::parse(odsParser);
138 if (failed(fieldNameAttrRes)) {
140 odsParser.getCurrentLocation(),
"failed to parse LLZK_FieldSpecAttr parameter 'fieldName' "
141 "which is to be a `StringAttr`"
146 if (odsParser.parseComma()) {
152 if (failed(primeRes)) {
154 odsParser.getCurrentLocation(),
155 "failed to parse LLZK_FieldSpecAttr parameter 'prime' which is to be an integer"
160 if (odsParser.parseGreater()) {
163 assert(succeeded(fieldNameAttrRes));
164 assert(succeeded(primeRes));
167 const llvm::DynamicAPInt &prime = *primeRes;
169 odsParser.getChecked<FieldSpecAttr>(odsLoc, odsParser.getContext(), *fieldNameAttrRes, prime);
174 return InFlightDiagnosticWrapper(odsParser.emitError(odsParser.getCurrentLocation()));
181void FieldSpecAttr::print(AsmPrinter &odsPrinter)
const {
182 Builder odsBuilder(getContext());
184 odsPrinter.printStrippedAttrOrType(getFieldName());
186 odsPrinter.printStrippedAttrOrType(getPrime());
194Attribute FeltConstAttr::parse(AsmParser &odsParser, Type) {
195 SMLoc odsLoc = odsParser.getCurrentLocation();
199 if (failed(valueRes)) {
201 odsParser.getCurrentLocation(),
202 "failed to parse LLZK_FeltConstAttr parameter 'rawValue' which is to be an integer"
210 if (odsParser.parseOptionalColon().succeeded()) {
211 FailureOr<FeltType> typeRes = FieldParser<FeltType>::parse(odsParser);
212 if (failed(typeRes)) {
214 odsParser.getCurrentLocation(),
215 "failed to parse LLZK_FeltConstAttr parameter 'type' which is to be a `FeltType`"
222 else if (odsParser.parseOptionalLess().succeeded()) {
223 FailureOr<StringAttr> fieldNameRes = FieldParser<StringAttr>::parse(odsParser);
224 if (failed(fieldNameRes)) {
226 odsParser.getCurrentLocation(),
"failed to parse LLZK_FeltConstAttr(version 1) field "
227 "name parameter which is to be a `StringAttr`"
231 if (odsParser.parseGreater()) {
234 type =
FeltType::get(odsParser.getContext(), (*fieldNameRes).getValue());
237 return odsParser.getChecked<FeltConstAttr>(odsLoc, odsParser.getContext(), *valueRes, type);
241void FeltConstAttr::print(AsmPrinter &odsPrinter)
const {
243 odsPrinter.printStrippedAttrOrType(getRawValue());
247 odsPrinter.printStrippedAttrOrType(ty);
271 if (
auto attr = llvm::dyn_cast<FeltConstAttr>(value)) {
277auto FeltDialect::initialize() ->
void {
285 #define GET_TYPEDEF_LIST
290 #define GET_ATTRDEF_LIST
294 addInterfaces<FeltDialectBytecodeInterface>();
Information about the prime finite field used for the interval analysis.
static void addField(llvm::StringRef fieldName, const llvm::DynamicAPInt &prime, EmitErrorFn errFn)
Add a new field to the set of available prime fields.
static llvm::LogicalResult verifyFieldDefined(llvm::StringRef fieldName, EmitErrorFn errFn)
Search for a field with the given name, reporting an error if the field is not found.
static const Field & getField(llvm::StringRef fieldName, EmitErrorFn errFn)
Get a Field from a given field name string.
static FeltConstantOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Type result, ::llzk::felt::FeltConstAttr value)
LLZK felt (Field ELemenT) type and operations.
::mlir::Operation * materializeConstant(::mlir::OpBuilder &builder, ::mlir::Attribute value, ::mlir::Type type, ::mlir::Location loc) override
Materialize a single constant operation from a given attribute value with the desired resultant type.
::llvm::LogicalResult verify(::llvm::function_ref<::mlir::InFlightDiagnostic()> emitError, ::mlir::StringAttr fieldName)
const ::llzk::Field & getField() const
::mlir::StringAttr getFieldName() const
static FeltType get(::mlir::MLIRContext *context, ::mlir::StringAttr fieldName)
mlir::FailureOr< DynamicAPIntValue > parseDynamicAPIntValue(mlir::AsmParser &parser)
Parse MLIR's signed integer literal and discard its encoding width.
mlir::FailureOr< llvm::DynamicAPInt > readDynamicAPInt(mlir::DialectBytecodeReader &reader)
Decode a signed integer, rejecting invalid widths before allocating storage.
OwningEmitErrorFn wrapNonNullableInFlightDiagnostic(llvm::function_ref< mlir::InFlightDiagnostic()> emitError)
void writeDynamicAPInt(mlir::DialectBytecodeWriter &writer, const llvm::DynamicAPInt &value)
Write the minimal signed two's-complement encoding of a mathematical integer.
This implements the bytecode interface for the LLZK dialect.