[NFC] Make prepareforemission an embedded pass run by the pass manager (#4015)

This commit is contained in:
Andrew Lenharth 2022-09-29 11:42:46 -05:00 committed by GitHub
parent a5035daed8
commit be732e05fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 79 additions and 18 deletions

View File

@ -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<mlir::Pass> createTestPrepareForEmissionPass();
std::unique_ptr<mlir::Pass>
createPrepareForEmissionPass(LoweringOptions options = LoweringOptions());
std::unique_ptr<mlir::Pass> createExportVerilogPass(llvm::raw_ostream &os);
std::unique_ptr<mlir::Pass> createExportVerilogPass();

View File

@ -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 = [{

View File

@ -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<HWModuleOp> 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<HWModuleOp> 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<ExportVerilogPass> {
@ -5056,7 +5054,15 @@ struct ExportVerilogPass : public ExportVerilogBase<ExportVerilogPass> {
// 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<hw::HWModuleOp>();
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<HWModuleOp> 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<hw::HWModuleOp>();
modulePM.addPass(createPrepareForEmissionPass(options));
if (failed(runPipeline(preparePM, getOperation())))
signalPassFailure();
if (failed(exportSplitVerilog(getOperation(), directoryName)))
signalPassFailure();
}

View File

@ -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> {
PrepareForEmissionPass(LoweringOptions options) : options(options) {}
void runOnOperation() override { prepareHWModule(getOperation(), options); }
protected:
LoweringOptions options;
};
} // end anonymous namespace
std::unique_ptr<mlir::Pass> circt::createTestPrepareForEmissionPass() {
return std::make_unique<TestPrepareForEmissionPass>();
}
std::unique_ptr<mlir::Pass>
circt::createPrepareForEmissionPass(LoweringOptions options) {
return std::make_unique<PrepareForEmissionPass>(options);
}

View File

@ -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"