diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-10-26 09:30:29 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-10-26 09:30:29 +0000 |
commit | 00d389c8010055eab6670c189c43024d1fb1824d (patch) | |
tree | cb359c0379cd06029ee75ba612f48fea9252bcc3 /gcc/lto-wrapper.c | |
parent | e1f53ecdc82e256102b6c456e0042c1d7afb546b (diff) | |
download | gcc-00d389c8010055eab6670c189c43024d1fb1824d.tar.gz |
2011-10-26 Richard Guenther <rguenther@suse.de>
PR lto/41844
* Makefile.in (lto-wrapper): Depend on and link against
opts-common.o.
(lto-wrapper.o): Depend on $(OPTS_H) and $(OPTIONS_H).
* lto-wrapper.c (get_options_from_collect_gcc_options): New function.
(run_gcc): Use it. Filter out language specific options.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180517 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/lto-wrapper.c')
-rw-r--r-- | gcc/lto-wrapper.c | 178 |
1 files changed, 108 insertions, 70 deletions
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c index f26b3aca510..f5f3dd24b45 100644 --- a/gcc/lto-wrapper.c +++ b/gcc/lto-wrapper.c @@ -43,6 +43,8 @@ along with GCC; see the file COPYING3. If not see #include "intl.h" #include "diagnostic.h" #include "obstack.h" +#include "opts.h" +#include "options.h" int debug; /* true if -save-temps. */ int verbose; /* true if -v. */ @@ -280,6 +282,52 @@ fork_execute (char **argv) /* Template of LTRANS dumpbase suffix. */ #define DUMPBASE_SUFFIX ".ltrans18446744073709551615" +/* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS + environment according to LANG_MASK. */ + +static void +get_options_from_collect_gcc_options (const char *collect_gcc, + const char *collect_gcc_options, + unsigned int lang_mask, + struct cl_decoded_option **decoded_options, + unsigned int *decoded_options_count) +{ + char *argv_storage; + const char **argv; + int i, j, argc; + + /* Count arguments. */ + argc = 0; + for (j = 0; collect_gcc_options[j] != '\0'; ++j) + if (collect_gcc_options[j] == '\'') + ++argc; + if (argc % 2 != 0) + fatal ("malformed COLLECT_GCC_OPTIONS"); + + /* Copy the options to a argv-like array. */ + argc /= 2; + argv = (const char **) xmalloc ((argc + 2) * sizeof (char *)); + argv[0] = collect_gcc; + argv_storage = xstrdup (collect_gcc_options); + for (i = 1, j = 0; argv_storage[j] != '\0'; ++j) + { + if (argv_storage[j] == '\'') + { + argv[i++] = &argv_storage[++j]; + while (argv_storage[j] != '\'') + ++j; + argv_storage[j] = '\0'; + } + } + argv[i] = NULL; + + decode_cmdline_options_to_array (argc, (const char **)argv, + lang_mask, + decoded_options, decoded_options_count); + free (argv); +} + + /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */ static void @@ -290,99 +338,88 @@ run_gcc (unsigned argc, char *argv[]) const char **argv_ptr; char *list_option_full = NULL; const char *linker_output = NULL; - const char *collect_gcc_options, *collect_gcc; + const char *collect_gcc, *collect_gcc_options; struct obstack env_obstack; - bool seen_o = false; int parallel = 0; int jobserver = 0; bool no_partition = false; + struct cl_decoded_option *decoded_options; + unsigned int decoded_options_count; /* Get the driver and options. */ collect_gcc = getenv ("COLLECT_GCC"); if (!collect_gcc) fatal ("environment variable COLLECT_GCC must be set"); - - /* Set the CFLAGS environment variable. */ collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS"); if (!collect_gcc_options) fatal ("environment variable COLLECT_GCC_OPTIONS must be set"); - - /* Count arguments. */ - i = 0; - for (j = 0; collect_gcc_options[j] != '\0'; ++j) - if (collect_gcc_options[j] == '\'') - ++i; - - if (i % 2 != 0) - fatal ("malformed COLLECT_GCC_OPTIONS"); + get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options, + CL_LANG_ALL, + &decoded_options, + &decoded_options_count); /* Initalize the common arguments for the driver. */ - new_argv = (const char **) xmalloc ((15 + i / 2 + argc) * sizeof (char *)); + new_argv = (const char **) xmalloc ((15 + decoded_options_count + argc) + * sizeof (char *)); argv_ptr = new_argv; *argv_ptr++ = collect_gcc; *argv_ptr++ = "-xlto"; *argv_ptr++ = "-c"; - for (j = 0; collect_gcc_options[j] != '\0'; ++j) - if (collect_gcc_options[j] == '\'') - { - char *option; - - ++j; - i = j; - while (collect_gcc_options[j] != '\'') - ++j; - - obstack_init (&env_obstack); - obstack_grow (&env_obstack, &collect_gcc_options[i], j - i); - obstack_1grow (&env_obstack, 0); - option = XOBFINISH (&env_obstack, char *); - if (seen_o) - { - linker_output = option; - seen_o = false; - continue; - } - - /* If we see -o, skip it and skip and record its argument. */ - if (option[0] == '-' && option[1] == 'o') - { - if (option[2] == '\0') - seen_o = true; - else - linker_output = &option[2]; - continue; - } + for (j = 1; j < decoded_options_count; ++j) + { + struct cl_decoded_option *option = &decoded_options[j]; - if (strcmp (option, "-save-temps") == 0) + /* Do not pass on frontend specific flags. */ + if (!(cl_options[option->opt_index].flags + & (CL_COMMON|CL_TARGET|CL_DRIVER))) + continue; + + switch (option->opt_index) + { + case OPT_o: + linker_output = option->arg; + /* We generate new intermediate output, drop this arg. */ + continue; + + case OPT_save_temps: debug = 1; - if (strcmp (option, "-v") == 0) + break; + + case OPT_v: verbose = 1; + break; - if (strcmp (option, "-flto-partition=none") == 0) + case OPT_flto_partition_none: no_partition = true; - /* We've handled these LTO options, do not pass them on. */ - if (strncmp (option, "-flto=", 6) == 0 - || !strcmp (option, "-flto")) - { - lto_mode = LTO_MODE_WHOPR; - if (option[5] == '=') - { - if (!strcmp (option + 6, "jobserver")) - { - jobserver = 1; - parallel = 1; - } - else - { - parallel = atoi (option + 6); - if (parallel <= 1) - parallel = 0; - } - } - } - else - *argv_ptr++ = option; - } + break; + + case OPT_flto_: + if (strcmp (option->arg, "jobserver") == 0) + { + jobserver = 1; + parallel = 1; + } + else + { + parallel = atoi (option->arg); + if (parallel <= 1) + parallel = 0; + } + /* Fallthru. */ + + case OPT_flto: + lto_mode = LTO_MODE_WHOPR; + /* We've handled these LTO options, do not pass them on. */ + continue; + + default: + break; + } + + /* Pass the option on. */ + *argv_ptr++ = option->orig_option_with_args_text; + } + if (no_partition) { lto_mode = LTO_MODE_LTO; @@ -662,6 +699,7 @@ main (int argc, char *argv[]) /* We may be called with all the arguments stored in some file and passed with @file. Expand them into argv before processing. */ expandargv (&argc, &argv); + run_gcc (argc, argv); return 0; |