Questions about LTO infrastructure and pragma omp target

Ilya Verbin iverbin@gmail.com
Mon Sep 16 17:14:00 GMT 2013


Hi Richard,

On 23 Aug 14:24, Richard Biener wrote:
> Ilya Verbin <iverbin@gmail.com> wrote:
> >I'm trying to implement the approach with modified lto-wrapper.
> >Suppose we have a bytecode of the routine foo, streamed during ompexp
> >pass into some section, say .gnu.omptarget_foo.
> >In function lto.c:do_whole_program_analysis() an extra partition should
> >be created, that will contain bytecode from .gnu.omptarget_foo, right?
> 
> Right.
> 
> Richard.

What if we leave WPA stage unchanged?
Here is a patch that passes "fat" object files (with host-side .gnu.lto_ and
target-side .gnu.target_lto_ sections) directly to the target-compiler.
(Currently it works only with -flto enabled.)  Then target-compiler reads
bytecode from .gnu.target_lto_ and produces target-side object file.
At the moment lto-wrapper uses collect_gcc as a target-compiler.  Also it
doesn't properly handle the command-line args.
This looks simpler than emit extra partitions during WPA.  What do you think?


---
 gcc/lto-streamer.c   |  8 ++++++--
 gcc/lto-streamer.h   |  1 +
 gcc/lto-wrapper.c    | 22 +++++++++++++++++++++-
 gcc/lto/lang.opt     |  4 ++++
 gcc/lto/lto-object.c |  5 +++--
 gcc/lto/lto.c        |  5 ++++-
 6 files changed, 39 insertions(+), 6 deletions(-)

diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c
index e7b66c1..9e19060 100644
--- a/gcc/lto-streamer.c
+++ b/gcc/lto-streamer.c
@@ -145,6 +145,7 @@ lto_get_section_name (int section_type, const char *name, struct lto_file_decl_d
   const char *add;
   char post[32];
   const char *sep;
+  const char *prefix;
 
   if (section_type == LTO_section_function_body)
     {
@@ -172,8 +173,11 @@ lto_get_section_name (int section_type, const char *name, struct lto_file_decl_d
   else if (f != NULL) 
     sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, f->id);
   else
-    sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, get_random_seed (false)); 
-  return concat (LTO_SECTION_NAME_PREFIX, sep, add, post, NULL);
+    sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, get_random_seed (false));
+
+  prefix = flag_openmp_target ? OMP_SECTION_NAME_PREFIX
+			      : LTO_SECTION_NAME_PREFIX;
+  return concat (prefix, sep, add, post, NULL);
 }
 
 
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index e7c89f1..df72e16 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -141,6 +141,7 @@ along with GCC; see the file COPYING3.  If not see
    name for the functions and static_initializers.  For other types of
    sections a '.' and the section type are appended.  */
 #define LTO_SECTION_NAME_PREFIX         ".gnu.lto_"
+#define OMP_SECTION_NAME_PREFIX         ".gnu.target_lto_"
 
 #define LTO_major_version 2
 #define LTO_minor_version 2
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index 15a34dd..f3b44ff 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -442,6 +442,7 @@ run_gcc (unsigned argc, char *argv[])
   unsigned i, j;
   const char **new_argv;
   const char **argv_ptr;
+  const char **target_argv;
   char *list_option_full = NULL;
   const char *linker_output = NULL;
   const char *collect_gcc, *collect_gcc_options;
@@ -452,7 +453,7 @@ run_gcc (unsigned argc, char *argv[])
   unsigned int fdecoded_options_count = 0;
   struct cl_decoded_option *decoded_options;
   unsigned int decoded_options_count;
-  struct obstack argv_obstack;
+  struct obstack argv_obstack, target_argv_obstack;
   int new_head_argc;
 
   /* Get the driver and options.  */
@@ -902,6 +903,25 @@ cont:
       free (input_names);
       free (list_option_full);
       obstack_free (&env_obstack, NULL);
+
+      /* Run gcc for target.  */
+      obstack_init (&target_argv_obstack);
+      obstack_ptr_grow (&target_argv_obstack, collect_gcc);
+      obstack_ptr_grow (&target_argv_obstack, "-xlto");
+      obstack_ptr_grow (&target_argv_obstack, "-fopenmp_target");
+      obstack_ptr_grow (&target_argv_obstack, "-c");
+      obstack_ptr_grow (&target_argv_obstack, "-o");
+      obstack_ptr_grow (&target_argv_obstack, "target.o");
+
+      /* Append the input objects.  */
+      for (i = 1; i < argc; ++i)
+	if (strncmp (argv[i], "-fresolution=", sizeof ("-fresolution=") - 1))
+	  obstack_ptr_grow (&target_argv_obstack, argv[i]);
+      obstack_ptr_grow (&target_argv_obstack, NULL);
+
+      target_argv = XOBFINISH (&target_argv_obstack, const char **);
+      fork_execute (CONST_CAST (char **, target_argv));
+      obstack_free (&target_argv_obstack, NULL);
     }
 
   obstack_free (&argv_obstack, NULL);
diff --git a/gcc/lto/lang.opt b/gcc/lto/lang.opt
index 7a9aede..cd0098c 100644
--- a/gcc/lto/lang.opt
+++ b/gcc/lto/lang.opt
@@ -40,4 +40,8 @@ fresolution=
 LTO Joined
 The resolution file
 
+fopenmp_target
+LTO Var(flag_openmp_target)
+Run LTO infrastructure to read target-side bytecode and to build it.
+
 ; This comment is to ensure we retain the blank line above.
diff --git a/gcc/lto/lto-object.c b/gcc/lto/lto-object.c
index 77be1fb..ccf06d2 100644
--- a/gcc/lto/lto-object.c
+++ b/gcc/lto/lto-object.c
@@ -226,9 +226,10 @@ lto_obj_add_section (void *data, const char *name, off_t offset,
   struct lto_section_slot s_slot;
   void **slot;
   struct lto_section_list *list = loasd->list;
+  const char *prefix = flag_openmp_target ? OMP_SECTION_NAME_PREFIX
+					  : LTO_SECTION_NAME_PREFIX;
 
-  if (strncmp (name, LTO_SECTION_NAME_PREFIX,
-	       strlen (LTO_SECTION_NAME_PREFIX)) != 0)
+  if (strncmp (name, prefix, strlen (prefix)))
     return 1;
 
   new_name = xstrdup (name);
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index c854589..d3bac3a 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -2677,9 +2677,12 @@ static int
 lto_section_with_id (const char *name, unsigned HOST_WIDE_INT *id)
 {
   const char *s;
+  const char *prefix = flag_openmp_target ? OMP_SECTION_NAME_PREFIX
+					  : LTO_SECTION_NAME_PREFIX;
 
-  if (strncmp (name, LTO_SECTION_NAME_PREFIX, strlen (LTO_SECTION_NAME_PREFIX)))
+  if (strncmp (name, prefix, strlen (prefix)))
     return 0;
+
   s = strrchr (name, '.');
   return s && sscanf (s, "." HOST_WIDE_INT_PRINT_HEX_PURE, id) == 1;
 }
-- 
1.7.11.7


Thanks,
  -- Ilya



More information about the Gcc mailing list