Question about storing summaries during LTO

Erick Ochoa erick.ochoa@theobroma-systems.com
Tue Dec 10 23:49:00 GMT 2019


Hello,

I am trying to understand how to store information in object files
during LTO. 

Is it possible to write arbitrary data in these sections?
There's not a lot of documentation about the specifics I need in the GCC
Internals.

I have made a simple LTO pass that writes
* "Hello world\n" into an LTO section during the write_summary stage, and
* during the read_summary stage it attempts to read the "Hello world\n",
string from the LTO section.

I don't really understand the interfaces yet, but I have "pattern
matched" code from ipa-cp.c to attempt to produce my desired result.
Can anyone point me in the right direction? Any help is greatly
appreciated. I include the small pass that I am using as a playground to
understand how to these interfaces work. I'll still continue working
on understanding the interfaces better.

By compiling and linking two simple files, the dump file for this pass
will contain the strings:

```
HELLO FROM READ SUMMARY
COULDN'T FIND IT
COULDN'T FIND IT
```

GCC will segfault, in a different pass. Probably due to these changes.

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 6b857bd..f4f1376 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1368,6 +1368,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/ipa-hello-world.c b/gcc/ipa-hello-world.c
new file mode 100644
index 0000000..76a5126
--- /dev/null
+++ b/gcc/ipa-hello-world.c
@@ -0,0 +1,106 @@
+#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"
+
+static void
+iphw_generate_summary (void)
+{
+}
+
+static void
+iphw_write_summary (void)
+{
+  struct output_block *ob;
+  ob = create_output_block (LTO_section_hello_world);
+  streamer_write_string (ob, ob->string_stream, "hello world\n", true);
+  lto_write_stream(ob->string_stream);
+  //produce_asm (ob, NULL);
+  destroy_output_block (ob);
+}
+
+static void
+iphw_read_summary (void)
+{
+  if (dump_file) fprintf(dump_file, "HELLO FROM READ SUMMARY\n");
+  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
+  struct lto_file_decl_data *file_data;
+  unsigned int j = 0;
+
+  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 (data && dump_file) fprintf(dump_file, "FROM READ SUMMARY %s\n", data);
+     else fprintf(dump_file, "COULDN'T FIND IT\n");
+  }
+}
+
+static unsigned int
+iphw_execute()
+{
+  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,
+           iphw_generate_summary,
+           iphw_write_summary,
+           iphw_read_summary,
+           NULL,
+           NULL,
+           NULL,
+           0,
+           NULL,
+           NULL)
+  {}
+
+  virtual bool gate(function*) { return true; }
+  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 dba195d..c26b334 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -236,6 +236,7 @@ enum lto_section_type
   LTO_section_ipa_hsa,
   LTO_section_lto,
   LTO_section_ipa_sra,
+  LTO_section_hello_world,
   LTO_N_SECTION_TYPES		/* Must be last.  */
 };
 
diff --git a/gcc/passes.def b/gcc/passes.def
index 798a391..52cd14b 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -146,6 +146,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 a987661..820daaa 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -498,6 +498,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);



More information about the Gcc mailing list