11 #include "mlir/IR/ImplicitLocOpBuilder.h"
12 #include "mlir/IR/Threading.h"
13 #include "mlir/Pass/Pass.h"
17 #define GEN_PASS_DEF_SPECIALIZEOPTION
18 #include "circt/Dialect/FIRRTL/Passes.h.inc"
23 using namespace circt;
24 using namespace firrtl;
27 struct SpecializeOptionPass
28 :
public circt::firrtl::impl::SpecializeOptionBase<SpecializeOptionPass> {
29 using SpecializeOptionBase::numInstances;
30 using SpecializeOptionBase::select;
32 void runOnOperation()
override {
33 auto circuit = getOperation();
35 markAllAnalysesPreserved();
39 DenseMap<StringAttr, OptionCaseOp> selected;
40 for (
const auto &optionAndCase : select) {
41 size_t eq = optionAndCase.find(
"=");
42 if (eq == std::string::npos) {
43 mlir::emitError(circuit.getLoc(),
44 "invalid option format: \"" + optionAndCase +
'"');
45 return signalPassFailure();
48 std::string optionName = optionAndCase.substr(0, eq);
49 auto optionOp = circuit.lookupSymbol<OptionOp>(optionName);
51 mlir::emitWarning(circuit.getLoc(),
"unknown option \"")
56 std::string caseName = optionAndCase.substr(eq + 1);
57 auto caseOp = optionOp.lookupSymbol<OptionCaseOp>(caseName);
59 mlir::emitWarning(circuit.getLoc(),
"invalid option case \"")
67 mlir::parallelForEach(
68 &getContext(), circuit.getOps<FModuleOp>(), [&](
auto module) {
69 module.walk([&](firrtl::InstanceChoiceOp inst) {
70 auto it = selected.find(inst.getOptionNameAttr());
71 if (it == selected.end()) {
72 inst.emitError(
"missing specialization for option ")
73 << inst.getOptionNameAttr();
78 ImplicitLocOpBuilder builder(inst.getLoc(), inst);
79 auto newInst = builder.create<InstanceOp>(
80 inst->getResultTypes(), inst.getTargetOrDefaultAttr(it->second),
81 inst.getNameAttr(), inst.getNameKindAttr(),
82 inst.getPortDirectionsAttr(), inst.getPortNamesAttr(),
83 inst.getAnnotationsAttr(), inst.getPortAnnotationsAttr(),
84 builder.getArrayAttr({}), UnitAttr{}, inst.getInnerSymAttr());
85 inst.replaceAllUsesWith(newInst);
99 return std::make_unique<SpecializeOptionPass>();
Direction get(bool isOutput)
Returns an output direction if isOutput is true, otherwise returns an input direction.
std::unique_ptr< mlir::Pass > createSpecializeOptionPass()
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.