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 <[email protected]>
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 <[email protected]> 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