CIRCT 22.0.0git
Loading...
Searching...
No Matches
LowerVariadic.cpp
Go to the documentation of this file.
1//===- LowerVariadic.cpp - Lowering Variadic to Binary Ops ------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass lowers variadic AndInverter operations to binary AndInverter
10// operations.
11//
12//===----------------------------------------------------------------------===//
13
17#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
18
19#define DEBUG_TYPE "synth-lower-variadic"
20
21namespace circt {
22namespace synth {
23#define GEN_PASS_DEF_LOWERVARIADIC
24#include "circt/Dialect/Synth/Transforms/SynthPasses.h.inc"
25} // namespace synth
26} // namespace circt
27
28using namespace circt;
29using namespace synth;
30
31//===----------------------------------------------------------------------===//
32// Rewrite patterns
33//===----------------------------------------------------------------------===//
34
35namespace {
36static Value lowerVariadicAndInverterOp(aig::AndInverterOp op,
37 OperandRange operands,
38 ArrayRef<bool> inverts,
39 PatternRewriter &rewriter) {
40 switch (operands.size()) {
41 case 0:
42 assert(0 && "cannot be called with empty operand range");
43 break;
44 case 1:
45 if (inverts[0])
46 return aig::AndInverterOp::create(rewriter, op.getLoc(), operands[0],
47 true);
48 else
49 return operands[0];
50 case 2:
51 return aig::AndInverterOp::create(rewriter, op.getLoc(), operands[0],
52 operands[1], inverts[0], inverts[1]);
53 default:
54 auto firstHalf = operands.size() / 2;
55 auto lhs =
56 lowerVariadicAndInverterOp(op, operands.take_front(firstHalf),
57 inverts.take_front(firstHalf), rewriter);
58 auto rhs =
59 lowerVariadicAndInverterOp(op, operands.drop_front(firstHalf),
60 inverts.drop_front(firstHalf), rewriter);
61 return aig::AndInverterOp::create(rewriter, op.getLoc(), lhs, rhs);
62 }
63
64 return Value();
65}
66
67struct VariadicOpConversion : OpRewritePattern<aig::AndInverterOp> {
68 using OpRewritePattern<aig::AndInverterOp>::OpRewritePattern;
69 LogicalResult matchAndRewrite(aig::AndInverterOp op,
70 PatternRewriter &rewriter) const override {
71 if (op.getInputs().size() <= 2)
72 return failure();
73
74 // TODO: This is a naive implementation that creates a balanced binary tree.
75 // We can improve by analyzing the dataflow and creating a tree that
76 // improves the critical path or area.
77 rewriter.replaceOp(op,
78 lowerVariadicAndInverterOp(op, op.getOperands(),
79 op.getInverted(), rewriter));
80 return success();
81 }
82};
83
84} // namespace
85
86static void populateLowerVariadicPatterns(RewritePatternSet &patterns) {
87 patterns.add<VariadicOpConversion>(patterns.getContext());
88}
89
90//===----------------------------------------------------------------------===//
91// Lower Variadic pass
92//===----------------------------------------------------------------------===//
93
94namespace {
95struct LowerVariadicPass : public impl::LowerVariadicBase<LowerVariadicPass> {
96 void runOnOperation() override;
97};
98} // namespace
99
100void LowerVariadicPass::runOnOperation() {
101 RewritePatternSet patterns(&getContext());
103 mlir::FrozenRewritePatternSet frozen(std::move(patterns));
104
105 if (failed(mlir::applyPatternsGreedily(getOperation(), frozen)))
106 return signalPassFailure();
107}
assert(baseType &&"element must be base type")
static void populateLowerVariadicPatterns(RewritePatternSet &patterns)
static Value lowerVariadicAndInverterOp(AndInverterOp op, OperandRange operands, ArrayRef< bool > inverts, PatternRewriter &rewriter)
Definition SynthOps.cpp:265
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
Definition synth.py:1