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 // Suppress false positive from `clang-tidy`
331 // NOLINTNEXTLINE(clang-analyzer-core.StackAddressEscape)
332 auto &props = result.getOrAddProperties<NewPodOp::Properties>();
333
334 SmallVector<Attribute> initializedRecords;
335 // The map may not preserve the order of the operands so it needs to be iterated using
336 // `initializedRecords` that preserves the original order.
337 llvm::StringMap<UnresolvedOp> initialValuesOperands;
338 auto parseElementFn = [&parser, &initializedRecords, &initialValuesOperands] {
339 StringAttr name;
340 UnresolvedOp operand;
341 if (failed(parseRecordInitialization(parser, name, operand))) {
342 return failure();
343 }
344 initializedRecords.push_back(name);
345 initialValuesOperands.insert({name.getValue(), operand});
346 return success();
347 };
348 auto initialValuesLoc = parser.getCurrentLocation();
349 if (parser.parseCommaSeparatedList(AsmParser::Delimiter::OptionalBraces, parseElementFn)) {
350 return failure();
351 }
352 SmallVector<int32_t> mapOperandsGroupSizes;
353 SmallVector<UnresolvedOp> allMapOperands;
354 Type indexTy = parser.getBuilder().getIndexType();
355 bool colonAlreadyParsed = true;
356 auto mapOperandsLoc = parser.getCurrentLocation();
357 // Peek to see if we have affine map operands.
358 // If we don't then the next token must be `:`
359 if (failed(parser.parseOptionalColon())) {
360 colonAlreadyParsed = false;
361 SmallVector<SmallVector<UnresolvedOp>> mapOperands {};
362 if (parseMultiDimAndSymbolList(parser, mapOperands, props.numDimsPerMap)) {
363 return failure();
364 }
365
366 mapOperandsGroupSizes.reserve(mapOperands.size());
367 for (const auto &subRange : mapOperands) {
368 allMapOperands.append(subRange.begin(), subRange.end());
369 mapOperandsGroupSizes.push_back(llzk::checkedCast<int32_t>(subRange.size()));
370 }
371 }
372
373 if (!colonAlreadyParsed && parser.parseColon()) {
374 return failure();
375 }
376
377 PodType resultType;
378 if (parser.parseCustomTypeWithFallback(resultType)) {
379 return failure();
380 }
381 // Now that we have the struct type we can resolve the operands
382 // using the types of the struct.
383 for (auto attr : initializedRecords) {
384 auto name = llvm::cast<StringAttr>(attr); // Per ODS spec of RecordAttr
385 auto lookup = resultType.getRecord(name.getValue(), [&parser, initialValuesLoc] {
386 return parser.emitError(initialValuesLoc);
387 });
388 if (failed(lookup)) {
389 return failure();
390 }
391 const auto &operand = initialValuesOperands.at(name.getValue());
392 if (failed(parser.resolveOperands({operand}, *lookup, initialValuesLoc, result.operands))) {
393 return failure();
394 }
395 }
396 props.operandSegmentSizes = {
397 llzk::checkedCast<int32_t>(initializedRecords.size()),
398 llzk::checkedCast<int32_t>(allMapOperands.size())
399 };
400 props.mapOpGroupSizes = parser.getBuilder().getDenseI32ArrayAttr(mapOperandsGroupSizes);
401 props.initializedRecords = parser.getBuilder().getArrayAttr(initializedRecords);
402 result.addTypes({resultType});
403
404 if (failed(parser.resolveOperands(allMapOperands, indexTy, mapOperandsLoc, result.operands))) {
405 return failure();
406 }
407 {
408 auto loc = parser.getCurrentLocation();
409 if (parser.parseOptionalAttrDict(result.attributes)) {
410 return failure();
411 }
412 if (failed(verifyInherentAttrs(result.name, result.attributes, [&]() {
413 return parser.emitError(loc) << '\'' << result.name.getStringRef() << "' op ";
414 }))) {
415 return failure();
416 }
417 }
418
419 return success();
420}
421
422void NewPodOp::print(OpAsmPrinter &printer) {
423 auto &os = printer.getStream();
424 auto initializedRecords = getInitializedRecordValues();
425 if (!initializedRecords.empty()) {
426 os << " { ";
427 llvm::interleaveComma(initializedRecords, os, [&os, &printer](auto record) {
428 printer.printSymbolName(record.name);
429 os << " = ";
430 printer.printOperand(record.value);
431 });
432 os << " } ";
433 }
435
436 os << " : ";
437
438 auto type = getResult().getType();
439 if (auto validType = llvm::dyn_cast<PodType>(type)) {
440 printer.printStrippedAttrOrType(validType);
441 } else {
442 printer.printType(type);
443 }
444
445 printer.printOptionalAttrDict(
446 (*this)->getAttrs(),
447 {"initializedRecords", "mapOpGroupSizes", "numDimsPerMap", "operandSegmentSizes"}
448 );
449}
450
451SmallVector<RecordValue>
452getInitializedRecordValues(ValueRange initialValues, ArrayAttr initializedRecords) {
453 return llvm::map_to_vector(llvm::zip_equal(initialValues, initializedRecords), [](auto pair) {
454 auto [value, name] = pair;
455 return RecordValue {.name = llvm::cast<StringAttr>(name).getValue(), .value = value};
456 });
457}
458
462
463//===----------------------------------------------------------------------===//
464// PodAccessOpInterface
465//===----------------------------------------------------------------------===//
466
469 const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices,
470 SmallVectorImpl<MemorySlot> & /*mustBeSafelyUsed*/, const DataLayout & /*dataLayout*/
471) {
472 if (slot.ptr != getPodRef()) {
473 return false;
474 }
475
476 StringAttr recordName = getRecordNameAttr();
477 if (!slot.subelementTypes.contains(recordName)) {
478 return false;
479 }
480
481 usedIndices.insert(recordName);
482 return true;
483}
484
487 const DestructurableMemorySlot &slot, DenseMap<Attribute, MemorySlot> &subslots,
488 OpBuilder & /*builder*/, const DataLayout & /*dataLayout*/
489) {
490 assert(slot.ptr == getPodRef());
491 assert(slot.elemType == getPodRefType());
492
493 StringAttr recordName = getRecordNameAttr();
494 const MemorySlot &memorySlot = subslots.at(recordName);
495 getPodRefMutable().set(memorySlot.ptr);
496
497 return DeletionKind::Keep;
498}
499
500//===----------------------------------------------------------------------===//
501// ReadPodOp
502//===----------------------------------------------------------------------===//
503
504namespace {
505
506LogicalResult readRecordNameProperty(DialectBytecodeReader &reader, StringAttr &recordName) {
507 auto versionOpt = reader.getDialectVersion<PODDialect>();
508 if (succeeded(versionOpt)) {
509 const auto &ver = static_cast<const LLZKDialectVersion &>(**versionOpt);
510 if (ver.majorVersion < 3) {
511 // Prior to v3 it was serialized as a `FlatSymbolRefAttr` instead of a `StringAttr`.
512 FlatSymbolRefAttr attr;
513 if (failed(reader.readAttribute(attr))) {
514 return failure();
515 }
516 recordName = attr.getAttr();
517 return success();
518 }
519 }
520
521 // Same as tablegen would generate to deserialize current-version IR.
522 return reader.readAttribute(recordName);
523}
524
525void writeRecordNameProperty(DialectBytecodeWriter &writer, StringAttr recordName) {
526 writer.writeAttribute(recordName);
527}
528
529} // namespace
530
531LogicalResult ReadPodOp::readProperties(DialectBytecodeReader &reader, OperationState &state) {
532 auto &prop = state.getOrAddProperties<Properties>();
533 return readRecordNameProperty(reader, prop.record_name);
534}
535
536void ReadPodOp::writeProperties(DialectBytecodeWriter &writer) {
537 writeRecordNameProperty(writer, getProperties().record_name);
538}
539
540LogicalResult ReadPodOp::verify() {
541 auto podTy = llvm::dyn_cast<PodType>(getPodRef().getType());
542 if (!podTy) {
543 return emitError() << "reference operand expected a plain-old-data struct but got "
544 << getPodRef().getType();
545 }
546
547 auto lookup = podTy.getRecord(getRecordName(), [this]() { return this->emitError(); });
548 if (failed(lookup)) {
549 return lookup;
550 }
551
552 if (getResult().getType() != *lookup) {
553 return emitOpError() << "has wrong result type; expected " << *lookup << ", got "
554 << getResult().getType();
555 }
556
557 return success();
558}
559
560//===----------------------------------------------------------------------===//
561// WritePodOp
562//===----------------------------------------------------------------------===//
563
564LogicalResult WritePodOp::readProperties(DialectBytecodeReader &reader, OperationState &state) {
565 // Suppress false positive from `clang-tidy`
566 // NOLINTNEXTLINE(clang-analyzer-core.StackAddressEscape)
567 auto &prop = state.getOrAddProperties<Properties>();
568 return readRecordNameProperty(reader, prop.record_name);
569}
570
571void WritePodOp::writeProperties(DialectBytecodeWriter &writer) {
572 writeRecordNameProperty(writer, getProperties().record_name);
573}
574
575LogicalResult WritePodOp::verify() {
576 auto podTy = llvm::dyn_cast<PodType>(getPodRef().getType());
577 if (!podTy) {
578 return emitError() << "reference operand expected a plain-old-data struct but got "
579 << getPodRef().getType();
580 }
581
582 auto lookup = podTy.getRecord(getRecordName(), [this]() { return this->emitError(); });
583 if (failed(lookup)) {
584 return lookup;
585 }
586
587 if (getValue().getType() != *lookup) {
588 return emitOpError() << "has wrong value type; expected " << *lookup << ", got "
589 << getValue().getType();
590 }
591
592 return success();
593}
594
595//===----------------------------------------------------------------------===//
596// Parsing/Printing helpers
597//===----------------------------------------------------------------------===//
598
599ParseResult parseRecordName(AsmParser &parser, StringAttr &name) {
600 FlatSymbolRefAttr symRef;
601 auto result = parser.parseCustomAttributeWithFallback(symRef);
602 if (succeeded(result)) {
603 name = symRef.getAttr();
604 }
605 return result;
606}
607
608void printRecordName(AsmPrinter &printer, Operation *, StringAttr name) {
609 printer.printSymbolName(name.getValue());
610}
611
612} // 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:422
::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:459
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:486
::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:468
::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:536
::llvm::LogicalResult readProperties(::mlir::DialectBytecodeReader &reader, ::mlir::OperationState &state)
Definition Ops.cpp:531
::llvm::LogicalResult verify()
Definition Ops.cpp:540
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:575
::llvm::LogicalResult readProperties(::mlir::DialectBytecodeReader &reader, ::mlir::OperationState &state)
Definition Ops.cpp:564
::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:571
::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:452
void printRecordName(AsmPrinter &printer, Operation *, StringAttr name)
Definition Ops.cpp:608
ParseResult parseRecordName(AsmParser &parser, StringAttr &name)
Definition Ops.cpp:599
constexpr T checkedCast(U u) noexcept
Definition Compare.h:94
void printMultiDimAndSymbolList(mlir::OpAsmPrinter &printer, mlir::Operation *op, mlir::OperandRangeRange multiMapOperands, mlir::DenseI32ArrayAttr numDimsPerMap)
Definition OpHelpers.h:184
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:176
void setInitializedRecords(const ::mlir::ArrayAttr &propValue)
Definition Ops.h.inc:46