LLZK 0.1.0
Veridise's ZK Language IR
Loading...
Searching...
No Matches
Ops.cpp
Go to the documentation of this file.
1//===-- Ops.cpp - Struct op implementations ---------------------*- C++ -*-===//
2//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2025 Veridise Inc.
6// SPDX-License-Identifier: Apache-2.0
7//
8//===----------------------------------------------------------------------===//
9
17
18#include <mlir/IR/IRMapping.h>
19#include <mlir/IR/OpImplementation.h>
20
21#include <llvm/ADT/MapVector.h>
22#include <llvm/ADT/STLExtras.h>
23#include <llvm/ADT/StringSet.h>
24
25// TableGen'd implementation files
27
28// TableGen'd implementation files
29#define GET_OP_CLASSES
31
32using namespace mlir;
33using namespace llzk::array;
34using namespace llzk::function;
35
36namespace llzk::component {
37
38bool isInStruct(Operation *op) { return succeeded(getParentOfType<StructDefOp>(op)); }
39
40FailureOr<StructDefOp> verifyInStruct(Operation *op) {
41 FailureOr<StructDefOp> res = getParentOfType<StructDefOp>(op);
42 if (failed(res)) {
43 return op->emitOpError() << "only valid within a '" << StructDefOp::getOperationName()
44 << "' ancestor";
45 }
46 return res;
47}
48
49bool isInStructFunctionNamed(Operation *op, char const *funcName) {
50 FailureOr<FuncDefOp> parentFuncOpt = getParentOfType<FuncDefOp>(op);
51 if (succeeded(parentFuncOpt)) {
52 FuncDefOp parentFunc = parentFuncOpt.value();
53 if (isInStruct(parentFunc.getOperation())) {
54 if (parentFunc.getSymName().compare(funcName) == 0) {
55 return true;
56 }
57 }
58 }
59 return false;
60}
61
62// Again, only valid/implemented for StructDefOp
63template <> LogicalResult SetFuncAllowAttrs<StructDefOp>::verifyTrait(Operation *structOp) {
64 assert(llvm::isa<StructDefOp>(structOp));
65 llvm::cast<StructDefOp>(structOp).getBody().walk([](FuncDefOp funcDef) {
66 if (funcDef.nameIsConstrain()) {
67 funcDef.setAllowConstraintAttr();
68 funcDef.setAllowWitnessAttr(false);
69 } else if (funcDef.nameIsCompute()) {
70 funcDef.setAllowConstraintAttr(false);
71 funcDef.setAllowWitnessAttr();
72 }
73 });
74 return success();
75}
76
77InFlightDiagnostic genCompareErr(StructDefOp &expected, Operation *origin, const char *aspect) {
78 std::string prefix = std::string();
79 if (SymbolOpInterface symbol = llvm::dyn_cast<SymbolOpInterface>(origin)) {
80 prefix += "\"@";
81 prefix += symbol.getName();
82 prefix += "\" ";
83 }
84 return origin->emitOpError().append(
85 prefix, "must use type of its ancestor '", StructDefOp::getOperationName(), "' \"",
86 expected.getHeaderString(), "\" as ", aspect, " type"
87 );
88}
89
92LogicalResult checkSelfType(
93 SymbolTableCollection &tables, StructDefOp &expectedStruct, Type actualType, Operation *origin,
94 const char *aspect
95) {
96 if (StructType actualStructType = llvm::dyn_cast<StructType>(actualType)) {
97 auto actualStructOpt =
98 lookupTopLevelSymbol<StructDefOp>(tables, actualStructType.getNameRef(), origin);
99 if (failed(actualStructOpt)) {
100 return origin->emitError().append(
101 "could not find '", StructDefOp::getOperationName(), "' named \"",
102 actualStructType.getNameRef(), '"'
103 );
104 }
105 StructDefOp actualStruct = actualStructOpt.value().get();
106 if (actualStruct != expectedStruct) {
107 return genCompareErr(expectedStruct, origin, aspect)
108 .attachNote(actualStruct.getLoc())
109 .append("uses this type instead");
110 }
111 // Check for an EXACT match in the parameter list since it must reference the "self" type.
112 if (expectedStruct.getConstParamsAttr() != actualStructType.getParams()) {
113 // To make error messages more consistent and meaningful, if the parameters don't match
114 // because the actual type uses symbols that are not defined, generate an error about the
115 // undefined symbol(s).
116 if (ArrayAttr tyParams = actualStructType.getParams()) {
117 if (failed(verifyParamsOfType(tables, tyParams.getValue(), actualStructType, origin))) {
118 return failure();
119 }
120 }
121 // Otherwise, generate an error stating the parent struct type must be used.
122 return genCompareErr(expectedStruct, origin, aspect)
123 .attachNote(actualStruct.getLoc())
124 .append("should be type of this '", StructDefOp::getOperationName(), '\'');
125 }
126 } else {
127 return genCompareErr(expectedStruct, origin, aspect);
128 }
129 return success();
130}
131
132//===------------------------------------------------------------------===//
133// StructDefOp
134//===------------------------------------------------------------------===//
135namespace {
136
137inline LogicalResult msgOneFunction(EmitErrorFn emitError, const Twine &name) {
138 return emitError() << "must define exactly one '" << name << "' function";
139}
140
141} // namespace
142
143StructType StructDefOp::getType(std::optional<ArrayAttr> constParams) {
144 auto pathRes = getPathFromRoot(*this);
145 assert(succeeded(pathRes)); // consistent with StructType::get() with invalid args
146 return StructType::get(pathRes.value(), constParams.value_or(getConstParamsAttr()));
147}
148
150 return buildStringViaCallback([this](llvm::raw_ostream &ss) {
151 FailureOr<SymbolRefAttr> pathToExpected = getPathFromRoot(*this);
152 if (succeeded(pathToExpected)) {
153 ss << pathToExpected.value();
154 } else {
155 // When there is a failure trying to get the resolved name of the struct,
156 // just print its symbol name directly.
157 ss << '@' << this->getSymName();
158 }
159 if (auto attr = this->getConstParamsAttr()) {
160 ss << '<' << attr << '>';
161 }
162 });
163}
164
165bool StructDefOp::hasParamNamed(StringAttr find) {
166 if (ArrayAttr params = this->getConstParamsAttr()) {
167 for (Attribute attr : params) {
168 assert(llvm::isa<FlatSymbolRefAttr>(attr)); // per ODS
169 if (llvm::cast<FlatSymbolRefAttr>(attr).getRootReference() == find) {
170 return true;
171 }
172 }
173 }
174 return false;
175}
176
178 auto res = getPathFromRoot(*this);
179 assert(succeeded(res));
180 return res.value();
181}
182
183LogicalResult StructDefOp::verifySymbolUses(SymbolTableCollection &tables) {
184 if (ArrayAttr params = this->getConstParamsAttr()) {
185 // Ensure struct parameter names are unique
186 llvm::StringSet<> uniqNames;
187 for (Attribute attr : params) {
188 assert(llvm::isa<FlatSymbolRefAttr>(attr)); // per ODS
189 StringRef name = llvm::cast<FlatSymbolRefAttr>(attr).getValue();
190 if (!uniqNames.insert(name).second) {
191 return this->emitOpError().append("has more than one parameter named \"@", name, '"');
192 }
193 }
194 // Ensure they do not conflict with existing symbols
195 for (Attribute attr : params) {
196 auto res = lookupTopLevelSymbol(tables, llvm::cast<FlatSymbolRefAttr>(attr), *this, false);
197 if (succeeded(res)) {
198 return this->emitOpError()
199 .append("parameter name \"@")
200 .append(llvm::cast<FlatSymbolRefAttr>(attr).getValue())
201 .append("\" conflicts with an existing symbol")
202 .attachNote(res->get()->getLoc())
203 .append("symbol already defined here");
204 }
205 }
206 }
207 return success();
208}
209
210namespace {
211
212inline LogicalResult checkMainFuncParamType(Type pType, FuncDefOp inFunc, bool appendSelf) {
213 if (isSignalType(pType)) {
214 return success();
215 } else if (auto arrayParamTy = llvm::dyn_cast<ArrayType>(pType)) {
216 if (isSignalType(arrayParamTy.getElementType())) {
217 return success();
218 }
219 }
220
221 std::string message = buildStringViaCallback([&inFunc, appendSelf](llvm::raw_ostream &ss) {
222 ss << "\"@" << COMPONENT_NAME_MAIN << "\" component \"@" << inFunc.getSymName()
223 << "\" function parameters must be one of: {";
224 if (appendSelf) {
225 ss << "!" << StructType::name << "<@" << COMPONENT_NAME_MAIN << ">, ";
226 }
227 ss << "!" << StructType::name << "<@" << COMPONENT_NAME_SIGNAL << ">, ";
228 ss << "!" << ArrayType::name << "<.. x !" << StructType::name << "<@" << COMPONENT_NAME_SIGNAL
229 << ">>}";
230 });
231 return inFunc.emitError(message);
232}
233
234} // namespace
235
237 assert(getBody().hasOneBlock()); // per ODS, SizedRegion<1>
238 std::optional<FuncDefOp> foundCompute = std::nullopt;
239 std::optional<FuncDefOp> foundConstrain = std::nullopt;
240 {
241 // Verify the following:
242 // 1. The only ops within the body are field and function definitions
243 // 2. The only functions defined in the struct are `compute()` and `constrain()`
244 OwningEmitErrorFn emitError = getEmitOpErrFn(this);
245 for (Operation &op : getBody().front()) {
246 if (!llvm::isa<FieldDefOp>(op)) {
247 if (FuncDefOp funcDef = llvm::dyn_cast<FuncDefOp>(op)) {
248 if (funcDef.nameIsCompute()) {
249 if (foundCompute) {
250 return msgOneFunction(emitError, FUNC_NAME_COMPUTE);
251 }
252 foundCompute = std::make_optional(funcDef);
253 } else if (funcDef.nameIsConstrain()) {
254 if (foundConstrain) {
255 return msgOneFunction(emitError, FUNC_NAME_CONSTRAIN);
256 }
257 foundConstrain = std::make_optional(funcDef);
258 } else {
259 // Must do a little more than a simple call to '?.emitOpError()' to
260 // tag the error with correct location and correct op name.
261 return op.emitError() << '\'' << getOperationName() << "' op " << "must define only \"@"
262 << FUNC_NAME_COMPUTE << "\" and \"@" << FUNC_NAME_CONSTRAIN
263 << "\" functions;" << " found \"@" << funcDef.getSymName() << '"';
264 }
265 } else {
266 return op.emitOpError() << "invalid operation in '" << StructDefOp::getOperationName()
267 << "'; only '" << FieldDefOp::getOperationName() << '\''
268 << " and '" << FuncDefOp::getOperationName()
269 << "' operations are permitted";
270 }
271 }
272 }
273 if (!foundCompute.has_value()) {
274 return msgOneFunction(emitError, FUNC_NAME_COMPUTE);
275 }
276 if (!foundConstrain.has_value()) {
277 return msgOneFunction(emitError, FUNC_NAME_CONSTRAIN);
278 }
279 }
280
281 // ASSERT: The `SetFuncAllowAttrs` trait on StructDefOp set the attributes correctly.
282 assert(foundConstrain->hasAllowConstraintAttr());
283 assert(!foundCompute->hasAllowConstraintAttr());
284 assert(!foundConstrain->hasAllowWitnessAttr());
285 assert(foundCompute->hasAllowWitnessAttr());
286
287 // Verify parameter types are valid. Skip the first parameter of the "constrain" function; it is
288 // already checked via verifyFuncTypeConstrain() in Function/IR/Ops.cpp.
289 ArrayRef<Type> computeParams = foundCompute->getFunctionType().getInputs();
290 ArrayRef<Type> constrainParams = foundConstrain->getFunctionType().getInputs().drop_front();
291 if (this->isMainComponent()) {
292 // Verify that the Struct has no parameters.
293 if (!isNullOrEmpty(this->getConstParamsAttr())) {
294 return this->emitError().append(
295 "The \"@", COMPONENT_NAME_MAIN, "\" component must have no parameters"
296 );
297 }
298 // Verify the input parameter types are legal. The error message is explicit about what types
299 // are allowed so there is no benefit to report multiple errors if more than one parameter in
300 // the referenced function has an illegal type.
301 for (Type t : computeParams) {
302 if (failed(checkMainFuncParamType(t, *foundCompute, false))) {
303 return failure(); // checkMainFuncParamType() already emits a sufficient error message
304 }
305 }
306 for (Type t : constrainParams) {
307 if (failed(checkMainFuncParamType(t, *foundConstrain, true))) {
308 return failure(); // checkMainFuncParamType() already emits a sufficient error message
309 }
310 }
311 }
312 // Verify that function input types from `compute()` and `constrain()` match, sans the first
313 // parameter of `constrain()` which is the instance of the parent struct.
314 if (!typeListsUnify(computeParams, constrainParams)) {
315 return foundConstrain->emitError()
316 .append(
317 "expected \"@", FUNC_NAME_CONSTRAIN,
318 "\" function argument types (sans the first one) to match \"@", FUNC_NAME_COMPUTE,
319 "\" function argument types"
320 )
321 .attachNote(foundCompute->getLoc())
322 .append("\"@", FUNC_NAME_COMPUTE, "\" function defined here");
323 }
324
325 return success();
326}
327
329 assert(getBody().hasOneBlock()); // per ODS, SizedRegion<1>
330 // Just search front() since there's only one Block.
331 for (Operation &op : getBody().front()) {
332 if (FieldDefOp fieldDef = llvm::dyn_cast_if_present<FieldDefOp>(op)) {
333 if (fieldName.compare(fieldDef.getSymNameAttr()) == 0) {
334 return fieldDef;
335 }
336 }
337 }
338 return nullptr;
339}
340
341std::vector<FieldDefOp> StructDefOp::getFieldDefs() {
342 assert(getBody().hasOneBlock()); // per ODS, SizedRegion<1>
343 // Just search front() since there's only one Block.
344 std::vector<FieldDefOp> res;
345 for (Operation &op : getBody().front()) {
346 if (FieldDefOp fieldDef = llvm::dyn_cast_if_present<FieldDefOp>(op)) {
347 res.push_back(fieldDef);
348 }
349 }
350 return res;
351}
352
354 return llvm::dyn_cast_if_present<FuncDefOp>(lookupSymbol(FUNC_NAME_COMPUTE));
355}
356
358 return llvm::dyn_cast_if_present<FuncDefOp>(lookupSymbol(FUNC_NAME_CONSTRAIN));
359}
360
362
363//===------------------------------------------------------------------===//
364// FieldDefOp
365//===------------------------------------------------------------------===//
366
368 OpBuilder &odsBuilder, OperationState &odsState, StringAttr sym_name, TypeAttr type,
369 bool isColumn
370) {
371 Properties &props = odsState.getOrAddProperties<Properties>();
372 props.setSymName(sym_name);
373 props.setType(type);
374 if (isColumn) {
375 props.column = odsBuilder.getUnitAttr();
376 }
377}
378
380 OpBuilder &odsBuilder, OperationState &odsState, StringRef sym_name, Type type, bool isColumn
381) {
382 build(odsBuilder, odsState, odsBuilder.getStringAttr(sym_name), TypeAttr::get(type), isColumn);
383}
384
386 OpBuilder &odsBuilder, OperationState &odsState, TypeRange resultTypes, ValueRange operands,
387 ArrayRef<NamedAttribute> attributes, bool isColumn
388) {
389 assert(operands.size() == 0u && "mismatched number of parameters");
390 odsState.addOperands(operands);
391 odsState.addAttributes(attributes);
392 assert(resultTypes.size() == 0u && "mismatched number of return types");
393 odsState.addTypes(resultTypes);
394 if (isColumn) {
395 odsState.getOrAddProperties<Properties>().column = odsBuilder.getUnitAttr();
396 }
397}
398
399void FieldDefOp::setPublicAttr(bool newValue) {
400 if (newValue) {
401 getOperation()->setAttr(PublicAttr::name, UnitAttr::get(getContext()));
402 } else {
403 getOperation()->removeAttr(PublicAttr::name);
404 }
405}
406
407static LogicalResult
408verifyFieldDefTypeImpl(Type fieldType, SymbolTableCollection &tables, Operation *origin) {
409 if (StructType fieldStructType = llvm::dyn_cast<StructType>(fieldType)) {
410 // Special case for StructType verifies that the field type can resolve and that it is NOT the
411 // parent struct (i.e., struct fields cannot create circular references).
412 auto fieldTypeRes = verifyStructTypeResolution(tables, fieldStructType, origin);
413 if (failed(fieldTypeRes)) {
414 return failure(); // above already emits a sufficient error message
415 }
416 FailureOr<StructDefOp> parentRes = getParentOfType<StructDefOp>(origin);
417 assert(succeeded(parentRes) && "FieldDefOp parent is always StructDefOp"); // per ODS def
418 if (fieldTypeRes.value() == parentRes.value()) {
419 return origin->emitOpError()
420 .append("type is circular")
421 .attachNote(parentRes.value().getLoc())
422 .append("references parent component defined here");
423 }
424 return success();
425 } else {
426 return verifyTypeResolution(tables, origin, fieldType);
427 }
428}
429
430LogicalResult FieldDefOp::verifySymbolUses(SymbolTableCollection &tables) {
431 Type fieldType = this->getType();
432 if (failed(verifyFieldDefTypeImpl(fieldType, tables, *this))) {
433 return failure();
434 }
435
436 if (!getColumn()) {
437 return success();
438 }
439 // If the field is marked as a column only a small subset of types are allowed.
440 if (!isValidColumnType(getType(), tables, *this)) {
441 return emitOpError() << "marked as column can only contain felts, arrays of column types, or "
442 "structs with columns, but field has type "
443 << getType();
444 }
445 return success();
446}
447
448//===------------------------------------------------------------------===//
449// FieldRefOp implementations
450//===------------------------------------------------------------------===//
451namespace {
452
453FailureOr<SymbolLookupResult<FieldDefOp>>
454getFieldDefOpImpl(FieldRefOpInterface refOp, SymbolTableCollection &tables, StructType tyStruct) {
455 Operation *op = refOp.getOperation();
456 auto structDefRes = tyStruct.getDefinition(tables, op);
457 if (failed(structDefRes)) {
458 return failure(); // getDefinition() already emits a sufficient error message
459 }
461 tables, SymbolRefAttr::get(refOp->getContext(), refOp.getFieldName()),
462 std::move(*structDefRes), op
463 );
464 if (failed(res)) {
465 return refOp->emitError() << "could not find '" << FieldDefOp::getOperationName()
466 << "' named \"@" << refOp.getFieldName() << "\" in \""
467 << tyStruct.getNameRef() << '"';
468 }
469 return std::move(res.value());
470}
471
472static FailureOr<SymbolLookupResult<FieldDefOp>>
473findField(FieldRefOpInterface refOp, SymbolTableCollection &tables) {
474 // Ensure the base component/struct type reference can be resolved.
475 StructType tyStruct = refOp.getStructType();
476 if (failed(tyStruct.verifySymbolRef(tables, refOp.getOperation()))) {
477 return failure();
478 }
479 // Ensure the field name can be resolved in that struct.
480 return getFieldDefOpImpl(refOp, tables, tyStruct);
481}
482
483static LogicalResult verifySymbolUsesImpl(
484 FieldRefOpInterface refOp, SymbolTableCollection &tables, SymbolLookupResult<FieldDefOp> &field
485) {
486 // Ensure the type of the referenced field declaration matches the type used in this op.
487 Type actualType = refOp.getVal().getType();
488 Type fieldType = field.get().getType();
489 if (!typesUnify(actualType, fieldType, field.getIncludeSymNames())) {
490 return refOp->emitOpError() << "has wrong type; expected " << fieldType << ", got "
491 << actualType;
492 }
493 // Ensure any SymbolRef used in the type are valid
494 return verifyTypeResolution(tables, refOp.getOperation(), actualType);
495}
496
497LogicalResult verifySymbolUsesImpl(FieldRefOpInterface refOp, SymbolTableCollection &tables) {
498 // Ensure the field name can be resolved in that struct.
499 auto field = findField(refOp, tables);
500 if (failed(field)) {
501 return field; // getFieldDefOp() already emits a sufficient error message
502 }
503 return verifySymbolUsesImpl(refOp, tables, *field);
504}
505
506} // namespace
507
508FailureOr<SymbolLookupResult<FieldDefOp>>
509FieldRefOpInterface::getFieldDefOp(SymbolTableCollection &tables) {
510 return getFieldDefOpImpl(*this, tables, getStructType());
511}
512
513LogicalResult FieldReadOp::verifySymbolUses(SymbolTableCollection &tables) {
514 auto field = findField(*this, tables);
515 if (failed(field)) {
516 return failure();
517 }
518 if (failed(verifySymbolUsesImpl(*this, tables, *field))) {
519 return failure();
520 }
521 // If the field is not a column and an offset was specified then fail to validate
522 if (!field->get().getColumn() && getTableOffset().has_value()) {
523 return emitOpError("cannot read with table offset from a field that is not a column")
524 .attachNote(field->get().getLoc())
525 .append("field defined here");
526 }
527
528 return success();
529}
530
531LogicalResult FieldWriteOp::verifySymbolUses(SymbolTableCollection &tables) {
532 // Ensure the write op only targets fields in the current struct.
533 FailureOr<StructDefOp> getParentRes = verifyInStruct(*this);
534 if (failed(getParentRes)) {
535 return failure(); // verifyInStruct() already emits a sufficient error message
536 }
537 if (failed(checkSelfType(tables, *getParentRes, getComponent().getType(), *this, "base value"))) {
538 return failure(); // checkSelfType() already emits a sufficient error message
539 }
540 // Perform the standard field ref checks.
541 return verifySymbolUsesImpl(*this, tables);
542}
543
544//===------------------------------------------------------------------===//
545// FieldReadOp
546//===------------------------------------------------------------------===//
547
549 OpBuilder &builder, OperationState &state, Type resultType, Value component, StringAttr field
550) {
551 Properties &props = state.getOrAddProperties<Properties>();
552 props.setFieldName(FlatSymbolRefAttr::get(field));
553 state.addTypes(resultType);
554 state.addOperands(component);
556}
557
559 OpBuilder &builder, OperationState &state, Type resultType, Value component, StringAttr field,
560 Attribute dist, ValueRange mapOperands, std::optional<int32_t> numDims
561) {
562 // '!mapOperands.empty()' implies 'numDims.has_value()'
563 assert(mapOperands.empty() || numDims.has_value());
564 state.addOperands(component);
565 state.addTypes(resultType);
566 if (numDims.has_value()) {
568 builder, state, ArrayRef({mapOperands}), builder.getDenseI32ArrayAttr({*numDims})
569 );
570 } else {
572 }
573 Properties &props = state.getOrAddProperties<Properties>();
574 props.setFieldName(FlatSymbolRefAttr::get(field));
575 props.setTableOffset(dist);
576}
577
579 OpBuilder &builder, OperationState &state, TypeRange resultTypes, ValueRange operands,
580 ArrayRef<NamedAttribute> attrs
581) {
582 state.addTypes(resultTypes);
583 state.addOperands(operands);
584 state.addAttributes(attrs);
585}
586
587LogicalResult FieldReadOp::verify() {
588 SmallVector<AffineMapAttr, 1> mapAttrs;
589 if (AffineMapAttr map =
590 llvm::dyn_cast_if_present<AffineMapAttr>(getTableOffset().value_or(nullptr))) {
591 mapAttrs.push_back(map);
592 }
594 getMapOperands(), getNumDimsPerMap(), mapAttrs, *this
595 );
596}
597
598//===------------------------------------------------------------------===//
599// CreateStructOp
600//===------------------------------------------------------------------===//
601
602void CreateStructOp::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
603 setNameFn(getResult(), "self");
604}
605
606LogicalResult CreateStructOp::verifySymbolUses(SymbolTableCollection &tables) {
607 FailureOr<StructDefOp> getParentRes = verifyInStruct(*this);
608 if (failed(getParentRes)) {
609 return failure(); // verifyInStruct() already emits a sufficient error message
610 }
611 if (failed(checkSelfType(tables, *getParentRes, this->getType(), *this, "result"))) {
612 return failure();
613 }
614 return success();
615}
616
617} // namespace llzk::component
MlirStringRef name
std::vector< llvm::StringRef > getIncludeSymNames() const
Return the stack of symbol names from the IncludeOp that were traversed to load this result.
static constexpr ::llvm::StringLiteral name
Definition Types.h.inc:51
::mlir::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:606
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition Ops.cpp:602
::mlir::TypedValue<::llzk::component::StructType > getResult()
Definition Ops.cpp.inc:220
FoldAdaptor::Properties Properties
Definition Ops.h.inc:262
void setPublicAttr(bool newValue=true)
Definition Ops.cpp:399
static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::StringAttr sym_name, ::mlir::TypeAttr type, bool isColumn=false)
static constexpr ::llvm::StringLiteral getOperationName()
Definition Ops.h.inc:292
::mlir::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:430
FoldAdaptor::Properties Properties
Definition Ops.h.inc:501
::mlir::LogicalResult verify()
Definition Ops.cpp:587
static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type resultType, ::mlir::Value component, ::mlir::StringAttr field)
::mlir::OperandRangeRange getMapOperands()
Definition Ops.cpp.inc:840
::llvm::ArrayRef< int32_t > getNumDimsPerMap()
Definition Ops.cpp.inc:1121
::mlir::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:513
::std::optional<::mlir::Attribute > getTableOffset()
Definition Ops.cpp.inc:1112
::mlir::FailureOr< SymbolLookupResult< FieldDefOp > > getFieldDefOp(::mlir::SymbolTableCollection &tables)
Gets the definition for the field referenced in this op.
Definition Ops.cpp:509
::llzk::component::StructType getStructType()
Gets the struct type of the target component.
::llvm::StringRef getFieldName()
Gets the field name attribute value from the FieldRefOp.
::mlir::Value getVal()
Gets the SSA Value that holds the read/write data for the FieldRefOp.
::mlir::TypedValue<::llzk::component::StructType > getComponent()
Definition Ops.cpp.inc:1423
::mlir::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:531
static mlir::LogicalResult verifyTrait(mlir::Operation *op)
::mlir::Region & getBody()
Definition Ops.cpp.inc:1810
StructType getType(::std::optional<::mlir::ArrayAttr > constParams={})
Gets the StructType representing this struct.
Definition Ops.cpp:143
FieldDefOp getFieldDef(::mlir::StringAttr fieldName)
Gets the FieldDefOp that defines the field in this structure with the given name, if present.
Definition Ops.cpp:328
::mlir::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:183
::mlir::ArrayAttr getConstParamsAttr()
Definition Ops.cpp.inc:1958
static constexpr ::llvm::StringLiteral getOperationName()
Definition Ops.h.inc:919
::std::vector< FieldDefOp > getFieldDefs()
Get all FieldDefOp in this structure.
Definition Ops.cpp:341
::llvm::StringRef getSymName()
Definition Ops.cpp.inc:1953
::mlir::SymbolRefAttr getFullyQualifiedName()
Return the full name for this struct from the root module, including any surrounding module scopes.
Definition Ops.cpp:177
::llzk::function::FuncDefOp getConstrainFuncOp()
Gets the FuncDefOp that defines the constrain function in this structure, if present.
Definition Ops.cpp:357
bool hasParamNamed(::mlir::StringAttr find)
Return true iff this StructDefOp has a parameter with the given name.
::mlir::LogicalResult verifyRegions()
Definition Ops.cpp:236
::llzk::function::FuncDefOp getComputeFuncOp()
Gets the FuncDefOp that defines the compute function in this structure, if present.
Definition Ops.cpp:353
bool isMainComponent()
Return true iff this StructDefOp is named "Main".
Definition Ops.cpp:361
::std::string getHeaderString()
Generate header string, in the same format as the assemblyFormat.
Definition Ops.cpp:149
::mlir::SymbolRefAttr getNameRef() const
static StructType get(::mlir::SymbolRefAttr structName)
Definition Types.cpp.inc:69
::mlir::FailureOr< SymbolLookupResult< StructDefOp > > getDefinition(::mlir::SymbolTableCollection &symbolTable, ::mlir::Operation *op) const
Gets the struct op that defines this struct.
Definition Types.cpp:39
::mlir::LogicalResult verifySymbolRef(::mlir::SymbolTableCollection &symbolTable, ::mlir::Operation *op)
Definition Types.cpp:64
static constexpr ::llvm::StringLiteral name
Definition Types.h.inc:38
void setAllowWitnessAttr(bool newValue=true)
Add (resp. remove) the allow_witness attribute to (resp. from) the function def.
Definition Ops.cpp:194
bool nameIsCompute()
Return true iff the function name is FUNC_NAME_COMPUTE (if needed, a check that this FuncDefOp is loc...
Definition Ops.h.inc:612
::llvm::StringRef getSymName()
Definition Ops.cpp.inc:1086
bool nameIsConstrain()
Return true iff the function name is FUNC_NAME_CONSTRAIN (if needed, a check that this FuncDefOp is l...
Definition Ops.h.inc:616
static constexpr ::llvm::StringLiteral getOperationName()
Definition Ops.h.inc:478
void setAllowConstraintAttr(bool newValue=true)
Add (resp. remove) the allow_constraint attribute to (resp. from) the function def.
Definition Ops.cpp:186
OpClass::Properties & buildInstantiationAttrsEmptyNoSegments(mlir::OpBuilder &odsBuilder, mlir::OperationState &odsState)
Utility for build() functions that initializes the mapOpGroupSizes, and numDimsPerMap attributes for ...
void buildInstantiationAttrsNoSegments(mlir::OpBuilder &odsBuilder, mlir::OperationState &odsState, mlir::ArrayRef< mlir::ValueRange > mapOperands, mlir::DenseI32ArrayAttr numDimsPerMap)
Utility for build() functions that initializes the mapOpGroupSizes, and numDimsPerMap attributes for ...
LogicalResult verifyAffineMapInstantiations(OperandRangeRange mapOps, ArrayRef< int32_t > numDimsPerMap, ArrayRef< AffineMapAttr > mapAttrs, Operation *origin)
InFlightDiagnostic genCompareErr(StructDefOp &expected, Operation *origin, const char *aspect)
Definition Ops.cpp:77
bool isInStruct(Operation *op)
Definition Ops.cpp:38
FailureOr< StructDefOp > verifyInStruct(Operation *op)
Definition Ops.cpp:40
bool isInStructFunctionNamed(Operation *op, char const *funcName)
Definition Ops.cpp:49
LogicalResult checkSelfType(SymbolTableCollection &tables, StructDefOp &expectedStruct, Type actualType, Operation *origin, const char *aspect)
Verifies that the given actualType matches the StructDefOp given (i.e., for the "self" type parameter...
Definition Ops.cpp:92
constexpr char FUNC_NAME_COMPUTE[]
Symbol name for the witness generation (and resp.
Definition Constants.h:27
bool typeListsUnify(Iter1 lhs, Iter2 rhs, mlir::ArrayRef< llvm::StringRef > rhsReversePrefix={}, UnificationMap *unifications=nullptr)
Return true iff the two lists of Type instances are equivalent or could be equivalent after full inst...
Definition TypeHelper.h:221
constexpr char COMPONENT_NAME_MAIN[]
Symbol name for the main entry point struct/component (if any).
Definition Constants.h:23
mlir::FailureOr< SymbolLookupResultUntyped > lookupTopLevelSymbol(mlir::SymbolTableCollection &tables, mlir::SymbolRefAttr symbol, mlir::Operation *origin, bool reportMissing=true)
constexpr char FUNC_NAME_CONSTRAIN[]
Definition Constants.h:28
llvm::function_ref< mlir::InFlightDiagnostic()> EmitErrorFn
Definition ErrorHelper.h:21
bool isValidColumnType(Type type, SymbolTableCollection &symbolTable, Operation *op)
bool isNullOrEmpty(mlir::ArrayAttr a)
std::function< mlir::InFlightDiagnostic()> OwningEmitErrorFn
Definition ErrorHelper.h:25
FailureOr< StructDefOp > verifyStructTypeResolution(SymbolTableCollection &tables, StructType ty, Operation *origin)
LogicalResult verifyTypeResolution(SymbolTableCollection &tables, Operation *origin, Type ty)
OwningEmitErrorFn getEmitOpErrFn(mlir::Operation *op)
Definition ErrorHelper.h:27
mlir::FailureOr< SymbolLookupResultUntyped > lookupSymbolIn(mlir::SymbolTableCollection &tables, mlir::SymbolRefAttr symbol, Within &&lookupWithin, mlir::Operation *origin, bool reportMissing=true)
LogicalResult verifyParamsOfType(SymbolTableCollection &tables, ArrayRef< Attribute > tyParams, Type parameterizedType, Operation *origin)
bool isSignalType(Type type)
mlir::FailureOr< OpClass > getParentOfType(mlir::Operation *op)
Return the closest surrounding parent operation that is of type 'OpClass'.
Definition OpHelpers.h:45
constexpr char COMPONENT_NAME_SIGNAL[]
Symbol name for the struct/component representing a signal.
Definition Constants.h:16
bool typesUnify(Type lhs, Type rhs, ArrayRef< StringRef > rhsReversePrefix, UnificationMap *unifications)
std::string buildStringViaCallback(Func &&appendFn, Args &&...args)
Generate a string by calling the given appendFn with an llvm::raw_ostream & as the first argument fol...
FailureOr< SymbolRefAttr > getPathFromRoot(SymbolOpInterface to, ModuleOp *foundRoot)
void setSymName(const ::mlir::StringAttr &propValue)
Definition Ops.h.inc:170
void setFieldName(const ::mlir::FlatSymbolRefAttr &propValue)
Definition Ops.h.inc:370