LLZK 3.0.0
An open-source IR for Zero Knowledge (ZK) circuits
Loading...
Searching...
No Matches
SharedImpl.h
Go to the documentation of this file.
1//===-- SharedImpl.h --------------------------------------------*- 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//===----------------------------------------------------------------------===//
13//===----------------------------------------------------------------------===//
14
15#pragma once
16
28
29#include <mlir/Dialect/Arith/IR/Arith.h>
30#include <mlir/Dialect/SCF/IR/SCF.h>
31#include <mlir/Dialect/SCF/Transforms/Patterns.h>
32#include <mlir/IR/Attributes.h>
33#include <mlir/IR/BuiltinAttributes.h>
34#include <mlir/IR/MLIRContext.h>
35#include <mlir/IR/Operation.h>
36#include <mlir/IR/PatternMatch.h>
37#include <mlir/IR/SymbolTable.h>
38#include <mlir/Transforms/DialectConversion.h>
39
40#include <llvm/ADT/DenseMap.h>
41#include <llvm/ADT/DenseSet.h>
42#include <llvm/ADT/STLExtras.h>
43#include <llvm/ADT/SmallVector.h>
44#include <llvm/Support/Debug.h>
45
46#define DEBUG_TYPE "poly-dialect-shared"
47
49
50namespace {
51
52// Default to true if the check is not for that particular operation type.
53template <typename Check> inline bool runCheck(mlir::Operation *op, Check check) {
54 if (auto specificOp =
55 llvm::dyn_cast_if_present<typename llvm::function_traits<Check>::template arg_t<0>>(op)) {
56 return check(specificOp);
57 }
58 return true;
59}
60
61} // namespace
62
64mlir::ConversionTarget newBaseTarget(mlir::MLIRContext *ctx);
65
68public:
69 mlir::SymbolTableCollection tables;
70
72 mlir::ModuleOp root, const SymbolDefTree &symDefTree, const SymbolUseGraph &symUseGraph
73 );
74
75protected:
76 mlir::ModuleOp rootMod;
79};
80
82bool isErasableDefinition(mlir::Operation *op);
83
86class FromEraseSet : public CleanupBase {
87public:
90 mlir::ModuleOp root, const SymbolDefTree &symDefTree, const SymbolUseGraph &symUseGraph,
91 llvm::DenseSet<mlir::SymbolRefAttr> &&tryToErasePaths
92 );
93
94 mlir::LogicalResult eraseUnusedDefinitions();
95
96 const llvm::DenseSet<mlir::SymbolOpInterface> &getTryToEraseSet() const { return tryToErase; }
97
98private:
100 llvm::DenseSet<mlir::SymbolOpInterface> tryToErase;
102 llvm::DenseMap<mlir::SymbolOpInterface, bool> visitedPlusSafetyResult;
104 llvm::DenseMap<const SymbolUseGraphNode *, mlir::SymbolOpInterface> lookupCache;
105
106 bool collectSafeToErase(mlir::SymbolOpInterface check);
107 bool collectSafeToErase(const SymbolDefTreeNode *check);
108 bool collectSafeToErase(const SymbolUseGraphNode *check);
109 mlir::SymbolOpInterface cachedLookup(const SymbolUseGraphNode *node);
110};
111
118
121getStructTypeWithParams(mlir::SymbolRefAttr nameRef, mlir::ArrayAttr params) {
122 return params && !params.empty() ? component::StructType::get(nameRef, params)
124}
125
128 mlir::SymbolRefAttr nameRef, mlir::MLIRContext *ctx, mlir::ArrayRef<mlir::Attribute> params
129) {
130 return params.empty() ? component::StructType::get(nameRef)
131 : component::StructType::get(nameRef, mlir::ArrayAttr::get(ctx, params));
132}
133
137 mlir::SmallVector<mlir::Attribute> remainingNames;
139 mlir::ArrayAttr concreteParamKey;
141 mlir::ArrayAttr rewrittenCallParams;
143 mlir::ArrayAttr namePattern;
144};
145
149mlir::FailureOr<InstantiationLayout> buildInstantiationLayout(
150 TemplateOp parentTemplate, mlir::ArrayAttr callParams,
151 const llvm::DenseMap<mlir::Attribute, mlir::Attribute> &paramNameToConcrete
152);
153
156void setInstantiationNamePattern(TemplateOp templateOp, mlir::ArrayAttr namePattern);
157
160 llvm::StringRef baseName, llvm::ArrayRef<mlir::Attribute> concreteAttrs
161);
162
164public:
165 virtual ~LegalityCheckCallback() = default;
166 virtual void checkStarted() = 0;
167 virtual void checkEnded(bool outcome) = 0;
168};
169
171public:
172 void checkStarted() override {}
173 void checkEnded(bool) override {}
174};
175
182template <typename... AdditionalOpClasses, typename... AdditionalChecks>
183mlir::ConversionTarget newConverterDefinedTarget(
184 mlir::TypeConverter &tyConv, mlir::MLIRContext *ctx, AdditionalChecks &&...checks
185) {
186 static EmptyLegalityCheckCallback empty;
187 return newConverterDefinedTargetWithCallback<AdditionalOpClasses...>(
188 tyConv, ctx, empty, (std::forward<AdditionalChecks>(checks))...
189 );
190}
191
198template <typename... AdditionalOpClasses, typename... AdditionalChecks>
200 mlir::TypeConverter &tyConv, mlir::MLIRContext *ctx, LegalityCheckCallback &cb,
201 AdditionalChecks &&...checks
202) {
203 mlir::ConversionTarget target = newBaseTarget(ctx);
204 auto inserter = [&](auto... opClasses) {
205 target.addDynamicallyLegalOp<decltype(opClasses)...>([&cb, &tyConv,
206 &checks...](mlir::Operation *op) {
207 LLVM_DEBUG(if (op) {
208 llvm::dbgs() << "[newConverterDefinedTarget] checking legality of ";
209 op->dump();
210 });
211 cb.checkStarted();
212 auto legality =
213 defaultLegalityCheck(tyConv, op) && (runCheck<AdditionalChecks>(op, checks) && ...);
214
215 cb.checkEnded(legality);
216 LLVM_DEBUG(if (legality) { llvm::dbgs() << "[newConverterDefinedTarget] is legal\n"; } else {
217 llvm::dbgs() << "[newConverterDefinedTarget] is not legal\n";
218 });
219 return legality;
220 });
221 };
222 std::apply(inserter, OpClassesWithStructTypes.NoGeneralBuilder);
223 std::apply(inserter, OpClassesWithStructTypes.WithGeneralBuilder);
224 applyToMoreTypes<decltype(inserter), AdditionalOpClasses...>(inserter);
225 return target;
226}
227
228} // namespace llzk::polymorphic::detail
229
230#undef DEBUG_TYPE
#define check(x)
Definition Ops.cpp:286
Reusable MLIR dialect conversion functions for LLZK StructType replacement.
Builds a tree structure representing the symbol table structure.
Builds a graph structure representing the relationships between symbols and their uses.
static StructType get(::mlir::SymbolRefAttr structName)
Definition Types.cpp.inc:79
const SymbolUseGraph & useGraph
Definition SharedImpl.h:78
mlir::SymbolTableCollection tables
Definition SharedImpl.h:69
CleanupBase(mlir::ModuleOp root, const SymbolDefTree &symDefTree, const SymbolUseGraph &symUseGraph)
mlir::LogicalResult eraseUnusedDefinitions()
const llvm::DenseSet< mlir::SymbolOpInterface > & getTryToEraseSet() const
Definition SharedImpl.h:96
FromEraseSet(mlir::ModuleOp root, const SymbolDefTree &symDefTree, const SymbolUseGraph &symUseGraph, llvm::DenseSet< mlir::SymbolRefAttr > &&tryToErasePaths)
Note: paths in tryToErase should be relative to root.
component::StructType getStructTypeWithParams(mlir::SymbolRefAttr nameRef, mlir::ArrayAttr params)
Build a struct type while representing an empty parameter list as absent.
Definition SharedImpl.h:121
mlir::ConversionTarget newConverterDefinedTargetWithCallback(mlir::TypeConverter &tyConv, mlir::MLIRContext *ctx, LegalityCheckCallback &cb, AdditionalChecks &&...checks)
Return a new ConversionTarget allowing all LLZK-required dialects and defining Op legality based on t...
Definition SharedImpl.h:199
mlir::ConversionTarget newConverterDefinedTarget(mlir::TypeConverter &tyConv, mlir::MLIRContext *ctx, AdditionalChecks &&...checks)
Return a new ConversionTarget allowing all LLZK-required dialects and defining Op legality based on t...
Definition SharedImpl.h:183
FailureOr< InstantiationLayout > buildInstantiationLayout(TemplateOp parentTemplate, ArrayAttr callParams, const DenseMap< Attribute, Attribute > &paramNameToConcrete)
array::ArrayType flattenInstantiatedArrayType(array::ArrayType inputTy, mlir::Type convertedElemTy)
Merge nested array dimensions produced by replacing an array element type.
void setInstantiationNamePattern(TemplateOp templateOp, ArrayAttr namePattern)
std::string buildOpaqueInstantiationName(StringRef baseName, ArrayRef< Attribute > concreteAttrs)
bool isErasableDefinition(mlir::Operation *op)
Return true iff op is a cleanup candidate.
mlir::ConversionTarget newBaseTarget(mlir::MLIRContext *ctx)
Return a new ConversionTarget allowing all LLZK-required dialects.
bool defaultLegalityCheck(const mlir::TypeConverter &tyConv, mlir::Operation *op)
Check whether an op is legal with respect to the given type converter, including TypeAttr attributes ...
Groups the information needed after concrete parameters have been chosen to decide how to name a new ...
Definition SharedImpl.h:136
mlir::ArrayAttr namePattern
The refined literal chunks; fully concrete generated templates clear this state.
Definition SharedImpl.h:143
mlir::SmallVector< mlir::Attribute > remainingNames
Definition SharedImpl.h:137
mlir::ArrayAttr concreteParamKey
Ordered [parameter-name, concrete-value, ...] entries for exact partial-function reuse.
Definition SharedImpl.h:139