diff --git a/src/Options.cc b/src/Options.cc index 2d0bb632c0..25f78e1da8 100644 --- a/src/Options.cc +++ b/src/Options.cc @@ -188,7 +188,8 @@ static void print_analysis_help() { 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, " dump-ZAM dump generated ZAM code, including intermediaries; implies gen-ZAM-code\n"); + fprintf(stderr, " dump-final-ZAM dump final 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-inline turn off inlining\n"); @@ -232,6 +233,8 @@ static void set_analysis_option(const char* opt, Options& opts) { 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, "dump-final-ZAM") ) + a_o.activate = a_o.dump_final_ZAM = true; else if ( util::streq(opt, "gen-C++") ) a_o.gen_CPP = true; else if ( util::streq(opt, "gen-standalone-C++") ) diff --git a/src/script_opt/ScriptOpt.cc b/src/script_opt/ScriptOpt.cc index f084a603d6..f515a4f16e 100644 --- a/src/script_opt/ScriptOpt.cc +++ b/src/script_opt/ScriptOpt.cc @@ -241,7 +241,7 @@ static void optimize_func(ScriptFuncPtr f, std::shared_ptr pf, std: if ( reporter->Errors() > 0 ) return; - if ( analysis_options.dump_ZAM ) + if ( analysis_options.dump_final_ZAM ) ZAM.Dump(); f->ReplaceBody(body, new_body); @@ -275,6 +275,7 @@ static void init_options() { check_env_opt("ZEEK_NO_ZAM_OPT", analysis_options.no_ZAM_opt); check_env_opt("ZEEK_NO_ZAM_CONTROL_FLOW_OPT", analysis_options.no_ZAM_control_flow_opt); check_env_opt("ZEEK_DUMP_ZAM", analysis_options.dump_ZAM); + check_env_opt("ZEEK_DUMP_FINAL_ZAM", analysis_options.dump_final_ZAM); check_env_opt("ZEEK_PROFILE", analysis_options.profile_ZAM); // Compile-to-C++-related options. @@ -339,7 +340,7 @@ static void init_options() { } if ( analysis_options.dump_ZAM ) - analysis_options.gen_ZAM_code = true; + analysis_options.dump_final_ZAM = analysis_options.gen_ZAM_code = true; if ( ! analysis_options.only_funcs.empty() || ! analysis_options.only_files.empty() ) { if ( analysis_options.gen_ZAM_code || generating_CPP ) diff --git a/src/script_opt/ScriptOpt.h b/src/script_opt/ScriptOpt.h index 6967333e5c..1a8c4c25fe 100644 --- a/src/script_opt/ScriptOpt.h +++ b/src/script_opt/ScriptOpt.h @@ -96,9 +96,12 @@ struct AnalyOpt { // If true, dump out the use-defs for each analyzed function. bool dump_uds = false; - // If true, dump out generated ZAM code. + // If true, dump out generated ZAM code, including intermediaries. bool dump_ZAM = false; + // If true, dump out final generated ZAM code (only). + bool dump_final_ZAM = false; + // If non-zero, looks for variables that are used-but-possibly-not-set, // or set-but-not-used. We store this as an int rather than a bool // because we might at some point extend the analysis to deeper forms diff --git a/src/script_opt/ZAM/Driver.cc b/src/script_opt/ZAM/Driver.cc index 2bdae1406b..a4be8b9d83 100644 --- a/src/script_opt/ZAM/Driver.cc +++ b/src/script_opt/ZAM/Driver.cc @@ -356,55 +356,70 @@ void ZAMCompiler::ConcretizeSwitchTables(const CaseMapsI& abstract_cases, Cas void ZAMCompiler::Dump() { bool remapped_frame = ! analysis_options.no_ZAM_opt; - if ( remapped_frame ) - printf("Original frame for %s:\n", func->GetName().c_str()); + if ( analysis_options.dump_ZAM ) { + if ( remapped_frame ) + printf("\nOriginal frame for %s:\n", func->GetName().c_str()); - for ( const auto& elem : frame_layout1 ) - printf("frame[%d] = %s\n", elem.second, elem.first->Name()); + for ( const auto& elem : frame_layout1 ) + printf("frame[%d] = %s\n", elem.second, elem.first->Name()); - if ( remapped_frame ) { - printf("Final frame for %s:\n", func->GetName().c_str()); + if ( remapped_frame ) { + printf("Final frame for %s:\n", func->GetName().c_str()); + + for ( auto i = 0U; i < shared_frame_denizens.size(); ++i ) { + printf("frame2[%d] =", i); + for ( auto& id : shared_frame_denizens[i].ids ) + printf(" %s", id->Name()); + printf("\n"); + } + } + + if ( ! insts2.empty() ) + printf("Pre-removal of dead code for %s:\n", func->GetName().c_str()); + + auto remappings = remapped_frame ? &shared_frame_denizens : nullptr; + + DumpInsts1(remappings); + + if ( ! insts2.empty() ) + printf("Final intermediary code for %s:\n", func->GetName().c_str()); + + remappings = remapped_frame ? &shared_frame_denizens_final : nullptr; + + for ( auto i = 0U; i < insts2.size(); ++i ) { + auto& inst = insts2[i]; + std::string liveness, depth; + + if ( inst->live ) + liveness = util::fmt("(labels %d)", inst->num_labels); + else + liveness = "(dead)"; + + if ( inst->loop_depth ) + depth = util::fmt(" (loop %d)", inst->loop_depth); + + printf("%d %s%s: ", i, liveness.c_str(), depth.c_str()); + + inst->Dump(stdout, &frame_denizens, remappings); + } + } + else if ( analysis_options.dump_final_ZAM ) { + ASSERT(remapped_frame); + + printf("\nFrame for %s:\n", func->GetName().c_str()); for ( auto i = 0U; i < shared_frame_denizens.size(); ++i ) { - printf("frame2[%d] =", i); + printf("frame[%d] =", i); for ( auto& id : shared_frame_denizens[i].ids ) printf(" %s", id->Name()); printf("\n"); } } - if ( ! insts2.empty() ) - printf("Pre-removal of dead code for %s:\n", func->GetName().c_str()); - - auto remappings = remapped_frame ? &shared_frame_denizens : nullptr; - - DumpInsts1(remappings); - - if ( ! insts2.empty() ) - printf("Final intermediary code for %s:\n", func->GetName().c_str()); - - remappings = remapped_frame ? &shared_frame_denizens_final : nullptr; - - for ( auto i = 0U; i < insts2.size(); ++i ) { - auto& inst = insts2[i]; - std::string liveness, depth; - - if ( inst->live ) - liveness = util::fmt("(labels %d)", inst->num_labels); - else - liveness = "(dead)"; - - if ( inst->loop_depth ) - depth = util::fmt(" (loop %d)", inst->loop_depth); - - printf("%d %s%s: ", i, liveness.c_str(), depth.c_str()); - - inst->Dump(stdout, &frame_denizens, remappings); - } - if ( ! insts2.empty() ) printf("Final code for %s:\n", func->GetName().c_str()); + auto remappings = remapped_frame ? &shared_frame_denizens_final : nullptr; for ( auto i = 0U; i < insts2.size(); ++i ) { auto& inst = insts2[i]; // printf("%s:%d\n", inst->loc->filename, inst->loc->first_line); diff --git a/src/script_opt/ZAM/README.md b/src/script_opt/ZAM/README.md index 90afbdbf09..103bb2a971 100644 --- a/src/script_opt/ZAM/README.md +++ b/src/script_opt/ZAM/README.md @@ -89,7 +89,8 @@ issues: |---|---| |`dump-uds` | Dump use-defs to _stdout_.| |`dump-xform` | Dump transformed scripts to _stdout_.| -|`dump-ZAM` | Dump generated ZAM code to _stdout_.| +|`dump-ZAM` | Dump generated ZAM code to _stdout_, including intermediaries.| +|`dump-final-ZAM` | Dump final generated ZAM code to _stdout_.| |`gen-ZAM-code` | Generate ZAM without additional optimizations.| |`help` | Print this list.| |`inline` | Inline function calls.|