CIRCT 20.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 "aig-lower-variadic"
20
21namespace circt {
22namespace aig {
23#define GEN_PASS_DEF_LOWERVARIADIC
24#include "circt/Dialect/AIG/AIGPasses.h.inc"
25} // namespace aig
26} // namespace circt
27
28using namespace circt;
29using namespace aig;
30
31//===----------------------------------------------------------------------===//
32// Rewrite patterns
33//===----------------------------------------------------------------------===//
34
35namespace {
36static Value lowerVariadicAndInverterOp(AndInverterOp op, OperandRange operands,
37 ArrayRef<bool> inverts,
38 PatternRewriter &rewriter) {
39 switch (operands.size()) {
40 case 0:
41 assert(0 && "cannot be called with empty operand range");
42 break;
43 case 1:
44 if (inverts[0])
45 return rewriter.create<AndInverterOp>(op.getLoc(), operands[0], true);
46 else
47 return operands[0];
48 case 2:
49 return rewriter.create<AndInverterOp>(op.getLoc(), operands[0], operands[1],
50 inverts[0], inverts[1]);
51 default:
52 auto firstHalf = operands.size() / 2;
53 auto lhs =
54 lowerVariadicAndInverterOp(op, operands.take_front(firstHalf),
55 inverts.take_front(firstHalf), rewriter);
56 auto rhs =
57 lowerVariadicAndInverterOp(op, operands.drop_front(firstHalf),
58 inverts.drop_front(firstHalf), rewriter);
59 return rewriter.create<AndInverterOp>(op.getLoc(), lhs, rhs);
60 }
61
62 return Value();
63}
64
65struct VariadicOpConversion : OpRewritePattern<aig::AndInverterOp> {
66 using OpRewritePattern<aig::AndInverterOp>::OpRewritePattern;
67 LogicalResult matchAndRewrite(AndInverterOp op,
68 PatternRewriter &rewriter) const override {
69 if (op.getInputs().size() <= 2)
70 return failure();
71
72 // TODO: This is a naive implementation that creates a balanced binary tree.
73 // We can improve by analyzing the dataflow and creating a tree that
74 // improves the critical path or area.
75 rewriter.replaceOp(op,
76 lowerVariadicAndInverterOp(op, op.getOperands(),
77 op.getInverted(), rewriter));
78 return success();
79 }
80};
81
82} // namespace
83
84static void populateLowerVariadicPatterns(RewritePatternSet &patterns) {
85 patterns.add<VariadicOpConversion>(patterns.getContext());
86}
87
88//===----------------------------------------------------------------------===//
89// Lower Variadic pass
90//===----------------------------------------------------------------------===//
91
92namespace {
93struct LowerVariadicPass : public impl::LowerVariadicBase<LowerVariadicPass> {
94 void runOnOperation() override;
95};
96} // namespace
97
98void LowerVariadicPass::runOnOperation() {
99 RewritePatternSet patterns(&getContext());
101 mlir::FrozenRewritePatternSet frozen(std::move(patterns));
102
103 if (failed(mlir::applyPatternsGreedily(getOperation(), frozen)))
104 return signalPassFailure();
105}
assert(baseType &&"element must be base type")
static void populateLowerVariadicPatterns(RewritePatternSet &patterns)
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.