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/StringSet.h>
23
24// TableGen'd implementation files
26
27// TableGen'd implementation files
28#define GET_OP_CLASSES
30
31using namespace mlir;
32using namespace llzk::array;
33using namespace llzk::function;
34
35namespace llzk::component {
36
37bool isInStruct(Operation *op) { return succeeded(getParentOfType<StructDefOp>(op)); }
38
39FailureOr<StructDefOp> verifyInStruct(Operation *op) {
40 FailureOr<StructDefOp> res = getParentOfType<StructDefOp>(op);
41 if (failed(res)) {
42 return op->emitOpError() << "only valid within a '" << StructDefOp::getOperationName()
43 << "' ancestor";
44 }
45 return res;
46}
47
48bool isInStructFunctionNamed(Operation *op, char const *funcName) {
49 FailureOr<FuncDefOp> parentFuncOpt = getParentOfType<FuncDefOp>(op);
50 if (succeeded(parentFuncOpt)) {
51 FuncDefOp parentFunc = parentFuncOpt.value();
52 if (isInStruct(parentFunc.getOperation())) {
53 if (parentFunc.getSymName().compare(funcName) == 0) {
54 return true;
55 }
56 }
57 }
58 return false;
59}
60
61// Again, only valid/implemented for StructDefOp
62template <> LogicalResult SetFuncAllowAttrs<StructDefOp>::verifyTrait(Operation *structOp) {
63 assert(llvm::isa<StructDefOp>(structOp));
64 llvm::cast<StructDefOp>(structOp).getBody().walk([](FuncDefOp funcDef) {
65 if (funcDef.nameIsConstrain()) {
66 funcDef.setAllowConstraintAttr();
67 funcDef.setAllowWitnessAttr(false);
68 } else if (funcDef.nameIsCompute()) {
69 funcDef.setAllowConstraintAttr(false);
70 funcDef.setAllowWitnessAttr();
71 }
72 });
73 return success();
74}
75
76InFlightDiagnostic genCompareErr(StructDefOp &expected, Operation *origin, const char *aspect) {
77 std::string prefix = std::string();
78 if (SymbolOpInterface symbol = llvm::dyn_cast<SymbolOpInterface>(origin)) {
79 prefix += "\"@";
80 prefix += symbol.getName();
81 prefix += "\" ";
82 }
83 return origin->emitOpError().append(
84 prefix, "must use type of its ancestor '", StructDefOp::getOperationName(), "' \"",
85 expected.getHeaderString(), "\" as ", aspect, " type"
86 );
87}
88
91LogicalResult checkSelfType(
92 SymbolTableCollection &tables, StructDefOp &expectedStruct, Type actualType, Operation *origin,
93 const char *aspect
94) {
95 if (StructType actualStructType = llvm::dyn_cast<StructType>(actualType)) {
96 auto actualStructOpt =
97 lookupTopLevelSymbol<StructDefOp>(tables, actualStructType.getNameRef(), origin);
98 if (failed(actualStructOpt)) {
99 return origin->emitError().append(
100 "could not find '", StructDefOp::getOperationName(), "' named \"",
101 actualStructType.getNameRef(), "\""
102 );
103 }
104 StructDefOp actualStruct = actualStructOpt.value().get();
105 if (actualStruct != expectedStruct) {
106 return genCompareErr(expectedStruct, origin, aspect)
107 .attachNote(actualStruct.getLoc())
108 .append("uses this type instead");
109 }
110 // Check for an EXACT match in the parameter list since it must reference the "self" type.
111 if (expectedStruct.getConstParamsAttr() != actualStructType.getParams()) {
112 // To make error messages more consistent and meaningful, if the parameters don't match
113 // because the actual type uses symbols that are not defined, generate an error about the
114 // undefined symbol(s).
115 if (ArrayAttr tyParams = actualStructType.getParams()) {
116 if (failed(verifyParamsOfType(tables, tyParams.getValue(), actualStructType, origin))) {
117 return failure();
118 }
119 }
120 // Otherwise, generate an error stating the parent struct type must be used.
121 return genCompareErr(expectedStruct, origin, aspect)
122 .attachNote(actualStruct.getLoc())
123 .append("should be type of this '", StructDefOp::getOperationName(), "'");
124 }
125 } else {
126 return genCompareErr(expectedStruct, origin, aspect);
127 }
128 return success();
129}
130
131//===------------------------------------------------------------------===//
132// StructDefOp
133//===------------------------------------------------------------------===//
134namespace {
135
136inline LogicalResult msgOneFunction(EmitErrorFn emitError, const Twine &name) {
137 return emitError() << "must define exactly one '" << name << "' function";
138}
139
140} // namespace
141
142StructType StructDefOp::getType(std::optional<ArrayAttr> constParams) {
143 auto pathRes = getPathFromRoot(*this);
144 assert(succeeded(pathRes)); // consistent with StructType::get() with invalid args
145 return StructType::get(pathRes.value(), constParams.value_or(getConstParamsAttr()));
146}
147
149 return buildStringViaCallback([this](llvm::raw_ostream &ss) {
150 FailureOr<SymbolRefAttr> pathToExpected = getPathFromRoot(*this);
151 if (succeeded(pathToExpected)) {
152 ss << pathToExpected.value();
153 } else {
154 // When there is a failure trying to get the resolved name of the struct,
155 // just print its symbol name directly.
156 ss << '@' << this->getSymName();
157 }
158 if (auto attr = this->getConstParamsAttr()) {
159 ss << '<' << attr << '>';
160 }
161 });
162}
163
164bool StructDefOp::hasParamNamed(StringAttr find) {
165 if (ArrayAttr params = this->getConstParamsAttr()) {
166 for (Attribute attr : params) {
167 assert(llvm::isa<FlatSymbolRefAttr>(attr)); // per ODS
168 if (llvm::cast<FlatSymbolRefAttr>(attr).getRootReference() == find) {
169 return true;
170 }
171 }
172 }
173 return false;
174}
175
177 auto res = getPathFromRoot(*this);
178 assert(succeeded(res));
179 return res.value();
180}
181
182LogicalResult StructDefOp::verifySymbolUses(SymbolTableCollection &tables) {
183 if (ArrayAttr params = this->getConstParamsAttr()) {
184 // Ensure struct parameter names are unique
185 llvm::StringSet<> uniqNames;
186 for (Attribute attr : params) {
187 assert(llvm::isa<FlatSymbolRefAttr>(attr)); // per ODS
188 StringRef name = llvm::cast<FlatSymbolRefAttr>(attr).getValue();
189 if (!uniqNames.insert(name).second) {
190 return this->emitOpError().append("has more than one parameter named \"@", name, "\"");
191 }
192 }
193 // Ensure they do not conflict with existing symbols
194 for (Attribute attr : params) {
195 auto res = lookupTopLevelSymbol(tables, llvm::cast<FlatSymbolRefAttr>(attr), *this, false);
196 if (succeeded(res)) {
197 return this->emitOpError()
198 .append("parameter name \"@")
199 .append(llvm::cast<FlatSymbolRefAttr>(attr).getValue())
200 .append("\" conflicts with an existing symbol")
201 .attachNote(res->get()->getLoc())
202 .append("symbol already defined here");
203 }
204 }
205 }
206 return success();
207}
208
209namespace {
210
211inline LogicalResult checkMainFuncParamType(Type pType, FuncDefOp inFunc, bool appendSelf) {
212 if (isSignalType(pType)) {
213 return success();
214 } else if (auto arrayParamTy = llvm::dyn_cast<ArrayType>(pType)) {
215 if (isSignalType(arrayParamTy.getElementType())) {
216 return success();
217 }
218 }
219
220 std::string message = buildStringViaCallback([&inFunc, appendSelf](llvm::raw_ostream &ss) {
221 ss << "\"@" << COMPONENT_NAME_MAIN << "\" component \"@" << inFunc.getSymName()
222 << "\" function parameters must be one of: {";
223 if (appendSelf) {
224 ss << "!" << StructType::name << "<@" << COMPONENT_NAME_MAIN << ">, ";
225 }
226 ss << "!" << StructType::name << "<@" << COMPONENT_NAME_SIGNAL << ">, ";
227 ss << "!" << ArrayType::name << "<.. x !" << StructType::name << "<@" << COMPONENT_NAME_SIGNAL
228 << ">>}";
229 });
230 return inFunc.emitError(message);
231}
232
233} // namespace
234
236 assert(getBody().hasOneBlock()); // per ODS, SizedRegion<1>
237 std::optional<FuncDefOp> foundCompute = std::nullopt;
238 std::optional<FuncDefOp> foundConstrain = std::nullopt;
239 {
240 // Verify the following:
241 // 1. The only ops within the body are field and function definitions
242 // 2. The only functions defined in the struct are `compute()` and `constrain()`
243 OwningEmitErrorFn emitError = getEmitOpErrFn(this);
244 for (Operation &op : getBody().front()) {
245 if (!llvm::isa<FieldDefOp>(op)) {
246 if (FuncDefOp funcDef = llvm::dyn_cast<FuncDefOp>(op)) {
247 if (funcDef.nameIsCompute()) {
248 if (foundCompute) {
249 return msgOneFunction(emitError, FUNC_NAME_COMPUTE);
250 }
251 foundCompute = std::make_optional(funcDef);
252 } else if (funcDef.nameIsConstrain()) {
253 if (foundConstrain) {
254 return msgOneFunction(emitError, FUNC_NAME_CONSTRAIN);
255 }
256 foundConstrain = std::make_optional(funcDef);
257 } else {
258 // Must do a little more than a simple call to '?.emitOpError()' to
259 // tag the error with correct location and correct op name.
260 return op.emitError() << "'" << getOperationName() << "' op " << "must define only \"@"
261 << FUNC_NAME_COMPUTE << "\" and \"@" << FUNC_NAME_CONSTRAIN
262 << "\" functions;" << " found \"@" << funcDef.getSymName()
263 << "\"";
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 (COMPONENT_NAME_MAIN == this->getSymName()) {
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 assert(numDims.has_value() != mapOperands.empty());
563 state.addOperands(component);
564 state.addTypes(resultType);
565 if (numDims.has_value()) {
567 builder, state, ArrayRef({mapOperands}), builder.getDenseI32ArrayAttr({*numDims})
568 );
569 } else {
571 }
572 Properties &props = state.getOrAddProperties<Properties>();
573 props.setFieldName(FlatSymbolRefAttr::get(field));
574 props.setTableOffset(dist);
575}
576
578 OpBuilder &builder, OperationState &state, TypeRange resultTypes, ValueRange operands,
579 ArrayRef<NamedAttribute> attrs
580) {
581 state.addTypes(resultTypes);
582 state.addOperands(operands);
583 state.addAttributes(attrs);
584}
585
586LogicalResult FieldReadOp::verify() {
587 SmallVector<AffineMapAttr, 1> mapAttrs;
588 if (AffineMapAttr map =
589 llvm::dyn_cast_if_present<AffineMapAttr>(getTableOffset().value_or(nullptr))) {
590 mapAttrs.push_back(map);
591 }
593 getMapOperands(), getNumDimsPerMap(), mapAttrs, *this
594 );
595}
596
597//===------------------------------------------------------------------===//
598// CreateStructOp
599//===------------------------------------------------------------------===//
600
601void CreateStructOp::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
602 setNameFn(getResult(), "self");
603}
604
605LogicalResult CreateStructOp::verifySymbolUses(SymbolTableCollection &tables) {
606 FailureOr<StructDefOp> getParentRes = verifyInStruct(*this);
607 if (failed(getParentRes)) {
608 return failure(); // verifyInStruct() already emits a sufficient error message
609 }
610 if (failed(checkSelfType(tables, *getParentRes, this->getType(), *this, "result"))) {
611 return failure();
612 }
613 return success();
614}
615
616} // namespace llzk::component
std::vector< llvm::StringRef > getIncludeSymNames()
static constexpr ::llvm::StringLiteral name
Definition Types.h.inc:51
::mlir::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:605
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition Ops.cpp:601
::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:586
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:142
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:182
::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:176
::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:235
::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:148
::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:76
bool isInStruct(Operation *op)
Definition Ops.cpp:37
FailureOr< StructDefOp > verifyInStruct(Operation *op)
Definition Ops.cpp:39
bool isInStructFunctionNamed(Operation *op, char const *funcName)
Definition Ops.cpp:48
LogicalResult checkSelfType(SymbolTableCollection &tables, StructDefOp &expectedStruct, Type actualType, Operation *origin, const char *aspect)
Verifies that the given actualType matches the StructDefOp given (i.e.
Definition Ops.cpp:91
constexpr char FUNC_NAME_COMPUTE[]
Symbol name for the witness generation (and resp.
Definition Constants.h:27
FailureOr< SymbolRefAttr > getPathFromRoot(StructDefOp &to)
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:18
bool isValidColumnType(Type type, SymbolTableCollection &symbolTable, Operation *op)
bool isNullOrEmpty(mlir::ArrayAttr a)
std::function< mlir::InFlightDiagnostic()> OwningEmitErrorFn
Definition ErrorHelper.h:22
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:24
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:32
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...
void setSymName(const ::mlir::StringAttr &propValue)
Definition Ops.h.inc:170
void setFieldName(const ::mlir::FlatSymbolRefAttr &propValue)
Definition Ops.h.inc:370