On Mon, Sep 16, 2013 at 7:14 PM, Ilya Verbin <[email protected]> wrote:
> Hi Richard,
>
> On 23 Aug 14:24, Richard Biener wrote:
>> Ilya Verbin <[email protected]> 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