Don't read lowering options from hidden global options (#4038)

Add a pass to overwrite lowering options on a module. This lets us get rid of the in-library cmdline option and move it to the two tools which need it. With this, prepare and export never change the lowering options.

Also make prepare a nested pass.
This commit is contained in:
Andrew Lenharth 2022-10-04 15:41:03 -05:00 committed by GitHub
parent b23acdac32
commit 5498d926f4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 215 additions and 168 deletions

View File

@ -18,7 +18,11 @@
namespace circt {
std::unique_ptr<mlir::Pass> createTestPrepareForEmissionPass();
std::unique_ptr<mlir::Pass>
createTestApplyLoweringOptionPass(llvm::StringRef options);
std::unique_ptr<mlir::Pass> createTestApplyLoweringOptionPass();
std::unique_ptr<mlir::Pass> createPrepareForEmissionPass();
std::unique_ptr<mlir::Pass> createExportVerilogPass(llvm::raw_ostream &os);
std::unique_ptr<mlir::Pass> createExportVerilogPass();

View File

@ -75,16 +75,33 @@ def ExportSplitChiselInterface : Pass<"export-split-chisel-interface", "firrtl::
// ExportVerilog and ExportSplitVerilog
//===----------------------------------------------------------------------===//
def TestPrepareForEmission : Pass<"test-prepare-for-emission",
"hw::HWModuleOp"> {
def TestApplyLoweringOption : Pass<"test-apply-lowering-options",
"mlir::ModuleOp"> {
let summary = "Apply lowering options";
let description = [{
This pass allows overriding lowering options. It is intended for test
construction.
}];
let constructor = "createTestApplyLoweringOptionPass()";
let dependentDialects = [
"circt::sv::SVDialect", "circt::comb::CombDialect", "circt::hw::HWDialect"
];
let options = [
Option<"options", "options", "std::string", "", "Lowering Options">
];
}
def PrepareForEmission : Pass<"prepare-for-emission",
"hw::HWModuleOp"> {
let summary = "Prepare IR for ExportVerilog";
let description = [{
This pass runs only PrepareForEmission logic for testing purpose.
This pass runs only PrepareForEmission.
It is not necessary for users to run this pass explicitly since
ExportVerilog internally runs PrepareForEmission.
}];
let constructor = "createTestPrepareForEmissionPass()";
let constructor = "createPrepareForEmissionPass()";
let dependentDialects = [
"circt::sv::SVDialect", "circt::comb::CombDialect", "circt::hw::HWDialect"
];

View File

@ -13,8 +13,9 @@
#ifndef CIRCT_SUPPORT_LOWERINGOPTIONS_H
#define CIRCT_SUPPORT_LOWERINGOPTIONS_H
#include "circt/Support/LLVM.h"
#include "mlir/IR/BuiltinAttributes.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
namespace mlir {
class ModuleOp;
@ -25,14 +26,14 @@ namespace circt {
/// Options which control the emission from CIRCT to Verilog.
struct LoweringOptions {
/// Error callback type used to indicate errors parsing the options string.
using ErrorHandlerT = function_ref<void(llvm::Twine)>;
using ErrorHandlerT = llvm::function_ref<void(llvm::Twine)>;
/// Create a LoweringOptions with the default values.
LoweringOptions() = default;
/// Create a LoweringOptions and read in options from a string,
/// overriding only the set options in the string.
LoweringOptions(StringRef options, ErrorHandlerT errorHandler);
LoweringOptions(llvm::StringRef options, ErrorHandlerT errorHandler);
/// Create a LoweringOptions with values loaded from an MLIR ModuleOp. This
/// loads a string attribute with the key `circt.loweringOptions`. If there is
@ -42,11 +43,11 @@ struct LoweringOptions {
/// Return the value of the `circt.loweringOptions` in the specified module
/// if present, or a null attribute if not.
static StringAttr getAttributeFrom(ModuleOp module);
static mlir::StringAttr getAttributeFrom(mlir::ModuleOp module);
/// Read in options from a string, overriding only the set options in the
/// string.
void parse(StringRef options, ErrorHandlerT callback);
void parse(llvm::StringRef options, ErrorHandlerT callback);
/// Returns a string representation of the options.
std::string toString() const;
@ -149,21 +150,7 @@ struct LoweringOptions {
/// Some lint tools dislike expressions being inlined into input ports so this
/// option avoids such warnings.
bool disallowExpressionInliningInPorts = false;
}; // namespace circt
/// Register commandline options for the verilog emitter.
void registerLoweringCLOptions();
/// Apply any command line specified style options to the mlir module.
void applyLoweringCLOptions(ModuleOp module);
/// Get a lowering option from CLI option or module op. This function first
/// tries constructing a lowering option from cli, and if it failed, lowering
/// option associated with `module` is used. This function doesn't change an
/// attribute of `module` so that it can be used by child operations of
/// mlir::ModuleOp in multi-threading environment.
LoweringOptions getLoweringCLIOption(ModuleOp module,
LoweringOptions::ErrorHandlerT);
};
} // namespace circt
#endif // CIRCT_SUPPORT_LOWERINGOPTIONS_H

View File

@ -0,0 +1,58 @@
//===- LoweringOptionsParser.h - CIRCT Lowering Option Parser ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Parser for lowering options.
//
//===----------------------------------------------------------------------===//
#ifndef CIRCT_SUPPORT_LOWERINGOPTIONSPARSER_H
#define CIRCT_SUPPORT_LOWERINGOPTIONSPARSER_H
#include "circt/Support/LLVM.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/CommandLine.h"
namespace circt {
/// Commandline parser for LoweringOptions. Delegates to the parser
/// defined by LoweringOptions.
struct LoweringOptionsParser : public llvm::cl::parser<LoweringOptions> {
LoweringOptionsParser(llvm::cl::Option &option)
: llvm::cl::parser<LoweringOptions>(option) {}
bool parse(llvm::cl::Option &option, StringRef argName, StringRef argValue,
LoweringOptions &value) {
bool failed = false;
value.parse(argValue, [&](Twine error) { failed = option.error(error); });
return failed;
}
};
struct LoweringOptionsOption
: llvm::cl::opt<LoweringOptions, false, LoweringOptionsParser> {
LoweringOptionsOption(llvm::cl::OptionCategory &cat)
: llvm::cl::opt<LoweringOptions, false, LoweringOptionsParser>{
"lowering-options",
llvm::cl::desc(
"Style options. Valid flags include: "
"noAlwaysComb, exprInEventControl, disallowPackedArrays, "
"disallowLocalVariables, verifLabels, emittedLineLength=<n>, "
"maximumNumberOfTermsPerExpression=<n>, "
"maximumNumberOfTermsInConcat=<n>, explicitBitcast, "
"maximumNumberOfVariadicOperands=<n>, "
"emitReplicatedOpsToHeader, "
"locationInfoStyle={plain,wrapInAtSquareBracket,none}, "
"disallowPortDeclSharing, printDebugInfo, useOldEmissionMode, "
"disallowExpressionInliningInPorts"),
llvm::cl::cat(cat), llvm::cl::value_desc("option")} {}
};
} // namespace circt
#endif // CIRCT_SUPPORT_LOWERINGOPTIONSPARSER_H

View File

@ -0,0 +1,43 @@
//===- ApplyLoweringOptions.cpp - Test pass for adding lowering options ---===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Pass for testing purposes to apply lowering options ot a module.
//
//===----------------------------------------------------------------------===//
#include "../PassDetail.h"
#include "circt/Conversion/ExportVerilog.h"
#include "circt/Dialect/Comb/CombDialect.h"
#include "circt/Dialect/HW/HWDialect.h"
#include "circt/Dialect/SV/SVDialect.h"
#include "circt/Support/LoweringOptions.h"
using namespace circt;
namespace {
struct TestApplyLoweringOptionPass
: public TestApplyLoweringOptionBase<TestApplyLoweringOptionPass> {
TestApplyLoweringOptionPass() = default;
void runOnOperation() override {
if (!options.hasValue()) {
markAllAnalysesPreserved();
return;
}
LoweringOptions opts(options, [this](llvm::Twine tw) {
getOperation().emitError(tw);
signalPassFailure();
});
opts.setAsAttribute(getOperation());
}
};
} // namespace
std::unique_ptr<mlir::Pass> circt::createTestApplyLoweringOptionPass() {
return std::make_unique<TestApplyLoweringOptionPass>();
}

View File

@ -1,5 +1,6 @@
add_circt_translation_library(CIRCTExportVerilog
ApplyLoweringOptions.cpp
ExportVerilog.cpp
LegalizeNames.cpp
PrepareForEmission.cpp

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"
@ -4969,26 +4970,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);
@ -5024,18 +5013,29 @@ 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> {
ExportVerilogPass(raw_ostream &os) : os(os) {}
void runOnOperation() override {
// Make sure LoweringOptions are applied to the module if it was overridden
// 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.
mlir::OpPassManager preparePM("builtin.module");
auto &modulePM = preparePM.nest<hw::HWModuleOp>();
modulePM.addPass(createPrepareForEmissionPass());
if (failed(runPipeline(preparePM, getOperation())))
return signalPassFailure();
if (failed(exportVerilog(getOperation(), os)))
signalPassFailure();
if (failed(exportVerilogImpl(getOperation(), os)))
return signalPassFailure();
}
private:
@ -5102,11 +5102,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));
@ -5166,6 +5166,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
@ -5174,12 +5183,15 @@ struct ExportSplitVerilogPass
directoryName = directory.str();
}
void runOnOperation() override {
// Make sure LoweringOptions are applied to the module if it was overridden
// on the command line.
// TODO: This should be moved up to circt-opt and circt-translate.
applyLoweringCLOptions(getOperation());
if (failed(exportSplitVerilog(getOperation(), directoryName)))
signalPassFailure();
// Prepare the ops in the module for emission.
mlir::OpPassManager preparePM("builtin.module");
auto &modulePM = preparePM.nest<hw::HWModuleOp>();
modulePM.addPass(createPrepareForEmissionPass());
if (failed(runPipeline(preparePM, getOperation())))
return signalPassFailure();
if (failed(exportSplitVerilogImpl(getOperation(), directoryName)))
return signalPassFailure();
}
};
} // end anonymous namespace

View File

@ -21,11 +21,11 @@
#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"
#include "llvm/ADT/TypeSwitch.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#define DEBUG_TYPE "prepare-for-emission"
@ -1019,19 +1019,17 @@ void ExportVerilog::prepareHWModule(hw::HWModuleOp module,
namespace {
struct TestPrepareForEmissionPass
: public TestPrepareForEmissionBase<TestPrepareForEmissionPass> {
TestPrepareForEmissionPass() {}
struct PrepareForEmissionPass
: public PrepareForEmissionBase<PrepareForEmissionPass> {
void runOnOperation() override {
HWModuleOp module = getOperation();
LoweringOptions options = getLoweringCLIOption(
cast<mlir::ModuleOp>(module->getParentOp()),
[&](llvm::Twine twine) { module.emitError(twine); });
LoweringOptions options(cast<mlir::ModuleOp>(module->getParentOp()));
prepareHWModule(module, options);
}
};
} // end anonymous namespace
std::unique_ptr<mlir::Pass> circt::createTestPrepareForEmissionPass() {
return std::make_unique<TestPrepareForEmissionPass>();
std::unique_ptr<mlir::Pass> circt::createPrepareForEmissionPass() {
return std::make_unique<PrepareForEmissionPass>();
}

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"

View File

@ -13,10 +13,9 @@
#include "circt/Support/LoweringOptions.h"
#include "mlir/IR/BuiltinOps.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
using namespace circt;
using namespace mlir;
//===----------------------------------------------------------------------===//
// LoweringOptions
@ -195,77 +194,3 @@ void LoweringOptions::parseFromAttribute(ModuleOp module) {
if (auto styleAttr = getAttributeFrom(module))
parse(styleAttr.getValue(), [&](Twine error) { module.emitError(error); });
}
//===----------------------------------------------------------------------===//
// Command Line Option Processing
//===----------------------------------------------------------------------===//
namespace {
/// Commandline parser for LoweringOptions. Delegates to the parser
/// defined by LoweringOptions.
struct LoweringOptionsParser : public llvm::cl::parser<LoweringOptions> {
LoweringOptionsParser(llvm::cl::Option &option)
: llvm::cl::parser<LoweringOptions>(option) {}
bool parse(llvm::cl::Option &option, StringRef argName, StringRef argValue,
LoweringOptions &value) {
bool failed = false;
value.parse(argValue, [&](Twine error) { failed = option.error(error); });
return failed;
}
};
/// Commandline arguments for verilog emission. Used to dynamically register
/// the command line arguments in multiple tools.
struct LoweringCLOptions {
llvm::cl::opt<LoweringOptions, false, LoweringOptionsParser> loweringOptions{
"lowering-options",
llvm::cl::desc(
"Style options. Valid flags include: "
"noAlwaysComb, exprInEventControl, disallowPackedArrays, "
"disallowLocalVariables, verifLabels, emittedLineLength=<n>, "
"maximumNumberOfTermsPerExpression=<n>, "
"maximumNumberOfTermsInConcat=<n>, explicitBitcast, "
"maximumNumberOfVariadicOperands=<n>, "
"emitReplicatedOpsToHeader, "
"locationInfoStyle={plain,wrapInAtSquareBracket,none}, "
"disallowPortDeclSharing, printDebugInfo, useOldEmissionMode, "
"disallowExpressionInliningInPorts"),
llvm::cl::value_desc("option")};
};
} // namespace
/// The staticly initialized command line options.
static llvm::ManagedStatic<LoweringCLOptions> clOptions;
void circt::registerLoweringCLOptions() { *clOptions; }
void circt::applyLoweringCLOptions(ModuleOp module) {
// If the command line options were not registered in the first place, there
// is nothing to parse.
if (!clOptions.isConstructed())
return;
// If an output style is applied on the command line, all previous options are
// discarded.
if (clOptions->loweringOptions.getNumOccurrences()) {
clOptions->loweringOptions.setAsAttribute(module);
}
}
LoweringOptions
circt::getLoweringCLIOption(mlir::ModuleOp module,
LoweringOptions::ErrorHandlerT errorHandler) {
// If the command line options were not registered in the first place, use the
// lowering option associated with module op.
if (!clOptions.isConstructed() ||
!clOptions->loweringOptions.getNumOccurrences()) {
if (auto styleAttr = LoweringOptions::getAttributeFrom(module))
return LoweringOptions(styleAttr, errorHandler);
// If the module doesn't have a lowering option, then use the default value.
return LoweringOptions();
}
return clOptions->loweringOptions.getValue();
}

View File

@ -1,10 +1,12 @@
// RUN: circt-opt --lowering-options=printDebugInfo --export-verilog %s | FileCheck %s
// RUN: circt-opt --export-verilog %s | FileCheck %s
// CHECK-LABEL: module symbols
// CHECK-NEXT: input baz /* inner_sym: bazSym */
module attributes {circt.loweringOptions="printDebugInfo"} {
hw.module @symbols(%baz: i1 {hw.exportPort = @bazSym}) -> () {
// CHECK: wire foo /* inner_sym: fooSym */;
%foo = sv.wire sym @fooSym : !hw.inout<i1>
// CHECK: reg bar /* inner_sym: barSym */;
%bar = sv.reg sym @barSym : !hw.inout<i1>
}
}

View File

@ -1,5 +1,5 @@
// RUN: circt-opt --export-verilog %s | FileCheck %s
// RUN: circt-opt --lowering-options=disallowLocalVariables --export-verilog %s | FileCheck %s --check-prefix=DISALLOW -strict-whitespace
// RUN: circt-opt --test-apply-lowering-options='options=disallowLocalVariables' --export-verilog %s | FileCheck %s --check-prefix=DISALLOW -strict-whitespace
// This checks ExportVerilog's support for "disallowLocalVariables" which
// prevents emitting 'automatic logic' and other local declarations.

View File

@ -1,4 +1,4 @@
// RUN: circt-opt %s -export-verilog -verify-diagnostics -o %t.mlir --lowering-options=useOldEmissionMode | FileCheck %s --strict-whitespace --check-prefixes=CHECK,OLD
// RUN: circt-opt %s -test-apply-lowering-options="options=useOldEmissionMode" -export-verilog -verify-diagnostics -o %t.mlir | FileCheck %s --strict-whitespace --check-prefixes=CHECK,OLD
// RUN: circt-opt %s -export-verilog -verify-diagnostics -o %t.mlir | FileCheck %s --check-prefixes=CHECK,NEW
// CHECK-LABEL: // external module E

View File

@ -1,8 +1,8 @@
// RUN: circt-opt --lowering-options=emittedLineLength=40 --export-verilog %s | FileCheck %s --check-prefixes=CHECK,SHORT
// RUN: circt-opt --test-apply-lowering-options='options=emittedLineLength=40' --export-verilog %s | FileCheck %s --check-prefixes=CHECK,SHORT
// RUN: circt-opt --export-verilog %s | FileCheck %s --check-prefixes=CHECK,DEFAULT
// RUN: circt-opt --lowering-options=emittedLineLength=180 --export-verilog %s | FileCheck %s --check-prefixes=CHECK,LONG
// RUN: circt-opt --lowering-options=emittedLineLength=40,maximumNumberOfTermsPerExpression=16 --export-verilog %s | FileCheck %s --check-prefixes=CHECK,LIMIT_SHORT
// RUN: circt-opt --lowering-options=maximumNumberOfTermsPerExpression=32 --export-verilog %s | FileCheck %s --check-prefixes=CHECK,LIMIT_LONG
// RUN: circt-opt --test-apply-lowering-options='options=emittedLineLength=180' --export-verilog %s | FileCheck %s --check-prefixes=CHECK,LONG
// RUN: circt-opt --test-apply-lowering-options='options=emittedLineLength=40,maximumNumberOfTermsPerExpression=16' --export-verilog %s | FileCheck %s --check-prefixes=CHECK,LIMIT_SHORT
// RUN: circt-opt --test-apply-lowering-options='options=maximumNumberOfTermsPerExpression=32' --export-verilog %s | FileCheck %s --check-prefixes=CHECK,LIMIT_LONG
hw.module @longvariadic(%a: i8) -> (b: i8) {
%1 = comb.add %a, %a, %a, %a, %a, %a, %a, %a, %a, %a, %a, %a, %a, %a, %a, %a,

View File

@ -1,4 +1,4 @@
// RUN: circt-opt -lowering-options=maximumNumberOfTermsPerExpression=4,disallowLocalVariables --export-verilog %s | FileCheck %s
// RUN: circt-opt -test-apply-lowering-options='options=maximumNumberOfTermsPerExpression=4,disallowLocalVariables' --export-verilog %s | FileCheck %s
// CHECK-LABEL: module large_use_in_procedural
hw.module @large_use_in_procedural(%clock: i1, %a: i1) {

View File

@ -1,4 +1,4 @@
// RUN: circt-opt %s -test-prepare-for-emission --split-input-file -verify-diagnostics | FileCheck %s
// RUN: circt-opt %s -prepare-for-emission --split-input-file -verify-diagnostics | FileCheck %s
// CHECK: @namehint_variadic
hw.module @namehint_variadic(%a: i3) -> (b: i3) {

View File

@ -1,6 +1,6 @@
// RUN: circt-opt --split-input-file --export-verilog %s | FileCheck %s --check-prefix=DEFAULT
// RUN: circt-opt --lowering-options= --split-input-file --export-verilog %s | FileCheck %s --check-prefix=CLEAR
// RUN: circt-opt --lowering-options=noAlwaysComb --split-input-file --export-verilog %s | FileCheck %s --check-prefix=NOALWAYSCOMB
// RUN: circt-opt --test-apply-lowering-options='options=' --split-input-file --export-verilog %s | FileCheck %s --check-prefix=CLEAR
// RUN: circt-opt --test-apply-lowering-options='options=noAlwaysComb' --split-input-file --export-verilog %s | FileCheck %s --check-prefix=NOALWAYSCOMB
hw.module @test() {
sv.alwayscomb {

View File

@ -1,5 +1,5 @@
// RUN: circt-opt %s -export-verilog -verify-diagnostics --lowering-options=exprInEventControl,explicitBitcast,maximumNumberOfTermsInConcat=10,useOldEmissionMode | FileCheck %s --strict-whitespace --check-prefixes=CHECK,OLD
// RUN: circt-opt %s -export-verilog -verify-diagnostics --lowering-options=exprInEventControl,explicitBitcast,maximumNumberOfTermsInConcat=10 | FileCheck %s --check-prefixes=CHECK,NEW
// RUN: circt-opt %s -test-apply-lowering-options='options=exprInEventControl,explicitBitcast,maximumNumberOfTermsInConcat=10,useOldEmissionMode' -export-verilog -verify-diagnostics | FileCheck %s --strict-whitespace --check-prefixes=CHECK,OLD
// RUN: circt-opt %s -test-apply-lowering-options='options=exprInEventControl,explicitBitcast,maximumNumberOfTermsInConcat=10' -export-verilog -verify-diagnostics | FileCheck %s --check-prefixes=CHECK,NEW
// CHECK-LABEL: module M1
// CHECK-NEXT: #(parameter [41:0] param1) (

View File

@ -1,5 +1,5 @@
// RUN: circt-opt --lowering-options= --export-verilog %s | FileCheck %s --check-prefix=CHECK-OFF
// RUN: circt-opt --lowering-options=verifLabels --export-verilog %s | FileCheck %s --check-prefix=CHECK-ON
// RUN: circt-opt --export-verilog %s | FileCheck %s --check-prefix=CHECK-OFF
// RUN: circt-opt --test-apply-lowering-options='options=verifLabels' --export-verilog %s | FileCheck %s --check-prefix=CHECK-ON
hw.module @foo(%clock: i1, %cond: i1) {
sv.initial {

View File

@ -1,5 +1,5 @@
// RUN: circt-opt -lowering-options=maximumNumberOfVariadicOperands=8 -export-verilog %s | FileCheck %s -check-prefixes=CHECK,MAX_8
// RUN: circt-opt -lowering-options=maximumNumberOfVariadicOperands=4 -export-verilog %s | FileCheck %s -check-prefixes=CHECK,MAX_4
// RUN: circt-opt -test-apply-lowering-options='options=maximumNumberOfVariadicOperands=8' -export-verilog %s | FileCheck %s -check-prefixes=CHECK,MAX_8
// RUN: circt-opt -test-apply-lowering-options='options=maximumNumberOfVariadicOperands=4' -export-verilog %s | FileCheck %s -check-prefixes=CHECK,MAX_4
hw.module @Baz(
%a0: i1, %a1: i1, %a2: i1, %a3: i1,

View File

@ -2,6 +2,6 @@
// CHECK: OVERVIEW: MLIR-based FIRRTL compiler
// CHECK: General {{[Oo]}}ptions
// CHECK: --lowering-options=
// CHECK: Generic Options
// CHECK: firtool Options
// CHECK: --lowering-options=

View File

@ -2,6 +2,6 @@
// CHECK: OVERVIEW: CIRCT HLS tool
// CHECK: General {{[Oo]}}ptions
// CHECK: --lowering-options=
// CHECK: Generic Options
// CHECK: hlstool Options
// CHECK: --lowering-options=

View File

@ -61,9 +61,6 @@ int main(int argc, char **argv) {
circt::test::registerAnalysisTestPasses();
circt::test::registerSchedulingTestPasses();
// Other command line options.
circt::registerLoweringCLOptions();
return mlir::failed(mlir::MlirOptMain(
argc, argv, "CIRCT modular optimizer driver", registry));
}

View File

@ -26,6 +26,7 @@
#include "circt/Dialect/Seq/SeqDialect.h"
#include "circt/Dialect/Seq/SeqPasses.h"
#include "circt/Support/LoweringOptions.h"
#include "circt/Support/LoweringOptionsParser.h"
#include "circt/Support/Version.h"
#include "circt/Transforms/Passes.h"
#include "mlir/Bytecode/BytecodeReader.h"
@ -408,6 +409,8 @@ static cl::opt<BuildMode> buildMode(
}
}));
static LoweringOptionsOption loweringOptions(mainCategory);
/// Create a simple canonicalizer pass.
static std::unique_ptr<Pass> createSimpleCanonicalizerPass() {
mlir::GreedyRewriteConfig config;
@ -757,7 +760,8 @@ processBuffer(MLIRContext &context, TimingScope &ts, llvm::SourceMgr &sourceMgr,
// Load the emitter options from the command line. Command line options if
// specified will override any module options.
applyLoweringCLOptions(module.get());
if (loweringOptions.getNumOccurrences())
loweringOptions.setAsAttribute(module.get());
if (failed(pm.run(module.get())))
return failure();
@ -812,10 +816,6 @@ processBuffer(MLIRContext &context, TimingScope &ts, llvm::SourceMgr &sourceMgr,
if (exportModuleHierarchy)
exportPm.addPass(sv::createHWExportModuleHierarchyPass(outputFilename));
// Load the emitter options from the command line. Command line options if
// specified will override any module options.
applyLoweringCLOptions(module.get());
if (failed(exportPm.run(module.get())))
return failure();
}
@ -1004,7 +1004,6 @@ int main(int argc, char **argv) {
registerPassManagerCLOptions();
registerDefaultTimingManagerCLOptions();
registerAsmPrinterCLOptions();
registerLoweringCLOptions();
cl::AddExtraVersionPrinter(
[](raw_ostream &os) { os << getCirctVersion() << '\n'; });
// Parse pass names in main to ensure static initialization completed.

View File

@ -50,6 +50,7 @@
#include "circt/Dialect/SV/SVPasses.h"
#include "circt/Dialect/Seq/SeqPasses.h"
#include "circt/Support/LoweringOptions.h"
#include "circt/Support/LoweringOptionsParser.h"
#include "circt/Transforms/Passes.h"
#include "circt/InitAllDialects.h"
@ -173,6 +174,8 @@ static cl::opt<unsigned> bufferSize("buffer-size",
cl::desc("Number of slots in each buffer"),
cl::init(2), cl::cat(mainCategory));
static LoweringOptionsOption loweringOptions(mainCategory);
// --------------------------------------------------------------------------
// (Configurable) pass pipelines
// --------------------------------------------------------------------------
@ -362,7 +365,8 @@ doHLSFlowDynamic(PassManager &pm, ModuleOp module,
pm.addPass(circt::sv::createSVTraceIVerilogPass());
if (outputFormat == OutputVerilog) {
applyLoweringCLOptions(module);
if (loweringOptions.getNumOccurrences())
loweringOptions.setAsAttribute(module);
pm.addPass(createExportVerilogPass(outputFile.value()->os()));
}
@ -508,7 +512,6 @@ int main(int argc, char **argv) {
registerPassManagerCLOptions();
registerDefaultTimingManagerCLOptions();
registerAsmPrinterCLOptions();
registerLoweringCLOptions();
// Parse pass names in main to ensure static initialization completed.
cl::ParseCommandLineOptions(argc, argv, "CIRCT HLS tool\n");