LLZK 2.1.1
An open-source IR for Zero Knowledge (ZK) circuits
Loading...
Searching...
No Matches
Ops.cpp
Go to the documentation of this file.
1//===-- Ops.cpp - POD operation implementations -----------------*- C++ -*-===//
2//
3// Part of the LLZK Project, under the Apache License v2.0.
4// See LICENSE.txt for license information.
5// Copyright 2026 Project LLZK
6// SPDX-License-Identifier: Apache-2.0
7//
8//===----------------------------------------------------------------------===//
9
11
17
18#include <mlir/IR/Builders.h>
19#include <mlir/IR/BuiltinAttributes.h>
20#include <mlir/IR/Diagnostics.h>
21#include <mlir/IR/OpImplementation.h>
22#include <mlir/IR/OperationSupport.h>
23#include <mlir/Support/LLVM.h>
24
25#include <llvm/ADT/STLExtras.h>
26#include <llvm/ADT/SmallString.h>
27#include <llvm/ADT/SmallVectorExtras.h>
28#include <llvm/ADT/StringSet.h>
29#include <llvm/ADT/TypeSwitch.h>
30#include <llvm/Support/Debug.h>
31
32#include <cstdint>
33#include <optional>
34
35// TableGen'd implementation files
37
38// TableGen'd implementation files
39#define GET_OP_CLASSES
41
42using namespace mlir;
43
44namespace llzk::pod {
45
46//===----------------------------------------------------------------------===//
47// NewPodOp
48//===----------------------------------------------------------------------===//
49
50namespace {
51static void buildCommon(
52 OpBuilder &builder, OperationState &state, PodType result, InitializedRecords initialValues
53) {
54 SmallVector<Value, 4> values;
55 SmallVector<StringRef, 4> names;
56
57 for (const auto &record : initialValues) {
58 names.push_back(record.name);
59 values.push_back(record.value);
60 }
61
62 auto &props = state.getOrAddProperties<NewPodOp::Properties>();
63 state.addTypes(result);
64 state.addOperands(values);
65 props.setInitializedRecords(builder.getStrArrayAttr(names));
66}
67} // namespace
68
70 OpBuilder &builder, OperationState &state, PodType result, ArrayRef<ValueRange> mapOperands,
71 DenseI32ArrayAttr numDimsPerMap, InitializedRecords initialValues
72) {
73 buildCommon(builder, state, result, initialValues);
75 builder, state, mapOperands, numDimsPerMap, llzk::checkedCast<int32_t>(initialValues.size())
76 );
77}
78
80 OpBuilder &builder, OperationState &state, PodType result, InitializedRecords initialValues
81) {
82 buildCommon(builder, state, result, initialValues);
84 builder, state, llzk::checkedCast<int32_t>(initialValues.size())
85 );
86}
87
88void NewPodOp::getAsmResultNames(llvm::function_ref<void(Value, StringRef)> setNameFn) {
89 setNameFn(getResult(), "pod");
90}
91
93SmallVector<DestructurableMemorySlot> NewPodOp::getDestructurableSlots() {
94 PodType podType = getType();
95 if (podType.getRecords().size() <= 1 || !getMapOperands().empty()) {
96 return {};
97 }
98 if (auto destructured = podType.getSubelementIndexMap()) {
99 return {DestructurableMemorySlot {{getResult(), podType}, std::move(*destructured)}};
100 }
101 return {};
102}
103
105DenseMap<Attribute, MemorySlot> NewPodOp::destructure(
106 const DestructurableMemorySlot &slot, const SmallPtrSetImpl<Attribute> &usedIndices,
107 OpBuilder &builder, SmallVectorImpl<DestructurableAllocationOpInterface> &newAllocators
108) {
109 assert(slot.ptr == getResult());
110 assert(slot.elemType == getType());
111
112 builder.setInsertionPointAfter(*this);
113
114 SmallVector<RecordValue> initializedRecords = getInitializedRecordValues();
115 DenseMap<Attribute, MemorySlot> slotMap;
116 for (Attribute index : usedIndices) {
117 auto recordName = llvm::dyn_cast<StringAttr>(index);
118 assert(recordName && "expected StringAttr");
119
120 Type destructAs = getType().getTypeAtIndex(recordName);
121 assert(destructAs == slot.subelementTypes.lookup(recordName));
122
123 auto destructAsPodTy = llvm::dyn_cast<PodType>(destructAs);
124 assert(destructAsPodTy && "expected PodType");
125
126 SmallVector<RecordValue, 1> initialValue;
127 for (RecordValue record : initializedRecords) {
128 if (record.name == recordName.getValue()) {
129 initialValue.push_back(record);
130 break;
131 }
132 }
133
134 auto subNew = builder.create<NewPodOp>(getLoc(), destructAsPodTy, initialValue);
135 newAllocators.push_back(subNew);
136 slotMap.try_emplace<MemorySlot>(index, {subNew.getResult(), destructAs});
137 }
138
139 return slotMap;
140}
141
143std::optional<DestructurableAllocationOpInterface> NewPodOp::handleDestructuringComplete(
144 const DestructurableMemorySlot &slot, OpBuilder & /*builder*/
145) {
146 assert(slot.ptr == getResult());
147 this->erase();
148 return std::nullopt;
149}
150
152SmallVector<MemorySlot> NewPodOp::getPromotableSlots() {
153 ArrayRef<RecordAttr> records = getType().getRecords();
154 if (records.size() != 1) {
155 return {};
156 }
157 return {MemorySlot {getResult(), records.front().getType()}};
158}
159
161Value NewPodOp::getDefaultValue(const MemorySlot &slot, OpBuilder &builder) {
162 assert(slot.ptr == getResult());
163 ArrayRef<RecordAttr> records = getType().getRecords();
164 assert(records.size() == 1 && "only single-record pods are promotable");
165 assert(records.front().getType() == slot.elemType);
166
167 StringRef recordName = records.front().getName().getValue();
168 for (RecordValue record : getInitializedRecordValues()) {
169 if (record.name == recordName) {
170 return record.value;
171 }
172 }
173 return builder.create<llzk::NonDetOp>(getLoc(), slot.elemType);
174}
175
177void NewPodOp::handleBlockArgument(const MemorySlot &, BlockArgument, OpBuilder &) {}
178
180std::optional<PromotableAllocationOpInterface> NewPodOp::handlePromotionComplete(
181 const MemorySlot &slot, Value defaultValue, OpBuilder & /*builder*/
182) {
183 assert(slot.ptr == getResult());
184 if (defaultValue && defaultValue.use_empty()) {
185 if (Operation *defOp = defaultValue.getDefiningOp()) {
186 if (llvm::isa<llzk::NonDetOp>(defOp)) {
187 defOp->erase();
188 }
189 }
190 }
191 this->erase();
192 return std::nullopt;
193}
194
195namespace {
196
197static void collectMapAttrs(Type type, SmallVector<AffineMapAttr> &mapAttrs) {
198 // clang-format off
199 llvm::TypeSwitch<Type, void>(type)
200 .Case([&mapAttrs](PodType t) {
201 for (auto record : t.getRecords()) {
202 collectMapAttrs(record.getType(), mapAttrs);
203 }
204 })
205 .Case([&mapAttrs](array::ArrayType t) {
206 for (auto a : t.getDimensionSizes()) {
207 if (auto m = llvm::dyn_cast<AffineMapAttr>(a)) {
208 mapAttrs.push_back(m);
209 }
210 }
211 })
212 .Case([&mapAttrs](component::StructType t) {
213 if (ArrayAttr params = t.getParams()) {
214 for (auto param : params) {
215 if (auto m = llvm::dyn_cast<AffineMapAttr>(param)) {
216 mapAttrs.push_back(m);
217 }
218 }
219 }
220 }).Default([](Type) {});
221 // clang-format on
222}
223
231static LogicalResult verifyInitialValues(
232 ValueRange values, ArrayRef<Attribute> names, PodType retTy,
233 llvm::function_ref<InFlightDiagnostic()> emitError
234) {
235 bool failed = false;
236 if (names.size() != values.size()) {
237 emitError() << "number of initialized records and initial values does not match ("
238 << names.size() << " != " << values.size() << ")";
239 failed = true;
240 }
241
242 llvm::StringMap<Type> records = retTy.getRecordMap();
243 llvm::StringSet<> seenNames;
244 for (auto [nameAttr, value] : llvm::zip_equal(names, values)) {
245 auto name = llvm::cast<StringAttr>(nameAttr).getValue(); // Per the ODS spec.
246 if (seenNames.contains(name)) {
247 emitError() << "found duplicated record name '" << name << '\'';
248 failed = true;
249 }
250 seenNames.insert(name);
251
252 if (!records.contains(name)) {
253 emitError() << "record '" << name << "' is not part of the struct";
254 failed = true;
255 continue;
256 }
257
258 auto valueTy = value.getType();
259 auto recordTy = records.at(name);
260 if (valueTy != recordTy) {
261 auto err = emitError();
262 err << "record '" << name << "' expected type " << recordTy << " but got " << valueTy;
263 if (typesUnify(valueTy, recordTy)) {
264 err.attachNote()
265 << "types " << valueTy << " and " << recordTy
266 << " can be unified. Perhaps you can add a 'poly.unifiable_cast' operation?";
267 }
268 failed = true;
269 }
270 }
271
272 return failure(failed);
273}
274
275static LogicalResult verifyAffineMapOperands(NewPodOp *op, Type retTy) {
276 SmallVector<AffineMapAttr> mapAttrs;
277 collectMapAttrs(retTy, mapAttrs);
279 op->getMapOperands(), op->getNumDimsPerMap(), mapAttrs, *op
280 );
281}
282
283} // namespace
284
285#define check(x) \
286 { \
287 failed = failed || mlir::failed(x); \
288 }
289
290LogicalResult NewPodOp::verify() {
291 auto retTy = llvm::dyn_cast<PodType>(getResult().getType());
292 assert(retTy); // per ODS spec of NewPodOp
293
294 bool failed = false;
295 check(
296 verifyInitialValues(getInitialValues(), getInitializedRecords().getValue(), retTy, [this]() {
297 return this->emitError();
298 })
299 );
300 check(verifyAffineMapOperands(this, retTy));
301
302 return failure(failed);
303}
304
305#undef check
306
307using UnresolvedOp = OpAsmParser::UnresolvedOperand;
308
309ParseResult
310parseRecordInitialization(OpAsmParser &parser, StringAttr &name, UnresolvedOp &operand) {
311 if (failed(parser.parseSymbolName(name))) {
312 return failure();
313 }
314
315 if (parser.parseEqual()) {
316 return failure();
317 }
318 return parser.parseOperand(operand);
319}
320
321ParseResult NewPodOp::parse(OpAsmParser &parser, OperationState &result) {
322 /* Grammar
323 * op : record_init map_operands `:` type($result) attr-dict
324 * record_init : `{` record_inits `}`| `{` `}` | $
325 * map_operands : custom<MapOperands> | $
326 * record_inits : symbol `=` operand `,` record_inits | symbol `=` operand
327 */
328
329 auto &props = result.getOrAddProperties<NewPodOp::Properties>();
330
331 SmallVector<Attribute> initializedRecords;
332 // The map may not preserve the order of the operands so it needs to be iterated using
333 // `initializedRecords` that preserves the original order.
334 llvm::StringMap<UnresolvedOp> initialValuesOperands;
335 auto parseElementFn = [&parser, &initializedRecords, &initialValuesOperands] {
336 StringAttr name;
337 UnresolvedOp operand;
338 if (failed(parseRecordInitialization(parser, name, operand))) {
339 return failure();
340 }
341 initializedRecords.push_back(name);
342 initialValuesOperands.insert({name.getValue(), operand});
343 return success();
344 };
345 auto initialValuesLoc = parser.getCurrentLocation();
346 if (parser.parseCommaSeparatedList(AsmParser::Delimiter::OptionalBraces, parseElementFn)) {
347 return failure();
348 }
349 SmallVector<int32_t> mapOperandsGroupSizes;
350 SmallVector<UnresolvedOp> allMapOperands;
351 Type indexTy = parser.getBuilder().getIndexType();
352 bool colonAlreadyParsed = true;
353 auto mapOperandsLoc = parser.getCurrentLocation();
354 // Peek to see if we have affine map operands.
355 // If we don't then the next token must be `:`
356 if (failed(parser.parseOptionalColon())) {
357 colonAlreadyParsed = false;
358 SmallVector<SmallVector<UnresolvedOp>> mapOperands {};
359 if (parseMultiDimAndSymbolList(parser, mapOperands, props.numDimsPerMap)) {
360 return failure();
361 }
362
363 mapOperandsGroupSizes.reserve(mapOperands.size());
364 for (const auto &subRange : mapOperands) {
365 allMapOperands.append(subRange.begin(), subRange.end());
366 mapOperandsGroupSizes.push_back(llzk::checkedCast<int32_t>(subRange.size()));
367 }
368 }
369
370 if (!colonAlreadyParsed && parser.parseColon()) {
371 return failure();
372 }
373
374 PodType resultType;
375 if (parser.parseCustomTypeWithFallback(resultType)) {
376 return failure();
377 }
378 // Now that we have the struct type we can resolve the operands
379 // using the types of the struct.
380 for (auto attr : initializedRecords) {
381 auto name = llvm::cast<StringAttr>(attr); // Per ODS spec of RecordAttr
382 auto lookup = resultType.getRecord(name.getValue(), [&parser, initialValuesLoc] {
383 return parser.emitError(initialValuesLoc);
384 });
385 if (failed(lookup)) {
386 return failure();
387 }
388 const auto &operand = initialValuesOperands.at(name.getValue());
389 if (failed(parser.resolveOperands({operand}, *lookup, initialValuesLoc, result.operands))) {
390 return failure();
391 }
392 }
393 props.operandSegmentSizes = {
394 llzk::checkedCast<int32_t>(initializedRecords.size()),
395 llzk::checkedCast<int32_t>(allMapOperands.size())
396 };
397 props.mapOpGroupSizes = parser.getBuilder().getDenseI32ArrayAttr(mapOperandsGroupSizes);
398 props.initializedRecords = parser.getBuilder().getArrayAttr(initializedRecords);
399 result.addTypes({resultType});
400
401 if (failed(parser.resolveOperands(allMapOperands, indexTy, mapOperandsLoc, result.operands))) {
402 return failure();
403 }
404 {
405 auto loc = parser.getCurrentLocation();
406 if (parser.parseOptionalAttrDict(result.attributes)) {
407 return failure();
408 }
409 if (failed(verifyInherentAttrs(result.name, result.attributes, [&]() {
410 return parser.emitError(loc) << '\'' << result.name.getStringRef() << "' op ";
411 }))) {
412 return failure();
413 }
414 }
415
416 return success();
417}
418
419void NewPodOp::print(OpAsmPrinter &printer) {
420 auto &os = printer.getStream();
421 auto initializedRecords = getInitializedRecordValues();
422 if (!initializedRecords.empty()) {
423 os << " { ";
424 llvm::interleaveComma(initializedRecords, os, [&os, &printer](auto record) {
425 printer.printSymbolName(record.name);
426 os << " = ";
427 printer.printOperand(record.value);
428 });
429 os << " } ";
430 }
432
433 os << " : ";
434
435 auto type = getResult().getType();
436 if (auto validType = llvm::dyn_cast<PodType>(type)) {
437 printer.printStrippedAttrOrType(validType);
438 } else {
439 printer.printType(type);
440 }
441
442 printer.printOptionalAttrDict(
443 (*this)->getAttrs(),
444 {"initializedRecords", "mapOpGroupSizes", "numDimsPerMap", "operandSegmentSizes"}
445 );
446}
447
448SmallVector<RecordValue>
449getInitializedRecordValues(ValueRange initialValues, ArrayAttr initializedRecords) {
450 return llvm::map_to_vector(llvm::zip_equal(initialValues, initializedRecords), [](auto pair) {
451 auto [value, name] = pair;
452 return RecordValue {.name = llvm::cast<StringAttr>(name).getValue(), .value = value};
453 });
454}
455
459
460//===----------------------------------------------------------------------===//
461// PodAccessOpInterface
462//===----------------------------------------------------------------------===//
463
466 const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices,
467 SmallVectorImpl<MemorySlot> & /*mustBeSafelyUsed*/, const DataLayout & /*dataLayout*/
468) {
469 if (slot.ptr != getPodRef()) {
470 return false;
471 }
472
473 StringAttr recordName = getRecordNameAsStringAttr();
474 if (!slot.subelementTypes.contains(recordName)) {
475 return false;
476 }
477
478 usedIndices.insert(recordName);
479 return true;
480}
481
484 const DestructurableMemorySlot &slot, DenseMap<Attribute, MemorySlot> &subslots,
485 OpBuilder & /*builder*/, const DataLayout & /*dataLayout*/
486) {
487 assert(slot.ptr == getPodRef());
488 assert(slot.elemType == getPodRefType());
489
490 StringAttr recordName = getRecordNameAsStringAttr();
491 const MemorySlot &memorySlot = subslots.at(recordName);
492 getPodRefMutable().set(memorySlot.ptr);
493
494 return DeletionKind::Keep;
495}
496
497//===----------------------------------------------------------------------===//
498// ReadPodOp
499//===----------------------------------------------------------------------===//
500
501LogicalResult ReadPodOp::verify() {
502 auto podTy = llvm::dyn_cast<PodType>(getPodRef().getType());
503 if (!podTy) {
504 return emitError() << "reference operand expected a plain-old-data struct but got "
505 << getPodRef().getType();
506 }
507
508 auto lookup = podTy.getRecord(getRecordName(), [this]() { return this->emitError(); });
509 if (failed(lookup)) {
510 return lookup;
511 }
512
513 if (getResult().getType() != *lookup) {
514 return emitError() << "operation result type and type of record do not match ("
515 << getResult().getType() << " != " << *lookup << ")";
516 }
517
518 return success();
519}
520
521//===----------------------------------------------------------------------===//
522// WritePodOp
523//===----------------------------------------------------------------------===//
524
525LogicalResult WritePodOp::verify() {
526 auto podTy = llvm::dyn_cast<PodType>(getPodRef().getType());
527 if (!podTy) {
528 return emitError() << "reference operand expected a plain-old-data struct but got "
529 << getPodRef().getType();
530 }
531
532 auto lookup = podTy.getRecord(getRecordName(), [this]() { return this->emitError(); });
533 if (failed(lookup)) {
534 return lookup;
535 }
536
537 if (getValue().getType() != *lookup) {
538 return emitError() << "type of source value and type of record do not match ("
539 << getValue().getType() << " != " << *lookup << ")";
540 }
541
542 return success();
543}
544
545//===----------------------------------------------------------------------===//
546// Parsing/Printing helpers
547//===----------------------------------------------------------------------===//
548
549ParseResult parseRecordName(AsmParser &parser, FlatSymbolRefAttr &name) {
550 return parser.parseCustomAttributeWithFallback(name);
551}
552
553void printRecordName(AsmPrinter &printer, Operation *, FlatSymbolRefAttr name) {
554 printer.printSymbolName(name.getValue());
555}
556
557} // namespace llzk::pod
within a display generated by the Derivative if and wherever such third party notices normally appear The contents of the NOTICE file are for informational purposes only and do not modify the License You may add Your own attribution notices within Derivative Works that You alongside or as an addendum to the NOTICE text from the provided that such additional attribution notices cannot be construed as modifying the License You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for or distribution of Your or for any such Derivative Works as a provided Your and distribution of the Work otherwise complies with the conditions stated in this License Submission of Contributions Unless You explicitly state any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this without any additional terms or conditions Notwithstanding the nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions Trademarks This License does not grant permission to use the trade names
Definition LICENSE.txt:139
#define check(x)
Definition Ops.cpp:285
void print(::mlir::OpAsmPrinter &p)
Definition Ops.cpp:419
::mlir::Operation::operand_range getInitialValues()
Definition Ops.h.inc:237
::mlir::OperandRangeRange getMapOperands()
Definition Ops.h.inc:241
::mlir::SmallVector<::llzk::pod::RecordValue > getInitializedRecordValues()
Definition Ops.cpp:456
static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::llzk::pod::InitializedRecords initialValues={})
Definition Ops.cpp.inc:458
::std::optional<::mlir::PromotableAllocationOpInterface > handlePromotionComplete(const ::mlir::MemorySlot &slot, ::mlir::Value defaultValue, ::mlir::OpBuilder &builder)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:180
::llvm::SmallVector<::mlir::DestructurableMemorySlot > getDestructurableSlots()
Required by DestructurableAllocationOpInterface / SROA pass.
Definition Ops.cpp:93
::llvm::SmallVector<::mlir::MemorySlot > getPromotableSlots()
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:152
::mlir::DenseI32ArrayAttr getNumDimsPerMapAttr()
Definition Ops.h.inc:275
::mlir::TypedValue<::llzk::pod::PodType > getResult()
Definition Ops.h.inc:257
::mlir::Value getDefaultValue(const ::mlir::MemorySlot &slot, ::mlir::OpBuilder &builder)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:161
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition Ops.cpp:88
FoldAdaptor::Properties Properties
Definition Ops.h.inc:188
::llvm::LogicalResult verifyInherentAttrs(::mlir::OperationName opName, ::mlir::NamedAttrList &attrs, llvm::function_ref<::mlir::InFlightDiagnostic()> emitError)
Definition Ops.cpp.inc:355
::llvm::LogicalResult verify()
Definition Ops.cpp:290
::llvm::DenseMap<::mlir::Attribute, ::mlir::MemorySlot > destructure(const ::mlir::DestructurableMemorySlot &slot, const ::llvm::SmallPtrSetImpl<::mlir::Attribute > &usedIndices, ::mlir::OpBuilder &builder, ::mlir::SmallVectorImpl<::mlir::DestructurableAllocationOpInterface > &newAllocators)
Required by DestructurableAllocationOpInterface / SROA pass.
Definition Ops.cpp:105
::std::optional<::mlir::DestructurableAllocationOpInterface > handleDestructuringComplete(const ::mlir::DestructurableMemorySlot &slot, ::mlir::OpBuilder &builder)
Required by DestructurableAllocationOpInterface / SROA pass.
Definition Ops.cpp:143
::mlir::ArrayAttr getInitializedRecords()
Definition Ops.cpp.inc:435
::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result)
Definition Ops.cpp:321
void handleBlockArgument(const ::mlir::MemorySlot &slot, ::mlir::BlockArgument argument, ::mlir::OpBuilder &builder)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:177
::mlir::OpOperand & getPodRefMutable()
Gets the mutable operand slot holding the SSA Value for the referenced pod.
::mlir::TypedValue<::llzk::pod::PodType > getPodRef()
Gets the SSA Value for the referenced pod.
inline ::llzk::pod::PodType getPodRefType()
Gets the type of the referenced pod.
::mlir::DeletionKind rewire(const ::mlir::DestructurableMemorySlot &slot, ::llvm::DenseMap<::mlir::Attribute, ::mlir::MemorySlot > &subslots, ::mlir::OpBuilder &builder, const ::mlir::DataLayout &dataLayout)
Required by companion interface DestructurableAccessorOpInterface / SROA pass.
Definition Ops.cpp:483
inline ::mlir::StringAttr getRecordNameAsStringAttr()
Gets the record name as an attribute suitable for destructuring indices.
bool canRewire(const ::mlir::DestructurableMemorySlot &slot, ::llvm::SmallPtrSetImpl<::mlir::Attribute > &usedIndices, ::mlir::SmallVectorImpl<::mlir::MemorySlot > &mustBeSafelyUsed, const ::mlir::DataLayout &dataLayout)
Required by companion interface DestructurableAccessorOpInterface / SROA pass.
Definition Ops.cpp:465
::llvm::FailureOr<::mlir::Type > getRecord(::llvm::StringRef name, ::llvm::function_ref<::mlir::InFlightDiagnostic()>) const
Searches a record by name.
Definition Types.cpp:50
::std::optional<::llvm::DenseMap<::mlir::Attribute, ::mlir::Type > > getSubelementIndexMap() const
Required by DestructurableTypeInterface / SROA pass.
Definition Types.cpp:77
::llvm::ArrayRef<::llzk::pod::RecordAttr > getRecords() const
::llvm::StringRef getRecordName()
Definition Ops.cpp.inc:643
::mlir::TypedValue<::mlir::Type > getResult()
Definition Ops.h.inc:499
::llvm::LogicalResult verify()
Definition Ops.cpp:501
::mlir::TypedValue<::llzk::pod::PodType > getPodRef()
Definition Ops.h.inc:480
::llvm::LogicalResult verify()
Definition Ops.cpp:525
::mlir::TypedValue<::mlir::Type > getValue()
Definition Ops.h.inc:713
::mlir::TypedValue<::llzk::pod::PodType > getPodRef()
Definition Ops.h.inc:709
::llvm::StringRef getRecordName()
Definition Ops.cpp.inc:985
OpClass::Properties & buildInstantiationAttrs(mlir::OpBuilder &odsBuilder, mlir::OperationState &odsState, mlir::ArrayRef< mlir::ValueRange > mapOperands, mlir::DenseI32ArrayAttr numDimsPerMap, int32_t firstSegmentSize=0)
Utility for build() functions that initializes the operandSegmentSizes, mapOpGroupSizes,...
LogicalResult verifyAffineMapInstantiations(OperandRangeRange mapOps, ArrayRef< int32_t > numDimsPerMap, ArrayRef< AffineMapAttr > mapAttrs, Operation *origin)
OpClass::Properties & buildInstantiationAttrsEmpty(mlir::OpBuilder &odsBuilder, mlir::OperationState &odsState, int32_t firstSegmentSize=0)
Utility for build() functions that initializes the operandSegmentSizes, mapOpGroupSizes,...
mlir::ArrayRef< RecordValue > InitializedRecords
Definition Types.h:25
OpAsmParser::UnresolvedOperand UnresolvedOp
Definition Ops.cpp:307
ParseResult parseRecordName(AsmParser &parser, FlatSymbolRefAttr &name)
Definition Ops.cpp:549
ParseResult parseRecordInitialization(OpAsmParser &parser, StringAttr &name, UnresolvedOp &operand)
Definition Ops.cpp:310
SmallVector< RecordValue > getInitializedRecordValues(ValueRange initialValues, ArrayAttr initializedRecords)
Definition Ops.cpp:449
void printRecordName(AsmPrinter &printer, Operation *, FlatSymbolRefAttr name)
Definition Ops.cpp:553
constexpr T checkedCast(U u) noexcept
Definition Compare.h:81
void printMultiDimAndSymbolList(mlir::OpAsmPrinter &printer, mlir::Operation *op, mlir::OperandRangeRange multiMapOperands, mlir::DenseI32ArrayAttr numDimsPerMap)
Definition OpHelpers.h:188
bool typesUnify(Type lhs, Type rhs, ArrayRef< StringRef > rhsReversePrefix, UnificationMap *unifications)
mlir::ParseResult parseMultiDimAndSymbolList(mlir::OpAsmParser &parser, mlir::SmallVector< mlir::SmallVector< mlir::OpAsmParser::UnresolvedOperand > > &multiMapOperands, mlir::DenseI32ArrayAttr &numDimsPerMap)
Definition OpHelpers.h:180
void setInitializedRecords(const ::mlir::ArrayAttr &propValue)
Definition Ops.h.inc:46