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

Reply via email to