Questions about LTO infrastructure and pragma omp target

Richard Biener richard.guenther@gmail.com
Tue Sep 17 08:12:00 GMT 2013


On Mon, Sep 16, 2013 at 7:14 PM, Ilya Verbin <iverbin@gmail.com> wrote:
> 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?

It looks more like a hack ;)  It certainly doesn't look scalable to multiple
target ISAs.  You also unconditionally invoke the target compiler (well, you
invoke the same compiler ...)

As far as I understand your patch the target IL is already produced by
the compile stage (always? what about possible target IL emit from
-ftree-parallelize-loops?)?

As I understand Jakub he prefers things to work without -flto as well, so
target IL has to be handled by a different linker plugin and LTO would merely
be required to pass the target IL sections through the LTO pipeline and re-emit
it during LTRANS?

Btw, at this point it's bad that LTO IL sections do not have something like
a section header - encoding all section properties in the section name is
not going to scale.  Any takers to add a section header to all LTO sections?
(add a first flag, "compressed_p" there, so we can finally mix compressed
and uncompressed sections).

Richard.

>
> ---
>  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