LLZK 2.1.1
An open-source IR for Zero Knowledge (ZK) circuits
Loading...
Searching...
No Matches
POD.cpp
Go to the documentation of this file.
1//===-- POD.cpp - POD dialect C API implementation --------------*- 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
10#include "llzk-c/Dialect/POD.h"
11
12#include "llzk-c/Support.h"
13
14#include "llzk/CAPI/Builder.h"
15#include "llzk/CAPI/Support.h"
19
20#include <mlir-c/BuiltinAttributes.h>
21#include <mlir-c/IR.h>
22#include <mlir-c/Pass.h>
23
24#include <mlir/CAPI/IR.h>
25#include <mlir/CAPI/Pass.h>
26#include <mlir/CAPI/Registration.h>
27#include <mlir/CAPI/Support.h>
28#include <mlir/CAPI/Wrap.h>
29#include <mlir/IR/Attributes.h>
30#include <mlir/IR/Diagnostics.h>
31#include <mlir/Support/LLVM.h>
32
33#include <llvm/ADT/STLExtras.h>
34#include <llvm/ADT/SmallVectorExtras.h>
35
36#include <cstdint>
37
38using namespace mlir;
39using namespace llzk;
40using namespace llzk::pod;
41
42static void registerLLZKPodTransformationPasses() { registerTransformationPasses(); }
43
44// Include the generated CAPI
49
50MLIR_DEFINE_CAPI_DIALECT_REGISTRATION(POD, llzk__pod, PODDialect)
51
52namespace {
53
54static SmallVector<RecordValue>
55fromRawRecordValues(intptr_t nValues, LlzkRecordValue const *values) {
56 return llvm::map_to_vector(ArrayRef(values, nValues), [](const auto &record) {
57 return RecordValue {.name = unwrap(record.name), .value = unwrap(record.value)};
58 });
59}
60
61} // namespace
62
63//===----------------------------------------------------------------------===//
64// RecordAttr
65//===----------------------------------------------------------------------===//
66
67MlirAttribute llzkPod_RecordAttrGetInferredContext(MlirIdentifier name, MlirType type) {
68 auto t = unwrap(type);
69 return wrap(RecordAttr::get(t.getContext(), unwrap(name), t));
70}
71
72//===----------------------------------------------------------------------===//
73// PodType
74//===----------------------------------------------------------------------===//
75
77 MlirContext context, intptr_t nRecords, LlzkRecordValue const *records
78) {
79 auto initialValues = fromRawRecordValues(nRecords, records);
80 return wrap(PodType::fromInitialValues(unwrap(context), initialValues));
81}
82
83void llzkPod_PodTypeGetRecords(MlirType type, MlirAttribute *dst) {
84 auto records = unwrap_cast<PodType>(type).getRecords();
85 MutableArrayRef<MlirAttribute> dstRef(dst, records.size());
86 llvm::transform(records, dstRef.begin(), [](auto record) { return wrap(record); });
87}
88
89namespace {
90
91static MlirType
92lookupRecordImpl(PodType type, StringRef name, llvm::function_ref<InFlightDiagnostic()> emitError) {
93 auto attr = type.getRecord(name, emitError);
94 if (failed(attr)) {
95 return MlirType {.ptr = nullptr};
96 }
97 return wrap(*attr);
98}
99
100} // namespace
101
102MlirType llzkPod_PodTypeLookupRecord(MlirType type, MlirStringRef name) {
103 auto pod = unwrap_cast<PodType>(type);
104 return lookupRecordImpl(pod, unwrap(name), [pod] {
105 auto *ctx = pod.getContext();
106 return ctx->getDiagEngine().emit(Builder(ctx).getUnknownLoc(), DiagnosticSeverity::Error);
107 });
108}
109
110MlirType
111llzkPod_PodTypeLookupRecordWithinLocation(MlirType type, MlirStringRef name, MlirLocation loc) {
112 auto pod = unwrap_cast<PodType>(type);
113 return lookupRecordImpl(pod, unwrap(name), [pod, loc] {
114 return pod.getContext()->getDiagEngine().emit(unwrap(loc), DiagnosticSeverity::Error);
115 });
116}
117
118MlirType
119llzkPod_PodTypeLookupRecordWithinOperation(MlirType type, MlirStringRef name, MlirOperation op) {
120 return lookupRecordImpl(unwrap_cast<PodType>(type), unwrap(name), [op] {
121 return unwrap(op)->emitError();
122 });
123}
124
125//===----------------------------------------------------------------------===//
126// NewPodOp
127//===----------------------------------------------------------------------===//
128
130 Pod, NewPodOp, InferredFromInitialValues, intptr_t nValues, LlzkRecordValue const *values
131) {
132 auto recordValues = fromRawRecordValues(nValues, values);
133 return wrap(create<NewPodOp>(builder, location, recordValues));
134}
135
137 Pod, NewPodOp, MlirType type, intptr_t nValues, LlzkRecordValue const *values
138) {
139 auto recordValues = fromRawRecordValues(nValues, values);
140 return wrap(create<NewPodOp>(builder, location, unwrap_cast<PodType>(type), recordValues));
141}
142
144 Pod, NewPodOp, WithMapOperands, MlirType type, intptr_t nValues, LlzkRecordValue const *values,
146) {
147 auto recordValues = fromRawRecordValues(nValues, values);
148 MapOperandsHelper<> mapOps(mapOperands.nMapOperands, mapOperands.mapOperands);
149 auto numDimsPerMap =
150 llzkAffineMapOperandsBuilderGetDimsPerMapAttr(mapOperands, mlirLocationGetContext(location));
151 return wrap(
153 builder, location, unwrap_cast<PodType>(type), *mapOps,
154 unwrap_cast<DenseI32ArrayAttr>(numDimsPerMap), recordValues
155 )
156 );
157}
void llzkPod_PodTypeGetRecords(MlirType type, MlirAttribute *dst)
Writes the records into the given array that must have been previously allocated with enough space.
Definition POD.cpp:83
MlirType llzkPod_PodTypeLookupRecord(MlirType type, MlirStringRef name)
Lookups a record type by name.
Definition POD.cpp:102
MlirAttribute llzkPod_RecordAttrGetInferredContext(MlirIdentifier name, MlirType type)
Creates a new llzk::pod::RecordAttr using the MlirContext of the given type.
Definition POD.cpp:67
MlirType llzkPod_PodTypeLookupRecordWithinLocation(MlirType type, MlirStringRef name, MlirLocation loc)
Lookups a record type by name.
Definition POD.cpp:111
MlirType llzkPod_PodTypeLookupRecordWithinOperation(MlirType type, MlirStringRef name, MlirOperation op)
Lookups a record type by name.
Definition POD.cpp:119
MlirType llzkPod_PodTypeGetFromInitialValues(MlirContext context, intptr_t nRecords, LlzkRecordValue const *records)
Creates an llzk::pod::PodType using a list of values for inferring the records.
Definition POD.cpp:76
MlirAttribute llzkAffineMapOperandsBuilderGetDimsPerMapAttr(LlzkAffineMapOperandsBuilder builder, MlirContext context)
Returns the number of dimensions per map represented as an attribute.
Definition Support.cpp:195
Helper for unwrapping the C arguments for the map operands.
Definition Support.h:61
::llvm::FailureOr<::mlir::Type > getRecord(::llvm::StringRef name, ::llvm::function_ref<::mlir::InFlightDiagnostic()>) const
Searches a record by name.
Definition Types.cpp:50
static PodType fromInitialValues(::mlir::MLIRContext *ctx, InitializedRecords init)
Creates a new type from a set of initialized records.
Definition Types.cpp:42
#define LLZK_DEFINE_OP_BUILD_METHOD(dialect, op,...)
Definition Support.h:31
#define LLZK_DEFINE_SUFFIX_OP_BUILD_METHOD(dialect, op, suffix,...)
Definition Support.h:27
void registerTransformationPasses()
mlir::Operation * create(MlirOpBuilder cBuilder, MlirLocation cLocation, Args &&...args)
Creates a new operation using an ODS build method.
Definition Builder.h:41
mlir::Location getUnknownLoc(mlir::MLIRContext *context)
Definition Builders.h:23
auto unwrap_cast(auto &from)
Definition Support.h:51
Encapsulates the arguments related to affine maps that are common in operation constructors that supp...
Definition Support.h:103
MlirValueRange * mapOperands
Definition Support.h:107
Information needed to define a pod RecordAttr given a name and a value that will be stored in the rec...
Definition POD.h:48