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
19
20#include <mlir/IR/Builders.h>
21#include <mlir/IR/BuiltinAttributes.h>
22#include <mlir/IR/Diagnostics.h>
23#include <mlir/IR/OpImplementation.h>
24#include <mlir/IR/OperationSupport.h>
25#include <mlir/Support/LLVM.h>
26
27#include <llvm/ADT/STLExtras.h>
28#include <llvm/ADT/SmallString.h>
29#include <llvm/ADT/SmallVectorExtras.h>
30#include <llvm/ADT/StringSet.h>
31#include <llvm/ADT/TypeSwitch.h>
32#include <llvm/Support/Debug.h>
33
34#include <cstdint>
35#include <optional>
36
37// TableGen'd implementation files
39
40// TableGen'd implementation files
41#define GET_OP_CLASSES
43
44using namespace mlir;
45
46namespace llzk::pod {
47
48//===----------------------------------------------------------------------===//
49// NewPodOp
50//===----------------------------------------------------------------------===//
51
52namespace {
53static void buildCommon(
54 OpBuilder &builder, OperationState &state, PodType result, InitializedRecords initialValues
55) {
56 SmallVector<Value, 4> values;
57 SmallVector<StringRef, 4> names;
58
59 for (const auto &record : initialValues) {
60 names.push_back(record.name);
61 values.push_back(record.value);
62 }
63
64 auto &props = state.getOrAddProperties<NewPodOp::Properties>();
65 state.addTypes(result);
66 state.addOperands(values);
67 props.setInitializedRecords(builder.getStrArrayAttr(names));
68}
69} // namespace
70
72 OpBuilder &builder, OperationState &state, PodType result, ArrayRef<ValueRange> mapOperands,
73 DenseI32ArrayAttr numDimsPerMap, InitializedRecords initialValues
74) {
75 buildCommon(builder, state, result, initialValues);
77 builder, state, mapOperands, numDimsPerMap, llzk::checkedCast<int32_t>(initialValues.size())
78 );
79}
80
82 OpBuilder &builder, OperationState &state, PodType result, InitializedRecords initialValues
83) {
84 buildCommon(builder, state, result, initialValues);
86 builder, state, llzk::checkedCast<int32_t>(initialValues.size())
87 );
88}
89
90void NewPodOp::getAsmResultNames(llvm::function_ref<void(Value, StringRef)> setNameFn) {
91 setNameFn(getResult(), "pod");
92}
93
95SmallVector<DestructurableMemorySlot> NewPodOp::getDestructurableSlots() {
96 PodType podType = getType();
97 if (podType.getRecords().size() <= 1 || !getMapOperands().empty()) {
98 return {};
99 }
100 if (auto destructured = podType.getSubelementIndexMap()) {
101 return {DestructurableMemorySlot {{getResult(), podType}, std::move(*destructured)}};
102 }
103 return {};
104}
105
107DenseMap<Attribute, MemorySlot> NewPodOp::destructure(
108 const DestructurableMemorySlot &slot, const SmallPtrSetImpl<Attribute> &usedIndices,
109 OpBuilder &builder, SmallVectorImpl<DestructurableAllocationOpInterface> &newAllocators
110) {
111 assert(slot.ptr == getResult());
112 assert(slot.elemType == getType());
113
114 builder.setInsertionPointAfter(*this);
115
116 SmallVector<RecordValue> initializedRecords = getInitializedRecordValues();
117 DenseMap<Attribute, MemorySlot> slotMap;
118 for (Attribute index : usedIndices) {
119 auto recordName = llvm::dyn_cast<StringAttr>(index);
120 assert(recordName && "expected StringAttr");
121
122 Type destructAs = getType().getTypeAtIndex(recordName);
123 assert(destructAs == slot.subelementTypes.lookup(recordName));
124
125 auto destructAsPodTy = llvm::dyn_cast<PodType>(destructAs);
126 assert(destructAsPodTy && "expected PodType");
127
128 SmallVector<RecordValue, 1> initialValue;
129 for (RecordValue record : initializedRecords) {
130 if (record.name == recordName.getValue()) {
131 initialValue.push_back(record);
132 break;
133 }
134 }
135
136 auto subNew = NewPodOp::create(builder, getLoc(), destructAsPodTy, initialValue);
137 newAllocators.push_back(subNew);
138 slotMap.try_emplace<MemorySlot>(index, {subNew.getResult(), destructAs});
139 }
140
141 return slotMap;
142}
143
145std::optional<DestructurableAllocationOpInterface> NewPodOp::handleDestructuringComplete(
146 const DestructurableMemorySlot &slot, OpBuilder & /*builder*/
147) {
148 assert(slot.ptr == getResult());
149 this->erase();
150 return std::nullopt;
151}
152
153namespace {
154
156static Value materializeValueCopyBefore(Operation *anchor, Value source, OpBuilder &builder) {
157 if (!llzk::requiresValueCopy(source.getType())) {
158 return source;
159 }
160 OpBuilder::InsertionGuard guard(builder);
161 builder.setInsertionPoint(anchor);
162 FailureOr<Value> copied = llzk::materializeValueCopy(builder, anchor->getLoc(), source);
163 assert(succeeded(copied) && "copy support must be checked before POD promotion");
164 return *copied;
165}
166
168static bool canRemovePodAccess(
169 Value podRef, Type accessedType, const MemorySlot &slot,
170 const SmallPtrSetImpl<OpOperand *> &blockingUses
171) {
172 if (blockingUses.size() != 1) {
173 return false;
174 }
175 Value blockingUse = (*blockingUses.begin())->get();
176 return blockingUse == slot.ptr && podRef == slot.ptr && accessedType == slot.elemType &&
178}
179
180} // namespace
181
183Value ReadPodOp::getStored(const MemorySlot &, OpBuilder &, Value, const DataLayout &) {
184 llvm_unreachable("getStored() should not be called on ReadPodOp");
185}
186
189 const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
190 SmallVectorImpl<OpOperand *> & /*newBlockingUses*/, const DataLayout & /*dataLayout*/
191) {
192 return canRemovePodAccess(getPodRef(), getResult().getType(), slot, blockingUses);
193}
194
197 const MemorySlot &, const SmallPtrSetImpl<OpOperand *> &, OpBuilder &builder,
198 Value reachingDefinition, const DataLayout &
199) {
200 getResult().replaceAllUsesWith(materializeValueCopyBefore(*this, reachingDefinition, builder));
201 return DeletionKind::Delete;
202}
203
205Value WritePodOp::getStored(const MemorySlot &, OpBuilder &builder, Value, const DataLayout &) {
206 return materializeValueCopyBefore(*this, getValue(), builder);
207}
208
211 const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
212 SmallVectorImpl<OpOperand *> & /*newBlockingUses*/, const DataLayout & /*dataLayout*/
213) {
214 return getValue() != slot.ptr &&
215 canRemovePodAccess(getPodRef(), getValue().getType(), slot, blockingUses);
216}
217
220 const MemorySlot &, const SmallPtrSetImpl<OpOperand *> &, OpBuilder &, Value, const DataLayout &
221) {
222 return DeletionKind::Delete;
223}
224
226SmallVector<MemorySlot> NewPodOp::getPromotableSlots() {
227 ArrayRef<RecordAttr> records = getType().getRecords();
228 if (records.size() != 1 || llzk::requiresUnsupportedValueCopy(records.front().getType())) {
229 return {};
230 }
231 return {MemorySlot {getResult(), records.front().getType()}};
232}
233
235Value NewPodOp::getDefaultValue(const MemorySlot &slot, OpBuilder &builder) {
236 assert(slot.ptr == getResult());
237 ArrayRef<RecordAttr> records = getType().getRecords();
238 assert(records.size() == 1 && "only single-record pods are promotable");
239 assert(records.front().getType() == slot.elemType);
240
241 StringRef recordName = records.front().getName().getValue();
242 for (RecordValue record : getInitializedRecordValues()) {
243 if (record.name == recordName) {
244 return materializeValueCopyBefore(*this, record.value, builder);
245 }
246 }
247 // Keep nested defaults visible to the allocation-based scalarization fixpoint. Each promoted
248 // read snapshots this storage independently, so mutating one read cannot affect another.
249 if (auto podType = llvm::dyn_cast<PodType>(slot.elemType)) {
250 OpBuilder::InsertionGuard guard(builder);
251 builder.setInsertionPoint(*this);
252 OperandRangeRange groups = getMapOperands();
253 SmallVector<ValueRange> mapOperands(groups.begin(), groups.end());
254 return NewPodOp::create(builder, getLoc(), podType, mapOperands, getNumDimsPerMapAttr());
255 }
256
257 return llzk::NonDetOp::create(builder, getLoc(), slot.elemType);
258}
259
261void NewPodOp::handleBlockArgument(const MemorySlot &, BlockArgument, OpBuilder &) {}
262
264std::optional<PromotableAllocationOpInterface> NewPodOp::handlePromotionComplete(
265 const MemorySlot &slot, Value defaultValue, OpBuilder & /*builder*/
266) {
267 assert(slot.ptr == getResult());
268 if (defaultValue && defaultValue.use_empty()) {
269 if (Operation *defOp = defaultValue.getDefiningOp()) {
270 if (llvm::isa<llzk::NonDetOp, NewPodOp>(defOp)) {
271 defOp->erase();
272 }
273 }
274 }
275 this->erase();
276 return std::nullopt;
277}
278
279void collectPodMapAttrs(Type type, SmallVector<AffineMapAttr> &mapAttrs) {
280 // clang-format off
281 llvm::TypeSwitch<Type, void>(type)
282 .Case([&mapAttrs](PodType t) {
283 for (auto record : t.getRecords()) {
284 collectPodMapAttrs(record.getType(), mapAttrs);
285 }
286 })
287 .Case([&mapAttrs](array::ArrayType t) {
288 for (auto a : t.getDimensionSizes()) {
289 if (auto m = llvm::dyn_cast<AffineMapAttr>(a)) {
290 mapAttrs.push_back(m);
291 }
292 }
293 })
294 .Case([&mapAttrs](component::StructType t) {
295 if (ArrayAttr params = t.getParams()) {
296 for (auto param : params) {
297 if (auto m = llvm::dyn_cast<AffineMapAttr>(param)) {
298 mapAttrs.push_back(m);
299 }
300 }
301 }
302 }).Default([](Type) {});
303 // clang-format on
304}
305
306namespace {
307
315static LogicalResult verifyInitialValues(
316 ValueRange values, ArrayRef<Attribute> names, PodType retTy,
317 llvm::function_ref<InFlightDiagnostic()> emitError
318) {
319 bool failed = false;
320 if (names.size() != values.size()) {
321 emitError() << "number of initialized records and initial values does not match ("
322 << names.size() << " != " << values.size() << ')';
323 failed = true;
324 }
325
326 llvm::StringMap<Type> records = retTy.getRecordMap();
327 llvm::StringSet<> seenNames;
328 for (auto [nameAttr, value] : llvm::zip_equal(names, values)) {
329 auto name = llvm::cast<StringAttr>(nameAttr).getValue(); // Per the ODS spec.
330 if (seenNames.contains(name)) {
331 emitError() << "found duplicated record name '" << name << '\'';
332 failed = true;
333 }
334 seenNames.insert(name);
335
336 if (!records.contains(name)) {
337 emitError() << "record '" << name << "' is not part of the struct";
338 failed = true;
339 continue;
340 }
341
342 auto valueTy = value.getType();
343 auto recordTy = records.at(name);
344 if (valueTy != recordTy) {
345 auto err = emitError();
346 err << "record '" << name << "' expected type " << recordTy << " but got " << valueTy;
347 if (typesUnify(valueTy, recordTy)) {
348 err.attachNote()
349 << "types " << valueTy << " and " << recordTy
350 << " can be unified. Perhaps you can add a 'poly.unifiable_cast' operation?";
351 }
352 failed = true;
353 }
354 }
355
356 return failure(failed);
357}
358
359static LogicalResult verifyAffineMapOperands(NewPodOp *op, Type retTy) {
360 SmallVector<AffineMapAttr> mapAttrs;
361 collectPodMapAttrs(retTy, mapAttrs);
363 op->getMapOperands(), op->getNumDimsPerMap(), mapAttrs, *op
364 );
365}
366
367} // namespace
368
369#define check(x) \
370 { \
371 failed = failed || mlir::failed(x); \
372 }
373
374LogicalResult NewPodOp::verify() {
375 auto retTy = llvm::dyn_cast<PodType>(getResult().getType());
376 assert(retTy); // per ODS spec of NewPodOp
377
378 bool failed = false;
379 check(
380 verifyInitialValues(getInitialValues(), getInitializedRecords().getValue(), retTy, [this]() {
381 return this->emitError();
382 })
383 );
384 check(verifyAffineMapOperands(this, retTy));
385
386 return failure(failed);
387}
388
389#undef check
390
391using UnresolvedOp = OpAsmParser::UnresolvedOperand;
392
393ParseResult
394parseRecordInitialization(OpAsmParser &parser, StringAttr &name, UnresolvedOp &operand) {
395 if (failed(parser.parseSymbolName(name))) {
396 return failure();
397 }
398
399 if (parser.parseEqual()) {
400 return failure();
401 }
402 return parser.parseOperand(operand);
403}
404
405ParseResult NewPodOp::parse(OpAsmParser &parser, OperationState &result) {
406 /* Grammar
407 * op : record_init map_operands `:` type($result) attr-dict
408 * record_init : `{` record_inits `}`| `{` `}` | $
409 * map_operands : custom<MapOperands> | $
410 * record_inits : symbol `=` operand `,` record_inits | symbol `=` operand
411 */
412
413 auto &props = result.getOrAddProperties<NewPodOp::Properties>();
414
415 SmallVector<Attribute> initializedRecords;
416 // The map may not preserve the order of the operands so it needs to be iterated using
417 // `initializedRecords` that preserves the original order.
418 llvm::StringMap<UnresolvedOp> initialValuesOperands;
419 auto parseElementFn = [&parser, &initializedRecords, &initialValuesOperands] {
420 StringAttr name;
421 UnresolvedOp operand;
422 if (failed(parseRecordInitialization(parser, name, operand))) {
423 return failure();
424 }
425 initializedRecords.push_back(name);
426 initialValuesOperands.insert({name.getValue(), operand});
427 return success();
428 };
429 auto initialValuesLoc = parser.getCurrentLocation();
430 if (parser.parseCommaSeparatedList(AsmParser::Delimiter::OptionalBraces, parseElementFn)) {
431 return failure();
432 }
433 SmallVector<int32_t> mapOperandsGroupSizes;
434 SmallVector<UnresolvedOp> allMapOperands;
435 Type indexTy = parser.getBuilder().getIndexType();
436 bool colonAlreadyParsed = true;
437 auto mapOperandsLoc = parser.getCurrentLocation();
438 // Peek to see if we have affine map operands.
439 // If we don't then the next token must be `:`
440 if (failed(parser.parseOptionalColon())) {
441 colonAlreadyParsed = false;
442 SmallVector<SmallVector<UnresolvedOp>> mapOperands {};
443 if (parseMultiDimAndSymbolList(parser, mapOperands, props.numDimsPerMap)) {
444 return failure();
445 }
446
447 mapOperandsGroupSizes.reserve(mapOperands.size());
448 for (const auto &subRange : mapOperands) {
449 allMapOperands.append(subRange.begin(), subRange.end());
450 mapOperandsGroupSizes.push_back(llzk::checkedCast<int32_t>(subRange.size()));
451 }
452 }
453
454 if (!colonAlreadyParsed && parser.parseColon()) {
455 return failure();
456 }
457
458 PodType resultType;
459 if (parser.parseCustomTypeWithFallback(resultType)) {
460 return failure();
461 }
462 // Now that we have the struct type we can resolve the operands
463 // using the types of the struct.
464 for (auto attr : initializedRecords) {
465 auto name = llvm::cast<StringAttr>(attr); // Per ODS spec of RecordAttr
466 auto lookup = resultType.getRecord(name.getValue(), [&parser, initialValuesLoc] {
467 return parser.emitError(initialValuesLoc);
468 });
469 if (failed(lookup)) {
470 return failure();
471 }
472 const auto &operand = initialValuesOperands.at(name.getValue());
473 if (failed(parser.resolveOperands({operand}, *lookup, initialValuesLoc, result.operands))) {
474 return failure();
475 }
476 }
477 props.operandSegmentSizes = {
478 llzk::checkedCast<int32_t>(initializedRecords.size()),
479 llzk::checkedCast<int32_t>(allMapOperands.size())
480 };
481 props.mapOpGroupSizes = parser.getBuilder().getDenseI32ArrayAttr(mapOperandsGroupSizes);
482 props.initializedRecords = parser.getBuilder().getArrayAttr(initializedRecords);
483 result.addTypes({resultType});
484
485 if (failed(parser.resolveOperands(allMapOperands, indexTy, mapOperandsLoc, result.operands))) {
486 return failure();
487 }
488 {
489 auto loc = parser.getCurrentLocation();
490 if (parser.parseOptionalAttrDict(result.attributes)) {
491 return failure();
492 }
493 if (failed(verifyInherentAttrs(result.name, result.attributes, [&]() {
494 return parser.emitError(loc) << '\'' << result.name.getStringRef() << "' op ";
495 }))) {
496 return failure();
497 }
498 }
499
500 return success();
501}
502
503void NewPodOp::print(OpAsmPrinter &printer) {
504 auto &os = printer.getStream();
505 auto initializedRecords = getInitializedRecordValues();
506 if (!initializedRecords.empty()) {
507 os << " { ";
508 llvm::interleaveComma(initializedRecords, os, [&os, &printer](auto record) {
509 printer.printSymbolName(record.name);
510 os << " = ";
511 printer.printOperand(record.value);
512 });
513 os << " } ";
514 }
516
517 os << " : ";
518
519 auto type = getResult().getType();
520 if (auto validType = llvm::dyn_cast<PodType>(type)) {
521 printer.printStrippedAttrOrType(validType);
522 } else {
523 printer.printType(type);
524 }
525
526 printer.printOptionalAttrDict(
527 (*this)->getAttrs(),
528 {"initializedRecords", "mapOpGroupSizes", "numDimsPerMap", "operandSegmentSizes"}
529 );
530}
531
532SmallVector<RecordValue>
533getInitializedRecordValues(ValueRange initialValues, ArrayAttr initializedRecords) {
534 return llvm::map_to_vector(llvm::zip_equal(initialValues, initializedRecords), [](auto pair) {
535 auto [value, name] = pair;
536 return RecordValue {.name = llvm::cast<StringAttr>(name).getValue(), .value = value};
537 });
538}
539
543
544//===----------------------------------------------------------------------===//
545// PodAccessOpInterface
546//===----------------------------------------------------------------------===//
547
550 const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices,
551 SmallVectorImpl<MemorySlot> & /*mustBeSafelyUsed*/, const DataLayout & /*dataLayout*/
552) {
553 if (slot.ptr != getPodRef()) {
554 return false;
555 }
556
557 StringAttr recordName = getRecordNameAttr();
558 if (!slot.subelementTypes.contains(recordName)) {
559 return false;
560 }
561
562 usedIndices.insert(recordName);
563 return true;
564}
565
568 const DestructurableMemorySlot &slot, DenseMap<Attribute, MemorySlot> &subslots,
569 OpBuilder & /*builder*/, const DataLayout & /*dataLayout*/
570) {
571 assert(slot.ptr == getPodRef());
572 assert(slot.elemType == getPodRefType());
573
574 StringAttr recordName = getRecordNameAttr();
575 const MemorySlot &memorySlot = subslots.at(recordName);
576 getPodRefMutable().set(memorySlot.ptr);
577
578 return DeletionKind::Keep;
579}
580
581//===----------------------------------------------------------------------===//
582// ReadPodOp
583//===----------------------------------------------------------------------===//
584
585namespace {
586
587LogicalResult readRecordNameProperty(DialectBytecodeReader &reader, StringAttr &recordName) {
588 auto versionOpt = reader.getDialectVersion<PODDialect>();
589 if (succeeded(versionOpt)) {
590 const auto &ver = static_cast<const LLZKDialectVersion &>(**versionOpt);
591 if (ver.majorVersion < 3) {
592 // Prior to v3 it was serialized as a `FlatSymbolRefAttr` instead of a `StringAttr`.
593 FlatSymbolRefAttr attr;
594 if (failed(reader.readAttribute(attr))) {
595 return failure();
596 }
597 recordName = attr.getAttr();
598 return success();
599 }
600 }
601
602 // Same as tablegen would generate to deserialize current-version IR.
603 return reader.readAttribute(recordName);
604}
605
606void writeRecordNameProperty(DialectBytecodeWriter &writer, StringAttr recordName) {
607 writer.writeAttribute(recordName);
608}
609
610} // namespace
611
612LogicalResult ReadPodOp::readProperties(DialectBytecodeReader &reader, OperationState &state) {
613 auto &prop = state.getOrAddProperties<Properties>();
614 return readRecordNameProperty(reader, prop.record_name);
615}
616
617void ReadPodOp::writeProperties(DialectBytecodeWriter &writer) {
618 writeRecordNameProperty(writer, getProperties().record_name);
619}
620
621LogicalResult ReadPodOp::verify() {
622 auto podTy = llvm::dyn_cast<PodType>(getPodRef().getType());
623 if (!podTy) {
624 return emitError("reference operand expected a plain-old-data struct but got ")
625 << getPodRef().getType();
626 }
627
628 auto lookup = podTy.getRecord(getRecordName(), [this]() { return this->emitError(); });
629 if (failed(lookup)) {
630 return lookup;
631 }
632
633 if (getResult().getType() != *lookup) {
634 return emitOpError() << "has wrong result type; expected " << *lookup << ", got "
635 << getResult().getType();
636 }
637
638 return success();
639}
640
641//===----------------------------------------------------------------------===//
642// WritePodOp
643//===----------------------------------------------------------------------===//
644
645LogicalResult WritePodOp::readProperties(DialectBytecodeReader &reader, OperationState &state) {
646 auto &prop = state.getOrAddProperties<Properties>();
647 return readRecordNameProperty(reader, prop.record_name);
648}
649
650void WritePodOp::writeProperties(DialectBytecodeWriter &writer) {
651 writeRecordNameProperty(writer, getProperties().record_name);
652}
653
654LogicalResult WritePodOp::verify() {
655 auto podTy = llvm::dyn_cast<PodType>(getPodRef().getType());
656 if (!podTy) {
657 return emitError() << "reference operand expected a plain-old-data struct but got "
658 << getPodRef().getType();
659 }
660
661 auto lookup = podTy.getRecord(getRecordName(), [this]() { return this->emitError(); });
662 if (failed(lookup)) {
663 return lookup;
664 }
665
666 if (getValue().getType() != *lookup) {
667 return emitOpError() << "has wrong value type; expected " << *lookup << ", got "
668 << getValue().getType();
669 }
670
671 return success();
672}
673
674//===----------------------------------------------------------------------===//
675// Parsing/Printing helpers
676//===----------------------------------------------------------------------===//
677
678ParseResult parseRecordName(AsmParser &parser, StringAttr &name) {
679 FlatSymbolRefAttr symRef;
680 auto result = parser.parseCustomAttributeWithFallback(symRef);
681 if (succeeded(result)) {
682 name = symRef.getAttr();
683 }
684 return result;
685}
686
687void printRecordName(AsmPrinter &printer, Operation *, StringAttr name) {
688 printer.printSymbolName(name.getValue());
689}
690
691} // 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
Apache License January AND DISTRIBUTION Definitions License shall mean the terms and conditions for and distribution as defined by Sections through of this document Licensor shall mean the copyright owner or entity authorized by the copyright owner that is granting the License Legal Entity shall mean the union of the acting entity and all other entities that control are controlled by or are under common control with that entity For the purposes of this definition control direct or to cause the direction or management of such whether by contract or including but not limited to software source documentation source
Definition LICENSE.txt:28
#define check(x)
Definition Ops.cpp:369
static NonDetOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Type res)
Definition Ops.cpp.inc:94
void print(::mlir::OpAsmPrinter &p)
Definition Ops.cpp:503
static NewPodOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::llzk::pod::InitializedRecords initialValues={})
Definition Ops.cpp.inc:466
::mlir::Operation::operand_range getInitialValues()
Definition Ops.h.inc:325
::mlir::OperandRangeRange getMapOperands()
Definition Ops.h.inc:329
::mlir::SmallVector<::llzk::pod::RecordValue > getInitializedRecordValues()
Definition Ops.cpp:540
static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::llzk::pod::InitializedRecords initialValues={})
Definition Ops.cpp.inc:460
::std::optional<::mlir::PromotableAllocationOpInterface > handlePromotionComplete(const ::mlir::MemorySlot &slot, ::mlir::Value defaultValue, ::mlir::OpBuilder &builder)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:264
::llvm::SmallVector<::mlir::DestructurableMemorySlot > getDestructurableSlots()
Required by DestructurableAllocationOpInterface / SROA pass.
Definition Ops.cpp:95
::llvm::SmallVector<::mlir::MemorySlot > getPromotableSlots()
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:226
::mlir::DenseI32ArrayAttr getNumDimsPerMapAttr()
Definition Ops.h.inc:363
::mlir::TypedValue<::llzk::pod::PodType > getResult()
Definition Ops.h.inc:345
::mlir::Value getDefaultValue(const ::mlir::MemorySlot &slot, ::mlir::OpBuilder &builder)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:235
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition Ops.cpp:90
FoldAdaptor::Properties Properties
Definition Ops.h.inc:273
::llvm::LogicalResult verifyInherentAttrs(::mlir::OperationName opName, ::mlir::NamedAttrList &attrs, llvm::function_ref<::mlir::InFlightDiagnostic()> emitError)
Definition Ops.cpp.inc:357
::llvm::LogicalResult verify()
Definition Ops.cpp:374
::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:107
::std::optional<::mlir::DestructurableAllocationOpInterface > handleDestructuringComplete(const ::mlir::DestructurableMemorySlot &slot, ::mlir::OpBuilder &builder)
Required by DestructurableAllocationOpInterface / SROA pass.
Definition Ops.cpp:145
::mlir::ArrayAttr getInitializedRecords()
Definition Ops.cpp.inc:437
::mlir::ParseResult parse(::mlir::OpAsmParser &parser, ::mlir::OperationState &result)
Definition Ops.cpp:405
void handleBlockArgument(const ::mlir::MemorySlot &slot, ::mlir::BlockArgument argument, ::mlir::OpBuilder &builder)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:261
Dialect for working with plain-old-data structs.
Definition Dialect.h.inc:13
::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:567
::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:549
::llvm::FailureOr<::mlir::Type > getRecord(::llvm::StringRef name, ::llvm::function_ref<::mlir::InFlightDiagnostic()>) const
Searches a record by name.
Definition Types.cpp:50
::llvm::StringMap<::mlir::Type > getRecordMap() const
Returns the records in map form.
Definition Types.cpp:59
::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:769
::mlir::TypedValue<::mlir::Type > getResult()
Definition Ops.h.inc:601
bool canUsesBeRemoved(const ::mlir::MemorySlot &slot, const ::llvm::SmallPtrSetImpl<::mlir::OpOperand * > &blockingUses, ::llvm::SmallVectorImpl<::mlir::OpOperand * > &newBlockingUses, const ::mlir::DataLayout &datalayout)
Required by PromotableMemOpInterface / mem2reg pass.
Definition Ops.cpp:188
void writeProperties(::mlir::DialectBytecodeWriter &writer)
Definition Ops.cpp:617
::llvm::LogicalResult readProperties(::mlir::DialectBytecodeReader &reader, ::mlir::OperationState &state)
Definition Ops.cpp:612
::llvm::LogicalResult verify()
Definition Ops.cpp:621
FoldAdaptor::Properties Properties
Definition Ops.h.inc:554
::mlir::TypedValue<::llzk::pod::PodType > getPodRef()
Definition Ops.h.inc:582
::mlir::DeletionKind removeBlockingUses(const ::mlir::MemorySlot &slot, const ::llvm::SmallPtrSetImpl< mlir::OpOperand * > &blockingUses, ::mlir::OpBuilder &builder, ::mlir::Value reachingDefinition, const ::mlir::DataLayout &dataLayout)
Required by PromotableMemOpInterface / mem2reg pass.
Definition Ops.cpp:196
::mlir::Value getStored(const ::mlir::MemorySlot &slot, ::mlir::OpBuilder &builder, ::mlir::Value reachingDef, const ::mlir::DataLayout &dataLayout)
Required by PromotableMemOpInterface / mem2reg pass.
Definition Ops.cpp:183
bool canUsesBeRemoved(const ::mlir::MemorySlot &slot, const ::llvm::SmallPtrSetImpl<::mlir::OpOperand * > &blockingUses, ::llvm::SmallVectorImpl<::mlir::OpOperand * > &newBlockingUses, const ::mlir::DataLayout &datalayout)
Required by PromotableMemOpInterface / mem2reg pass.
Definition Ops.cpp:210
::llvm::LogicalResult verify()
Definition Ops.cpp:654
::llvm::LogicalResult readProperties(::mlir::DialectBytecodeReader &reader, ::mlir::OperationState &state)
Definition Ops.cpp:645
::mlir::TypedValue<::mlir::Type > getValue()
Definition Ops.h.inc:838
::mlir::TypedValue<::llzk::pod::PodType > getPodRef()
Definition Ops.h.inc:834
FoldAdaptor::Properties Properties
Definition Ops.h.inc:806
::mlir::DeletionKind removeBlockingUses(const ::mlir::MemorySlot &slot, const ::llvm::SmallPtrSetImpl< mlir::OpOperand * > &blockingUses, ::mlir::OpBuilder &builder, ::mlir::Value reachingDefinition, const ::mlir::DataLayout &dataLayout)
Required by PromotableMemOpInterface / mem2reg pass.
Definition Ops.cpp:219
::mlir::Value getStored(const ::mlir::MemorySlot &slot, ::mlir::OpBuilder &builder, ::mlir::Value reachingDef, const ::mlir::DataLayout &dataLayout)
Required by PromotableMemOpInterface / mem2reg pass.
Definition Ops.cpp:205
void writeProperties(::mlir::DialectBytecodeWriter &writer)
Definition Ops.cpp:650
::llvm::StringRef getRecordName()
Definition Ops.cpp.inc:1171
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:391
void collectPodMapAttrs(Type type, SmallVector< AffineMapAttr > &mapAttrs)
Definition Ops.cpp:279
ParseResult parseRecordInitialization(OpAsmParser &parser, StringAttr &name, UnresolvedOp &operand)
Definition Ops.cpp:394
SmallVector< RecordValue > getInitializedRecordValues(ValueRange initialValues, ArrayAttr initializedRecords)
Definition Ops.cpp:533
void printRecordName(AsmPrinter &printer, Operation *, StringAttr name)
Definition Ops.cpp:687
ParseResult parseRecordName(AsmParser &parser, StringAttr &name)
Definition Ops.cpp:678
constexpr T checkedCast(U u) noexcept
Definition Compare.h:94
bool requiresUnsupportedValueCopy(mlir::Type type)
Return whether type requires a value copy that cannot currently be materialized.
Definition ValueCopy.h:58
FailureOr< Value > materializeValueCopy(OpBuilder &builder, Location loc, Value source)
Definition ValueCopy.cpp:68
bool requiresValueCopy(Type type)
Definition ValueCopy.cpp:38
void printMultiDimAndSymbolList(mlir::OpAsmPrinter &printer, mlir::Operation *op, mlir::OperandRangeRange multiMapOperands, mlir::DenseI32ArrayAttr numDimsPerMap)
Definition OpHelpers.h:144
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:136
void setInitializedRecords(const ::mlir::ArrayAttr &propValue)
Definition Ops.h.inc:126