From f6445a792e62ec857b2d955cd23a10cc70caafd8 Mon Sep 17 00:00:00 2001 From: Vern Paxson Date: Sun, 9 Jun 2024 15:04:08 -0700 Subject: [PATCH] -O validate-ZAM option --- auxil/gen-zam | 2 +- src/CMakeLists.txt | 2 +- src/Options.cc | 9 +++++--- src/script_opt/ScriptOpt.cc | 10 ++++----- src/script_opt/ScriptOpt.h | 9 ++++++++ .../ZAM/{OpAnaly.cc => Validate.cc} | 21 +++++++------------ src/script_opt/ZAM/ZOp.h | 12 +++++++++++ src/zeek-setup.cc | 4 ++-- .../Baseline.zam/opt.validate-ZAM/output | 2 ++ testing/btest/opt/validate-ZAM.zeek | 5 +++++ 10 files changed, 51 insertions(+), 25 deletions(-) rename src/script_opt/ZAM/{OpAnaly.cc => Validate.cc} (93%) create mode 100644 testing/btest/Baseline.zam/opt.validate-ZAM/output create mode 100644 testing/btest/opt/validate-ZAM.zeek diff --git a/auxil/gen-zam b/auxil/gen-zam index 425223e05c..fb80a00cf6 160000 --- a/auxil/gen-zam +++ b/auxil/gen-zam @@ -1 +1 @@ -Subproject commit 425223e05c4deb6f8f6e4fa4f7219bf1136271ec +Subproject commit fb80a00cf697c93ffe9d122e70bda7dc80dafb1f diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 838db90afb..f9ec58d7bd 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -441,10 +441,10 @@ set(MAIN_SRCS script_opt/ZAM/Expr.cc script_opt/ZAM/Inst-Gen.cc script_opt/ZAM/Low-Level.cc - script_opt/ZAM/OpAnaly.cc script_opt/ZAM/Profile.cc script_opt/ZAM/Stmt.cc script_opt/ZAM/Support.cc + script_opt/ZAM/Validate.cc script_opt/ZAM/Vars.cc script_opt/ZAM/ZBody.cc script_opt/ZAM/ZInst.cc diff --git a/src/Options.cc b/src/Options.cc index 0c15fbe074..c0c6ff3d4e 100644 --- a/src/Options.cc +++ b/src/Options.cc @@ -194,6 +194,7 @@ static void print_analysis_help() { fprintf(stderr, " optimize-AST optimize the (transformed) AST; implies xform\n"); fprintf(stderr, " profile-ZAM generate to zprof.out a ZAM execution profile; implies -O ZAM\n"); fprintf(stderr, " report-recursive report on recursive functions and exit\n"); + fprintf(stderr, " validate-ZAM perform internal assessment of synthesized ZAM instructions and exit\n"); fprintf(stderr, " xform transform scripts to \"reduced\" form\n"); fprintf(stderr, "\n--optimize options when generating C++:\n"); @@ -220,14 +221,14 @@ static void set_analysis_option(const char* opt, Options& opts) { exit(0); } - if ( util::streq(opt, "dump-uds") ) + if ( util::streq(opt, "allow-cond") ) + a_o.allow_cond = 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, "allow-cond") ) - a_o.allow_cond = true; else if ( util::streq(opt, "gen-C++") ) a_o.gen_CPP = true; else if ( util::streq(opt, "gen-standalone-C++") ) @@ -254,6 +255,8 @@ static void set_analysis_option(const char* opt, Options& opts) { a_o.report_uncompilable = true; else if ( util::streq(opt, "use-C++") ) a_o.use_CPP = true; + else if ( util::streq(opt, "validate-ZAM") ) + a_o.validate_ZAM = true; else if ( util::streq(opt, "xform") ) a_o.activate = true; diff --git a/src/script_opt/ScriptOpt.cc b/src/script_opt/ScriptOpt.cc index e93ea36c00..105a884cb1 100644 --- a/src/script_opt/ScriptOpt.cc +++ b/src/script_opt/ScriptOpt.cc @@ -446,12 +446,7 @@ static void generate_CPP() { CPPCompile cpp(funcs, pfs, gen_name, standalone, report); } -extern void analyze_ZAM_insts(); - static void analyze_scripts_for_ZAM() { - // analyze_ZAM_insts(); - // exit(0); - if ( analysis_options.usage_issues > 0 && analysis_options.optimize_AST ) { fprintf(stderr, "warning: \"-O optimize-AST\" option is incompatible with -u option, " @@ -566,6 +561,11 @@ void clear_script_analysis() { void analyze_scripts(bool no_unused_warnings) { init_options(); + if ( analysis_options.validate_ZAM ) { + validate_ZAM_insts(); + return; + } + // Any standalone compiled scripts have already been instantiated // at this point, but may require post-loading-of-scripts finalization. for ( auto cb : standalone_finalizations ) diff --git a/src/script_opt/ScriptOpt.h b/src/script_opt/ScriptOpt.h index 1f58c99a9a..e4c614a330 100644 --- a/src/script_opt/ScriptOpt.h +++ b/src/script_opt/ScriptOpt.h @@ -61,6 +61,10 @@ struct AnalyOpt { // recursive, and exit. Only germane if running the inliner. bool report_recursive = false; + // If true, assess the instructions generated from ZAM templates + // for validity, and exit. + bool validate_ZAM = false; + // If true, generate ZAM code for applicable function bodies, // activating all optimizations. bool gen_ZAM = false; @@ -241,6 +245,11 @@ extern bool should_analyze(const ScriptFuncPtr& f, const StmtPtr& body); // suppressed by the flag) and optimization. extern void analyze_scripts(bool no_unused_warnings); +// Conduct internal validation of ZAM instructions. Upon success, generates +// a terse report to stdout. Exits with an internal error if a problem is +// encountered. +extern void validate_ZAM_insts(); + // Called when all script processing is complete and we can discard // unused ASTs and associated state. extern void clear_script_analysis(); diff --git a/src/script_opt/ZAM/OpAnaly.cc b/src/script_opt/ZAM/Validate.cc similarity index 93% rename from src/script_opt/ZAM/OpAnaly.cc rename to src/script_opt/ZAM/Validate.cc index 90b0f3e85a..a6038fb69e 100644 --- a/src/script_opt/ZAM/OpAnaly.cc +++ b/src/script_opt/ZAM/Validate.cc @@ -9,12 +9,6 @@ using std::string; namespace zeek::detail { -struct ZAMInstDesc { - string op_class; - string op_types; - string op_desc; -}; - std::unordered_map zam_inst_desc = { #include "ZAM-Desc.h" @@ -31,14 +25,14 @@ static std::map type_pats = { {'U', "uint_val|AsCount\\(\\)"}, {'V', "vector_val|AsVector(Ref)?\\(\\)"}, }; -int num_valid = 0; -int num_tested = 0; -int num_skipped = 0; +static int num_valid = 0; +static int num_tested = 0; +static int num_skipped = 0; void analyze_ZAM_inst(const char* op_name, const ZAMInstDesc& zid) { auto& oc = zid.op_class; auto& ot = zid.op_types; - auto& eval = zid.op_desc; + auto& eval = zid.op_eval; bool have_ot = ! ot.empty(); @@ -82,7 +76,7 @@ void analyze_ZAM_inst(const char* op_name, const ZAMInstDesc& zid) { if ( ! std::regex_search(eval, std::regex(op)) ) reporter->InternalError("%s: operand %s not found", op_name, op.c_str()); - ++num_skipped; + ++num_skipped; continue; } @@ -90,7 +84,7 @@ void analyze_ZAM_inst(const char* op_name, const ZAMInstDesc& zid) { if ( tp == type_pats.end() ) reporter->InternalError("%s: instruction type %c not found", op_name, ot_i); match_pat += ".(" + tp->second + ")"; - ++num_tested; + ++num_tested; } if ( ! std::regex_search(eval, std::regex(match_pat)) ) @@ -99,7 +93,8 @@ void analyze_ZAM_inst(const char* op_name, const ZAMInstDesc& zid) { ++num_valid; } -void analyze_ZAM_insts() { +void validate_ZAM_insts() { + // The following primes a data structure we access. (void)AssignmentFlavor(OP_NOP, TYPE_VOID, false); for ( int i = 0; i < int(OP_NOP); ++i ) { diff --git a/src/script_opt/ZAM/ZOp.h b/src/script_opt/ZAM/ZOp.h index 12cb0c4118..72ae94ddd3 100644 --- a/src/script_opt/ZAM/ZOp.h +++ b/src/script_opt/ZAM/ZOp.h @@ -4,6 +4,8 @@ #pragma once +#include + namespace zeek::detail { // Opcodes associated with ZAM instructions. @@ -59,6 +61,16 @@ enum ZAMOp1Flavor { OP1_INTERNAL, // we're doing some internal manipulation of the slot }; +// Used to describe ZAM instructions for validation. +struct ZAMInstDesc { + std::string op_class; // associated class + std::string op_types; // operand types + std::string op_eval; // evaluation +}; + +// Provides access to the validation description of each operation. +extern std::unordered_map zam_inst_desc; + // Maps an operand to its flavor. extern ZAMOp1Flavor op1_flavor[]; diff --git a/src/zeek-setup.cc b/src/zeek-setup.cc index cb1b019c74..557f886b7c 100644 --- a/src/zeek-setup.cc +++ b/src/zeek-setup.cc @@ -927,8 +927,8 @@ SetupResult setup(int argc, char** argv, Options* zopts) { analyze_scripts(options.no_unused_warnings); - if ( analysis_options.report_recursive ) { - // This option is report-and-exit. + if ( analysis_options.report_recursive || analysis_options.validate_ZAM ) { + // These options are report-and-exit. early_shutdown(); exit(0); } diff --git a/testing/btest/Baseline.zam/opt.validate-ZAM/output b/testing/btest/Baseline.zam/opt.validate-ZAM/output new file mode 100644 index 0000000000..b2acd53e11 --- /dev/null +++ b/testing/btest/Baseline.zam/opt.validate-ZAM/output @@ -0,0 +1,2 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +1226 valid, 1830 tested, 413 skipped diff --git a/testing/btest/opt/validate-ZAM.zeek b/testing/btest/opt/validate-ZAM.zeek new file mode 100644 index 0000000000..2640581f58 --- /dev/null +++ b/testing/btest/opt/validate-ZAM.zeek @@ -0,0 +1,5 @@ +# @TEST-DOC: ZAM maintenance script for validating synthesized operations. +# @TEST-REQUIRES: test "${ZEEK_ZAM}" == "1" +# +# @TEST-EXEC: zeek -b -O validate-ZAM %INPUT >output +# @TEST-EXEC: btest-diff output