[circt-verilog] Fix lint only mode, refactor pass population

If circt-verilog is run in lint-only mode, actually make the tool exit
out after the initial parsing through Slang. All diagnostics have been
reported at that point, and we can just exit out without bothering with
any IR modifications.

Also refactor the way circt-verilog populates its pass pipeline a bit.
This commit is contained in:
Fabian Schuiki 2024-08-03 10:10:18 -07:00
parent f470dac1ed
commit 6eda5a2b5e
No known key found for this signature in database
GPG Key ID: C42F5825FC5275E6
2 changed files with 63 additions and 26 deletions

View File

@ -258,6 +258,11 @@ LogicalResult ImportDriver::importVerilog(ModuleOp module) {
return failure();
compileTimer.stop();
// If we were only supposed to lint the input, return here. This leaves the
// module empty, but any Slang linting messages got reported as diagnostics.
if (options.mode == ImportVerilogOptions::Mode::OnlyLint)
return success();
// Traverse the parsed Verilog AST and map it to the equivalent CIRCT ops.
mlirContext->loadDialect<moore::MooreDialect, hw::HWDialect, scf::SCFDialect,
func::FuncDialect>();

View File

@ -15,6 +15,7 @@
#include "circt/Conversion/ImportVerilog.h"
#include "circt/Conversion/MooreToCore.h"
#include "circt/Dialect/Moore/MoorePasses.h"
#include "circt/Support/Passes.h"
#include "circt/Support/Version.h"
#include "mlir/IR/BuiltinOps.h"
#include "mlir/Pass/PassManager.h"
@ -216,27 +217,58 @@ struct CLOptions {
static CLOptions opts;
/// Parse specified files that had been translated into Moore dialect IR. After
/// that simplify these files like deleting local variables, and then emit the
/// resulting Moore dialect IR .
static LogicalResult populateMooreTransforms(mlir::PassManager &pm) {
auto &modulePM = pm.nest<moore::SVModuleOp>();
modulePM.addPass(moore::createLowerConcatRefPass());
modulePM.addPass(moore::createSimplifyProceduresPass());
//===----------------------------------------------------------------------===//
// Pass Pipeline
//===----------------------------------------------------------------------===//
pm.addPass(mlir::createSROA());
pm.addPass(mlir::createMem2Reg());
/// Optimize and simplify the Moore dialect IR.
static void populateMooreTransforms(PassManager &pm) {
{
// Perform an initial cleanup and preprocessing across all
// modules/functions.
auto &anyPM = pm.nestAny();
anyPM.addPass(mlir::createCSEPass());
anyPM.addPass(createSimpleCanonicalizerPass());
}
// TODO: like dedup pass.
{
// Perform module-specific transformations.
auto &modulePM = pm.nest<moore::SVModuleOp>();
modulePM.addPass(moore::createLowerConcatRefPass());
modulePM.addPass(moore::createSimplifyProceduresPass());
}
return success();
{
// Perform a final cleanup across all modules/functions.
auto &anyPM = pm.nestAny();
anyPM.addPass(mlir::createSROA());
anyPM.addPass(mlir::createMem2Reg());
anyPM.addPass(mlir::createCSEPass());
anyPM.addPass(createSimpleCanonicalizerPass());
}
}
/// Convert Moore dialect IR into core dialect IR
static LogicalResult populateMooreToCoreLowering(mlir::PassManager &pm) {
static void populateMooreToCoreLowering(PassManager &pm) {
// Perform the conversion.
pm.addPass(createConvertMooreToCorePass());
return success();
{
// Conversion to the core dialects likely uncovers new canonicalization
// opportunities.
auto &anyPM = pm.nestAny();
anyPM.addPass(mlir::createCSEPass());
anyPM.addPass(createSimpleCanonicalizerPass());
}
}
/// Populate the given pass manager with transformations as configured by the
/// command line options.
static void populatePasses(PassManager &pm) {
populateMooreTransforms(pm);
if (opts.loweringMode == LoweringMode::OutputIRMoore)
return;
populateMooreToCoreLowering(pm);
}
//===----------------------------------------------------------------------===//
@ -308,23 +340,23 @@ static LogicalResult executeWithSources(MLIRContext *context,
if (failed(importVerilog(sourceMgr, context, ts, module.get(), &options)))
return failure();
PassManager pm(context);
if (opts.loweringMode == LoweringMode::OutputIRMoore ||
opts.loweringMode == LoweringMode::OutputIRHW) {
// If the user requested for the files to be only linted, the module remains
// empty and there is nothing left to do.
if (opts.loweringMode == LoweringMode::OnlyLint)
return success();
// Simplify the Moore dialect IR.
if (failed(populateMooreTransforms(pm)))
// If the user requested anything besides simply parsing the input, run the
// appropriate transformation passes according to the command line options.
if (opts.loweringMode != LoweringMode::OnlyParse) {
PassManager pm(context);
pm.enableVerifier(true);
if (failed(applyPassManagerCLOptions(pm)))
return failure();
populatePasses(pm);
if (failed(pm.run(module.get())))
return failure();
if (opts.loweringMode == LoweringMode::OutputIRHW)
// Convert Moore IR into core IR.
if (failed(populateMooreToCoreLowering(pm)))
return failure();
}
if (failed(pm.run(module.get())))
return failure();
// Print the final MLIR.
module->print(outputFile->os());
outputFile->keep();