Hi Martin, thanks for taking some time to help me. I think I accidentally deleted the original hello world pass, but I have re-made it and I still have the same problem. I copy paste the patch at the bottom. Just to give some more context:
I am running the following command: $PATH_TO_GCC/gcc -fipa-hello-world -flto main.c -fdump-ipa-hello-world With the following simple main.c file: ``` int foo () { return 0; } int bar() { return 1; } int main() { foo(); bar(); } ``` And I get the following output from the dump files: a-main.c.079i.hello-world: ``` name of cgraph: main name of cgraph: bar name of cgraph: foo hello world from write summary writing 3 writing bar writing foo writing main ``` a.wpa.079i.hello-world: ``` hello from read summary iteration = 1, data = f hello from wpa ``` Many thanks again, and do let me know if there's anything I can do to help. >From 8e0e2c7d821baab8ac6dbdd6fad5911110e8332b Mon Sep 17 00:00:00 2001 From: Erick Ochoa <eoc...@gcc.gnu.org> Date: Tue, 6 Apr 2021 16:34:48 +0200 Subject: [PATCH] Simple hello world for IPA_PASS --- gcc/Makefile.in | 1 + gcc/common.opt | 4 ++ gcc/ipa-hello-world.c | 159 ++++++++++++++++++++++++++++++++++++++++++ gcc/lto-streamer.h | 1 + gcc/passes.def | 1 + gcc/tree-pass.h | 1 + 6 files changed, 167 insertions(+) create mode 100644 gcc/ipa-hello-world.c diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 8a5fb3fd99c..567505e61f7 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1438,6 +1438,7 @@ OBJS = \ incpath.o \ init-regs.o \ internal-fn.o \ + ipa-hello-world.o \ ipa-cp.o \ ipa-sra.o \ ipa-devirt.o \ diff --git a/gcc/common.opt b/gcc/common.opt index a75b44ee47e..d221a4bf05c 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -3490,4 +3490,8 @@ fipa-ra Common Var(flag_ipa_ra) Optimization Use caller save register across calls if possible. +fipa-hello-world +Common Var(flag_ipa_hello_world) Optimization +Hello world example. + ; This comment is to ensure we retain the blank line above. diff --git a/gcc/ipa-hello-world.c b/gcc/ipa-hello-world.c new file mode 100644 index 00000000000..dcaf8238d6c --- /dev/null +++ b/gcc/ipa-hello-world.c @@ -0,0 +1,159 @@ +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "backend.h" +#include "tree.h" +#include "gimple-expr.h" +#include "predict.h" +#include "alloc-pool.h" +#include "tree-pass.h" +#include "cgraph.h" +#include "diagnostic.h" +#include "fold-const.h" +#include "gimple-fold.h" +#include "symbol-summary.h" +#include "tree-vrp.h" +#include "ipa-prop.h" +#include "tree-pretty-print.h" +#include "tree-inline.h" +#include "ipa-fnsummary.h" +#include "ipa-utils.h" +#include "tree-ssa-ccp.h" +#include "stringpool.h" +#include "attribs.h" +#include "gimple.h" +#include "lto-streamer.h" +#include "data-streamer.h" + + +hash_map<cgraph_node *, const char*> *hello_summaries = NULL; + +static void +ipa_hello_world_generate_summary (void) +{ + hello_summaries = new hash_map<cgraph_node*, const char*>; + struct cgraph_node *node = NULL; + FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node) + { + if (dump_file) fprintf(dump_file, "name of cgraph: %s\n", node->name()); + hello_summaries->put(node, node->name()); + } +} + +static void +ipa_hello_world_write_summary (void) +{ + gcc_assert(hello_summaries); + struct output_block *ob = create_output_block (LTO_section_hello_world); + gcc_assert(ob); + if (dump_file) fprintf(dump_file, "hello world from write summary\n"); + lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder; + if (dump_file) fprintf(dump_file, "writing %ld\n", hello_summaries->elements()); + streamer_write_uhwi (ob, hello_summaries->elements()); + + for (auto i = hello_summaries->begin(), e = hello_summaries->end(); +i != e; ++i) + { + if (dump_file) fprintf(dump_file, "writing %s\n", (*i).second); + streamer_write_uhwi(ob, lto_symtab_encoder_encode(encoder, (*i).first)); + streamer_write_string (ob, ob->main_stream, (*i).second, true); + } + produce_asm (ob, NULL); + destroy_output_block (ob); + //delete hello_summaries; +} + +static void +ipa_hello_world_read_summary (void) +{ + struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data (); + struct lto_file_decl_data *file_data; + unsigned int j = 0; + if (dump_file) fprintf(dump_file, "hello from read summary\n"); + while ((file_data = file_data_vec[j++])) + { + size_t len; + const char *data = + lto_get_summary_section_data (file_data, LTO_section_hello_world, &len); + if (dump_file) fprintf(dump_file, "iteration = %d, data = %s\n", j, data ? "t" : "f"); + if (!data) continue; + + // This has not been executed with my simple example programs + const struct lto_function_header *header = (const struct lto_function_header*) data; + gcc_assert(header); + gcc_assert(header->cfg_size); + const int cfg_offset = sizeof (struct lto_function_header); + const int main_offset = cfg_offset + header->cfg_size; + const int string_offset = main_offset + header->main_size; + class data_in *data_in; + + lto_input_block ib ((const char *) data + main_offset, header->main_size, + file_data->mode_table); + data_in + = lto_data_in_create (file_data, (const char *) data + string_offset, + header->string_size, vNULL); + unsigned int n = streamer_read_uhwi (&ib); + //hello_summaries = new hash_map<cgraph_node*, char*>; + for (unsigned i = 0; i < n; i++) + { + unsigned int index = streamer_read_uhwi(&ib); + lto_symtab_encoder_t encoder = file_data->symtab_node_encoder; + struct cgraph_node *cnode = dyn_cast<cgraph_node *> +(lto_symtab_encoder_deref(encoder, index)); + gcc_assert(cnode); + const char* string = streamer_read_string (data_in, &ib); + if (dump_file) fprintf(dump_file, string); + } + } + +} + + + +static unsigned int +iphw_execute() +{ + if (dump_file) fprintf(dump_file, "hello from wpa\n"); + return 0; +} + +namespace { +const pass_data pass_data_ipa_hello_world = +{ + IPA_PASS, + "hello-world", + OPTGROUP_NONE, + TV_NONE, + (PROP_cfg | PROP_ssa), + 0, + 0, + 0, + 0, +}; + +class pass_ipa_hello_world : public ipa_opt_pass_d +{ +public: + pass_ipa_hello_world (gcc::context *ctx) + : ipa_opt_pass_d (pass_data_ipa_hello_world, ctx, + ipa_hello_world_generate_summary, + ipa_hello_world_write_summary, + ipa_hello_world_read_summary, + NULL, + NULL, + NULL, + 0, + NULL, + NULL) + {} + + virtual bool gate(function*) { return flag_ipa_hello_world; } + virtual unsigned execute (function*) { return iphw_execute(); } +}; +} // anon namespace + +ipa_opt_pass_d* +make_pass_ipa_hello_world (gcc::context *ctx) +{ + return new pass_ipa_hello_world (ctx); +} diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 5c7cd84d46f..fb96cc357c6 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -228,6 +228,7 @@ enum lto_section_type LTO_section_ipa_sra, LTO_section_odr_types, LTO_section_ipa_modref, + LTO_section_hello_world, LTO_N_SECTION_TYPES /* Must be last. */ }; diff --git a/gcc/passes.def b/gcc/passes.def index e9ed3c7bc57..54a7df36425 100644 --- a/gcc/passes.def +++ b/gcc/passes.def @@ -153,6 +153,7 @@ along with GCC; see the file COPYING3. If not see NEXT_PASS (pass_ipa_profile); NEXT_PASS (pass_ipa_icf); NEXT_PASS (pass_ipa_devirt); + NEXT_PASS (pass_ipa_hello_world); NEXT_PASS (pass_ipa_cp); NEXT_PASS (pass_ipa_sra); NEXT_PASS (pass_ipa_cdtor_merge); diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 15693fee150..5ab807f045d 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -510,6 +510,7 @@ extern ipa_opt_pass_d *make_pass_ipa_fn_summary (gcc::context *ctxt); extern ipa_opt_pass_d *make_pass_ipa_inline (gcc::context *ctxt); extern simple_ipa_opt_pass *make_pass_ipa_free_lang_data (gcc::context *ctxt); extern simple_ipa_opt_pass *make_pass_ipa_free_fn_summary (gcc::context *ctxt); +extern ipa_opt_pass_d *make_pass_ipa_hello_world (gcc::context *ctxt); extern ipa_opt_pass_d *make_pass_ipa_cp (gcc::context *ctxt); extern ipa_opt_pass_d *make_pass_ipa_sra (gcc::context *ctxt); extern ipa_opt_pass_d *make_pass_ipa_icf (gcc::context *ctxt); -- 2.27.0 On Tue, 6 Apr 2021 at 14:07, Martin Jambor <mjam...@suse.cz> wrote: > > Hi, > > On Fri, Mar 26 2021, Erick Ochoa via Gcc wrote: > > I already have some experience developing SIMPLE_IPA_PASSes, but I am > > looking to understand IPA_PASSes better. I have made a hello world ipa > > pass that stores "hello world $FUNCTION_NAME" in the function > > summaries; however, I am having trouble reading this information back. > > Can someone help me understand how to use these interfaces correctly? > > > > At the moment, it **seems** to be writing information correctly. > > (I.e., it doesn't segfault when attempting to write data.) However, in > > my read summary function (ipa_hello_world_read_summary (void)) the > > function `lto_get_summary_section_data (file_data, > > LTO_section_ipa_hello_world, &len);` always returns NULL and > > `file_data_vec` is of size 1. This means that at run time, there is > > only one call to `lto_get_summary_section_data` and it returns NULL. > > I looked at the code you posted and compared it with streaming in > ipa-sra.c and did not spot any difference that could result in this > behavior. > > I guess you have checked that the functions are called from proper > hooks? (I.e. from write_summary and read_summary or > write_optimization_summary and read_optimization_summary, depending on > what you are trying to do, and not some mixture of these combinations?) > > You can try and send the whole patch (hopefully a hello world pass would > not be too large) and I can have a look. > > Martin