From be732e05fede8cc996ca0e71a4ba76028373c0ca Mon Sep 17 00:00:00 2001 From: Andrew Lenharth Date: Thu, 29 Sep 2022 11:42:46 -0500 Subject: [PATCH] [NFC] Make prepareforemission an embedded pass run by the pass manager (#4015) --- include/circt/Conversion/ExportVerilog.h | 3 + include/circt/Conversion/Passes.td | 20 +++++++ .../ExportVerilog/ExportVerilog.cpp | 58 +++++++++++++------ .../ExportVerilog/PrepareForEmission.cpp | 15 ++++- lib/Conversion/PassDetail.h | 1 + 5 files changed, 79 insertions(+), 18 deletions(-) diff --git a/include/circt/Conversion/ExportVerilog.h b/include/circt/Conversion/ExportVerilog.h index 66ad927cf4..2403b1b722 100644 --- a/include/circt/Conversion/ExportVerilog.h +++ b/include/circt/Conversion/ExportVerilog.h @@ -13,12 +13,15 @@ #ifndef CIRCT_TRANSLATION_EXPORTVERILOG_H #define CIRCT_TRANSLATION_EXPORTVERILOG_H +#include "circt/Support/LoweringOptions.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/Pass/Pass.h" namespace circt { std::unique_ptr createTestPrepareForEmissionPass(); +std::unique_ptr +createPrepareForEmissionPass(LoweringOptions options = LoweringOptions()); std::unique_ptr createExportVerilogPass(llvm::raw_ostream &os); std::unique_ptr createExportVerilogPass(); diff --git a/include/circt/Conversion/Passes.td b/include/circt/Conversion/Passes.td index 211a389f36..5338cf7dcf 100644 --- a/include/circt/Conversion/Passes.td +++ b/include/circt/Conversion/Passes.td @@ -90,6 +90,26 @@ def TestPrepareForEmission : Pass<"test-prepare-for-emission", ]; } +def PrepareForEmission : Pass<"prepare-for-emission", + "hw::HWModuleOp"> { + let summary = "Prepare IR for ExportVerilog"; + let description = [{ + This pass runs only PrepareForEmission logic. + It is not necessary for users to run this pass explicitly since + ExportVerilog internally schedules PrepareForEmission. + }]; + + let constructor = "createPrepareForEmissionPass()"; + let dependentDialects = [ + "circt::sv::SVDialect", "circt::comb::CombDialect", "circt::hw::HWDialect" + ]; + let options = [ + Option<"options", "opts", "LoweringOptions", + "", "Lowering options"> + ]; + +} + def ExportVerilog : Pass<"export-verilog", "mlir::ModuleOp"> { let summary = "Emit the IR to a (System)Verilog file"; let description = [{ diff --git a/lib/Conversion/ExportVerilog/ExportVerilog.cpp b/lib/Conversion/ExportVerilog/ExportVerilog.cpp index 7e0e3fc10b..db2c920e30 100644 --- a/lib/Conversion/ExportVerilog/ExportVerilog.cpp +++ b/lib/Conversion/ExportVerilog/ExportVerilog.cpp @@ -34,6 +34,7 @@ #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/ImplicitLocOpBuilder.h" #include "mlir/IR/Threading.h" +#include "mlir/Pass/PassManager.h" #include "mlir/Support/FileUtilities.h" #include "llvm/ADT/MapVector.h" #include "llvm/ADT/STLExtras.h" @@ -4991,26 +4992,14 @@ void SharedEmitterState::emitOps(EmissionList &thingsToEmit, raw_ostream &os, } } -/// Prepare the given MLIR module for emission. -static void prepareForEmission(ModuleOp module, - const LoweringOptions &options) { - SmallVector modulesToPrepare; - module.walk([&](HWModuleOp op) { modulesToPrepare.push_back(op); }); - parallelForEach(module->getContext(), modulesToPrepare, - [&](auto op) { prepareHWModule(op, options); }); -} - //===----------------------------------------------------------------------===// // Unified Emitter //===----------------------------------------------------------------------===// -LogicalResult circt::exportVerilog(ModuleOp module, llvm::raw_ostream &os) { - // Prepare the ops in the module for emission and legalize the names that will - // end up in the output. - LoweringOptions options(module); - prepareForEmission(module, options); +static LogicalResult exportVerilogImpl(ModuleOp module, llvm::raw_ostream &os) { GlobalNameTable globalNames = legalizeGlobalNames(module); + LoweringOptions options(module); SharedEmitterState emitter(module, options, std::move(globalNames)); emitter.gatherFiles(false); @@ -5046,6 +5035,15 @@ LogicalResult circt::exportVerilog(ModuleOp module, llvm::raw_ostream &os) { return failure(emitter.encounteredError); } +LogicalResult circt::exportVerilog(ModuleOp module, llvm::raw_ostream &os) { + LoweringOptions options(module); + SmallVector modulesToPrepare; + module.walk([&](HWModuleOp op) { modulesToPrepare.push_back(op); }); + parallelForEach(module->getContext(), modulesToPrepare, + [&](auto op) { prepareHWModule(op, options); }); + return exportVerilogImpl(module, os); +} + namespace { struct ExportVerilogPass : public ExportVerilogBase { @@ -5056,7 +5054,15 @@ struct ExportVerilogPass : public ExportVerilogBase { // TODO: This should be moved up to circt-opt and circt-translate. applyLoweringCLOptions(getOperation()); - if (failed(exportVerilog(getOperation(), os))) + // Prepare the ops in the module for emission. + LoweringOptions options(getOperation()); + mlir::OpPassManager preparePM("builtin.module"); + auto &modulePM = preparePM.nest(); + modulePM.addPass(createPrepareForEmissionPass(options)); + if (failed(runPipeline(preparePM, getOperation()))) + signalPassFailure(); + + if (failed(exportVerilogImpl(getOperation(), os))) signalPassFailure(); } @@ -5124,11 +5130,11 @@ static void createSplitOutputFile(StringAttr fileName, FileInfo &file, output->keep(); } -LogicalResult circt::exportSplitVerilog(ModuleOp module, StringRef dirname) { +static LogicalResult exportSplitVerilogImpl(ModuleOp module, + StringRef dirname) { // Prepare the ops in the module for emission and legalize the names that will // end up in the output. LoweringOptions options(module); - prepareForEmission(module, options); GlobalNameTable globalNames = legalizeGlobalNames(module); SharedEmitterState emitter(module, options, std::move(globalNames)); @@ -5188,6 +5194,15 @@ LogicalResult circt::exportSplitVerilog(ModuleOp module, StringRef dirname) { return failure(emitter.encounteredError); } +LogicalResult circt::exportSplitVerilog(ModuleOp module, StringRef dirname) { + LoweringOptions options(module); + SmallVector modulesToPrepare; + module.walk([&](HWModuleOp op) { modulesToPrepare.push_back(op); }); + parallelForEach(module->getContext(), modulesToPrepare, + [&](auto op) { prepareHWModule(op, options); }); + return exportSplitVerilogImpl(module, dirname); +} + namespace { struct ExportSplitVerilogPass @@ -5200,6 +5215,15 @@ struct ExportSplitVerilogPass // on the command line. // TODO: This should be moved up to circt-opt and circt-translate. applyLoweringCLOptions(getOperation()); + + // Prepare the ops in the module for emission. + LoweringOptions options(getOperation()); + mlir::OpPassManager preparePM("builtin.module"); + auto &modulePM = preparePM.nest(); + modulePM.addPass(createPrepareForEmissionPass(options)); + if (failed(runPipeline(preparePM, getOperation()))) + signalPassFailure(); + if (failed(exportSplitVerilog(getOperation(), directoryName))) signalPassFailure(); } diff --git a/lib/Conversion/ExportVerilog/PrepareForEmission.cpp b/lib/Conversion/ExportVerilog/PrepareForEmission.cpp index da0dd03ef8..b0bdac7afa 100644 --- a/lib/Conversion/ExportVerilog/PrepareForEmission.cpp +++ b/lib/Conversion/ExportVerilog/PrepareForEmission.cpp @@ -21,7 +21,6 @@ #include "ExportVerilogInternals.h" #include "circt/Conversion/ExportVerilog.h" #include "circt/Dialect/Comb/CombOps.h" -#include "circt/Support/LoweringOptions.h" #include "mlir/IR/ImplicitLocOpBuilder.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallPtrSet.h" @@ -994,8 +993,22 @@ struct TestPrepareForEmissionPass prepareHWModule(module, options); } }; + +struct PrepareForEmissionPass + : public PrepareForEmissionBase { + PrepareForEmissionPass(LoweringOptions options) : options(options) {} + void runOnOperation() override { prepareHWModule(getOperation(), options); } + +protected: + LoweringOptions options; +}; } // end anonymous namespace std::unique_ptr circt::createTestPrepareForEmissionPass() { return std::make_unique(); } + +std::unique_ptr +circt::createPrepareForEmissionPass(LoweringOptions options) { + return std::make_unique(options); +} diff --git a/lib/Conversion/PassDetail.h b/lib/Conversion/PassDetail.h index 97a7455c4e..cdc55133ff 100644 --- a/lib/Conversion/PassDetail.h +++ b/lib/Conversion/PassDetail.h @@ -10,6 +10,7 @@ #ifndef CONVERSION_PASSDETAIL_H #define CONVERSION_PASSDETAIL_H +#include "circt/Support/LoweringOptions.h" #include "mlir/IR/BuiltinOps.h" #include "mlir/IR/DialectRegistry.h" #include "mlir/Pass/Pass.h"