LLZK 2.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 - Array 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 2025 Veridise Inc.
6// SPDX-License-Identifier: Apache-2.0
7//
8//===----------------------------------------------------------------------===//
9
11
15#include "llzk/Util/Compare.h"
17
18#include <mlir/Dialect/Arith/IR/Arith.h>
19#include <mlir/Dialect/Utils/IndexingUtils.h>
20#include <mlir/IR/Attributes.h>
21#include <mlir/IR/BuiltinOps.h>
22#include <mlir/IR/Diagnostics.h>
23#include <mlir/IR/OwningOpRef.h>
24#include <mlir/IR/SymbolTable.h>
25#include <mlir/IR/ValueRange.h>
26#include <mlir/Support/LogicalResult.h>
27
28#include <llvm/ADT/ArrayRef.h>
29#include <llvm/ADT/Twine.h>
30
31// TableGen'd implementation files
33
34// TableGen'd implementation files
35#define GET_OP_CLASSES
37
38using namespace mlir;
39
40namespace llzk::array {
41
42//===------------------------------------------------------------------===//
43// CreateArrayOp
44//===------------------------------------------------------------------===//
45
47 OpBuilder &odsBuilder, OperationState &odsState, ArrayType result, ValueRange elements
48) {
49 odsState.addTypes(result);
50 odsState.addOperands(elements);
51 // This builds CreateArrayOp from a list of elements. In that case, the dimensions of the array
52 // type cannot be defined via an affine map which means there are no affine map operands.
54 odsBuilder, odsState, llzk::checkedCast<int32_t>(elements.size())
55 );
56}
57
59 OpBuilder &odsBuilder, OperationState &odsState, ArrayType result,
60 ArrayRef<ValueRange> mapOperands, DenseI32ArrayAttr numDimsPerMap
61) {
62 odsState.addTypes(result);
64 odsBuilder, odsState, mapOperands, numDimsPerMap
65 );
66}
67
68LogicalResult CreateArrayOp::verifySymbolUses(SymbolTableCollection &tables) {
69 // Ensure any SymbolRef used in the type are valid
70 return verifyTypeResolution(tables, *this, llvm::cast<Type>(getType()));
71}
72
73void CreateArrayOp::getAsmResultNames(OpAsmSetValueNameFn setNameFn) {
74 setNameFn(getResult(), "array");
75}
76
77llvm::SmallVector<Type> CreateArrayOp::resultTypeToElementsTypes(Type resultType) {
78 // The ODS restricts $result with LLZK_ArrayType so this cast is safe.
79 ArrayType a = llvm::cast<ArrayType>(resultType);
80 return llvm::SmallVector<Type>(a.getNumElements(), a.getElementType());
81}
82
83ParseResult CreateArrayOp::parseInferredArrayType(
84 OpAsmParser & /*parser*/, llvm::SmallVector<Type, 1> &elementsTypes,
85 ArrayRef<OpAsmParser::UnresolvedOperand> elements, Type resultType
86) {
87 assert(elementsTypes.size() == 0); // it was not yet initialized
88 // If the '$elements' operand is not empty, then the expected type for the operand
89 // is computed to match the type of the '$result'. Otherwise, it remains empty.
90 if (elements.size() > 0) {
91 elementsTypes.append(resultTypeToElementsTypes(resultType));
92 }
93 return success();
94}
95
96void CreateArrayOp::printInferredArrayType(
97 OpAsmPrinter &printer, CreateArrayOp, TypeRange, OperandRange, Type
98) {
99 // nothing to print, it's derived and therefore not represented in the output
100}
101
102LogicalResult CreateArrayOp::verify() {
103 Type retTy = getResult().getType();
104 assert(llvm::isa<ArrayType>(retTy)); // per ODS spec of CreateArrayOp
105
106 // Collect the array dimensions that are defined via AffineMapAttr
107 SmallVector<AffineMapAttr> mapAttrs;
108 // Extend the lifetime of the temporary to suppress warnings.
109 ArrayType arrTy = llvm::cast<ArrayType>(retTy);
110 for (Attribute a : arrTy.getDimensionSizes()) {
111 if (AffineMapAttr m = dyn_cast<AffineMapAttr>(a)) {
112 mapAttrs.push_back(m);
113 }
114 }
116 getMapOperands(), getNumDimsPerMap(), mapAttrs, *this
117 );
118}
119
121SmallVector<DestructurableMemorySlot> CreateArrayOp::getDestructurableSlots() {
122 assert(getElements().empty() && "must run after initialization is split from allocation");
123 ArrayType arrType = getType();
124 if (!arrType.hasStaticShape() || arrType.getNumElements() == 1) {
125 return {};
126 }
127 if (auto destructured = arrType.getSubelementIndexMap()) {
128 return {DestructurableMemorySlot {{getResult(), arrType}, std::move(*destructured)}};
129 }
130 return {};
131}
132
134DenseMap<Attribute, MemorySlot> CreateArrayOp::destructure(
135 const DestructurableMemorySlot &slot, const SmallPtrSetImpl<Attribute> &usedIndices,
136 OpBuilder &builder, SmallVectorImpl<DestructurableAllocationOpInterface> &newAllocators
137) {
138 assert(slot.ptr == getResult());
139 assert(slot.elemType == getType());
140
141 builder.setInsertionPointAfter(*this);
142
143 DenseMap<Attribute, MemorySlot> slotMap; // result
144 for (Attribute index : usedIndices) {
145 // This is an ArrayAttr since indexing is multi-dimensional
146 ArrayAttr indexAsArray = llvm::dyn_cast<ArrayAttr>(index);
147 assert(indexAsArray && "expected ArrayAttr");
148
149 Type destructAs = getType().getTypeAtIndex(indexAsArray);
150 assert(destructAs == slot.subelementTypes.lookup(indexAsArray));
151
152 ArrayType destructAsArrayTy = llvm::dyn_cast<ArrayType>(destructAs);
153 assert(destructAsArrayTy && "expected ArrayType");
154
155 auto subCreate = builder.create<CreateArrayOp>(getLoc(), destructAsArrayTy);
156 newAllocators.push_back(subCreate);
157 slotMap.try_emplace<MemorySlot>(index, {subCreate.getResult(), destructAs});
158 }
159
160 return slotMap;
161}
162
164std::optional<DestructurableAllocationOpInterface> CreateArrayOp::handleDestructuringComplete(
165 const DestructurableMemorySlot &slot, OpBuilder & /*builder*/
166) {
167 assert(slot.ptr == getResult());
168 this->erase();
169 return std::nullopt;
170}
171
173SmallVector<MemorySlot> CreateArrayOp::getPromotableSlots() {
174 ArrayType arrType = getType();
175 if (!arrType.hasStaticShape()) {
176 return {};
177 }
178 // Can only support arrays containing a single element (the SROA pass can be run first to
179 // destructure all arrays into size-1 arrays).
180 if (arrType.getNumElements() != 1) {
181 return {};
182 }
183 return {MemorySlot {getResult(), arrType.getElementType()}};
184}
185
187Value CreateArrayOp::getDefaultValue(const MemorySlot &slot, OpBuilder &builder) {
188 return builder.create<llzk::NonDetOp>(getLoc(), slot.elemType);
189}
190
192void CreateArrayOp::handleBlockArgument(const MemorySlot &, BlockArgument, OpBuilder &) {}
193
195std::optional<PromotableAllocationOpInterface> CreateArrayOp::handlePromotionComplete(
196 const MemorySlot & /*slot*/, Value defaultValue, OpBuilder & /*builder*/
197) {
198 if (defaultValue.use_empty()) {
199 defaultValue.getDefiningOp()->erase();
200 } else {
201 this->erase();
202 }
203 // Return `nullopt` because it produces only a single slot
204 return std::nullopt;
205}
206
207//===------------------------------------------------------------------===//
208// ArrayAccessOpInterface
209//===------------------------------------------------------------------===//
210
214 ArrayType arrTy = getArrRefType();
215 if (arrTy.hasStaticShape()) {
216 if (auto converted = ArrayIndexGen::from(arrTy).checkAndConvert(getIndices())) {
217 return ArrayAttr::get(getContext(), *converted);
218 }
219 }
220 return nullptr;
221}
222
225 const DestructurableMemorySlot &slot, SmallPtrSetImpl<Attribute> &usedIndices,
226 SmallVectorImpl<MemorySlot> & /*mustBeSafelyUsed*/, const DataLayout & /*dataLayout*/
227) {
228 if (slot.ptr != getArrRef()) {
229 return false;
230 }
231
232 ArrayAttr indexAsAttr = indexOperandsToAttributeArray();
233 if (!indexAsAttr) {
234 return false;
235 }
236
237 // Scalar read/write case has 0 dimensions in the read/write value.
238 if (!getValueOperandDims().empty()) {
239 return false;
240 }
241
242 // Just insert the index.
243 usedIndices.insert(indexAsAttr);
244 return true;
245}
246
249 const DestructurableMemorySlot &slot, DenseMap<Attribute, MemorySlot> &subslots,
250 OpBuilder &builder, const DataLayout & /*dataLayout*/
251) {
252 assert(slot.ptr == getArrRef());
253 assert(slot.elemType == getArrRefType());
254 // ASSERT: non-scalar read/write should have been desugared earlier
255 assert(getValueOperandDims().empty() && "only scalar read/write supported");
256
257 ArrayAttr indexAsAttr = indexOperandsToAttributeArray();
258 assert(indexAsAttr && "canRewire() should have returned false");
259 const MemorySlot &memorySlot = subslots.at(indexAsAttr);
260
261 // Temporarily set insertion point before the current op for what's built below
262 OpBuilder::InsertionGuard guard(builder);
263 builder.setInsertionPoint(this->getOperation());
264
265 // Write to the sub-slot created for the index of `this`, using index 0
266 getArrRefMutable().set(memorySlot.ptr);
267 getIndicesMutable().clear();
268 getIndicesMutable().assign(builder.create<arith::ConstantIndexOp>(getLoc(), 0));
269
270 return DeletionKind::Keep;
271}
272
273//===------------------------------------------------------------------===//
274// ReadArrayOp
275//===------------------------------------------------------------------===//
276
277namespace {
278
279LogicalResult
280ensureNumIndicesMatchDims(ArrayType ty, size_t numIndices, const OwningEmitErrorFn &errFn) {
281 ArrayRef<Attribute> dims = ty.getDimensionSizes();
282 // Ensure the number of provided indices matches the array dimensions
283 auto compare = numIndices <=> dims.size();
284 if (compare != 0) {
285 return errFn().append(
286 "has ", (compare < 0 ? "insufficient" : "too many"), " indexed dimensions: expected ",
287 dims.size(), " but found ", numIndices
288 );
289 }
290 return success();
291}
292
293} // namespace
294
295LogicalResult ReadArrayOp::verifySymbolUses(SymbolTableCollection &tables) {
296 // Ensure any SymbolRef used in the type are valid
297 return verifyTypeResolution(tables, *this, ArrayRef<Type> {getArrRef().getType(), getType()});
298}
299
301 MLIRContext * /*context*/, std::optional<Location> /*location*/, ReadArrayOpAdaptor adaptor,
302 llvm::SmallVectorImpl<Type> &inferredReturnTypes
303) {
304 inferredReturnTypes.resize(1);
305 Type lvalType = adaptor.getArrRef().getType();
306 assert(llvm::isa<ArrayType>(lvalType)); // per ODS spec of ReadArrayOp
307 inferredReturnTypes[0] = llvm::cast<ArrayType>(lvalType).getElementType();
308 return success();
309}
310
311bool ReadArrayOp::isCompatibleReturnTypes(TypeRange l, TypeRange r) {
312 return singletonTypeListsUnify(l, r);
313}
314
315LogicalResult ReadArrayOp::verify() {
316 // Ensure the number of indices used match the shape of the array exactly.
317 return ensureNumIndicesMatchDims(getArrRefType(), getIndices().size(), getEmitOpErrFn(this));
318}
319
322 const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
323 SmallVectorImpl<OpOperand *> & /*newBlockingUses*/, const DataLayout & /*datalayout*/
324) {
325 if (blockingUses.size() != 1) {
326 return false;
327 }
328 Value blockingUse = (*blockingUses.begin())->get();
329 return blockingUse == slot.ptr && getArrRef() == slot.ptr &&
330 getResult().getType() == slot.elemType;
331}
332
335 const MemorySlot & /*slot*/, const SmallPtrSetImpl<OpOperand *> & /*blockingUses*/,
336 OpBuilder & /*builder*/, Value reachingDefinition, const DataLayout & /*dataLayout*/
337) {
338 // `canUsesBeRemoved` checked this blocking use must be the loaded `slot.ptr`
339 getResult().replaceAllUsesWith(reachingDefinition);
340 return DeletionKind::Delete;
341}
342
343//===------------------------------------------------------------------===//
344// WriteArrayOp
345//===------------------------------------------------------------------===//
346
347LogicalResult WriteArrayOp::verifySymbolUses(SymbolTableCollection &tables) {
348 // Ensure any SymbolRef used in the type are valid
350 tables, *this, ArrayRef<Type> {getArrRefType(), getRvalue().getType()}
351 );
352}
353
354LogicalResult WriteArrayOp::verify() {
355 // Ensure the number of indices used match the shape of the array exactly.
356 return ensureNumIndicesMatchDims(getArrRefType(), getIndices().size(), getEmitOpErrFn(this));
357}
358
361 const MemorySlot &slot, const SmallPtrSetImpl<OpOperand *> &blockingUses,
362 SmallVectorImpl<OpOperand *> & /*newBlockingUses*/, const DataLayout & /*datalayout*/
363) {
364 if (blockingUses.size() != 1) {
365 return false;
366 }
367 Value blockingUse = (*blockingUses.begin())->get();
368 return blockingUse == slot.ptr && getArrRef() == slot.ptr && getRvalue() != slot.ptr &&
369 getRvalue().getType() == slot.elemType;
370}
371
374 const MemorySlot &, const SmallPtrSetImpl<OpOperand *> &, OpBuilder &, Value, const DataLayout &
375) {
376 return DeletionKind::Delete;
377}
378
379//===------------------------------------------------------------------===//
380// ExtractArrayOp
381//===------------------------------------------------------------------===//
382
383LogicalResult ExtractArrayOp::verifySymbolUses(SymbolTableCollection &tables) {
384 // Ensure any SymbolRef used in the type are valid
385 return verifyTypeResolution(tables, *this, getArrRefType());
386}
387
389 MLIRContext * /*context*/, std::optional<Location> location, ExtractArrayOpAdaptor adaptor,
390 llvm::SmallVectorImpl<Type> &inferredReturnTypes
391) {
392 size_t numToSkip = adaptor.getIndices().size();
393 Type arrRefType = adaptor.getArrRef().getType();
394 assert(llvm::isa<ArrayType>(arrRefType)); // per ODS spec of ExtractArrayOp
395 ArrayType arrRefArrType = llvm::cast<ArrayType>(arrRefType);
396 ArrayRef<Attribute> arrRefDimSizes = arrRefArrType.getDimensionSizes();
397
398 // Check for invalid cases
399 auto compare = numToSkip <=> arrRefDimSizes.size();
400 if (compare == 0) {
401 return mlir::emitOptionalError(
402 location, '\'', ExtractArrayOp::getOperationName(),
403 "' op cannot select all dimensions of an array. Use '", ReadArrayOp::getOperationName(),
404 "' instead."
405 );
406 } else if (compare > 0) {
407 return mlir::emitOptionalError(
408 location, '\'', ExtractArrayOp::getOperationName(),
409 "' op cannot select more dimensions than exist in the source array"
410 );
411 }
412
413 // Generate and store reduced array type
414 inferredReturnTypes.resize(1);
415 inferredReturnTypes[0] =
416 ArrayType::get(arrRefArrType.getElementType(), arrRefDimSizes.drop_front(numToSkip));
417 return success();
418}
419
420bool ExtractArrayOp::isCompatibleReturnTypes(TypeRange l, TypeRange r) {
421 return singletonTypeListsUnify(l, r);
422}
423
424//===------------------------------------------------------------------===//
425// InsertArrayOp
426//===------------------------------------------------------------------===//
427
428LogicalResult InsertArrayOp::verifySymbolUses(SymbolTableCollection &tables) {
429 // Ensure any SymbolRef used in the types are valid
431 tables, *this, ArrayRef<Type> {getArrRefType(), getRvalue().getType()}
432 );
433}
434
435LogicalResult InsertArrayOp::verify() {
436 ArrayType baseArrRefArrType = getArrRefType();
437 Type rValueType = getRvalue().getType();
438 assert(llvm::isa<ArrayType>(rValueType)); // per ODS spec of InsertArrayOp
439 ArrayType rValueArrType = llvm::cast<ArrayType>(rValueType);
440
441 // size of lhs dimensions == numIndices + size of rhs dimensions
442 size_t lhsDims = baseArrRefArrType.getDimensionSizes().size();
443 size_t numIndices = getIndices().size();
444 size_t rhsDims = rValueArrType.getDimensionSizes().size();
445
446 // Ensure the number of indices specified does not exceed base dimension count.
447 if (numIndices > lhsDims) {
448 return emitOpError("cannot select more dimensions than exist in the source array");
449 }
450
451 // Ensure the rValue dimension count equals the base reduced dimension count
452 auto compare = (numIndices + rhsDims) <=> lhsDims;
453 if (compare != 0) {
454 return emitOpError().append(
455 "has ", (compare < 0 ? "insufficient" : "too many"), " indexed dimensions: expected ",
456 (lhsDims - rhsDims), " but found ", numIndices
457 );
458 }
459
460 // Having verified the indices are of appropriate size, we verify the subarray type.
461 // This will verify the dimensions of the subarray, which is why we only check the
462 // size of the indices above.
463 return verifySubArrayType(getEmitOpErrFn(this), baseArrRefArrType, rValueArrType);
464}
465
466//===------------------------------------------------------------------===//
467// ArrayLengthOp
468//===------------------------------------------------------------------===//
469
470LogicalResult ArrayLengthOp::verifySymbolUses(SymbolTableCollection &tables) {
471 // Ensure any SymbolRef used in the type are valid
472 return verifyTypeResolution(tables, *this, getArrRefType());
473}
474
475} // namespace llzk::array
::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:248
::mlir::Operation::operand_range getIndices()
Gets the operand range containing the index for each dimension.
::mlir::OpOperand & getArrRefMutable()
Gets the mutable operand slot holding the SSA Value for the referenced array.
inline ::mlir::ArrayRef<::mlir::Attribute > getValueOperandDims()
Compute the dimensions of the read/write value.
::mlir::ArrayAttr indexOperandsToAttributeArray()
Returns the multi-dimensional indices of the array access as an Attribute array or a null pointer if ...
Definition Ops.cpp:213
::mlir::TypedValue<::llzk::array::ArrayType > getArrRef()
Gets the SSA Value for the referenced array.
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:224
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced array.
::mlir::MutableOperandRange getIndicesMutable()
Gets the mutable operand range containing the index for each dimension.
static ArrayIndexGen from(ArrayType)
Construct new ArrayIndexGen. Will assert if hasStaticShape() is false.
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced base array.
Definition Ops.h.inc:192
::llvm::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:470
::mlir::Type getElementType() const
::std::optional<::llvm::DenseMap<::mlir::Attribute, ::mlir::Type > > getSubelementIndexMap() const
Required by DestructurableTypeInterface / SROA pass.
Definition Types.cpp:120
static ArrayType get(::mlir::Type elementType, ::llvm::ArrayRef<::mlir::Attribute > dimensionSizes)
Definition Types.cpp.inc:83
::llvm::ArrayRef<::mlir::Attribute > getDimensionSizes() const
static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::llzk::array::ArrayType result, ::mlir::ValueRange elements={})
::mlir::TypedValue<::llzk::array::ArrayType > getResult()
Definition Ops.h.inc:408
::llvm::SmallVector<::mlir::DestructurableMemorySlot > getDestructurableSlots()
Required by DestructurableAllocationOpInterface / SROA pass.
Definition Ops.cpp:121
::std::optional<::mlir::PromotableAllocationOpInterface > handlePromotionComplete(const ::mlir::MemorySlot &slot, ::mlir::Value defaultValue, ::mlir::OpBuilder &builder)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:195
::std::optional<::mlir::DestructurableAllocationOpInterface > handleDestructuringComplete(const ::mlir::DestructurableMemorySlot &slot, ::mlir::OpBuilder &builder)
Required by DestructurableAllocationOpInterface / SROA pass.
Definition Ops.cpp:164
::llvm::LogicalResult verify()
Definition Ops.cpp:102
::mlir::Value getDefaultValue(const ::mlir::MemorySlot &slot, ::mlir::OpBuilder &builder)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:187
::llvm::SmallVector<::mlir::MemorySlot > getPromotableSlots()
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:173
::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:134
::llvm::ArrayRef< int32_t > getNumDimsPerMap()
Definition Ops.cpp.inc:541
void getAsmResultNames(::mlir::OpAsmSetValueNameFn setNameFn)
Definition Ops.cpp:73
void handleBlockArgument(const ::mlir::MemorySlot &slot, ::mlir::BlockArgument argument, ::mlir::OpBuilder &builder)
Required by PromotableAllocationOpInterface / mem2reg pass.
Definition Ops.cpp:192
::mlir::OperandRangeRange getMapOperands()
Definition Ops.h.inc:392
::mlir::Operation::operand_range getElements()
Definition Ops.h.inc:388
::llvm::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:68
static bool isCompatibleReturnTypes(::mlir::TypeRange l, ::mlir::TypeRange r)
Definition Ops.cpp:420
::llvm::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:383
::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, ::std::optional<::mlir::Location > location, ::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes, ::mlir::OpaqueProperties properties, ::mlir::RegionRange regions, ::llvm::SmallVectorImpl<::mlir::Type > &inferredReturnTypes)
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced base array.
Definition Ops.h.inc:640
static constexpr ::llvm::StringLiteral getOperationName()
Definition Ops.h.inc:578
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced base array.
Definition Ops.h.inc:794
::mlir::Operation::operand_range getIndices()
Definition Ops.h.inc:753
::llvm::LogicalResult verify()
Definition Ops.cpp:435
::mlir::TypedValue<::llzk::array::ArrayType > getRvalue()
Definition Ops.h.inc:757
::llvm::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:428
::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:334
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced base array.
Definition Ops.h.inc:958
::mlir::TypedValue<::mlir::Type > getResult()
Definition Ops.h.inc:923
::mlir::TypedValue<::llzk::array::ArrayType > getArrRef()
Definition Ops.h.inc:899
::mlir::Operation::operand_range getIndices()
Definition Ops.h.inc:903
::llvm::LogicalResult inferReturnTypes(::mlir::MLIRContext *context, ::std::optional<::mlir::Location > location, ::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes, ::mlir::OpaqueProperties properties, ::mlir::RegionRange regions, ::llvm::SmallVectorImpl<::mlir::Type > &inferredReturnTypes)
::llvm::LogicalResult verify()
Definition Ops.cpp:315
::llvm::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:295
static constexpr ::llvm::StringLiteral getOperationName()
Definition Ops.h.inc:888
static bool isCompatibleReturnTypes(::mlir::TypeRange l, ::mlir::TypeRange r)
Definition Ops.cpp:311
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:321
::llvm::LogicalResult verify()
Definition Ops.cpp:354
::mlir::Operation::operand_range getIndices()
Definition Ops.h.inc:1071
inline ::llzk::array::ArrayType getArrRefType()
Gets the type of the referenced base array.
Definition Ops.h.inc:1119
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:360
::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:373
::mlir::TypedValue<::llzk::array::ArrayType > getArrRef()
Definition Ops.h.inc:1067
::llvm::LogicalResult verifySymbolUses(::mlir::SymbolTableCollection &symbolTable)
Definition Ops.cpp:347
::mlir::TypedValue<::mlir::Type > getRvalue()
Definition Ops.h.inc:1075
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,...
LogicalResult verifySubArrayType(EmitErrorFn emitError, ArrayType arrayType, ArrayType subArrayType)
Determine if the subArrayType is a valid subarray of arrayType.
bool singletonTypeListsUnify(Iter1 lhs, Iter2 rhs, mlir::ArrayRef< llvm::StringRef > rhsReversePrefix={}, UnificationMap *unifications=nullptr)
Definition TypeHelper.h:251
constexpr T checkedCast(U u) noexcept
Definition Compare.h:81
LogicalResult verifyTypeResolution(SymbolTableCollection &tables, Operation *origin, Type ty)
OwningEmitErrorFn getEmitOpErrFn(mlir::Operation *op)
std::function< InFlightDiagnosticWrapper()> OwningEmitErrorFn
This type is required in cases like the functions below to take ownership of the lambda so it is not ...