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