LLZK
3.0.0
An open-source IR for Zero Knowledge (ZK) circuits
Toggle main menu visibility
Loading...
Searching...
No Matches
LowerBoolQuantifiersPass.cpp
Go to the documentation of this file.
1
//===-- LowerBoolQuantifiersPass.cpp ---------------------------*- 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
//===----------------------------------------------------------------------===//
13
//===----------------------------------------------------------------------===//
14
15
#include "
llzk/Dialect/Array/IR/Ops.h
"
16
#include "
llzk/Dialect/Array/IR/Types.h
"
17
#include "
llzk/Dialect/Bool/IR/Ops.h
"
18
#include "
llzk/Dialect/Bool/IR/Utils.h
"
19
#include "
llzk/Dialect/Bool/Transforms/TransformationPasses.h
"
20
#include "
llzk/Transforms/ConversionUtils.h
"
21
22
#include <mlir/Dialect/Arith/IR/Arith.h>
23
#include <mlir/Dialect/SCF/IR/SCF.h>
24
#include <mlir/IR/IRMapping.h>
25
#include <mlir/Transforms/GreedyPatternRewriteDriver.h>
26
27
// Include the generated base pass class definitions.
28
namespace
llzk::boolean
{
29
#define GEN_PASS_DEF_LOWERBOOLQUANTIFIERSPASS
30
#include "
llzk/Dialect/Bool/Transforms/TransformationPasses.h.inc
"
31
}
// namespace llzk::boolean
32
33
using namespace
mlir
;
34
using namespace
llzk
;
35
using namespace
llzk::array
;
36
using namespace
llzk::boolean
;
37
38
namespace
{
39
40
41
static
Value buildQuantifierIterValue(
42
Location loc, Value sort,
ArrayType
sortType, Value index, PatternRewriter &rewriter
43
) {
44
if
(sortType.
getDimensionSizes
().size() == 1) {
45
return
ReadArrayOp::create
(rewriter, loc, sort, ValueRange {index});
46
}
47
48
Type iterType =
getQuantifierOpDomainIterType
(sortType);
49
return
ExtractArrayOp::create
(rewriter, loc, iterType, sort, ValueRange {index});
50
}
51
53
template
<
typename
QuantifierOp,
typename
CombineOp>
54
static
LogicalResult
55
lowerQuantifier(QuantifierOp op, PatternRewriter &rewriter,
bool
initialValue) {
56
PatternRewriter::InsertionGuard guard(rewriter);
57
Location loc = op.getLoc();
58
auto
sortType =
cast<ArrayType>
(op.getSort().getType());
59
60
Value lowerBound = arith::ConstantIndexOp::create(rewriter, loc, 0);
61
Value upperBound =
ArrayLengthOp::create
(rewriter, loc, op.getSort(), lowerBound);
62
Value step = arith::ConstantIndexOp::create(rewriter, loc, 1);
63
Value init = arith::ConstantIntOp::create(rewriter, loc, rewriter.getI1Type(), initialValue);
64
65
auto
loop = scf::ForOp::create(rewriter, loc, lowerBound, upperBound, step, ValueRange {init});
66
preserveDiscardableAttrs
(op, loop);
67
68
Block &loopBody = *loop.getBody();
69
if
(!loopBody.empty()) {
70
rewriter.eraseOp(&loopBody.back());
71
}
72
73
rewriter.setInsertionPointToStart(&loopBody);
74
Value iterValue =
75
buildQuantifierIterValue(loc, op.getSort(), sortType, loop.getInductionVar(), rewriter);
76
77
IRMapping mapping;
78
mapping.map(op.getBody()->getArgument(0), iterValue);
79
for
(Operation &nestedOp : op.getBody()->without_terminator()) {
80
rewriter.clone(nestedOp, mapping);
81
}
82
83
auto
yieldOp =
cast<YieldOp>
(op.getBody()->getTerminator());
84
Value predicate = mapping.lookupOrDefault(yieldOp.getValue());
85
Value combined = CombineOp::create(rewriter, loc, loop.getRegionIterArg(0), predicate);
86
scf::YieldOp::create(rewriter, loc, combined);
87
88
rewriter.replaceOp(op, loop.getResults());
89
return
success();
90
}
91
92
class
LowerForAllOp :
public
OpRewritePattern<ForAllOp> {
93
public
:
94
using
OpRewritePattern<
ForAllOp
>::OpRewritePattern;
95
96
LogicalResult matchAndRewrite(
ForAllOp
op, PatternRewriter &rewriter)
const override
{
97
return
lowerQuantifier<ForAllOp, AndBoolOp>(op, rewriter,
/*initialValue=*/
true
);
98
}
99
};
100
101
class
LowerExistsOp :
public
OpRewritePattern<ExistsOp> {
102
public
:
103
using
OpRewritePattern<
ExistsOp
>::OpRewritePattern;
104
105
LogicalResult matchAndRewrite(
ExistsOp
op, PatternRewriter &rewriter)
const override
{
106
return
lowerQuantifier<ExistsOp, OrBoolOp>(op, rewriter,
/*initialValue=*/
false
);
107
}
108
};
109
110
class
PassImpl :
public
llzk::boolean::impl::LowerBoolQuantifiersPassBase
<PassImpl> {
111
using
Base = LowerBoolQuantifiersPassBase<PassImpl>;
112
113
public
:
114
using
Base::Base;
115
116
void
runOnOperation()
override
{
117
RewritePatternSet patterns(&getContext());
118
patterns.add<LowerForAllOp, LowerExistsOp>(&getContext());
119
120
if
(failed(applyPatternsGreedily(getOperation(), std::move(patterns)))) {
121
signalPassFailure();
122
}
123
}
124
};
125
126
}
// namespace
Ops.h
Types.h
Ops.h
TransformationPasses.h.inc
TransformationPasses.h
ConversionUtils.h
Utils.h
llzk::array::ArrayLengthOp::create
static ArrayLengthOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Type length, ::mlir::Value arr_ref, ::mlir::Value dim)
Definition
Ops.cpp.inc:155
llzk::array::ArrayType
Definition
Types.h.inc:48
llzk::array::ArrayType::getDimensionSizes
::llvm::ArrayRef<::mlir::Attribute > getDimensionSizes() const
Definition
Types.cpp.inc:205
llzk::array::ExtractArrayOp::create
static ExtractArrayOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Type result, ::mlir::Value arr_ref, ::mlir::ValueRange indices)
Definition
Ops.cpp.inc:1050
llzk::array::ReadArrayOp::create
static ReadArrayOp create(::mlir::OpBuilder &builder, ::mlir::Location location, ::mlir::Type result, ::mlir::Value arr_ref, ::mlir::ValueRange indices)
Definition
Ops.cpp.inc:1758
llzk::boolean::ExistsOp
Definition
Ops.h.inc:253
llzk::boolean::ForAllOp
Definition
Ops.h.inc:442
llzk::boolean::impl::LowerBoolQuantifiersPassBase
Definition
LowerBoolQuantifiersPass.cpp:25
llzk::array
Definition
Ops.cpp:43
llzk::boolean
Definition
Ops.cpp:30
llzk::boolean::getQuantifierOpDomainIterType
mlir::Type getQuantifierOpDomainIterType(llzk::array::ArrayType arr)
Extracts the type used for a quantifier op block argument.
Definition
Utils.h:20
llzk::cast
Definition
Ops.cpp:71
llzk
Definition
AnalysisPassEnums.cpp:19
llzk::preserveDiscardableAttrs
OpTy preserveDiscardableAttrs(mlir::Operation *src, OpTy dst)
Copy discardable attributes from src to dst.
Definition
ConversionUtils.h:49
mlir
Definition
CommonCAPIGen.h:50
lib
Dialect
Bool
Transforms
LowerBoolQuantifiersPass.cpp
Generated by
1.17.0
Copyright 2025 Veridise Inc. under the Apache License v2.0. Copyright 2026 Project LLZK under the Apache License v2.0.