On Thu, Oct 02, 2014 at 07:14:57PM +0400, Ilya Verbin wrote:
> @@ -1296,6 +1297,9 @@ static const char *const standard_startfile_prefix_2
> relative to the driver. */
> static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
>
> +/* A prefix to be used when this is an accelerator compiler. */
> +static const char *const accel_dir_suffix = ACCEL_DIR_SUFFIX;
Is ACCEL_DIR_SUFFIX here "" or something starting with "/ ?
> @@ -4122,15 +4126,15 @@ process_command (unsigned int decoded_options_count,
> }
>
> gcc_assert (!IS_ABSOLUTE_PATH (tooldir_base_prefix));
> - tooldir_prefix2 = concat (tooldir_base_prefix, spec_machine,
> + tooldir_prefix2 = concat (tooldir_base_prefix, spec_host_machine,
> dir_separator_str, NULL);
>
> /* Look for tools relative to the location from which the driver is
> running, or, if that is not available, the configured prefix. */
> tooldir_prefix
> = concat (gcc_exec_prefix ? gcc_exec_prefix : standard_exec_prefix,
> - spec_machine, dir_separator_str,
> - spec_version, dir_separator_str, tooldir_prefix2, NULL);
> + spec_host_machine, dir_separator_str, spec_version,
> + accel_dir_suffix, dir_separator_str, tooldir_prefix2, NULL);
> free (tooldir_prefix2);
>
> add_prefix (&exec_prefixes,
The reason I'm asking is that otherwise it seems gcc.c heavily uses
dir_separator_str for the separators. Don't have any experience with
targets where DIR_SEPARATOR is not / though, perhaps it is a non-issue.
> @@ -6878,8 +6882,8 @@ main (int argc, char **argv)
>
> /* Read specs from a file if there is one. */
>
> - machine_suffix = concat (spec_machine, dir_separator_str,
> - spec_version, dir_separator_str, NULL);
> + machine_suffix = concat (spec_host_machine, dir_separator_str,
> spec_version,
> + accel_dir_suffix, dir_separator_str, NULL);
> just_machine_suffix = concat (spec_machine, dir_separator_str, NULL);
>
> specs_file = find_a_file (&startfile_prefixes, "specs", R_OK, true);
> @@ -6889,16 +6893,17 @@ main (int argc, char **argv)
> else
> init_spec ();
>
> +#ifndef ACCEL_COMPILER
> /* We need to check standard_exec_prefix/just_machine_suffix/specs
> for any override of as, ld and libraries. */
> specs_file = (char *) alloca (strlen (standard_exec_prefix)
> + strlen (just_machine_suffix) + sizeof ("specs"));
> -
> strcpy (specs_file, standard_exec_prefix);
> strcat (specs_file, just_machine_suffix);
> strcat (specs_file, "specs");
> if (access (specs_file, R_OK) == 0)
> read_specs (specs_file, true, false);
> +#endif
Why do you want to disable specs reading for the accel compiler?
Then users won't have the possibility to override defaults etc. easily...
> @@ -7097,6 +7103,16 @@ main (int argc, char **argv)
> obstack_grow (&collect_obstack, argv[0], strlen (argv[0]) + 1);
> xputenv (XOBFINISH (&collect_obstack, char *));
>
> + if (strlen (OFFLOAD_TARGETS) > 0)
> + {
> + obstack_init (&collect_obstack);
> + obstack_grow (&collect_obstack, "OFFLOAD_TARGET_NAMES=",
> + sizeof ("OFFLOAD_TARGET_NAMES=") - 1);
> + obstack_grow (&collect_obstack, OFFLOAD_TARGETS,
> + strlen (OFFLOAD_TARGETS) + 1);
> + xputenv (XOBFINISH (&collect_obstack, char *));
> + }
> +
I'm surprised to see the obstack_init call here, but looking at
gcc.c, I'm surprised to see it in more places.
I've always thought that obstack_init was something you invoke generally
once on a given obstack object, then work with the obstack and then
obstack_free (..., NULL) it at the end. Now, if it wants the obstack to be
live until exit, it just would not obstack_free it. But calling
obstack_init on the already initialized obstack results IMHO in memory
leaks. It should be initialized just once somewhere.
> /* Set up to remember the pathname of the lto wrapper. */
>
> if (have_c)
> diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
> index 08fd090..2c9b503 100644
> --- a/gcc/lto-wrapper.c
> +++ b/gcc/lto-wrapper.c
> @@ -49,6 +49,8 @@ along with GCC; see the file COPYING3. If not see
> #include "lto-section-names.h"
> #include "collect-utils.h"
>
> +#define OFFLOAD_TARGET_NAMES_ENV "OFFLOAD_TARGET_NAMES"
Missing comment about the env var and what it is for.
> +/* Prepare a target image for offload TARGET, using mkoffload tool from
> + COMPILER_PATH. Return the name of the resultant object file. */
> +
> +static char *
> +compile_offload_image (const char *target, const char *compiler_path,
> + unsigned in_argc, char *in_argv[])
> +{
> + char *filename = NULL;
> + char **argv;
> + char *suffix
> + = XALLOCAVEC (char, strlen ("/accel//mkoffload") + strlen (target) + 1);
Use sizeof ("/accel//mkoffload") + strlen (target) instead?
> + strcpy (suffix, "/accel/");
> + strcat (suffix, target);
> + strcat (suffix, "/mkoffload");
> +
> + char **paths = NULL;
> + unsigned n_paths = parse_env_var (compiler_path, &paths, suffix);
> +
> + const char *compiler = NULL;
> + for (unsigned i = 0; i < n_paths; i++)
> + if (access_check (paths[i], X_OK) == 0)
> + {
> + compiler = paths[i];
> + break;
> + }
> +
> + if (!compiler)
> + goto out;
> +
> + /* Generate temporary output file name. */
> + filename = make_temp_file (".target.o");
> +
> + struct obstack argv_obstack;
> + obstack_init (&argv_obstack);
> + obstack_ptr_grow (&argv_obstack, compiler);
> + obstack_ptr_grow (&argv_obstack, "-o");
> + obstack_ptr_grow (&argv_obstack, filename);
> +
> + for (unsigned i = 1; i < in_argc; i++)
> + obstack_ptr_grow (&argv_obstack, in_argv[i]);
> + obstack_ptr_grow (&argv_obstack, NULL);
> +
> + argv = XOBFINISH (&argv_obstack, char **);
> + fork_execute (argv[0], argv, true);
> + obstack_free (&argv_obstack, NULL);
> +
> + out:
The goto is probably unnecessary here, indenting all the lines by
4 more spaces and using if (compiler) { ... } instead doesn't need
any further warpping.
> + free_array_of_ptrs ((void **) paths, n_paths);
> + return filename;
> +}
> +
> + /* By default linker does not discard .gnu.offload_lto_* sections. */
> + const char *linker_script = make_temp_file ("_linker_script.x");
> + FILE *stream = fopen (linker_script, "w");
> + if (!stream)
> + fatal_error ("fopen %s: %m", linker_script);
> + fprintf (stream, "SECTIONS { /DISCARD/ : { *("
> + OFFLOAD_SECTION_NAME_PREFIX "*) } }\n");
> + fclose (stream);
> + printf ("%s\n", linker_script);
> +
> + goto finish;
> + }
Does this work with gold? Are there any other linkers that support plugins,
but don't support linker scripts this way?
Jakub