10 #include "mlir/IR/ImplicitLocOpBuilder.h"
11 #include "mlir/IR/Threading.h"
14 using namespace circt;
15 using namespace firrtl;
18 struct SpecializeOptionPass
19 :
public SpecializeOptionBase<SpecializeOptionPass> {
20 using SpecializeOptionBase::numInstances;
21 using SpecializeOptionBase::select;
23 void runOnOperation()
override {
24 auto circuit = getOperation();
26 markAllAnalysesPreserved();
30 DenseMap<StringAttr, OptionCaseOp> selected;
31 for (
const auto &optionAndCase : select) {
32 size_t eq = optionAndCase.find(
"=");
33 if (eq == std::string::npos) {
34 mlir::emitError(circuit.getLoc(),
35 "invalid option format: \"" + optionAndCase +
'"');
36 return signalPassFailure();
39 std::string optionName = optionAndCase.substr(0, eq);
40 auto optionOp = circuit.lookupSymbol<OptionOp>(optionName);
42 mlir::emitWarning(circuit.getLoc(),
"unknown option \"")
47 std::string caseName = optionAndCase.substr(eq + 1);
48 auto caseOp = optionOp.lookupSymbol<OptionCaseOp>(caseName);
50 mlir::emitWarning(circuit.getLoc(),
"invalid option case \"")
58 mlir::parallelForEach(
59 &getContext(), circuit.getOps<FModuleOp>(), [&](
auto module) {
60 module.walk([&](firrtl::InstanceChoiceOp inst) {
61 auto it = selected.find(inst.getOptionNameAttr());
62 if (it == selected.end()) {
63 inst.emitError(
"missing specialization for option ")
64 << inst.getOptionNameAttr();
69 ImplicitLocOpBuilder builder(inst.getLoc(), inst);
70 auto newInst = builder.create<InstanceOp>(
71 inst->getResultTypes(), inst.getTargetOrDefaultAttr(it->second),
72 inst.getNameAttr(), inst.getNameKindAttr(),
73 inst.getPortDirectionsAttr(), inst.getPortNamesAttr(),
74 inst.getAnnotationsAttr(), inst.getPortAnnotationsAttr(),
75 builder.getArrayAttr({}), UnitAttr{}, inst.getInnerSymAttr());
76 inst.replaceAllUsesWith(newInst);
90 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.