Mercurial > hg > CbC > CbC_gcc
diff gcc/lto-wrapper.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
line wrap: on
line diff
--- a/gcc/lto-wrapper.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/lto-wrapper.c Tue Mar 22 17:18:12 2011 +0900 @@ -32,7 +32,7 @@ The above will print something like /tmp/ccwbQ8B2.lto.o - If -fwhopr is used instead, more than one file might be produced + If WHOPR is used instead, more than one file might be produced ./ccXj2DTk.lto.ltrans.o ./ccCJuXGv.lto.ltrans.o */ @@ -40,9 +40,7 @@ #include "config.h" #include "system.h" #include "coretypes.h" -#include "tm.h" #include "intl.h" -#include "libiberty.h" #include "obstack.h" int debug; /* true if -save-temps. */ @@ -60,29 +58,52 @@ static char *ltrans_output_file; static char *flto_out; static char *args_name; +static unsigned int nr; +static char **input_names; +static char **output_names; +static char *makefile; static void maybe_unlink_file (const char *); -/* Delete tempfiles and exit function. */ + /* Delete tempfiles. */ static void -lto_wrapper_exit (int status) +lto_wrapper_cleanup (void) { static bool cleanup_done = false; - if (!cleanup_done) - { - /* Setting cleanup_done prevents an infinite loop if one of the - calls to maybe_unlink_file fails. */ - cleanup_done = true; + unsigned int i; + + if (cleanup_done) + return; + + /* Setting cleanup_done prevents an infinite loop if one of the + calls to maybe_unlink_file fails. */ + cleanup_done = true; - if (ltrans_output_file) - maybe_unlink_file (ltrans_output_file); - if (flto_out) - maybe_unlink_file (flto_out); - if (args_name) - maybe_unlink_file (args_name); + if (ltrans_output_file) + maybe_unlink_file (ltrans_output_file); + if (flto_out) + maybe_unlink_file (flto_out); + if (args_name) + maybe_unlink_file (args_name); + if (makefile) + maybe_unlink_file (makefile); + for (i = 0; i < nr; ++i) + { + maybe_unlink_file (input_names[i]); + if (output_names[i]) + maybe_unlink_file (output_names[i]); } - exit (status); +} + +static void +fatal_signal (int signum) +{ + signal (signum, SIG_DFL); + lto_wrapper_cleanup (); + /* Get the same signal again, this time not handled, + so its normal effect occurs. */ + kill (getpid (), signum); } /* Just die. CMSGID is the error message. */ @@ -98,7 +119,8 @@ fprintf (stderr, "\n"); va_end (ap); - lto_wrapper_exit (FATAL_EXIT_CODE); + lto_wrapper_cleanup (); + exit (FATAL_EXIT_CODE); } @@ -116,7 +138,8 @@ fprintf (stderr, ": %s\n", xstrerror (e)); va_end (ap); - lto_wrapper_exit (FATAL_EXIT_CODE); + lto_wrapper_cleanup (); + exit (FATAL_EXIT_CODE); } @@ -208,7 +231,8 @@ { if (! debug) { - if (unlink_if_ordinary (file)) + if (unlink_if_ordinary (file) + && errno != ENOENT) fatal_perror ("deleting LTRANS file %s", file); } else @@ -248,6 +272,7 @@ collect_wait (new_argv[0], pex); maybe_unlink_file (args_name); + args_name = NULL; free (at_args); } @@ -268,6 +293,8 @@ 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"); @@ -330,26 +357,42 @@ 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 (strcmp (option, "-flto") == 0) - lto_mode = LTO_MODE_LTO; - else if (strncmp (option, "-fwhopr", 7) == 0) + if (strncmp (option, "-flto=", 6) == 0 + || !strcmp (option, "-flto")) { lto_mode = LTO_MODE_WHOPR; - if (option[7] == '=') + if (option[5] == '=') { - parallel = atoi (option+8); - if (parallel <= 1) - parallel = 0; + 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; + jobserver = 0; + parallel = 0; + } if (linker_output) { char *output_dir, *base, *name; + bool bit_bucket = strcmp (linker_output, HOST_BIT_BUCKET) == 0; output_dir = xstrdup (linker_output); base = output_dir; @@ -364,8 +407,11 @@ static char current_dir[] = { '.', DIR_SEPARATOR, '\0' }; output_dir = current_dir; } - *argv_ptr++ = "-dumpdir"; - *argv_ptr++ = output_dir; + if (!bit_bucket) + { + *argv_ptr++ = "-dumpdir"; + *argv_ptr++ = output_dir; + } *argv_ptr++ = "-dumpbase"; } @@ -379,9 +425,8 @@ 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) + else { const char *list_option = "-fltrans-output-list="; size_t list_option_len = strlen (list_option); @@ -390,13 +435,21 @@ if (linker_output) { char *dumpbase = (char *) xmalloc (strlen (linker_output) - + sizeof(".wpa") + 1); + + sizeof (".wpa") + 1); strcpy (dumpbase, linker_output); strcat (dumpbase, ".wpa"); argv_ptr[0] = dumpbase; } - ltrans_output_file = make_temp_file (".ltrans.out"); + if (linker_output && debug) + { + ltrans_output_file = (char *) xmalloc (strlen (linker_output) + + sizeof (".ltrans.out") + 1); + strcpy (ltrans_output_file, linker_output); + strcat (ltrans_output_file, ".ltrans.out"); + } + else + 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; @@ -407,15 +460,12 @@ strcpy (tmp, ltrans_output_file); argv_ptr[2] = "-fwpa"; - argv_ptr[3] = "-combine"; } - else - fatal ("invalid LTO mode"); /* 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; + argv_ptr[2 + i] = argv[i]; + argv_ptr[2 + i] = NULL; fork_execute (CONST_CAST (char **, new_argv)); @@ -425,30 +475,20 @@ free (flto_out); flto_out = NULL; } - else if (lto_mode == LTO_MODE_WHOPR) + else { FILE *stream = fopen (ltrans_output_file, "r"); - unsigned int nr = 0; - char **input_names = NULL; - char **output_names = NULL; - char *makefile = NULL; FILE *mstream = NULL; if (!stream) fatal_perror ("fopen: %s", ltrans_output_file); - argv_ptr[1] = "-fltrans"; - - if (parallel) - { - makefile = make_temp_file (".mk"); - mstream = fopen (makefile, "w"); - } - + /* Parse the list of LTRANS inputs from the WPA stage. */ + nr = 0; for (;;) { const unsigned piece = 32; - char *output_name; + char *output_name = NULL; char *buf, *input_name = (char *)xmalloc (piece); size_t len; @@ -467,44 +507,6 @@ if (input_name[0] == '*') output_name = &input_name[1]; - else - { - /* Otherwise, add FILES[I] to lto_execute_ltrans command line - and add the resulting file to LTRANS output list. */ - - /* Replace the .o suffix with a .ltrans.o suffix and write - the resulting name to the LTRANS output list. */ - obstack_init (&env_obstack); - obstack_grow (&env_obstack, input_name, strlen (input_name) - 2); - obstack_grow (&env_obstack, ".ltrans.o", sizeof (".ltrans.o")); - output_name = XOBFINISH (&env_obstack, char *); - - if (linker_output) - { - char *dumpbase - = (char *) xmalloc (strlen (linker_output) - + sizeof(DUMPBASE_SUFFIX) + 1); - snprintf (dumpbase, - strlen (linker_output) + sizeof(DUMPBASE_SUFFIX), - "%s.ltrans%u", linker_output, nr); - argv_ptr[0] = dumpbase; - } - - argv_ptr[2] = "-o"; - argv_ptr[3] = output_name; - argv_ptr[4] = input_name; - argv_ptr[5] = NULL; - - if (parallel) - { - fprintf (mstream, "%s:\n\t@%s ", output_name, new_argv[0]); - for (i = 1; new_argv[i] != NULL; ++i) - fprintf (mstream, " '%s'", new_argv[i]); - fprintf (mstream, "\n"); - } - else - fork_execute (CONST_CAST (char **, new_argv)); - } nr++; input_names = (char **)xrealloc (input_names, nr * sizeof (char *)); @@ -512,25 +514,96 @@ input_names[nr-1] = input_name; output_names[nr-1] = output_name; } + fclose (stream); + maybe_unlink_file (ltrans_output_file); + ltrans_output_file = NULL; + + if (parallel) + { + makefile = make_temp_file (".mk"); + mstream = fopen (makefile, "w"); + } + + /* Execute the LTRANS stage for each input file (or prepare a + makefile to invoke this in parallel). */ + for (i = 0; i < nr; ++i) + { + char *output_name; + char *input_name = input_names[i]; + /* If it's a pass-through file do nothing. */ + if (output_names[i]) + continue; + + /* Replace the .o suffix with a .ltrans.o suffix and write + the resulting name to the LTRANS output list. */ + obstack_init (&env_obstack); + obstack_grow (&env_obstack, input_name, strlen (input_name) - 2); + obstack_grow (&env_obstack, ".ltrans.o", sizeof (".ltrans.o")); + output_name = XOBFINISH (&env_obstack, char *); + + /* Adjust the dumpbase if the linker output file was seen. */ + if (linker_output) + { + char *dumpbase + = (char *) xmalloc (strlen (linker_output) + + sizeof(DUMPBASE_SUFFIX) + 1); + snprintf (dumpbase, + strlen (linker_output) + sizeof(DUMPBASE_SUFFIX), + "%s.ltrans%u", linker_output, i); + argv_ptr[0] = dumpbase; + } + + argv_ptr[1] = "-fltrans"; + argv_ptr[2] = "-o"; + argv_ptr[3] = output_name; + argv_ptr[4] = input_name; + argv_ptr[5] = NULL; + if (parallel) + { + fprintf (mstream, "%s:\n\t@%s ", output_name, new_argv[0]); + for (j = 1; new_argv[j] != NULL; ++j) + fprintf (mstream, " '%s'", new_argv[j]); + fprintf (mstream, "\n"); + } + else + fork_execute (CONST_CAST (char **, new_argv)); + + output_names[i] = output_name; + } if (parallel) { struct pex_obj *pex; char jobs[32]; + fprintf (mstream, "all:"); for (i = 0; i < nr; ++i) fprintf (mstream, " \\\n\t%s", output_names[i]); fprintf (mstream, "\n"); fclose (mstream); - new_argv[0] = "make"; + if (!jobserver) + { + /* Avoid passing --jobserver-fd= and similar flags + unless jobserver mode is explicitly enabled. */ + putenv (xstrdup ("MAKEFLAGS=")); + putenv (xstrdup ("MFLAGS=")); + } + new_argv[0] = getenv ("MAKE"); + if (!new_argv[0]) + new_argv[0] = "make"; new_argv[1] = "-f"; new_argv[2] = makefile; - snprintf (jobs, 31, "-j%d", parallel); - new_argv[3] = jobs; - new_argv[4] = "all"; - new_argv[5] = NULL; + i = 3; + if (!jobserver) + { + snprintf (jobs, 31, "-j%d", parallel); + new_argv[i++] = jobs; + } + new_argv[i++] = "all"; + new_argv[i++] = NULL; pex = collect_execute (CONST_CAST (char **, new_argv)); collect_wait (new_argv[0], pex); maybe_unlink_file (makefile); + makefile = NULL; } for (i = 0; i < nr; ++i) { @@ -539,14 +612,11 @@ maybe_unlink_file (input_names[i]); free (input_names[i]); } + nr = 0; free (output_names); free (input_names); - fclose (stream); - maybe_unlink_file (ltrans_output_file); free (list_option_full); } - else - fatal ("invalid LTO mode"); obstack_free (&env_obstack, NULL); } @@ -559,6 +629,24 @@ { gcc_init_libintl (); + if (signal (SIGINT, SIG_IGN) != SIG_IGN) + signal (SIGINT, fatal_signal); +#ifdef SIGHUP + if (signal (SIGHUP, SIG_IGN) != SIG_IGN) + signal (SIGHUP, fatal_signal); +#endif + if (signal (SIGTERM, SIG_IGN) != SIG_IGN) + signal (SIGTERM, fatal_signal); +#ifdef SIGPIPE + if (signal (SIGPIPE, SIG_IGN) != SIG_IGN) + signal (SIGPIPE, fatal_signal); +#endif +#ifdef SIGCHLD + /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will + receive the signal. A different setting is inheritable */ + signal (SIGCHLD, SIG_DFL); +#endif + /* 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);