Hi Richard, On 23 Aug 14:24, Richard Biener wrote: > Ilya Verbin <iver...@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