This moves lto-wrapper over to use common option processing to parse and re-emit options from COLLECT_GCC_OPTIONS. In a second step I will move the merging/complaining about different options in different LTO input files to the LTO driver (which is what lto-wrapper is).
Bootstrap and regtest pending on x86_64-unknown-linux-gnu. Joseph, does this look like a sensible use of the common machinery? Do we want the init from COLLECT_GCC_OPTIONS in opts-common.c instead? Thanks, Richard. 2011-10-25 Richard Guenther <rguent...@suse.de> * 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. Index: gcc/Makefile.in =================================================================== *** gcc/Makefile.in (revision 180429) --- gcc/Makefile.in (working copy) *************** collect2-aix.o : collect2-aix.c $(CONFIG *** 2069,2080 **** tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(OBSTACK_H) collect2.h intl.h $(DIAGNOSTIC_CORE_H) ! lto-wrapper$(exeext): lto-wrapper.o $(LIBDEPS) ! +$(LINKER) $(ALL_COMPILERFLAGS) $(LDFLAGS) -o T$@ lto-wrapper.o $(LIBS) mv -f T$@ $@ lto-wrapper.o: lto-wrapper.c $(CONFIG_H) $(SYSTEM_H) coretypes.h intl.h \ ! $(OBSTACK_H) $(DIAGNOSTIC_H) # Files used by all variants of C. c-family/c-common.o : c-family/c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ --- 2069,2081 ---- tlink.o: tlink.c $(DEMANGLE_H) $(HASHTAB_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(OBSTACK_H) collect2.h intl.h $(DIAGNOSTIC_CORE_H) ! lto-wrapper$(exeext): lto-wrapper.o ggc-none.o libcommon-target.a $(LIBDEPS) ! +$(LINKER) $(ALL_COMPILERFLAGS) $(LDFLAGS) -o T$@ \ ! lto-wrapper.o ggc-none.o libcommon-target.a $(LIBS) mv -f T$@ $@ lto-wrapper.o: lto-wrapper.c $(CONFIG_H) $(SYSTEM_H) coretypes.h intl.h \ ! $(OBSTACK_H) $(DIAGNOSTIC_H) $(OPTS_H) $(OPTIONS_H) # Files used by all variants of C. c-family/c-common.o : c-family/c-common.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ Index: gcc/lto-wrapper.c =================================================================== *** gcc/lto-wrapper.c (revision 180429) --- gcc/lto-wrapper.c (working copy) *************** along with GCC; see the file COPYING3. *** 43,48 **** --- 43,50 ---- #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. */ *************** fork_execute (char **argv) *** 280,285 **** --- 282,333 ---- /* Template of LTRANS dumpbase suffix. */ #define DUMPBASE_SUFFIX ".ltrans18446744073709551615" + /* Create decoded options from the COLLECT_GCC_OPTIONS environment. */ + + static void + get_options_from_collect_gcc_options (struct cl_decoded_option **decoded_options, + unsigned int *decoded_options_count) + { + char *collect_gcc_options; + const char **argv; + int i, j, argc; + + /* 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. */ + 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 + 1) * sizeof (char *)); + collect_gcc_options = xstrdup (collect_gcc_options); + for (i = 0, j = 0; collect_gcc_options[j] != '\0'; ++j) + { + if (collect_gcc_options[j] == '\'') + { + argv[i++] = &collect_gcc_options[++j]; + while (collect_gcc_options[j] != '\'') + ++j; + collect_gcc_options[j] = '\0'; + } + } + argv[i] = NULL; + + decode_cmdline_options_to_array (argc, (const char **)argv, + CL_COMMON | CL_TARGET, + decoded_options, decoded_options_count); + } + + /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */ static void *************** run_gcc (unsigned argc, char *argv[]) *** 290,388 **** 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; int parallel = 0; int jobserver = 0; bool no_partition = 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; ! } ! if (strcmp (option, "-save-temps") == 0) debug = 1; ! if (strcmp (option, "-v") == 0) verbose = 1; ! if (strcmp (option, "-flto-partition=none") == 0) 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; ! } if (no_partition) { lto_mode = LTO_MODE_LTO; --- 338,417 ---- const char **argv_ptr; char *list_option_full = NULL; const char *linker_output = NULL; ! const char *collect_gcc; struct obstack env_obstack; 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"); ! get_options_from_collect_gcc_options (&decoded_options, ! &decoded_options_count); ! sleep(10); /* Initalize the common arguments for the driver. */ ! 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; j < decoded_options_count; ++j) ! { ! struct cl_decoded_option *option = &decoded_options[j]; ! 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; ! break; ! ! case OPT_v: verbose = 1; + break; ! case OPT_flto_partition_none: no_partition = true; ! 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; *************** main (int argc, char *argv[]) *** 662,667 **** --- 691,697 ---- /* 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;