verilator/src/V3OptionParser.h

168 lines
6.2 KiB
C
Raw Normal View History

// -*- 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
// 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
const std::unique_ptr<Impl> m_pimpl;
// METHODS
ActionIfs* find(const char* optp);
template <class ACT, class ARG>
ActionIfs& add(const string& opt, ARG arg);
static bool hasPrefixFNo(const char* strp); // Returns true if strp starts with "-fno"
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"
virtual bool isFOnOffAllowed() const = 0; // true if "-fno-opt" is allowd
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
struct FOnOff {}; // For ActionFOnOff
struct OnOff {}; // For ActionOnOff
struct Set {}; // For ActionSet
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
struct CbPartialMatch {}; // For ActionCbPartialMatch
struct CbPartialMatchVal {}; // For ActionCbPartialMatchVal
struct CbVal {}; // For ActionCbVal
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;
ActionIfs& operator()(const char* optp, FOnOff, bool*) const;
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;
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)
: m_parser(parser) {}
};
#define V3OPTION_PARSER_DECL_TAGS \
const auto Set VL_ATTR_UNUSED = V3OptionParser::AppendHelper::Set{}; \
const auto FOnOff VL_ATTR_UNUSED = V3OptionParser::AppendHelper::FOnOff{}; \
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{}; \
const auto CbOnOff VL_ATTR_UNUSED = V3OptionParser::AppendHelper::CbOnOff{}; \
const auto CbPartialMatch VL_ATTR_UNUSED = V3OptionParser::AppendHelper::CbPartialMatch{}; \
const auto CbPartialMatchVal VL_ATTR_UNUSED \
= V3OptionParser::AppendHelper::CbPartialMatchVal{}; \
const auto CbVal VL_ATTR_UNUSED = V3OptionParser::AppendHelper::CbVal{};
//######################################################################
#endif // guard