CIRCT  18.0.0git
LogicExporter.cpp
Go to the documentation of this file.
1 //===- LogicExporter.cpp - class to extrapolate CIRCT IR logic --*- 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 file defines the logic-exporting class for the `circt-lec` tool.
10 ///
11 //===----------------------------------------------------------------------===//
12 
17 #include "llvm/ADT/TypeSwitch.h"
18 
19 #define DEBUG_TYPE "lec-exporter"
20 
21 using namespace circt;
22 using namespace mlir;
23 
24 namespace {
25 
26 /// This class provides logic-exporting functions for the implemented
27 /// operations, along with a dispatcher to visit the correct handler.
28 struct Visitor : public hw::StmtVisitor<Visitor, LogicalResult>,
29  public hw::TypeOpVisitor<Visitor, LogicalResult>,
30  public comb::CombinationalVisitor<Visitor, LogicalResult> {
31  using hw::StmtVisitor<Visitor, LogicalResult>::visitStmt;
32  using hw::TypeOpVisitor<Visitor, LogicalResult>::visitTypeOp;
33  using comb::CombinationalVisitor<Visitor, LogicalResult>::visitComb;
34  friend class hw::StmtVisitor<Visitor, LogicalResult>;
35  friend class hw::TypeOpVisitor<Visitor, LogicalResult>;
36  friend class comb::CombinationalVisitor<Visitor, LogicalResult>;
37 
38  Visitor(Solver::Circuit *circuit) : circuit(circuit) {}
39  Solver::Circuit *circuit;
40 
41  /// Handles `builtin.module` logic exporting.
42  LogicalResult visit(ModuleOp op, llvm::StringRef targetModule) {
43  for (auto hwModule : op.getOps<hw::HWModuleOp>()) {
44  if (targetModule.empty() || hwModule.getName() == targetModule) {
45  LLVM_DEBUG(llvm::dbgs()
46  << "Using module `" << hwModule.getName() << "`\n");
47  return visit(hwModule);
48  }
49  }
50  op.emitError("module not found");
51  return failure();
52  }
53 
54  /// Handles `hw.module` logic exporting.
55  LogicalResult visit(hw::HWModuleOp op) {
56  for (auto argument : op.getBodyBlock()->getArguments())
57  circuit->addInput(argument);
58  for (auto &op : op.getOps())
59  if (failed(dispatch(&op)))
60  return failure();
61  return success();
62  }
63 
64  LogicalResult visitUnhandledOp(Operation *op) {
65  op->emitOpError("not supported");
66  return failure();
67  }
68 
69  /// Dispatches an operation to the appropriate visit function.
70  LogicalResult dispatch(Operation *op) { return dispatchStmtVisitor(op); }
71 
72  //===--------------------------------------------------------------------===//
73  // hw::StmtVisitor
74  //===--------------------------------------------------------------------===//
75 
76  LogicalResult visitStmt(hw::InstanceOp op) {
77  if (auto hwModule =
78  llvm::dyn_cast<hw::HWModuleOp>(op.getReferencedModuleSlow())) {
79  circuit->addInstance(op.getInstanceName(), hwModule, op->getOperands(),
80  op->getResults());
81  return success();
82  }
83  op.emitError("instantiated module `" + op.getModuleName() +
84  "` is not an HW module");
85  return failure();
86  }
87 
88  LogicalResult visitStmt(hw::OutputOp op) {
89  for (auto operand : op.getOperands())
90  circuit->addOutput(operand);
91  return success();
92  }
93 
94  LogicalResult visitInvalidStmt(Operation *op) {
95  return dispatchTypeOpVisitor(op);
96  }
97  LogicalResult visitUnhandledStmt(Operation *op) {
98  return visitUnhandledOp(op);
99  }
100 
101  //===--------------------------------------------------------------------===//
102  // hw::TypeOpVisitor
103  //===--------------------------------------------------------------------===//
104 
105  LogicalResult visitTypeOp(hw::ConstantOp op) {
106  circuit->addConstant(op.getResult(), op.getValue());
107  return success();
108  }
109 
110  LogicalResult visitInvalidTypeOp(Operation *op) {
111  return dispatchCombinationalVisitor(op);
112  }
113  LogicalResult visitUnhandledTypeOp(Operation *op) {
114  return visitUnhandledOp(op);
115  }
116 
117  //===--------------------------------------------------------------------===//
118  // comb::CombinationalVisitor
119  //===--------------------------------------------------------------------===//
120 
121  // Visit a comb operation with a variadic number of operands.
122  template <typename OpTy, typename FnTy>
123  LogicalResult visitVariadicCombOp(OpTy op, FnTy fn) {
124  if (!op.getTwoState())
125  return op.emitOpError("without 'bin' unsupported");
126  (circuit->*fn)(op.getResult(), op.getOperands());
127  return success();
128  }
129 
130  // Visit a comb operation with two operands.
131  template <typename OpTy, typename FnTy>
132  LogicalResult visitBinaryCombOp(OpTy op, FnTy fn) {
133  if (!op.getTwoState())
134  return op.emitOpError("without 'bin' unsupported");
135  (circuit->*fn)(op.getResult(), op.getLhs(), op.getRhs());
136  return success();
137  }
138 
139  // Visit a comb operation with one operand.
140  template <typename OpTy, typename FnTy>
141  LogicalResult visitUnaryCombOp(OpTy op, FnTy fn) {
142  if (!op.getTwoState())
143  return op.emitOpError("without 'bin' unsupported");
144  (circuit->*fn)(op.getResult(), op.getInput());
145  return success();
146  }
147 
148  LogicalResult visitComb(comb::AddOp op) {
149  return visitVariadicCombOp(op, &Solver::Circuit::performAdd);
150  }
151  LogicalResult visitComb(comb::AndOp op) {
152  return visitVariadicCombOp(op, &Solver::Circuit::performAnd);
153  }
154  LogicalResult visitComb(comb::ConcatOp op) {
155  circuit->performConcat(op.getResult(), op.getOperands());
156  return success();
157  }
158  LogicalResult visitComb(comb::DivSOp op) {
159  return visitBinaryCombOp(op, &Solver::Circuit::performDivS);
160  }
161  LogicalResult visitComb(comb::DivUOp op) {
162  return visitBinaryCombOp(op, &Solver::Circuit::performDivU);
163  }
164  LogicalResult visitComb(comb::ExtractOp op) {
165  circuit->performExtract(op.getResult(), op.getInput(), op.getLowBit());
166  return success();
167  }
168  LogicalResult visitComb(comb::ICmpOp op) {
169  if (!op.getTwoState())
170  return op.emitOpError("without 'bin' unsupported");
171  return circuit->performICmp(op.getResult(), op.getPredicate(), op.getLhs(),
172  op.getRhs());
173  }
174  LogicalResult visitComb(comb::ModSOp op) {
175  return visitBinaryCombOp(op, &Solver::Circuit::performModS);
176  }
177  LogicalResult visitComb(comb::ModUOp op) {
178  return visitBinaryCombOp(op, &Solver::Circuit::performModU);
179  }
180  LogicalResult visitComb(comb::MulOp op) {
181  return visitVariadicCombOp(op, &Solver::Circuit::performMul);
182  }
183  LogicalResult visitComb(comb::MuxOp op) {
184  if (!op.getTwoState())
185  return op.emitOpError("without 'bin' unsupported");
186  circuit->performMux(op.getResult(), op.getCond(), op.getTrueValue(),
187  op.getFalseValue());
188  return success();
189  }
190  LogicalResult visitComb(comb::OrOp op) {
191  return visitVariadicCombOp(op, &Solver::Circuit::performOr);
192  }
193  LogicalResult visitComb(comb::ParityOp op) {
194  return visitUnaryCombOp(op, &Solver::Circuit::performParity);
195  }
196  LogicalResult visitComb(comb::ReplicateOp op) {
197  circuit->performReplicate(op.getResult(), op.getInput());
198  return success();
199  }
200  LogicalResult visitComb(comb::ShlOp op) {
201  return visitBinaryCombOp(op, &Solver::Circuit::performShl);
202  }
203  LogicalResult visitComb(comb::ShrSOp op) {
204  return visitBinaryCombOp(op, &Solver::Circuit::performShrS);
205  }
206  LogicalResult visitComb(comb::ShrUOp op) {
207  return visitBinaryCombOp(op, &Solver::Circuit::performShrU);
208  }
209  LogicalResult visitComb(comb::SubOp op) {
210  return visitVariadicCombOp(op, &Solver::Circuit::performSub);
211  }
212  LogicalResult visitComb(comb::XorOp op) {
213  return visitVariadicCombOp(op, &Solver::Circuit::performXor);
214  }
215 
216  LogicalResult visitUnhandledComb(Operation *op) {
217  return visitUnhandledOp(op);
218  }
219 };
220 } // namespace
221 
222 LogicalResult LogicExporter::run(ModuleOp &builtinModule) {
223  return Visitor(circuit).visit(builtinModule, moduleName);
224 }
225 
226 LogicalResult LogicExporter::run(hw::HWModuleOp &module) {
227  return Visitor(circuit).visit(module);
228 }
mlir::LogicalResult run(mlir::ModuleOp &module)
Initializes the exporting by visiting the builtin module.
The representation of a circuit within a logical engine.
Definition: Circuit.h:35
void performConcat(mlir::Value result, mlir::OperandRange operands)
Definition: Circuit.cpp:116
void performAdd(mlir::Value result, mlir::OperandRange operands)
Definition: Circuit.cpp:102
void performParity(mlir::Value result, mlir::Value input)
Definition: Circuit.cpp:264
void performShl(mlir::Value result, mlir::Value lhs, mlir::Value rhs)
Definition: Circuit.cpp:301
void addInstance(llvm::StringRef instanceName, circt::hw::HWModuleOp op, mlir::OperandRange arguments, mlir::ResultRange results)
Definition: Circuit.cpp:58
void performMux(mlir::Value result, mlir::Value cond, mlir::Value trueValue, mlir::Value falseValue)
Definition: Circuit.cpp:242
mlir::LogicalResult performICmp(mlir::Value result, circt::comb::ICmpPredicate predicate, mlir::Value lhs, mlir::Value rhs)
Definition: Circuit.cpp:157
void performOr(mlir::Value result, mlir::OperandRange operands)
Definition: Circuit.cpp:257
void performXor(mlir::Value result, mlir::OperandRange operands)
Definition: Circuit.cpp:343
void performShrS(mlir::Value result, mlir::Value lhs, mlir::Value rhs)
Definition: Circuit.cpp:313
void performMul(mlir::Value result, mlir::OperandRange operands)
Definition: Circuit.cpp:235
void performSub(mlir::Value result, mlir::OperandRange operands)
Definition: Circuit.cpp:336
void performDivU(mlir::Value result, mlir::Value lhs, mlir::Value rhs)
Definition: Circuit.cpp:134
void addConstant(mlir::Value result, const mlir::APInt &value)
Definition: Circuit.cpp:52
void performAnd(mlir::Value result, mlir::OperandRange operands)
Definition: Circuit.cpp:109
void addInput(mlir::Value)
Add an input to the circuit; internally a new value gets allocated.
Definition: Circuit.cpp:27
void performExtract(mlir::Value result, mlir::Value input, uint32_t lowBit)
Definition: Circuit.cpp:145
void performModS(mlir::Value result, mlir::Value lhs, mlir::Value rhs)
Definition: Circuit.cpp:213
void performReplicate(mlir::Value result, mlir::Value input)
Definition: Circuit.cpp:282
void performShrU(mlir::Value result, mlir::Value lhs, mlir::Value rhs)
Definition: Circuit.cpp:325
void performModU(mlir::Value result, mlir::Value lhs, mlir::Value rhs)
Definition: Circuit.cpp:224
void addOutput(mlir::Value)
Add an output to the circuit.
Definition: Circuit.cpp:35
void performDivS(mlir::Value result, mlir::Value lhs, mlir::Value rhs)
Definition: Circuit.cpp:123
This file defines an intermediate representation for circuits acting as an abstraction for constraint...
Definition: DebugAnalysis.h:21
mlir::raw_indented_ostream & dbgs()
Definition: Utility.h:28