LLZK 3.0.0
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
18
19#include <mlir/IR/Builders.h>
20#include <mlir/IR/BuiltinAttributes.h>
21#include <mlir/IR/Diagnostics.h>
22#include <mlir/IR/OpImplementation.h>
23#include <mlir/IR/OperationSupport.h>
24#include <mlir/Support/LLVM.h>
25
26#include <llvm/ADT/STLExtras.h>
27#include <llvm/ADT/SmallString.h>
28#include <llvm/ADT/SmallVectorExtras.h>
29#include <llvm/ADT/StringSet.h>
30#include <llvm/ADT/TypeSwitch.h>
31#include <llvm/Support/Debug.h>
32
33#include <cstdint>
34#include <optional>
35
36// TableGen'd implementation files
38
39// TableGen'd implementation files
40#define GET_OP_CLASSES
42
43using namespace mlir;
44
45namespace llzk::pod {
46
47//===----------------------------------------------------------------------===//
48// NewPodOp
49//===----------------------------------------------------------------------===//
50
51namespace {
52static void buildCommon(
53 OpBuilder &builder, OperationState &state, PodType result, InitializedRecords initialValues
54) {
55 SmallVector<Value, 4> values;
56 SmallVector<StringRef, 4> names;
57
58 for (const auto &record : initialValues) {
59 names.push_back(record.name);
60 values.push_back(record.value);
61 }
62
63 auto &props = state.getOrAddProperties<NewPodOp::Properties>();
64 state.addTypes(result);
65 state.addOperands(values);
66 props.setInitializedRecords(builder.getStrArrayAttr(names));
67}
68} // namespace
69
71 OpBuilder &builder, OperationState &state, PodType result, ArrayRef<ValueRange> mapOperands,
72 DenseI32ArrayAttr numDimsPerMap, InitializedRecords initialValues
73) {
74 buildCommon(builder, state, result, initialValues);
76 builder, state, mapOperands, numDimsPerMap, llzk::checkedCast<int32_t>(initialValues.size())
77 );
78}
79
81 OpBuilder &builder, OperationState &state, PodType result, InitializedRecords initialValues
82) {
83 buildCommon(builder, state, result, initialValues);
85 builder, state, llzk::checkedCast<int32_t>(initialValues.size())
86 );
87}
88
89void NewPodOp::getAsmResultNames(llvm::function_ref<void(Value, StringRef)> setNameFn) {
90 setNameFn(getResult(), "pod");
91}
92
94SmallVector<DestructurableMemorySlot> NewPodOp::getDestructurableSlots() {
95 PodType podType = getType();
96 if (podType.getRecords().size() <= 1 || !getMapOperands().empty()) {
97 return {};
98 }
99 if (auto destructured = podType.getSubelementIndexMap()) {
100 return {DestructurableMemorySlot {{getResult(), podType}, std::move(*destructured)}};
101 }
102 return {};
103}
104
106DenseMap<Attribute, MemorySlot> NewPodOp::destructure(
107 const DestructurableMemorySlot &slot, const SmallPtrSetImpl<Attribute> &usedIndices,
108 OpBuilder &builder, SmallVectorImpl<DestructurableAllocationOpInterface> &newAllocators
109) {
110 assert(slot.ptr == getResult());
111 assert(slot.elemType == getType());
112
113 builder.setInsertionPointAfter(*this);
114
115 SmallVector<RecordValue> initializedRecords = getInitializedRecordValues();
116 DenseMap<Attribute, MemorySlot> slotMap;
117 for (Attribute index : usedIndices) {
118 auto recordName = llvm::dyn_cast<StringAttr>(index);
119 assert(recordName && "expected StringAttr");
120
121 Type destructAs = getType().getTypeAtIndex(recordName);
122 assert(destructAs == slot.subelementTypes.lookup(recordName));
123
124 auto destructAsPodTy = llvm::dyn_cast<PodType>(destructAs);
125 assert(destructAsPodTy && "expected PodType");
126
127 SmallVector<RecordValue, 1> initialValue;
128 for (RecordValue record : initializedRecords) {
129 if (record.name == recordName.getValue()) {
130 initialValue.push_back(record);
131 break;
132 }
133 }
134
135 auto subNew = builder.create<NewPodOp>(getLoc(), destructAsPodTy, initialValue);
136 newAllocators.push_back(subNew);
137 slotMap.try_emplace<MemorySlot>(index, {subNew.getResult(), destructAs});
138 }
139
140 return slotMap;
141}
142
144std::optional<DestructurableAllocationOpInterface> NewPodOp::handleDestructuringComplete(
145 const DestructurableMemorySlot &slot, OpBuilder & /*builder*/
146) {
147 assert(slot.ptr == getResult());
148 this->erase();
149 return std::nullopt;
150}
151
153SmallVector<MemorySlot> NewPodOp::getPromotableSlots() {
154 ArrayRef<RecordAttr> records = getType().getRecords();
155 if (records.size() != 1) {
156 return {};
157 }
158 return {MemorySlot {getResult(), records.front().getType()}};
159}
160
162Value NewPodOp::getDefaultValue(const MemorySlot &slot, OpBuilder &builder) {
163 assert(slot.ptr == getResult());
164 ArrayRef<RecordAttr> records = getType().getRecords();
165 assert(records.size() == 1 && "only single-record pods are promotable");
166 assert(records.front().getType() == slot.elemType);
167
168 StringRef recordName = records.front().getName().getValue();
169 for (RecordValue record : getInitializedRecordValues()) {
170 if (record.name == recordName) {
171 return record.value;
172 }
173 }
174 return builder.create<llzk::NonDetOp>(getLoc(), slot.elemType);
175}
176
178void NewPodOp::handleBlockArgument(const MemorySlot &, BlockArgument, OpBuilder &) {}
179
181std::optional<PromotableAllocationOpInterface> NewPodOp::handlePromotionComplete(
182 const MemorySlot &slot, Value defaultValue, OpBuilder & /*builder*/
183) {
184 assert(slot.ptr == getResult());
185 if (defaultValue && defaultValue.use_empty()) {
186 if (Operation *defOp = defaultValue.getDefiningOp()) {
187 if (llvm::isa<llzk::NonDetOp>(defOp)) {
188 defOp->erase();
189 }
190 }
191 }
192 this->erase();
193 return std::nullopt;
194}
195
196namespace {
197
198static void collectMapAttrs(Type type, SmallVector<AffineMapAttr> &mapAttrs) {
199 // clang-format off
200 llvm::TypeSwitch<Type, void>(type)
201 .Case([&mapAttrs](PodType t) {
202 for (auto record : t.getRecords()) {
203 collectMapAttrs(record.getType(), mapAttrs);
204 }
205 })
206 .Case([&mapAttrs](array::ArrayType t) {
207 for (auto a : t.getDimensionSizes()) {
208 if (auto m = llvm::dyn_cast<AffineMapAttr>(a)) {
209 mapAttrs.push_back(m);
210 }
211 }
212 })
213 .Case([&mapAttrs](component::StructType t) {
214 if (ArrayAttr params = t.getParams()) {
215 for (auto param : params) {
216 if (auto m = llvm::dyn_cast<AffineMapAttr>(param)) {
217 mapAttrs.push_back(m);
218 }
219 }
220 }
221 }).Default([](Type) {});
222 // clang-format on
223}
224
232static LogicalResult verifyInitialValues(
233 ValueRange values, ArrayRef<Attribute> names, PodType retTy,
234 llvm::function_ref<InFlightDiagnostic()> emitError
235) {
236 bool failed = false;
237 if (names.size() != values.size()) {
238 emitError() << "number of initialized records and initial values does not match ("
239 << names.size() << " != " << values.size() << ")";
240 failed = true;
241 }
242
243 llvm::StringMap<Type> records = retTy.getRecordMap();
244 llvm::StringSet<> seenNames;
245 for (auto [nameAttr, value] : llvm::zip_equal(names, values)) {
246 auto name = llvm::cast<StringAttr>(nameAttr).getValue(); // Per the ODS spec.
247 if (seenNames.contains(name)) {
248 emitError() << "found duplicated record name '" << name << '\'';
249 failed = true;
250 }
251 seenNames.insert(name);
252
253 if (!records.contains(name)) {
254 emitError() << "record '" << name << "' is not part of the struct";
255 failed = true;
256 continue;
257 }
258
259 auto valueTy = value.getType();
260 auto recordTy = records.at(name);
261 if (valueTy != recordTy) {
262 auto err = emitError();
263 err << "record '" << name << "' expected type " << recordTy << " but got " << valueTy;
264 if (typesUnify(valueTy, recordTy)) {
265 err.attachNote()
266 << "types " << valueTy << " and " << recordTy
267 << " can be unified. Perhaps you can add a 'poly.unifiable_cast' operation?";
268 }
269 failed = true;
270 }
271 }
272
273 return failure(failed);
274}
275
276static LogicalResult verifyAffineMapOperands(NewPodOp *op, Type retTy) {
277 SmallVector<AffineMapAttr> mapAttrs;
278 collectMapAttrs(retTy, mapAttrs);
280 op->getMapOperands(), op->getNumDimsPerMap(), mapAttrs, *op
281 );
282}
283
284} // namespace
285
286#define check(x) \
287 { \
288 failed = failed || mlir::failed(x); \
289 }
290
291LogicalResult NewPodOp::verify() {
292 auto retTy = llvm::dyn_cast<PodType>(getResult().getType());
293 assert(retTy); // per ODS spec of NewPodOp
294
295 bool failed = false;
296 check(
297 verifyInitialValues(getInitialValues(), getInitializedRecords().getValue(), retTy, [this]() {
298 return this->emitError();
299 })
300 );
301 check(verifyAffineMapOperands(this, retTy));
302
303 return failure(failed);
304}
305
306#undef check
307
308using UnresolvedOp = OpAsmParser::UnresolvedOperand;
309
310ParseResult
311parseRecordInitialization(OpAsmParser &parser, StringAttr &name, UnresolvedOp &operand) {
312 if (failed(parser.parseSymbolName(name))) {
313 return failure();
314 }
315
316 if (parser.parseEqual()) {
317 return failure();
318 }
319 return parser.parseOperand(operand);
320}
321
322ParseResult NewPodOp::parse(OpAsmParser &parser, OperationState &result) {
323 /* Grammar
324 * op : record_init map_operands `:` type($result) attr-dict
325 * record_init : `{` record_inits `}`| `{` `}` | $
326 * map_operands : custom<MapOperands> | $
327 * record_inits : symbol `=` operand `,` record_inits | symbol `=` operand
328 */
329
330 auto &props = result.getOrAddProperties<NewPodOp::Properties>();
331
332 SmallVector<Attribute> initializedRecords;
333 // The map may not preserve the order of the operands so it needs to be iterated using
334 // `initializedRecords` that preserves the original order.
335 llvm::StringMap<UnresolvedOp> initialValuesOperands;
336 auto parseElementFn = [&parser, &initializedRecords, &initialValuesOperands] {
337 StringAttr name;
338 UnresolvedOp operand;
339 if (failed(parseRecordInitialization(parser, name, operand))) {
340 return failure();
341 }
342 initializedRecords.push_back(name);
343 initialValuesOperands.insert({name.getValue(), operand});
344 return success();
345 };
346 auto initialValuesLoc = parser.getCurrentLocation();
347 if (parser.parseCommaSeparatedList(AsmParser::Delimiter::OptionalBraces, parseElementFn)) {
348 return failure();
349 }
350 SmallVector<int32_t> mapOperandsGroupSizes;
351 SmallVector<UnresolvedOp> allMapOperands;
352 Type indexTy = parser.getBuilder().getIndexType();
353 bool colonAlreadyParsed = true;
354 auto mapOperandsLoc = parser.getCurrentLocation();
355 // Peek to see if we have affine map operands.
356 // If we don't then the next token must be `:`
357 if (failed(parser.parseOptionalColon())) {
358 colonAlreadyParsed = false;
359 SmallVector<SmallVector<UnresolvedOp>> mapOperands {};
360 if (parseMultiDimAndSymbolList(parser, mapOperands, props.numDimsPerMap)) {
361 return failure();
362 }
363
364 mapOperandsGroupSizes.reserve(mapOperands.size());
365 for (const auto &subRange : mapOperands) {
366 allMapOperands.append(subRange.begin(), subRange.end());
367 mapOperandsGroupSizes.push_back(llzk::checkedCast<int32_t>(subRange.size()));
368 }
369 }
370
371 if (!colonAlreadyParsed && parser.parseColon()) {
372 return failure();
373 }
374
375 PodType resultType;
376 if (parser.parseCustomTypeWithFallback(resultType)) {
377 return failure();
378 }
379 // Now that we have the struct type we can resolve the operands
380 // using the types of the struct.
381 for (auto attr : initializedRecords) {
382 auto name = llvm::cast<StringAttr>(attr); // Per ODS spec of RecordAttr
383 auto lookup = resultType.getRecord(name.getValue(), [&parser, initialValuesLoc] {
384 return parser.emitError(initialValuesLoc);
385 });
386 if (failed(lookup)) {
387 return failure();
388 }
389 const auto &operand = initialValuesOperands.at(name.getValue());
390 if (failed(parser.resolveOperands({operand}, *lookup, initialValuesLoc, result.operands))) {
391 return failure();
392 }
393 }
394 props.operandSegmentSizes = {
395 llzk::checkedCast<int32_t>(initializedRecords.size()),
396 llzk::checkedCast<int32_t>(allMapOperands.size())
397 };
398 props.mapOpGroupSizes = parser.getBuilder().getDenseI32ArrayAttr(mapOperandsGroupSizes);
399 props.initializedRecords = parser.getBuilder().getArrayAttr(initializedRecords);
400 result.addTypes({resultType});
401
402 if (failed(parser.resolveOperands(allMapOperands, indexTy, mapOperandsLoc, result.operands))) {
403 return failure();
404 }
405 {
406 auto loc = parser.getCurrentLocation();
407 if (parser.parseOptionalAttrDict(result.attributes)) {
408 return failure();
409 }
410 if (failed(verifyInherentAttrs(result.name, result.attributes, [&]() {
411 return parser.emitError(loc) << '\'' << result.name.getStringRef() << "' op ";
412 }))) {
413 return failure();
414 }
415 }
416
417 return success();
418}
419
420void NewPodOp::print(OpAsmPrinter &printer) {
421 auto &os = printer.getStream();
422 auto initializedRecords = getInitializedRecordValues();
423 if (!initializedRecords.empty()) {
424 os << " { ";
425 llvm::interleaveComma(initializedRecords, os, [&os, &printer](auto record) {
426 printer.printSymbolName(record.name);
427 os << " = ";
428 printer.printOperand(record.value);
429 });
430 os << " } ";
431 }
433
434 os << " : ";
435
436 auto type = getResult().getType();
437 if (auto validType = llvm::dyn_cast<PodType>(type)) {
438 printer.printStrippedAttrOrType(validType);
439 } else {
440 printer.printType(type);
441 }
442
443 printer.printOptionalAttrDict(
444 (*this)->getAttrs(),
445 {"initializedRecords", "mapOpGroupSizes", "numDimsPerMap", "operandSegmentSizes"}
446 );
447}
448
449SmallVector<RecordValue>
450getInitializedRecordValues(ValueRange initialValues, ArrayAttr initializedRecords) {
451 return llvm::map_to_vector(llvm::zip_equal(initialValues, initializedRecords), [](auto pair) {
452 auto [value, name] = pair;
453 return RecordValue {.name = llvm::cast<StringAttr>(name).getValue(), .value = value};
454 });
455}
456
460
461//===----------------------------------------------------------------------===//
462// PodAccessOpInterface
463//===----------------------------------------------------------------------===//
464
467 const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices,
468 SmallVectorImpl<MemorySlot> & /*mustBeSafelyUsed*/, const DataLayout & /*dataLayout*/
469) {
470 if (slot.ptr != getPodRef()) {
471 return false;
472 }
473
474 StringAttr recordName = getRecordNameAttr();
475 if (!slot.subelementTypes.contains(recordName)) {
476 return false;
477 }
478
479 usedIndices.insert(recordName);
480 return true;
481}
482
485 const DestructurableMemorySlot &slot, DenseMap<Attribute, MemorySlot> &subslots,
486 OpBuilder & /*builder*/, const DataLayout & /*dataLayout*/
487) {
488 assert(slot.ptr == getPodRef());
489 assert(slot.elemType == getPodRefType());
490
491 StringAttr recordName = getRecordNameAttr();
492 const MemorySlot &memorySlot = subslots.at(recordName);
493 getPodRefMutable().set(memorySlot.ptr);
494
495 return DeletionKind::Keep;
496}
497
498//===----------------------------------------------------------------------===//
499// ReadPodOp
500//===----------------------------------------------------------------------===//
501
502namespace {
503
504LogicalResult readRecordNameProperty(DialectBytecodeReader &reader, StringAttr &recordName) {
505 auto versionOpt = reader.getDialectVersion<PODDialect>();
506 if (succeeded(versionOpt)) {
507 const auto &ver = static_cast<const LLZKDialectVersion &>(**versionOpt);
508 if (ver.majorVersion < 3) {
509 // Prior to v3 it was serialized as a `FlatSymbolRefAttr` instead of a `StringAttr`.
510 FlatSymbolRefAttr attr;
511 if (failed(reader.readAttribute(attr))) {
512 return failure();
513 }
514 recordName = attr.getAttr();
515 return success();
516 }
517 }
518
519 // Same as tablegen would generate to deserialize current-version IR.
520 return reader.readAttribute(recordName);
521}
522
523void writeRecordNameProperty(DialectBytecodeWriter &writer, StringAttr recordName) {
524 writer.writeAttribute(recordName);
525}
526
527} // namespace
528
529LogicalResult ReadPodOp::readProperties(DialectBytecodeReader &reader, OperationState &state) {
530 auto &prop = state.getOrAddProperties<Properties>();
531 return readRecordNameProperty(reader, prop.record_name);
532}
533
534void ReadPodOp::writeProperties(DialectBytecodeWriter &writer) {
535 writeRecordNameProperty(writer, getProperties().record_name);
536}
537
538LogicalResult ReadPodOp::verify() {
539 auto podTy = llvm::dyn_cast<PodType>(getPodRef().getType());
540 if (!podTy) {
541 return emitError() << "reference operand expected a plain-old-data struct but got "
542 << getPodRef().getType();
543 }
544
545 auto lookup = podTy.getRecord(getRecordName(), [this]() { return this->emitError(); });
546 if (failed(lookup)) {
547 return lookup;
548 }
549
550 if (getResult().getType() != *lookup) {
551 return emitError() << "operation result type and type of record do not match ("
552 << getResult().getType() << " != " << *lookup << ")";
553 }
554
555 return success();
556}
557
558//===----------------------------------------------------------------------===//
559// WritePodOp
560//===----------------------------------------------------------------------===//
561
562LogicalResult WritePodOp::readProperties(DialectBytecodeReader &reader, OperationState &state) {
563 auto &prop = state.getOrAddProperties<Properties>();
564 return readRecordNameProperty(reader, prop.record_name);
565}
566
567void WritePodOp::writeProperties(DialectBytecodeWriter &writer) {
568 writeRecordNameProperty(writer, getProperties().record_name);
569}
570
571LogicalResult WritePodOp::verify() {
572 auto podTy = llvm::dyn_cast<PodType>(getPodRef().getType());
573 if (!podTy) {
574 return emitError() << "reference operand expected a plain-old-data struct but got "
575 << getPodRef().getType();
576 }
577
578 auto lookup = podTy.getRecord(getRecordName(), [this]() { return this->emitError(); });
579 if (failed(lookup)) {
580 return lookup;
581 }
582
583 if (getValue().getType() != *lookup) {
584 return emitError() << "type of source value and type of record do not match ("
585 << getValue().getType() << " != " << *lookup << ")";
586 }
587
588 return success();
589}
590
591//===----------------------------------------------------------------------===//
592// Parsing/Printing helpers
593//===----------------------------------------------------------------------===//
594
595ParseResult parseRecordName(AsmParser &parser, StringAttr &name) {
596 FlatSymbolRefAttr symRef;
597 auto result = parser.parseCustomAttributeWithFallback(symRef);
598 if (succeeded(result)) {
599 name = symRef.getAttr();
600 }
601 return result;
602}
603
604void printRecordName(AsmPrinter &printer, Operation *, StringAttr name) {
605 printer.printSymbolName(name.getValue());
606}
607
608} // 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:286
void print(::mlir::OpAsmPrinter &p)
Definition Ops.cpp:420
::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:457
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:181
::llvm::SmallVector<::mlir::DestructurableMemorySlot > getDestructurableSlots()
Required by DestructurableAllocationOpInterface / SROA pass.
Definition Ops.cpp:94
::llvm::SmallVector<::mlir::MemorySlot > getPromotableSlots()
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:153
::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:162
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition Ops.cpp:89
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:291
::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:106
::std::optional<::mlir::DestructurableAllocationOpInterface > handleDestructuringComplete(const ::mlir::DestructurableMemorySlot &slot, ::mlir::OpBuilder &builder)
Required by DestructurableAllocationOpInterface / SROA pass.
Definition Ops.cpp:144
::mlir::ArrayAttr getInitializedRecords()
Definition Ops.cpp.inc:435
::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result)
Definition Ops.cpp:322
void handleBlockArgument(const ::mlir::MemorySlot &slot, ::mlir::BlockArgument argument, ::mlir::OpBuilder &builder)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:178
::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:484
::mlir::StringAttr getRecordNameAttr()
Gets the record name attribute from the pod access op.
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:466
::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:632
::mlir::TypedValue<::mlir::Type > getResult()
Definition Ops.h.inc:499
void writeProperties(::mlir::DialectBytecodeWriter &writer)
Definition Ops.cpp:534
::llvm::LogicalResult readProperties(::mlir::DialectBytecodeReader &reader, ::mlir::OperationState &state)
Definition Ops.cpp:529
::llvm::LogicalResult verify()
Definition Ops.cpp:538
FoldAdaptor::Properties Properties
Definition Ops.h.inc:452
::mlir::TypedValue<::llzk::pod::PodType > getPodRef()
Definition Ops.h.inc:480
::llvm::LogicalResult verify()
Definition Ops.cpp:571
::llvm::LogicalResult readProperties(::mlir::DialectBytecodeReader &reader, ::mlir::OperationState &state)
Definition Ops.cpp:562
::mlir::TypedValue<::mlir::Type > getValue()
Definition Ops.h.inc:716
::mlir::TypedValue<::llzk::pod::PodType > getPodRef()
Definition Ops.h.inc:712
FoldAdaptor::Properties Properties
Definition Ops.h.inc:684
void writeProperties(::mlir::DialectBytecodeWriter &writer)
Definition Ops.cpp:567
::llvm::StringRef getRecordName()
Definition Ops.cpp.inc:977
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:308
ParseResult parseRecordInitialization(OpAsmParser &parser, StringAttr &name, UnresolvedOp &operand)
Definition Ops.cpp:311
SmallVector< RecordValue > getInitializedRecordValues(ValueRange initialValues, ArrayAttr initializedRecords)
Definition Ops.cpp:450
void printRecordName(AsmPrinter &printer, Operation *, StringAttr name)
Definition Ops.cpp:604
ParseResult parseRecordName(AsmParser &parser, StringAttr &name)
Definition Ops.cpp:595
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