17#include <mlir/IR/Operation.h>
26typeContainsSignals(Type type, SymbolTableCollection &tables, Operation *origin);
29static FailureOr<bool> structContainsSignals(
30 component::StructDefOp def, SymbolTableCollection &tables, Operation *origin
32 for (component::MemberDefOp member : def.getMemberDefs()) {
36 auto nested = typeContainsSignals(member.getType(), tables, origin);
49typeContainsSignals(Type type, SymbolTableCollection &tables, Operation *origin) {
50 if (
auto structType = dyn_cast<component::StructType>(type)) {
51 auto defLookup = structType.getDefinition(tables, origin);
52 if (failed(defLookup)) {
55 return structContainsSignals(defLookup->get(), tables, origin);
61static LogicalResult appendSignalLeafBindings(
62 Type type, ArrayRef<std::string> prefix, SmallVectorImpl<OutputBinding> &out, Operation *origin
64 if (isa<felt::FeltType, array::ArrayType>(type)) {
66 OutputBinding {llvm::SmallVector<std::string>(prefix.begin(), prefix.end()), type}
71 if (
auto podType = dyn_cast<pod::PodType>(type)) {
72 for (pod::RecordAttr record : podType.getRecords()) {
73 llvm::SmallVector<std::string> path(prefix.begin(), prefix.end());
74 path.push_back(record.getName().getValue().str());
75 if (failed(appendSignalLeafBindings(record.getType(), path, out, origin))) {
82 origin->emitError(
"signal members in llzk-witgen must be felts, felt arrays, or PODs of felts");
87static LogicalResult appendStructSignalBindings(
88 component::StructDefOp def, SymbolTableCollection &tables, Operation *origin,
89 SmallVectorImpl<OutputBinding> &out, ArrayRef<std::string> prefix = {}
91 for (component::MemberDefOp member : def.getMemberDefs()) {
92 llvm::SmallVector<std::string> path(prefix.begin(), prefix.end());
93 path.push_back(member.getSymName().str());
96 if (failed(appendSignalLeafBindings(member.getType(), path, out, origin))) {
102 auto nested = typeContainsSignals(member.getType(), tables, origin);
103 if (failed(nested)) {
110 auto structType = dyn_cast<component::StructType>(member.getType());
112 member.emitError(
"non-struct signal container is unsupported in llzk-witgen");
115 auto defLookup = structType.getDefinition(tables, origin);
116 if (failed(defLookup)) {
119 if (failed(appendStructSignalBindings(defLookup->get(), tables, origin, out, path))) {
128insertLeafJSON(llvm::json::Object &root, ArrayRef<std::string> path, llvm::json::Value value) {
132 if (path.size() == 1) {
133 root[path.front()] = std::move(value);
137 llvm::json::Value *slot = &root[path.front()];
138 if (!slot->getAsObject()) {
139 *slot = llvm::json::Object();
141 insertLeafJSON(*slot->getAsObject(), path.drop_front(), std::move(value));
153 llvm::SmallVector<InputBinding> bindings;
154 bindings.reserve(computeFunc.getNumArguments());
155 for (
unsigned i = 0; i < computeFunc.getNumArguments(); ++i) {
157 if (std::optional<StringAttr> argName = computeFunc.
getArgNameAttr(i)) {
158 name = argName->getValue().str();
160 name =
"arg" + std::to_string(i);
172 llvm::SmallVector<OutputBinding> bindings;
175 if (!member.hasPublicAttr()) {
178 bindings.push_back(
OutputBinding {{member.getSymName().str()}, member.getType()});
183 if (failed(appendStructSignalBindings(mainDef, tables, origin, bindings))) {
191 ArrayRef<OutputBinding> bindings, ArrayRef<llvm::json::Value> serializedLeaves
193 llvm::json::Object result;
194 for (
auto [binding, leaf] : llvm::zip(bindings, serializedLeaves)) {
195 insertLeafJSON(result, binding.path, llvm::json::Value(leaf));
197 return llvm::json::Value(std::move(result));
::std::vector< MemberDefOp > getMemberDefs()
Get all MemberDefOp in this structure.
bool isMainComponent()
Return true iff this struct.def is the main struct. See llzk::MAIN_ATTR_NAME.
::llvm::ArrayRef<::mlir::Type > getArgumentTypes()
Required by FunctionOpInterface.
::std::optional<::mlir::StringAttr > getArgNameAttr(unsigned index)
Return the function.arg_name attribute for the argument at the given index.
llvm::SmallVector< InputBinding > collectInputBindings(function::FuncDefOp computeFunc)
Collect stable JSON bindings for the main compute inputs.
OutputScope
Select the JSON scope emitted by llzk-witgen.
FailureOr< llvm::SmallVector< OutputBinding > > collectOutputBindings(component::StructDefOp mainDef, SymbolTableCollection &tables, Operation *origin, OutputScope scope)
Collect the selected output bindings for the requested scope.
llvm::json::Value buildSignalsJSONObject(ArrayRef< OutputBinding > bindings, ArrayRef< llvm::json::Value > serializedLeaves)
Assemble a nested JSON object from selected witness leaves.
bool memberIsSignal(component::StructDefOp owner, component::MemberDefOp member)
Return true iff the member is considered a witness signal.
Describe one selected witness output leaf.