36 mlir::OpBuilder &builder;
37 mlir::SymbolTableCollection &tables;
44 for (mlir::Attribute record : info.
family) {
45 auto entry = llvm::dyn_cast<mlir::DictionaryAttr>(record);
46 auto origin = entry ? entry.getAs<mlir::TypeAttr>(
FAMILY_TYPE_KEY) : mlir::TypeAttr();
47 auto indices = entry ? entry.getAs<mlir::ArrayAttr>(
FAMILY_INDICES_KEY) : mlir::ArrayAttr();
48 if (!origin || !indices || origin.getValue() != type ||
49 indices.size() != info.
indices.size()) {
52 bool matches = llvm::all_of(llvm::zip(indices, info.
indices), [](
auto pair) {
53 auto attr = llvm::dyn_cast<mlir::IntegerAttr>(std::get<0>(pair));
54 return attr && attr.getValue().isSignedIntN(64) && attr.getInt() == std::get<1>(pair);
60 if (!
id || !
id.getValue().isSignedIntN(64) ||
id.getInt() < 0) {
64 specializations.resolve(tables, type,
id.getInt(), site,
"constraint flattening");
65 if (mlir::failed(target)) {
66 return mlir::failure();
69 return constraintError(site,
"ambiguous concrete struct family element");
73 return mlir::success();
79 auto type = llvm::dyn_cast<component::StructType>(value.getType());
81 return mlir::success();
83 if (info.
family && mlir::failed(resolveFamily(type, info, site))) {
84 return mlir::failure();
87 return mlir::success();
90 if (mlir::failed(target)) {
91 return mlir::failure();
94 return constraintError(site,
"requires a concrete struct or matching poly.family element");
97 return mlir::success();
104 if (mlir::failed(resolved)) {
105 return mlir::failure();
107 auto parent = *resolved;
109 return constraintError(site,
"member read requires concrete non-column component storage");
111 auto member = parent.definition.getMemberDef(builder.getStringAttr(read.
getMemberName()));
112 if (!member || member.getColumn()) {
115 if (parent.definition != main && !member.hasPublicAttr()) {
116 return constraintError(site,
"run llzk-expose-child-members before reading child storage");
119 tables, llvm::cast<component::StructType>(read.
getComponent().getType()).getNameRef(), site
121 if (mlir::failed(rolled)) {
122 return mlir::failure();
124 if (!
typesUnify(read.getType(), member.getType())) {
125 return constraintError(site,
"member read type does not match the concrete specialization");
127 auto declared = rolled->get().getMemberDef(builder.getStringAttr(read.
getMemberName()));
128 if (rolled->get() != parent.definition &&
129 (!declared || !declared.hasPublicAttr() ||
130 !
typesUnify(read.getType(), declared.getType(), rolled->getNamespace()))) {
132 site,
"concrete family member cannot be represented through the rolled storage type"
137 info.
signal = bool(member.getSignal()) || (parent.definition == main && member.hasPublicAttr());
138 return mlir::success();
144 mlir::OpBuilder &outputBuilder, mlir::SymbolTableCollection &symbolTables,
147 : main(mainDefinition), builder(outputBuilder), tables(symbolTables), facts(scalarFacts),
148 specializations(rootModule) {}
153 mlir::FailureOr<StorageDescription>
describe(mlir::Value value, mlir::Operation *site) {
155 if (
auto argument = llvm::dyn_cast<mlir::BlockArgument>(value)) {
157 info.
signal = argument.getArgNumber() != 0;
159 if (mlir::failed(memberInfo(member, info, site))) {
160 return mlir::failure();
163 auto parent =
describe(element.getArrRef(), site);
164 if (mlir::failed(parent)) {
165 return mlir::failure();
170 for (mlir::Value index : element.getIndices()) {
171 auto coordinate = facts.integer(index);
173 return constraintError(site,
"array path requires compile-time indices");
175 info.
indices.push_back(*coordinate);
179 auto parent =
describe(record.getPodRef(), site);
180 if (mlir::failed(parent)) {
181 return mlir::failure();
185 if (llvm::isa<array::ArrayType>(value.getType())) {
190 if (mlir::failed(resolveComponent(value, info, site))) {
191 return mlir::failure();