CIRCT  20.0.0git
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 
16 #include "circt/Dialect/HW/HWOps.h"
17 #include "mlir/Transforms/GreedyPatternRewriteDriver.h"
18 
19 #define DEBUG_TYPE "aig-lower-variadic"
20 
21 namespace circt {
22 namespace aig {
23 #define GEN_PASS_DEF_LOWERVARIADIC
24 #include "circt/Dialect/AIG/AIGPasses.h.inc"
25 } // namespace aig
26 } // namespace circt
27 
28 using namespace circt;
29 using namespace aig;
30 
31 //===----------------------------------------------------------------------===//
32 // Rewrite patterns
33 //===----------------------------------------------------------------------===//
34 
35 namespace {
36 static 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 
65 struct VariadicOpConversion : OpRewritePattern<aig::AndInverterOp> {
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 
84 static void populateLowerVariadicPatterns(RewritePatternSet &patterns) {
85  patterns.add<VariadicOpConversion>(patterns.getContext());
86 }
87 
88 //===----------------------------------------------------------------------===//
89 // Lower Variadic pass
90 //===----------------------------------------------------------------------===//
91 
92 namespace {
93 struct LowerVariadicPass : public impl::LowerVariadicBase<LowerVariadicPass> {
94  void runOnOperation() override;
95 };
96 } // namespace
97 
98 void LowerVariadicPass::runOnOperation() {
99  RewritePatternSet patterns(&getContext());
101  mlir::FrozenRewritePatternSet frozen(std::move(patterns));
102 
103  if (failed(mlir::applyPatternsAndFoldGreedily(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.
Definition: DebugAnalysis.h:21