diff --git a/src/Options.cc b/src/Options.cc index 347df2cef6..8999bc4f74 100644 --- a/src/Options.cc +++ b/src/Options.cc @@ -142,59 +142,84 @@ void usage(const char* prog, int code) exit(code); } +static void print_analysis_help() + { + fprintf(stderr, "--optimize options when using ZAM:\n"); + fprintf(stderr, " ZAM execute scripts using ZAM and all optimizations\n"); + fprintf(stderr, " help print this list\n"); + fprintf(stderr, " report-uncompilable print names of functions that can't be compiled\n"); + fprintf(stderr, "\n primarily for developers:\n"); + fprintf(stderr, " dump-uds dump use-defs to stdout; implies xform\n"); + fprintf(stderr, " dump-xform dump transformed scripts to stdout; implies xform\n"); + fprintf(stderr, " dump-ZAM dump generated ZAM code; implies gen-ZAM-code\n"); + fprintf(stderr, " gen-ZAM-code generate ZAM code (without turning on additional optimizations)\n"); + fprintf(stderr, " inline inline function calls\n"); + fprintf(stderr, " no-ZAM-opt omit low-level ZAM optimization\n"); + fprintf(stderr, " optimize-all optimize all scripts, even inlined ones\n"); + fprintf(stderr, " optimize-AST optimize the (transformed) AST; implies xform\n"); + fprintf(stderr, " profile-ZAM generate to stdout a ZAM execution profile\n"); + fprintf(stderr, " report-recursive report on recursive functions and exit\n"); + fprintf(stderr, " xform transform scripts to \"reduced\" form\n"); + + fprintf(stderr, "\n--optimize options when generating C++:\n"); + fprintf(stderr, " gen-C++ generate C++ script bodies\n"); + fprintf(stderr, " gen-standalone-C++ generate \"standalone\" C++ script bodies\n"); + fprintf(stderr, " help print this list\n"); + fprintf(stderr, " report-C++ report available C++ script bodies and exit\n"); + fprintf(stderr, " report-uncompilable print names of functions that can't be compiled\n"); + fprintf(stderr, " use-C++ use available C++ script bodies\n"); + fprintf(stderr, "\n experimental options for incremental compilation:\n"); + fprintf(stderr, " add-C++ generate private C++ for any missing script bodies\n"); + fprintf(stderr, " update-C++ generate reusable C++ for any missing script bodies\n"); + } + static void set_analysis_option(const char* opt, Options& opts) { - if ( ! opt || util::streq(opt, "all") ) + auto& a_o = opts.analysis_options; + + if ( ! opt || util::streq(opt, "ZAM") ) { - opts.analysis_options.inliner = true; - opts.analysis_options.activate = true; - opts.analysis_options.optimize_AST = true; + a_o.inliner = a_o.optimize_AST = a_o.activate = true; + a_o.gen_ZAM = true; return; } if ( util::streq(opt, "help") ) { - fprintf(stderr, "--optimize options:\n"); - fprintf(stderr, " all equivalent to \"inline\" and \"activate\"\n"); - fprintf(stderr, " add-C++ generate private C++ for any missing script bodies\n"); - fprintf(stderr, " compile-all *if* compiling, compile all scripts, even inlined ones\n"); - fprintf(stderr, " dump-uds dump use-defs to stdout; implies xform\n"); - fprintf(stderr, " dump-xform dump transformed scripts to stdout; implies xform\n"); - fprintf(stderr, " gen-C++ generate C++ script bodies\n"); - fprintf(stderr, " gen-standalone-C++ generate \"standalone\" C++ script bodies\n"); - fprintf(stderr, " help print this list\n"); - fprintf(stderr, " inline inline function calls\n"); - fprintf(stderr, " optimize-AST optimize the (transformed) AST; implies xform\n"); - fprintf(stderr, " recursive report on recursive functions and exit\n"); - fprintf(stderr, " report-C++ report available C++ script bodies and exit\n"); - fprintf(stderr, " update-C++ generate reusable C++ for any missing script bodies\n"); - fprintf(stderr, " use-C++ use available C++ script bodies\n"); - fprintf(stderr, " xform tranform scripts to \"reduced\" form\n"); + print_analysis_help(); exit(0); } - auto& a_o = opts.analysis_options; - if ( util::streq(opt, "add-C++") ) a_o.add_CPP = true; - else if ( util::streq(opt, "compile-all") ) - a_o.activate = a_o.compile_all = true; else if ( util::streq(opt, "dump-uds") ) a_o.activate = a_o.dump_uds = true; else if ( util::streq(opt, "dump-xform") ) a_o.activate = a_o.dump_xform = true; + else if ( util::streq(opt, "dump-ZAM") ) + a_o.activate = a_o.dump_ZAM = true; else if ( util::streq(opt, "gen-C++") ) a_o.gen_CPP = true; else if ( util::streq(opt, "gen-standalone-C++") ) a_o.gen_standalone_CPP = true; + else if ( util::streq(opt, "gen-ZAM-code") ) + a_o.activate = a_o.gen_ZAM_code = true; else if ( util::streq(opt, "inline") ) a_o.inliner = true; + else if ( util::streq(opt, "no-ZAM-opt") ) + a_o.activate = a_o.no_ZAM_opt = true; + else if ( util::streq(opt, "optimize-all") ) + a_o.activate = a_o.compile_all = true; else if ( util::streq(opt, "optimize-AST") ) a_o.activate = a_o.optimize_AST = true; - else if ( util::streq(opt, "recursive") ) - a_o.inliner = a_o.report_recursive = true; + else if ( util::streq(opt, "profile-ZAM") ) + a_o.activate = a_o.profile_ZAM = true; else if ( util::streq(opt, "report-C++") ) a_o.report_CPP = true; + else if ( util::streq(opt, "report-recursive") ) + a_o.inliner = a_o.report_recursive = true; + else if ( util::streq(opt, "report-uncompilable") ) + a_o.report_uncompilable = true; else if ( util::streq(opt, "update-C++") ) a_o.update_CPP = true; else if ( util::streq(opt, "use-C++") ) @@ -204,7 +229,9 @@ static void set_analysis_option(const char* opt, Options& opts) else { - fprintf(stderr,"zeek: unrecognized --optimize option: %s\n", opt); + fprintf(stderr,"zeek: unrecognized -O/--optimize option: %s\n\n", + opt); + print_analysis_help(); exit(1); } } diff --git a/src/script_opt/ScriptOpt.h b/src/script_opt/ScriptOpt.h index 4e4d506b5b..5de3f0e507 100644 --- a/src/script_opt/ScriptOpt.h +++ b/src/script_opt/ScriptOpt.h @@ -19,12 +19,50 @@ namespace zeek::detail { // Flags controlling what sorts of analysis to do. struct AnalyOpt { + + // If non-nil, then only analyze the given function/event/hook. + // Applies to both ZAM and C++. + std::optional only_func; + + // For a given compilation target, report functions that can't + // be compiled. + bool report_uncompilable = false; + + + ////// Options relating to ZAM: + // Whether to analyze scripts. bool activate = false; + // If true, compile all compileable functions, even those that + // are inlined. Mainly useful for ensuring compatibility for + // some tests in the test suite. + bool compile_all = false; + // Whether to optimize the AST. bool optimize_AST = false; + // If true, do global inlining. + bool inliner = false; + + // If true, report which functions are directly and indirectly + // recursive, and exit. Only germane if running the inliner. + bool report_recursive = false; + + // If true, generate ZAM code for applicable function bodies, + // activating all optimizations. + bool gen_ZAM = false; + + // Generate ZAM code, but do not turn on optimizations unless + // specified. + bool gen_ZAM_code = false; + + // Deactivate the low-level ZAM optimizer. + bool no_ZAM_opt = false; + + // Produce a profile of ZAM execution. + bool profile_ZAM = false; + // If true, dump out transformed code: the results of reducing // interpreted scripts, and, if optimize is set, of then optimizing // them. Always done if only_func is set. @@ -33,11 +71,23 @@ struct AnalyOpt { // If true, dump out the use-defs for each analyzed function. bool dump_uds = false; - // If non-nil, then only analyze the given function/event/hook. - std::optional only_func; + // If true, dump out generated ZAM code. + bool dump_ZAM = false; - // If true, do global inlining. - bool inliner = false; + // If non-zero, looks for variables that are used-but-possibly-not-set, + // or set-but-not-used. + // + // If > 1, also reports on uses of uninitialized record fields and + // analyzes nested records in depth. Warning: with the current + // data structures this greatly increases analysis time. + // + // Included here with other ZAM-related options since conducting + // the analysis requires activating some of the machinery used + // for ZAM. + int usage_issues = 0; + + + ////// Options relating to C++: // If true, generate C++; bool gen_CPP = false; @@ -61,25 +111,8 @@ struct AnalyOpt { // If true, use C++ bodies if available. bool use_CPP = false; - // If true, compile all compileable functions, even those that - // are inlined. Mainly useful for ensuring compatibility for - // some tests in the test suite. - bool compile_all = false; - // If true, report on available C++ bodies. bool report_CPP = false; - - // If true, report which functions are directly and indirectly - // recursive, and exit. Only germane if running the inliner. - bool report_recursive = false; - - // If non-zero, looks for variables that are used-but-possibly-not-set, - // or set-but-not-used. - // - // If > 1, also reports on uses of uninitialized record fields and - // analyzes nested records in depth. Warning: with the current - // data structures this greatly increases analysis time. - int usage_issues = 0; }; extern AnalyOpt analysis_options;