2021-05-03 23:30:18 +02:00
|
|
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
// DESCRIPTION: Verilator: Command line option parser
|
|
|
|
|
//
|
|
|
|
|
// Code available from: https://verilator.org
|
|
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
//
|
2022-01-01 14:26:40 +01:00
|
|
|
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
2021-05-03 23:30:18 +02:00
|
|
|
// can redistribute it and/or modify it under the terms of either the GNU
|
|
|
|
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
|
|
|
|
// Version 2.0.
|
|
|
|
|
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
|
|
|
|
//
|
|
|
|
|
//*************************************************************************
|
|
|
|
|
|
|
|
|
|
#ifndef VERILATOR_V3OPTION_PARSER_H_
|
|
|
|
|
#define VERILATOR_V3OPTION_PARSER_H_
|
|
|
|
|
|
|
|
|
|
#include "config_build.h"
|
|
|
|
|
#include "verilatedos.h"
|
|
|
|
|
|
|
|
|
|
#include <functional>
|
|
|
|
|
#include <memory>
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
// Not to include V3Option.h here so that VlcMain or other executables can use this file easily.
|
|
|
|
|
#ifndef V3OPTION_PARSER_NO_VOPTION_BOOL
|
|
|
|
|
class VOptionBool;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Typycal usage would look as below.
|
|
|
|
|
// See also V3Options::parseOptsList() in V3Optoins.cpp for more detailed usage.
|
|
|
|
|
//
|
|
|
|
|
// V3OptionParser parser;
|
|
|
|
|
// V3OptionParser::AppendHelper DECL_OPTION{parser};
|
|
|
|
|
// V3OPTION_PARSER_DECL_TAGS;
|
|
|
|
|
//
|
|
|
|
|
// DECL_OPPTION("-help", CbCall, []() { showHelp(); });
|
|
|
|
|
// DECL_OPPTION("-some_opt", Set, &m_intMember});
|
|
|
|
|
// parser.finalize();
|
|
|
|
|
// for (int i = 1; i < argc;) {
|
|
|
|
|
// if (int consumed = parser.parse(i, argc, argv)) {
|
|
|
|
|
// i += consumed;
|
|
|
|
|
// } else { // error
|
|
|
|
|
// cerr << parser.getSuggestion(argv[i]) << endl;
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
//######################################################################
|
|
|
|
|
// V3 OptionParser
|
|
|
|
|
|
|
|
|
|
class V3OptionParser final {
|
|
|
|
|
public:
|
|
|
|
|
// TYPES
|
|
|
|
|
class ActionIfs;
|
|
|
|
|
// Functor to register options to V3OptionParser
|
|
|
|
|
class AppendHelper;
|
|
|
|
|
struct Impl;
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// MEMBERS
|
2021-11-26 23:55:36 +01:00
|
|
|
const std::unique_ptr<Impl> m_pimpl;
|
2021-05-03 23:30:18 +02:00
|
|
|
|
|
|
|
|
// METHODS
|
|
|
|
|
ActionIfs* find(const char* optp);
|
2022-08-05 11:56:57 +02:00
|
|
|
template <class ACT, class ARG>
|
|
|
|
|
ActionIfs& add(const string& opt, ARG arg);
|
2022-06-04 01:41:59 +02:00
|
|
|
static bool hasPrefixFNo(const char* strp); // Returns true if strp starts with "-fno"
|
2021-05-03 23:30:18 +02:00
|
|
|
static bool hasPrefixNo(const char* strp); // Returns true if strp starts with "-no"
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// METHODS
|
|
|
|
|
// Returns how many args are consumed. 0 means not match
|
|
|
|
|
int parse(int idx, int argc, char* argv[]);
|
|
|
|
|
// Find the most similar option
|
|
|
|
|
string getSuggestion(const char* str) const;
|
|
|
|
|
void addSuggestionCandidate(const string& s);
|
|
|
|
|
// Call this function after all options are registered.
|
|
|
|
|
void finalize();
|
|
|
|
|
|
|
|
|
|
// CONSTRUCTORS
|
|
|
|
|
V3OptionParser();
|
|
|
|
|
~V3OptionParser();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class V3OptionParser::ActionIfs VL_NOT_FINAL {
|
|
|
|
|
public:
|
|
|
|
|
virtual ~ActionIfs() = default;
|
|
|
|
|
virtual bool isValueNeeded() const = 0; // Need val of "-opt val"
|
2022-06-04 01:41:59 +02:00
|
|
|
virtual bool isFOnOffAllowed() const = 0; // true if "-fno-opt" is allowd
|
2021-05-03 23:30:18 +02:00
|
|
|
virtual bool isOnOffAllowed() const = 0; // true if "-no-opt" is allowd
|
|
|
|
|
virtual bool isPartialMatchAllowed() const = 0; // true if "-Wno-" matches "-Wno-fatal"
|
|
|
|
|
virtual bool isUndocumented() const = 0; // Will not be suggested in typo
|
|
|
|
|
// Set a value or run callback
|
|
|
|
|
virtual void exec(const char* optp, const char* valp) = 0;
|
|
|
|
|
// Mark this option undocumented. (Exclude this option from suggestion list).
|
|
|
|
|
virtual void undocumented() = 0;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// A helper class to register options
|
|
|
|
|
class V3OptionParser::AppendHelper final {
|
|
|
|
|
public:
|
|
|
|
|
// TYPES
|
|
|
|
|
// Tag to specify which operator() to call
|
2022-06-04 01:41:59 +02:00
|
|
|
struct FOnOff {}; // For ActionFOnOff
|
2021-05-03 23:30:18 +02:00
|
|
|
struct OnOff {}; // For ActionOnOff
|
2022-06-04 01:41:59 +02:00
|
|
|
struct Set {}; // For ActionSet
|
|
|
|
|
|
2021-05-03 23:30:18 +02:00
|
|
|
struct CbCall {}; // For ActionCbCall
|
Introduce DFG based combinational logic optimizer (#3527)
Added a new data-flow graph (DFG) based combinational logic optimizer.
The capabilities of this covers a combination of V3Const and V3Gate, but
is also more capable of transforming combinational logic into simplified
forms and more.
This entail adding a new internal representation, `DfgGraph`, and
appropriate `astToDfg` and `dfgToAst` conversion functions. The graph
represents some of the combinational equations (~continuous assignments)
in a module, and for the duration of the DFG passes, it takes over the
role of AstModule. A bulk of the Dfg vertices represent expressions.
These vertex classes, and the corresponding conversions to/from AST are
mostly auto-generated by astgen, together with a DfgVVisitor that can be
used for dynamic dispatch based on vertex (operation) types.
The resulting combinational logic graph (a `DfgGraph`) is then optimized
in various ways. Currently we perform common sub-expression elimination,
variable inlining, and some specific peephole optimizations, but there
is scope for more optimizations in the future using the same
representation. The optimizer is run directly before and after inlining.
The pre inline pass can operate on smaller graphs and hence converges
faster, but still has a chance of substantially reducing the size of the
logic on some designs, making inlining both faster and less memory
intensive. The post inline pass can then optimize across the inlined
module boundaries. No optimization is performed across a module
boundary.
For debugging purposes, each peephole optimization can be disabled
individually via the -fno-dfg-peepnole-<OPT> option, where <OPT> is one
of the optimizations listed in V3DfgPeephole.h, for example
-fno-dfg-peephole-remove-not-not.
The peephole patterns currently implemented were mostly picked based on
the design that inspired this work, and on that design the optimizations
yields ~30% single threaded speedup, and ~50% speedup on 4 threads. As
you can imagine not having to haul around redundant combinational
networks in the rest of the compilation pipeline also helps with memory
consumption, and up to 30% peak memory usage of Verilator was observed
on the same design.
Gains on other arbitrary designs are smaller (and can be improved by
analyzing those designs). For example OpenTitan gains between 1-15%
speedup depending on build type.
2022-09-23 17:46:22 +02:00
|
|
|
struct CbFOnOff {}; // For ActionCbFOnOff
|
|
|
|
|
struct CbOnOff {}; // For ActionCbOnOff
|
2021-05-03 23:30:18 +02:00
|
|
|
struct CbPartialMatch {}; // For ActionCbPartialMatch
|
|
|
|
|
struct CbPartialMatchVal {}; // For ActionCbPartialMatchVal
|
2022-06-04 01:41:59 +02:00
|
|
|
struct CbVal {}; // For ActionCbVal
|
2021-05-03 23:30:18 +02:00
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
// MEMBERS
|
|
|
|
|
V3OptionParser& m_parser; // The actual option registory
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
// METHODS
|
|
|
|
|
ActionIfs& operator()(const char* optp, Set, bool*) const;
|
|
|
|
|
#ifndef V3OPTION_PARSER_NO_VOPTION_BOOL
|
|
|
|
|
ActionIfs& operator()(const char* optp, Set, VOptionBool*) const;
|
|
|
|
|
#endif
|
|
|
|
|
ActionIfs& operator()(const char* optp, Set, int*) const;
|
|
|
|
|
ActionIfs& operator()(const char* optp, Set, string*) const;
|
|
|
|
|
|
2022-06-04 01:41:59 +02:00
|
|
|
ActionIfs& operator()(const char* optp, FOnOff, bool*) const;
|
2021-05-03 23:30:18 +02:00
|
|
|
ActionIfs& operator()(const char* optp, OnOff, bool*) const;
|
|
|
|
|
#ifndef V3OPTION_PARSER_NO_VOPTION_BOOL
|
|
|
|
|
ActionIfs& operator()(const char* optp, OnOff, VOptionBool*) const;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
ActionIfs& operator()(const char* optp, CbCall, std::function<void(void)>) const;
|
Introduce DFG based combinational logic optimizer (#3527)
Added a new data-flow graph (DFG) based combinational logic optimizer.
The capabilities of this covers a combination of V3Const and V3Gate, but
is also more capable of transforming combinational logic into simplified
forms and more.
This entail adding a new internal representation, `DfgGraph`, and
appropriate `astToDfg` and `dfgToAst` conversion functions. The graph
represents some of the combinational equations (~continuous assignments)
in a module, and for the duration of the DFG passes, it takes over the
role of AstModule. A bulk of the Dfg vertices represent expressions.
These vertex classes, and the corresponding conversions to/from AST are
mostly auto-generated by astgen, together with a DfgVVisitor that can be
used for dynamic dispatch based on vertex (operation) types.
The resulting combinational logic graph (a `DfgGraph`) is then optimized
in various ways. Currently we perform common sub-expression elimination,
variable inlining, and some specific peephole optimizations, but there
is scope for more optimizations in the future using the same
representation. The optimizer is run directly before and after inlining.
The pre inline pass can operate on smaller graphs and hence converges
faster, but still has a chance of substantially reducing the size of the
logic on some designs, making inlining both faster and less memory
intensive. The post inline pass can then optimize across the inlined
module boundaries. No optimization is performed across a module
boundary.
For debugging purposes, each peephole optimization can be disabled
individually via the -fno-dfg-peepnole-<OPT> option, where <OPT> is one
of the optimizations listed in V3DfgPeephole.h, for example
-fno-dfg-peephole-remove-not-not.
The peephole patterns currently implemented were mostly picked based on
the design that inspired this work, and on that design the optimizations
yields ~30% single threaded speedup, and ~50% speedup on 4 threads. As
you can imagine not having to haul around redundant combinational
networks in the rest of the compilation pipeline also helps with memory
consumption, and up to 30% peak memory usage of Verilator was observed
on the same design.
Gains on other arbitrary designs are smaller (and can be improved by
analyzing those designs). For example OpenTitan gains between 1-15%
speedup depending on build type.
2022-09-23 17:46:22 +02:00
|
|
|
ActionIfs& operator()(const char* optp, CbFOnOff, std::function<void(bool)>) const;
|
2021-05-03 23:30:18 +02:00
|
|
|
ActionIfs& operator()(const char* optp, CbOnOff, std::function<void(bool)>) const;
|
|
|
|
|
ActionIfs& operator()(const char* optp, CbVal, std::function<void(int)>) const;
|
|
|
|
|
ActionIfs& operator()(const char* optp, CbVal, std::function<void(const char*)>) const;
|
|
|
|
|
|
|
|
|
|
ActionIfs& operator()(const char* optp, CbPartialMatch,
|
|
|
|
|
std::function<void(const char*)>) const;
|
|
|
|
|
ActionIfs& operator()(const char* optp, CbPartialMatchVal,
|
|
|
|
|
std::function<void(const char*, const char*)>) const;
|
|
|
|
|
|
|
|
|
|
// CONSTRUCTORS
|
|
|
|
|
explicit AppendHelper(V3OptionParser& parser)
|
2021-05-12 23:45:56 +02:00
|
|
|
: m_parser(parser) {}
|
2021-05-03 23:30:18 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#define V3OPTION_PARSER_DECL_TAGS \
|
2021-05-09 00:04:22 +02:00
|
|
|
const auto Set VL_ATTR_UNUSED = V3OptionParser::AppendHelper::Set{}; \
|
2022-06-04 01:41:59 +02:00
|
|
|
const auto FOnOff VL_ATTR_UNUSED = V3OptionParser::AppendHelper::FOnOff{}; \
|
2021-05-09 00:04:22 +02:00
|
|
|
const auto OnOff VL_ATTR_UNUSED = V3OptionParser::AppendHelper::OnOff{}; \
|
|
|
|
|
const auto CbCall VL_ATTR_UNUSED = V3OptionParser::AppendHelper::CbCall{}; \
|
Introduce DFG based combinational logic optimizer (#3527)
Added a new data-flow graph (DFG) based combinational logic optimizer.
The capabilities of this covers a combination of V3Const and V3Gate, but
is also more capable of transforming combinational logic into simplified
forms and more.
This entail adding a new internal representation, `DfgGraph`, and
appropriate `astToDfg` and `dfgToAst` conversion functions. The graph
represents some of the combinational equations (~continuous assignments)
in a module, and for the duration of the DFG passes, it takes over the
role of AstModule. A bulk of the Dfg vertices represent expressions.
These vertex classes, and the corresponding conversions to/from AST are
mostly auto-generated by astgen, together with a DfgVVisitor that can be
used for dynamic dispatch based on vertex (operation) types.
The resulting combinational logic graph (a `DfgGraph`) is then optimized
in various ways. Currently we perform common sub-expression elimination,
variable inlining, and some specific peephole optimizations, but there
is scope for more optimizations in the future using the same
representation. The optimizer is run directly before and after inlining.
The pre inline pass can operate on smaller graphs and hence converges
faster, but still has a chance of substantially reducing the size of the
logic on some designs, making inlining both faster and less memory
intensive. The post inline pass can then optimize across the inlined
module boundaries. No optimization is performed across a module
boundary.
For debugging purposes, each peephole optimization can be disabled
individually via the -fno-dfg-peepnole-<OPT> option, where <OPT> is one
of the optimizations listed in V3DfgPeephole.h, for example
-fno-dfg-peephole-remove-not-not.
The peephole patterns currently implemented were mostly picked based on
the design that inspired this work, and on that design the optimizations
yields ~30% single threaded speedup, and ~50% speedup on 4 threads. As
you can imagine not having to haul around redundant combinational
networks in the rest of the compilation pipeline also helps with memory
consumption, and up to 30% peak memory usage of Verilator was observed
on the same design.
Gains on other arbitrary designs are smaller (and can be improved by
analyzing those designs). For example OpenTitan gains between 1-15%
speedup depending on build type.
2022-09-23 17:46:22 +02:00
|
|
|
const auto CbFOnOff VL_ATTR_UNUSED = V3OptionParser::AppendHelper::CbFOnOff{}; \
|
2021-05-09 00:04:22 +02:00
|
|
|
const auto CbOnOff VL_ATTR_UNUSED = V3OptionParser::AppendHelper::CbOnOff{}; \
|
|
|
|
|
const auto CbPartialMatch VL_ATTR_UNUSED = V3OptionParser::AppendHelper::CbPartialMatch{}; \
|
|
|
|
|
const auto CbPartialMatchVal VL_ATTR_UNUSED \
|
2022-06-04 01:41:59 +02:00
|
|
|
= V3OptionParser::AppendHelper::CbPartialMatchVal{}; \
|
|
|
|
|
const auto CbVal VL_ATTR_UNUSED = V3OptionParser::AppendHelper::CbVal{};
|
2021-05-03 23:30:18 +02:00
|
|
|
|
|
|
|
|
//######################################################################
|
|
|
|
|
|
|
|
|
|
#endif // guard
|