From cf96bae709f621f31c4319cac26d9852f835337c Mon Sep 17 00:00:00 2001 From: Richard Guenther Date: Tue, 18 May 2010 15:11:01 +0000 Subject: re PR lto/44143 (-fdump-tree-all for lto does not work as expected) 2010-05-18 Richard Guenther PR lto/44143 * lto-wrapper.c (verbose): New variable. Initialize from -v. (debug): Initialize from -save-temps. (collect_execute): Print command-line when verbose. (run_gcc): Always use COLLECT_GCC_OPTIONS. Use fork_execute for ltrans invocation. Produce -dumpbase flag again. (process_args): Remove. (main): Simplify. * collect2.c (maybe_run_lto_and_relink): Only pass object files to lto-wrapper. * gcc.c (LINK_COMMAND_SPEC): Likewise. From-SVN: r159536 --- gcc/ChangeLog | 14 +++ gcc/collect2.c | 43 +------ gcc/gcc.c | 6 - gcc/lto-wrapper.c | 368 +++++++++++++++++++++--------------------------------- 4 files changed, 159 insertions(+), 272 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4519c0ae..1327cf9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2010-05-18 Richard Guenther + + PR lto/44143 + * lto-wrapper.c (verbose): New variable. Initialize from -v. + (debug): Initialize from -save-temps. + (collect_execute): Print command-line when verbose. + (run_gcc): Always use COLLECT_GCC_OPTIONS. Use fork_execute + for ltrans invocation. Produce -dumpbase flag again. + (process_args): Remove. + (main): Simplify. + * collect2.c (maybe_run_lto_and_relink): Only pass object + files to lto-wrapper. + * gcc.c (LINK_COMMAND_SPEC): Likewise. + 2010-05-18 Jan Hubicka * opts.c (decode_options): Do not disable whopr at ipa_cp. diff --git a/gcc/collect2.c b/gcc/collect2.c index 5322e10..0669a4e 100644 --- a/gcc/collect2.c +++ b/gcc/collect2.c @@ -940,10 +940,8 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst, if (lto_objects.first) { - const char *opts; char **lto_c_argv; const char **lto_c_ptr; - const char *cp; const char **p, **q, **r; const char **lto_o_ptr; struct lto_object *list; @@ -954,52 +952,15 @@ maybe_run_lto_and_relink (char **lto_ld_argv, char **object_lst, if (!lto_wrapper) fatal ("COLLECT_LTO_WRAPPER must be set."); + num_lto_c_args++; + /* There is at least one object file containing LTO info, so we need to run the LTO back end and relink. */ - /* Get compiler options passed down from the parent `gcc' command. - These must be passed to the LTO back end. */ - opts = getenv ("COLLECT_GCC_OPTIONS"); - - /* Increment the argument count by the number of inherited options. - Some arguments may be filtered out later. Again, an upper bound - suffices. */ - - cp = opts; - - while (cp && *cp) - { - extract_string (&cp); - num_lto_c_args++; - } - obstack_free (&temporary_obstack, temporary_firstobj); - - if (debug) - num_lto_c_args++; - - /* Increment the argument count by the number of initial - arguments added below. */ - num_lto_c_args += 9; - lto_c_argv = (char **) xcalloc (sizeof (char *), num_lto_c_args); lto_c_ptr = CONST_CAST2 (const char **, char **, lto_c_argv); *lto_c_ptr++ = lto_wrapper; - *lto_c_ptr++ = c_file_name; - - cp = opts; - - while (cp && *cp) - { - const char *s = extract_string (&cp); - - /* Pass the option or argument to the wrapper. */ - *lto_c_ptr++ = xstrdup (s); - } - obstack_free (&temporary_obstack, temporary_firstobj); - - if (debug) - *lto_c_ptr++ = xstrdup ("-debug"); /* Add LTO objects to the wrapper command line. */ for (list = lto_objects.first; list; list = list->next) diff --git a/gcc/gcc.c b/gcc/gcc.c index 6455437..41569fc 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -781,15 +781,9 @@ proper position among the other output files. */ %{fuse-linker-plugin: \ -plugin %(linker_plugin_file) \ -plugin-opt=%(lto_wrapper) \ - -plugin-opt=%(lto_gcc) \ -plugin-opt=-fresolution=%u.res \ %{static|static-libgcc:-plugin-opt=-pass-through=%(lto_libgcc)} \ %{static:-plugin-opt=-pass-through=-lc} \ - %{O*:-plugin-opt=-O%*} \ - %{w:-plugin-opt=-w} \ - %{f*:-plugin-opt=-f%*} \ - %{m*:-plugin-opt=-m%*} \ - %{v:-plugin-opt=-v} \ } \ %{flto} %{fwhopr} %l " LINK_PIE_SPEC \ "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\ diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c index 3d88c8f..5c9650e 100644 --- a/gcc/lto-wrapper.c +++ b/gcc/lto-wrapper.c @@ -45,12 +45,13 @@ along with GCC; see the file COPYING3. If not see #include "libiberty.h" #include "obstack.h" -int debug; /* true if -debug */ +int debug; /* true if -save-temps. */ +int verbose; /* true if -v. */ enum lto_mode_d { - LTO_MODE_NONE, /* Not doing LTO. */ - LTO_MODE_LTO, /* Normal LTO. */ - LTO_MODE_WHOPR /* WHOPR. */ + LTO_MODE_NONE, /* Not doing LTO. */ + LTO_MODE_LTO, /* Normal LTO. */ + LTO_MODE_WHOPR /* WHOPR. */ }; /* Current LTO mode. */ @@ -129,7 +130,7 @@ collect_execute (char **argv) const char *errmsg; int err; - if (debug) + if (verbose) { char **p_argv; const char *str; @@ -255,27 +256,118 @@ fork_execute (char **argv) static void run_gcc (unsigned argc, char *argv[]) { - unsigned i; - unsigned new_argc = argc; + unsigned i, j; const char **new_argv; const char **argv_ptr; char *list_option_full = NULL; + const char *linker_output = NULL; + const char *collect_gcc_options, *collect_gcc; + struct obstack env_obstack; + bool seen_o = false; + + /* 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"); + + /* Initalize the common arguments for the driver. */ + new_argv = (const char **) xmalloc ((15 + i / 2 + 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; + } - new_argc += 12; - new_argv = (const char **) xcalloc (sizeof (char *), new_argc); + if (strcmp (option, "-save-temps") == 0) + debug = 1; + if (strcmp (option, "-v") == 0) + verbose = 1; + + /* We've handled these LTO options, do not pass them on. */ + if (strcmp (option, "-flto") == 0) + lto_mode = LTO_MODE_LTO; + else if (strcmp (option, "-fwhopr") == 0) + lto_mode = LTO_MODE_WHOPR; + else + *argv_ptr++ = option; + } + + if (linker_output) + { + char *output_dir, *base, *name; - argv_ptr = new_argv; + output_dir = xstrdup (linker_output); + base = output_dir; + for (name = base; *name; name++) + if (IS_DIR_SEPARATOR (*name)) + base = name + 1; + *base = '\0'; + + linker_output = &linker_output[base - output_dir]; + if (*output_dir == '\0') + { + static char current_dir[] = { '.', DIR_SEPARATOR, '\0' }; + output_dir = current_dir; + } + *argv_ptr++ = "-dumpdir"; + *argv_ptr++ = output_dir; + + *argv_ptr++ = "-dumpbase"; + } + else + argv_ptr--; - *argv_ptr++ = argv[0]; - *argv_ptr++ = "-combine"; - *argv_ptr++ = "-x"; - *argv_ptr++ = "lto"; - *argv_ptr++ = "-c"; if (lto_mode == LTO_MODE_LTO) { flto_out = make_temp_file (".lto.o"); - *argv_ptr++ = "-o"; - *argv_ptr++ = flto_out; + if (linker_output) + argv_ptr[0] = linker_output; + argv_ptr[1] = "-o"; + argv_ptr[2] = flto_out; + argv_ptr[3] = "-combine"; } else if (lto_mode == LTO_MODE_WHOPR) { @@ -283,80 +375,38 @@ run_gcc (unsigned argc, char *argv[]) size_t list_option_len = strlen (list_option); char *tmp; + if (linker_output) + { + char *dumpbase = (char *) xmalloc (strlen (linker_output) + + sizeof(".wpa") + 1); + strcpy (dumpbase, linker_output); + strcat (dumpbase, ".wpa"); + argv_ptr[0] = dumpbase; + } + ltrans_output_file = make_temp_file (".ltrans.out"); list_option_full = (char *) xmalloc (sizeof (char) * (strlen (ltrans_output_file) + list_option_len + 1)); tmp = list_option_full; - *argv_ptr++ = tmp; + argv_ptr[1] = tmp; strcpy (tmp, list_option); tmp += list_option_len; strcpy (tmp, ltrans_output_file); - *argv_ptr++ = "-fwpa"; + argv_ptr[2] = "-fwpa"; + argv_ptr[3] = "-combine"; } else fatal ("invalid LTO mode"); - /* Add inherited GCC options to the LTO back end command line. - Filter out some obviously inappropriate options that will - conflict with the options that we force above. We pass - all of the remaining options on to LTO, and let it complain - about any it doesn't like. Note that we invoke LTO via the - `gcc' driver, so the usual option processing takes place. - Except for `-flto' and `-fwhopr', we should only filter options that - are meaningful to `ld', lest an option go silently unclaimed. */ - for (i = 1; i < argc; i++) - { - const char *s = argv[i]; - - if (strcmp (s, "-flto") == 0 || strcmp (s, "-fwhopr") == 0) - /* We've handled this LTO option, don't pass it on. */ - ; - else if (*s == '-' && s[1] == 'o') - { - /* Drop `-o' and its filename argument. We will use a - temporary file for the LTO output. The `-o' option - will be interpreted by the linker. */ - if (s[2] == '\0') - { - char *output_dir, *base, *name; - - i++; - output_dir = xstrdup (argv[i]); - base = output_dir; - for (name = base; *name; name++) - if (IS_DIR_SEPARATOR (*name)) - base = name + 1; - *base = '\0'; - - *argv_ptr++ = "-dumpbase"; - if (*output_dir == '\0') - { - static char current_dir[] = - { '.', DIR_SEPARATOR, '\0' }; - output_dir = current_dir; - *argv_ptr++ = argv[i]; - } - else - *argv_ptr++ = &argv[i][base - output_dir]; - - *argv_ptr++ = "-dumpdir"; - *argv_ptr++ = output_dir; - } - } - else - /* Pass the option or argument to LTO. */ - *argv_ptr++ = s; - } - - *argv_ptr = NULL; + /* Append the input objects and possible preceeding arguments. */ + for (i = 1; i < argc; ++i) + argv_ptr[3 + i] = argv[i]; + argv_ptr[3 + i] = NULL; fork_execute (CONST_CAST (char **, new_argv)); - free (new_argv); - new_argv = NULL; - if (lto_mode == LTO_MODE_LTO) { printf("%s\n", flto_out); @@ -366,85 +416,12 @@ run_gcc (unsigned argc, char *argv[]) else if (lto_mode == LTO_MODE_WHOPR) { FILE *stream = fopen (ltrans_output_file, "r"); - const char *collect_gcc_options, *collect_gcc; - struct obstack env_obstack; - bool seen_dumpbase = false; - bool seen_o = false; - char *dumpbase_suffix = NULL; - unsigned j; + int nr = 0; if (!stream) fatal_perror ("fopen: %s", ltrans_output_file); - /* 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"); - - /* Initalize the arguments for the LTRANS driver. */ - new_argv = (const char **) xmalloc ((8 + i / 2) * 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); - if (seen_dumpbase) - obstack_grow (&env_obstack, DUMPBASE_SUFFIX, - sizeof (DUMPBASE_SUFFIX)); - else - obstack_1grow (&env_obstack, 0); - option = XOBFINISH (&env_obstack, char *); - if (seen_dumpbase) - { - dumpbase_suffix = option + 7 + j - i; - seen_dumpbase = false; - } - if (seen_o) - { - seen_o = false; - continue; - } - - /* If we see -o, skip it and its argument. */ - if (strncmp (option, "-o", 2) == 0) - { - seen_o = true; - continue; - } - - /* LTRANS does not need -fwhopr. */ - if (strncmp (option, "-fwhopr", 7) != 0) - { - if (strncmp (option, "-dumpbase", 9) == 0) - seen_dumpbase = true; - *argv_ptr++ = option; - } - } - *argv_ptr++ = "-fltrans"; + argv_ptr[1] = "-fltrans"; for (;;) { @@ -473,11 +450,6 @@ cont: } else { - struct pex_obj *pex; - const char *errmsg; - int err; - int status; - /* Otherwise, add FILES[I] to lto_execute_ltrans command line and add the resulting file to LTRANS output list. */ @@ -488,44 +460,23 @@ cont: obstack_grow (&env_obstack, ".ltrans.o", sizeof (".ltrans.o")); output_name = XOBFINISH (&env_obstack, char *); - argv_ptr[0] = "-o"; - argv_ptr[1] = output_name; - argv_ptr[2] = input_name; - argv_ptr[3] = NULL; - - /* Append a sequence number to -dumpbase for LTRANS. */ - if (dumpbase_suffix) - snprintf (dumpbase_suffix, sizeof (DUMPBASE_SUFFIX) - 7, - "%lu", (unsigned long) i); - - /* Execute the driver. */ - pex = pex_init (0, "lto1", NULL); - if (pex == NULL) - fatal ("pex_init failed: %s", xstrerror (errno)); - - errmsg = pex_run (pex, PEX_LAST | PEX_SEARCH, new_argv[0], - CONST_CAST (char **, new_argv), - NULL, NULL, &err); - if (errmsg) - fatal ("%s: %s", errmsg, xstrerror (err)); - - if (!pex_get_status (pex, 1, &status)) - fatal ("can't get program status: %s", xstrerror (errno)); - - if (status) + if (linker_output) { - if (WIFSIGNALED (status)) - { - int sig = WTERMSIG (status); - fatal ("%s terminated with signal %d [%s]%s", - new_argv[0], sig, strsignal (sig), - WCOREDUMP (status) ? ", core dumped" : ""); - } - else - fatal ("%s terminated with status %d", new_argv[0], status); + char *dumpbase + = (char *) xmalloc (strlen (linker_output) + + sizeof(DUMPBASE_SUFFIX) + 1); + snprintf (dumpbase, + strlen (linker_output) + sizeof(DUMPBASE_SUFFIX), + "%s.ltrans%d", linker_output, nr++); + argv_ptr[0] = dumpbase; } - pex_free (pex); + argv_ptr[2] = "-o"; + argv_ptr[3] = output_name; + argv_ptr[4] = input_name; + argv_ptr[5] = NULL; + + fork_execute (CONST_CAST (char **, new_argv)); maybe_unlink_file (input_name); } @@ -536,38 +487,11 @@ cont: fclose (stream); maybe_unlink_file (ltrans_output_file); free (list_option_full); - obstack_free (&env_obstack, NULL); } else fatal ("invalid LTO mode"); -} - - -/* Parse the command line. Copy any unused argument to GCC_ARGV. ARGC is the - number of arguments. ARGV contains the arguments. */ - -static int -process_args (int argc, char *argv[], char *gcc_argv[]) -{ - int i; - int j = 0; - for (i = 1; i < argc; i ++) - { - if (! strcmp (argv[i], "-debug")) - debug = 1; - else if (! strcmp (argv[i], "-flto")) - lto_mode = LTO_MODE_LTO; - else if (! strcmp (argv[i], "-fwhopr")) - lto_mode = LTO_MODE_WHOPR; - else - { - gcc_argv[j] = argv[i]; - j++; - } - } - - return j; + obstack_free (&env_obstack, NULL); } @@ -576,18 +500,12 @@ process_args (int argc, char *argv[], char *gcc_argv[]) int main (int argc, char *argv[]) { - char **gcc_argv; - int gcc_argc; - gcc_init_libintl (); /* 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); - gcc_argv = (char **) xcalloc (sizeof (char *), argc); - gcc_argc = process_args (argc, argv, gcc_argv); - run_gcc (gcc_argc, gcc_argv); - free (gcc_argv); + run_gcc (argc, argv); return 0; } -- cgit v1.1