circt-reduce,firtool,llhd-sim: cleanup --help output, put options in category (#2979)

* circt-reduce: cleanup --help output, put options in category

Hides unrelated options from LLVM+co, and makes it easier
to find the most relevant options at glance.

When building CIRCT against LLVM built as shared libraries
(as preferred by many Linux distributions) this greatly
reduces the number of options printed.

* firtool: cleanup --help output, put options in category

Hides unrelated options from LLVM+co, and makes it easier
to find the most relevant options at glance.

When building CIRCT against LLVM built as shared libraries
(as preferred by many Linux distributions) this greatly
reduces the number of options printed.

* llhd-sim: group llhd-sim options in --help output

Hides unrelated options from LLVM+co, and makes it easier
to find the most relevant options at glance.

When building CIRCT against LLVM built as shared libraries
(as preferred by many Linux distributions) this greatly
reduces the number of options printed.

Even for the statically linked version more commonly used
with CIRCT, the help output is significantly reduced.

* llhd-sim: touchup optimizationLevel cl::opt to be static (NFCI)

* test/llhd-sim: Add commandline test

* circt-reduce: check categories in help test

* firtool: check categories in help test

* firtool: add new option to mainCategory too
This commit is contained in:
Will Dietz 2022-05-03 16:02:57 -05:00 committed by GitHub
parent 167d0e3ae0
commit 61e5d42e6b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 156 additions and 97 deletions

View File

@ -1,3 +1,7 @@
// RUN: circt-reduce --help | FileCheck %s
// RUN: circt-reduce --help | FileCheck %s --implicit-check-not='{{[Oo]}}ptions:'
// CHECK: OVERVIEW: CIRCT test case reduction tool
// CHECK: OPTIONS
// CHECK: General {{[Oo]}}ptions
// CHECK: Generic Options
// CHECK: circt-reduce Options

View File

@ -1,4 +1,7 @@
// RUN: firtool --help | FileCheck %s
//
// RUN: firtool --help | FileCheck %s --implicit-check-not='{{[Oo]}}ptions:'
// CHECK: OVERVIEW: MLIR-based FIRRTL compiler
// CHECK: General {{[Oo]}}ptions
// CHECK: --lowering-options=
// CHECK: Generic Options
// CHECK: firtool Options

View File

@ -0,0 +1,7 @@
// REQUIRES: llhd-sim
// RUN: llhd-sim --help | FileCheck %s --implicit-check-not='{{[Oo]}}ptions:'
// CHECK: OVERVIEW: LLHD simulator
// CHECK: OPTIONS
// CHECK: Generic Options
// CHECK: llhd-sim Options

View File

@ -37,42 +37,54 @@ using namespace circt;
// Options
//===----------------------------------------------------------------------===//
static cl::opt<std::string>
inputFilename(cl::Positional, cl::desc("<input file>"), cl::Required);
static cl::OptionCategory mainCategory("circt-reduce Options");
static cl::opt<std::string> inputFilename(cl::Positional,
cl::desc("<input file>"),
cl::Required, cl::cat(mainCategory));
static cl::opt<std::string>
outputFilename("o", cl::init("-"),
cl::desc("Output filename for the reduced test case"));
cl::desc("Output filename for the reduced test case"),
cl::cat(mainCategory));
static cl::opt<bool>
keepBest("keep-best", cl::init(true),
cl::desc("Keep overwriting the output with better reductions"));
cl::desc("Keep overwriting the output with better reductions"),
cl::cat(mainCategory));
static cl::opt<bool> skipInitial(
"skip-initial", cl::init(false),
cl::desc("Skip checking the initial input for interestingness"));
static cl::opt<bool>
skipInitial("skip-initial", cl::init(false),
cl::desc("Skip checking the initial input for interestingness"),
cl::cat(mainCategory));
static cl::opt<bool> listReductions("list", cl::init(false),
cl::desc("List all available reductions"));
cl::desc("List all available reductions"),
cl::cat(mainCategory));
static cl::list<std::string> includeReductions(
"include", cl::ZeroOrMore,
cl::desc("Only run a subset of the available reductions"));
static cl::list<std::string>
includeReductions("include", cl::ZeroOrMore,
cl::desc("Only run a subset of the available reductions"),
cl::cat(mainCategory));
static cl::list<std::string>
excludeReductions("exclude", cl::ZeroOrMore,
cl::desc("Do not run some of the available reductions"));
cl::desc("Do not run some of the available reductions"),
cl::cat(mainCategory));
static cl::opt<std::string> testerCommand(
"test", cl::Required,
cl::desc("A command or script to check if output is interesting"));
cl::desc("A command or script to check if output is interesting"),
cl::cat(mainCategory));
static cl::list<std::string>
testerArgs("test-arg", cl::ZeroOrMore,
cl::desc("Additional arguments to the test"));
cl::desc("Additional arguments to the test"),
cl::cat(mainCategory));
static cl::opt<bool> verbose("v", cl::init(true),
cl::desc("Print reduction progress to stderr"));
cl::desc("Print reduction progress to stderr"),
cl::cat(mainCategory));
//===----------------------------------------------------------------------===//
// Tool Implementation
@ -285,6 +297,10 @@ static LogicalResult execute(MLIRContext &context) {
int main(int argc, char **argv) {
llvm::InitLLVM y(argc, argv);
// Hide default LLVM options, other than for this tool.
// MLIR options are added below.
cl::HideUnrelatedOptions(mainCategory);
// Parse the command line options provided by the user.
registerMLIRContextCLOptions();
registerAsmPrinterCLOptions();

View File

@ -53,194 +53,206 @@ using namespace circt;
/// input.
enum InputFormatKind { InputUnspecified, InputFIRFile, InputMLIRFile };
static cl::OptionCategory mainCategory("firtool Options");
static cl::opt<InputFormatKind> inputFormat(
"format", cl::desc("Specify input file format:"),
cl::values(clEnumValN(InputUnspecified, "autodetect",
"Autodetect input format"),
clEnumValN(InputFIRFile, "fir", "Parse as .fir file"),
clEnumValN(InputMLIRFile, "mlir", "Parse as .mlir file")),
cl::init(InputUnspecified));
cl::init(InputUnspecified), cl::cat(mainCategory));
static cl::opt<std::string>
inputFilename(cl::Positional, cl::desc("<input file>"), cl::init("-"));
static cl::opt<std::string> inputFilename(cl::Positional,
cl::desc("<input file>"),
cl::init("-"), cl::cat(mainCategory));
static cl::opt<std::string>
outputFilename("o",
cl::desc("Output filename, or directory for split output"),
cl::value_desc("filename"), cl::init("-"));
static cl::opt<std::string> outputFilename(
"o", cl::desc("Output filename, or directory for split output"),
cl::value_desc("filename"), cl::init("-"), cl::cat(mainCategory));
static cl::opt<bool>
splitInputFile("split-input-file",
cl::desc("Split the input file into pieces and process each "
"chunk independently"),
cl::init(false), cl::Hidden);
cl::init(false), cl::Hidden, cl::cat(mainCategory));
static cl::opt<bool>
verifyDiagnostics("verify-diagnostics",
cl::desc("Check that emitted diagnostics match "
"expected-* lines on the corresponding line"),
cl::init(false), cl::Hidden);
cl::init(false), cl::Hidden, cl::cat(mainCategory));
static cl::opt<bool> disableOptimization("disable-opt",
cl::desc("disable optimizations"));
cl::desc("disable optimizations"),
cl::cat(mainCategory));
static cl::opt<bool> inliner("inline",
cl::desc("Run the FIRRTL module inliner"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<bool> enableAnnotationWarning(
"warn-on-unprocessed-annotations",
cl::desc("Warn about annotations that were not removed by lower-to-hw"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<bool> disableAnnotationsClassless(
"disable-annotation-classless",
cl::desc("Ignore annotations without a class when parsing"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<bool> disableAnnotationsUnknown(
"disable-annotation-unknown",
cl::desc("Ignore unknown annotations when parsing"), cl::init(false));
cl::desc("Ignore unknown annotations when parsing"), cl::init(false),
cl::cat(mainCategory));
static cl::opt<bool> disableNamePreservation(
"disable-name-preservation",
cl::desc("Don't generate debug taps for named FIRRTL wires and nodes"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<bool>
emitMetadata("emit-metadata",
cl::desc("emit metadata for metadata annotations"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<bool> emitOMIR("emit-omir",
cl::desc("emit OMIR annotations to a JSON file"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<bool> replSeqMem(
"repl-seq-mem",
cl::desc(
"replace the seq mem for macro replacement and emit relevant metadata"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<bool>
preserveAggregate("preserve-aggregate",
cl::desc("preserve aggregate types in lower types"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<bool> preservePublicTypes(
"preserve-public-types",
cl::desc("force to lower ports of toplevel and external modules"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<std::string>
replSeqMemCircuit("repl-seq-mem-circuit",
cl::desc("circuit root for seq mem metadata"),
cl::init(""));
cl::init(""), cl::cat(mainCategory));
static cl::opt<std::string>
replSeqMemFile("repl-seq-mem-file",
cl::desc("file name for seq mem metadata"), cl::init(""));
cl::desc("file name for seq mem metadata"), cl::init(""),
cl::cat(mainCategory));
static cl::opt<bool>
ignoreReadEnableMem("ignore-read-enable-mem",
cl::desc("ignore the read enable signal, instead of "
"assigning X on read disable"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<bool> imconstprop(
"imconstprop",
cl::desc(
"Enable intermodule constant propagation and dead code elimination"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<bool>
lowerTypes("lower-types",
cl::desc("run the lower-types pass within lower-to-hw"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<bool> expandWhens("expand-whens",
cl::desc("disable the expand-whens pass"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<bool>
blackBoxMemory("blackbox-memory",
cl::desc("Create a black box for all memory operations"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<bool>
dedup("dedup", cl::desc("deduplicate structurally identical modules"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<bool>
ignoreFIRLocations("ignore-fir-locators",
cl::desc("ignore the @info locations in the .fir file"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<bool>
lowerCHIRRTL("lower-chirrtl",
cl::desc("lower CHIRRTL memories to FIRRTL memories"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<bool> wireDFT("wire-dft", cl::desc("wire the DFT ports"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<bool>
inferWidths("infer-widths",
cl::desc("run the width inference pass on firrtl"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<bool>
inferResets("infer-resets",
cl::desc("run the reset inference pass on firrtl"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<bool>
injectDUTHierarchy("inject-dut-hierarchy",
cl::desc("add a level of hierarchy to the DUT"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<bool>
prefixModules("prefix-modules",
cl::desc("prefix modules with NestedPrefixAnnotation"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<bool> extractTestCode("extract-test-code",
cl::desc("run the extract test code pass"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<bool>
grandCentral("firrtl-grand-central",
cl::desc("create interfaces and data/memory taps from SiFive "
"Grand Central annotations"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<bool> exportModuleHierarchy(
"export-module-hierarchy",
cl::desc("export module and instance hierarchy as JSON"), cl::init(false));
cl::desc("export module and instance hierarchy as JSON"), cl::init(false),
cl::cat(mainCategory));
static cl::opt<bool>
checkCombCycles("firrtl-check-comb-cycles",
cl::desc("check combinational cycles on firrtl"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<bool> newAnno("new-anno",
cl::desc("enable new annotation handling"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<bool> removeUnusedPorts("remove-unused-ports",
cl::desc("enable unused ports pruning"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<bool> mergeConnections(
"merge-connections",
cl::desc("merge field-level connections into full aggregate connections"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::opt<bool>
mergeConnectionsAgggresively("merge-connections-aggressive-merging",
cl::desc("merge connections aggressively"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
/// Enable the pass to merge the read and write ports of a memory, if their
/// enable conditions are mutually exclusive.
static cl::opt<bool>
inferMemReadWrite("infer-rw",
cl::desc("enable infer read write ports for memory"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
enum OutputFormatKind {
OutputParseOnly,
@ -268,50 +280,48 @@ static cl::opt<OutputFormatKind> outputFormat(
"Emit Verilog (one file per module; specify "
"directory with -o=<dir>)"),
clEnumValN(OutputDisabled, "disable-output", "Do not output anything")),
cl::init(OutputVerilog));
cl::init(OutputVerilog), cl::cat(mainCategory));
static cl::opt<bool>
verifyPasses("verify-each",
cl::desc("Run the verifier after each transformation pass"),
cl::init(true));
cl::init(true), cl::cat(mainCategory));
static cl::list<std::string>
inputAnnotationFilenames("annotation-file",
cl::desc("Optional input annotation file"),
cl::CommaSeparated, cl::value_desc("filename"));
static cl::list<std::string> inputAnnotationFilenames(
"annotation-file", cl::desc("Optional input annotation file"),
cl::CommaSeparated, cl::value_desc("filename"), cl::cat(mainCategory));
static cl::list<std::string>
inputOMIRFilenames("omir-file",
cl::desc("Optional input object model 2.0 file"),
cl::CommaSeparated, cl::value_desc("filename"));
static cl::list<std::string> inputOMIRFilenames(
"omir-file", cl::desc("Optional input object model 2.0 file"),
cl::CommaSeparated, cl::value_desc("filename"), cl::cat(mainCategory));
static cl::opt<std::string>
omirOutFile("output-omir", cl::desc("file name for the output omir"),
cl::init(""));
cl::init(""), cl::cat(mainCategory));
static cl::opt<std::string> blackBoxRootPath(
"blackbox-path",
cl::desc("Optional path to use as the root of black box annotations"),
cl::value_desc("path"), cl::init(""));
cl::value_desc("path"), cl::init(""), cl::cat(mainCategory));
static cl::opt<bool>
verbosePassExecutions("verbose-pass-executions",
cl::desc("Log executions of toplevel module passes"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<bool> stripDebugInfo(
"strip-debug-info",
cl::desc("Disable source locator information in output Verilog"),
cl::init(false));
cl::init(false), cl::cat(mainCategory));
static cl::opt<std::string>
sigmapPrefix("sigmap-prefix",
cl::desc("prefix for signal mapping module dut path"),
cl::init(""));
cl::init(""), cl::cat(mainCategory));
static cl::opt<std::string>
sigmapDut("sigmap-dut",
cl::desc("dut for signal mapping target correction"),
cl::init(""));
cl::init(""), cl::cat(mainCategory));
/// Create a simple canonicalizer pass.
static std::unique_ptr<Pass> createSimpleCanonicalizerPass() {
@ -778,6 +788,10 @@ static LogicalResult executeFirtool(MLIRContext &context) {
int main(int argc, char **argv) {
InitLLVM y(argc, argv);
// Hide default LLVM options, other than for this tool.
// MLIR options are added below.
cl::HideUnrelatedOptions(mainCategory);
// Register any pass manager command line options.
registerMLIRContextCLOptions();
registerPassManagerCLOptions();

View File

@ -38,49 +38,59 @@ using namespace mlir::func;
using namespace circt;
using namespace circt::llhd::sim;
static cl::opt<std::string>
inputFilename(cl::Positional, cl::desc("<input-file>"), cl::init("-"));
static cl::OptionCategory mainCategory("llhd-sim Options");
static cl::opt<std::string> inputFilename(cl::Positional,
cl::desc("<input-file>"),
cl::init("-"), cl::cat(mainCategory));
static cl::opt<std::string> outputFilename("o", cl::desc("Output filename"),
cl::value_desc("filename"),
cl::init("-"));
cl::init("-"),
cl::cat(mainCategory));
static cl::opt<int> nSteps("n", cl::desc("Set the maximum number of steps"),
cl::value_desc("max-steps"));
cl::value_desc("max-steps"), cl::cat(mainCategory));
static cl::opt<uint64_t> maxTime(
"T",
cl::desc("Stop the simulation after the given amount of simulation time in "
"picoseconds, including all sub-steps for that real-time step"),
cl::value_desc("max-time"));
cl::value_desc("max-time"), cl::cat(mainCategory));
static cl::opt<bool>
dumpLLVMDialect("dump-llvm-dialect",
cl::desc("Dump the LLVM IR dialect module"));
cl::desc("Dump the LLVM IR dialect module"),
cl::cat(mainCategory));
static cl::opt<bool> dumpLLVMIR("dump-llvm-ir",
cl::desc("Dump the LLVM IR module"));
cl::desc("Dump the LLVM IR module"),
cl::cat(mainCategory));
static cl::opt<bool> dumpMLIR("dump-mlir",
cl::desc("Dump the original MLIR module"));
cl::desc("Dump the original MLIR module"),
cl::cat(mainCategory));
static cl::opt<bool> dumpLayout("dump-layout",
cl::desc("Dump the gathered instance layout"));
cl::desc("Dump the gathered instance layout"),
cl::cat(mainCategory));
static cl::opt<std::string> root(
"root",
cl::desc("Specify the name of the entity to use as root of the design"),
cl::value_desc("root_name"), cl::init("root"));
static cl::alias rootA("r", cl::desc("Alias for -root"), cl::aliasopt(root));
cl::value_desc("root_name"), cl::init("root"), cl::cat(mainCategory));
static cl::alias rootA("r", cl::desc("Alias for -root"), cl::aliasopt(root),
cl::cat(mainCategory));
enum OptLevel { O0, O1, O2, O3 };
cl::opt<OptLevel> optimizationLevel(
cl::desc("Choose optimization level:"), cl::init(O2),
cl::values(clEnumVal(O0, "Run passes and codegen at O0"),
clEnumVal(O1, "Run passes and codegen at O1"),
clEnumVal(O2, "Run passes and codegen at O2"),
clEnumVal(O3, "Run passes and codegen at O3")));
static cl::opt<OptLevel>
optimizationLevel(cl::desc("Choose optimization level:"), cl::init(O2),
cl::values(clEnumVal(O0, "Run passes and codegen at O0"),
clEnumVal(O1, "Run passes and codegen at O1"),
clEnumVal(O2, "Run passes and codegen at O2"),
clEnumVal(O3, "Run passes and codegen at O3")),
cl::cat(mainCategory));
static cl::opt<TraceMode> traceMode(
"trace-format", cl::desc("Choose the dump format:"),
@ -101,14 +111,16 @@ static cl::opt<TraceMode> traceMode(
TraceMode::NamedOnly, "named-only",
"Only dump changes for real-time steps, only for top-level "
"instance and signals not having the default name '(sig)?[0-9]*'"),
clEnumValN(TraceMode::None, "none", "Don't dump a signal trace")));
clEnumValN(TraceMode::None, "none", "Don't dump a signal trace")),
cl::cat(mainCategory));
static cl::list<std::string>
sharedLibs("shared-libs",
cl::desc("Libraries to link dynamically. Specify absolute path "
"to llhd-signals-runtime-wrappers for GCC or Windows. "
"Optional otherwise."),
cl::ZeroOrMore, cl::MiscFlags::CommaSeparated);
cl::ZeroOrMore, cl::MiscFlags::CommaSeparated,
cl::cat(mainCategory));
static int dumpLLVM(ModuleOp module, MLIRContext &context) {
if (dumpLLVMDialect) {
@ -148,6 +160,9 @@ static LogicalResult applyMLIRPasses(ModuleOp module) {
int main(int argc, char **argv) {
InitLLVM y(argc, argv);
// Hide default LLVM options, other than for this tool.
cl::HideUnrelatedOptions(mainCategory);
cl::ParseCommandLineOptions(argc, argv, "LLHD simulator\n");
// Set up the input and output files.