28#define GEN_PASS_DEF_LOWERBOOLQUANTIFIERSPASS
40static Value buildQuantifierIterValue(
41 Location loc, Value sort,
ArrayType sortType, Value index, PatternRewriter &rewriter
44 return rewriter.create<
ReadArrayOp>(loc, sort, ValueRange {index});
48 return rewriter.create<
ExtractArrayOp>(loc, iterType, sort, ValueRange {index});
52template <
typename QuantifierOp,
typename CombineOp>
54lowerQuantifier(QuantifierOp op, PatternRewriter &rewriter,
bool initialValue) {
55 PatternRewriter::InsertionGuard guard(rewriter);
56 Location loc = op.getLoc();
59 Value lowerBound = rewriter.create<arith::ConstantIndexOp>(loc, 0);
60 Value upperBound = rewriter.create<
ArrayLengthOp>(loc, op.getSort(), lowerBound);
61 Value step = rewriter.create<arith::ConstantIndexOp>(loc, 1);
62 Value init = rewriter.create<arith::ConstantIntOp>(loc, initialValue, rewriter.getI1Type());
64 auto loop = rewriter.create<scf::ForOp>(loc, lowerBound, upperBound, step, ValueRange {init});
65 loop->setDiscardableAttrs(op->getDiscardableAttrDictionary());
67 Block &loopBody = *loop.getBody();
68 if (!loopBody.empty()) {
69 rewriter.eraseOp(&loopBody.back());
72 rewriter.setInsertionPointToStart(&loopBody);
74 buildQuantifierIterValue(loc, op.getSort(), sortType, loop.getInductionVar(), rewriter);
77 mapping.map(op.getBody()->getArgument(0), iterValue);
78 for (Operation &nestedOp : op.getBody()->without_terminator()) {
79 rewriter.clone(nestedOp, mapping);
83 Value predicate = mapping.lookupOrDefault(yieldOp.getValue());
84 Value combined = rewriter.create<CombineOp>(loc, loop.getRegionIterArg(0), predicate);
85 rewriter.create<scf::YieldOp>(loc, combined);
87 rewriter.replaceOp(op, loop.getResults());
96 return lowerQuantifier<ForAllOp, AndBoolOp>(op, rewriter,
true);
105 return lowerQuantifier<ExistsOp, OrBoolOp>(op, rewriter,
false);