Multiple exit loop handling in ivopts. Regression tested on x86-64/linux
[official-gcc.git] / gcc / lto-wrapper.c
blobda120b38e58fcc0ea319f9dcf5e07119cb8a87f7
1 /* Wrapper to call lto. Used by collect2 and the linker plugin.
2 Copyright (C) 2009, 2010 Free Software Foundation, Inc.
4 Factored out of collect2 by Rafael Espindola <espindola@google.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
23 /* This program is passed a gcc, a list of gcc arguments and a list of
24 object files containing IL. It scans the argument list to check if
25 we are in whopr mode or not modifies the arguments and needed and
26 prints a list of output files on stdout.
28 Example:
30 $ lto-wrapper gcc/xgcc -B gcc a.o b.o -o test -flto
32 The above will print something like
33 /tmp/ccwbQ8B2.lto.o
35 If -fwhopr is used instead, more than one file might be produced
36 ./ccXj2DTk.lto.ltrans.o
37 ./ccCJuXGv.lto.ltrans.o
40 #include "config.h"
41 #include "system.h"
42 #include "coretypes.h"
43 #include <errno.h>
44 #include <signal.h>
45 #if ! defined( SIGCHLD ) && defined( SIGCLD )
46 # define SIGCHLD SIGCLD
47 #endif
48 #include "intl.h"
49 #include "libiberty.h"
50 #include "obstack.h"
52 #ifndef HAVE_KILL
53 #define kill(p,s) raise(s)
54 #endif
56 int debug; /* true if -save-temps. */
57 int verbose; /* true if -v. */
59 enum lto_mode_d {
60 LTO_MODE_NONE, /* Not doing LTO. */
61 LTO_MODE_LTO, /* Normal LTO. */
62 LTO_MODE_WHOPR /* WHOPR. */
65 /* Current LTO mode. */
66 static enum lto_mode_d lto_mode = LTO_MODE_NONE;
68 static char *ltrans_output_file;
69 static char *flto_out;
70 static char *args_name;
71 static unsigned int nr;
72 static char **input_names;
73 static char **output_names;
74 static char *makefile;
76 static void maybe_unlink_file (const char *);
78 /* Delete tempfiles. */
80 static void
81 lto_wrapper_cleanup (void)
83 static bool cleanup_done = false;
84 unsigned int i;
86 if (cleanup_done)
87 return;
89 /* Setting cleanup_done prevents an infinite loop if one of the
90 calls to maybe_unlink_file fails. */
91 cleanup_done = true;
93 if (ltrans_output_file)
94 maybe_unlink_file (ltrans_output_file);
95 if (flto_out)
96 maybe_unlink_file (flto_out);
97 if (args_name)
98 maybe_unlink_file (args_name);
99 if (makefile)
100 maybe_unlink_file (makefile);
101 for (i = 0; i < nr; ++i)
103 maybe_unlink_file (input_names[i]);
104 if (output_names[i])
105 maybe_unlink_file (output_names[i]);
109 static void
110 fatal_signal (int signum)
112 signal (signum, SIG_DFL);
113 lto_wrapper_cleanup ();
114 /* Get the same signal again, this time not handled,
115 so its normal effect occurs. */
116 kill (getpid (), signum);
119 /* Just die. CMSGID is the error message. */
121 static void __attribute__ ((format (printf, 1, 2)))
122 fatal (const char * cmsgid, ...)
124 va_list ap;
126 va_start (ap, cmsgid);
127 fprintf (stderr, "lto-wrapper: ");
128 vfprintf (stderr, _(cmsgid), ap);
129 fprintf (stderr, "\n");
130 va_end (ap);
132 lto_wrapper_cleanup ();
133 exit (FATAL_EXIT_CODE);
137 /* Die when sys call fails. CMSGID is the error message. */
139 static void __attribute__ ((format (printf, 1, 2)))
140 fatal_perror (const char *cmsgid, ...)
142 int e = errno;
143 va_list ap;
145 va_start (ap, cmsgid);
146 fprintf (stderr, "lto-wrapper: ");
147 vfprintf (stderr, _(cmsgid), ap);
148 fprintf (stderr, ": %s\n", xstrerror (e));
149 va_end (ap);
151 lto_wrapper_cleanup ();
152 exit (FATAL_EXIT_CODE);
156 /* Execute a program, and wait for the reply. ARGV are the arguments. The
157 last one must be NULL. */
159 static struct pex_obj *
160 collect_execute (char **argv)
162 struct pex_obj *pex;
163 const char *errmsg;
164 int err;
166 if (verbose)
168 char **p_argv;
169 const char *str;
171 for (p_argv = argv; (str = *p_argv) != (char *) 0; p_argv++)
172 fprintf (stderr, " %s", str);
174 fprintf (stderr, "\n");
177 fflush (stdout);
178 fflush (stderr);
180 pex = pex_init (0, "lto-wrapper", NULL);
181 if (pex == NULL)
182 fatal_perror ("pex_init failed");
184 /* Do not use PEX_LAST here, we use our stdout for communicating with
185 collect2 or the linker-plugin. Any output from the sub-process
186 will confuse that. */
187 errmsg = pex_run (pex, PEX_SEARCH, argv[0], argv, NULL,
188 NULL, &err);
189 if (errmsg != NULL)
191 if (err != 0)
193 errno = err;
194 fatal_perror (errmsg);
196 else
197 fatal (errmsg);
200 return pex;
204 /* Wait for a process to finish, and exit if a nonzero status is found.
205 PROG is the program name. PEX is the process we should wait for. */
207 static int
208 collect_wait (const char *prog, struct pex_obj *pex)
210 int status;
212 if (!pex_get_status (pex, 1, &status))
213 fatal_perror ("can't get program status");
214 pex_free (pex);
216 if (status)
218 if (WIFSIGNALED (status))
220 int sig = WTERMSIG (status);
221 if (WCOREDUMP (status))
222 fatal ("%s terminated with signal %d [%s], core dumped",
223 prog, sig, strsignal (sig));
224 else
225 fatal ("%s terminated with signal %d [%s]",
226 prog, sig, strsignal (sig));
229 if (WIFEXITED (status))
230 fatal ("%s returned %d exit status", prog, WEXITSTATUS (status));
233 return 0;
237 /* Unlink a temporary LTRANS file unless requested otherwise. */
239 static void
240 maybe_unlink_file (const char *file)
242 if (! debug)
244 if (unlink_if_ordinary (file)
245 && errno != ENOENT)
246 fatal_perror ("deleting LTRANS file %s", file);
248 else
249 fprintf (stderr, "[Leaving LTRANS %s]\n", file);
253 /* Execute program ARGV[0] with arguments ARGV. Wait for it to finish. */
255 static void
256 fork_execute (char **argv)
258 struct pex_obj *pex;
259 char *new_argv[3];
260 char *at_args;
261 FILE *args;
262 int status;
264 args_name = make_temp_file (".args");
265 at_args = concat ("@", args_name, NULL);
266 args = fopen (args_name, "w");
267 if (args == NULL)
268 fatal ("failed to open %s", args_name);
270 status = writeargv (&argv[1], args);
272 if (status)
273 fatal ("could not write to temporary file %s", args_name);
275 fclose (args);
277 new_argv[0] = argv[0];
278 new_argv[1] = at_args;
279 new_argv[2] = NULL;
281 pex = collect_execute (new_argv);
282 collect_wait (new_argv[0], pex);
284 maybe_unlink_file (args_name);
285 args_name = NULL;
286 free (at_args);
289 /* Template of LTRANS dumpbase suffix. */
290 #define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
292 /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
294 static void
295 run_gcc (unsigned argc, char *argv[])
297 unsigned i, j;
298 const char **new_argv;
299 const char **argv_ptr;
300 char *list_option_full = NULL;
301 const char *linker_output = NULL;
302 const char *collect_gcc_options, *collect_gcc;
303 struct obstack env_obstack;
304 bool seen_o = false;
305 int parallel = 0;
307 /* Get the driver and options. */
308 collect_gcc = getenv ("COLLECT_GCC");
309 if (!collect_gcc)
310 fatal ("environment variable COLLECT_GCC must be set");
312 /* Set the CFLAGS environment variable. */
313 collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
314 if (!collect_gcc_options)
315 fatal ("environment variable COLLECT_GCC_OPTIONS must be set");
317 /* Count arguments. */
318 i = 0;
319 for (j = 0; collect_gcc_options[j] != '\0'; ++j)
320 if (collect_gcc_options[j] == '\'')
321 ++i;
323 if (i % 2 != 0)
324 fatal ("malformed COLLECT_GCC_OPTIONS");
326 /* Initalize the common arguments for the driver. */
327 new_argv = (const char **) xmalloc ((15 + i / 2 + argc) * sizeof (char *));
328 argv_ptr = new_argv;
329 *argv_ptr++ = collect_gcc;
330 *argv_ptr++ = "-xlto";
331 *argv_ptr++ = "-c";
332 for (j = 0; collect_gcc_options[j] != '\0'; ++j)
333 if (collect_gcc_options[j] == '\'')
335 char *option;
337 ++j;
338 i = j;
339 while (collect_gcc_options[j] != '\'')
340 ++j;
342 obstack_init (&env_obstack);
343 obstack_grow (&env_obstack, &collect_gcc_options[i], j - i);
344 obstack_1grow (&env_obstack, 0);
345 option = XOBFINISH (&env_obstack, char *);
346 if (seen_o)
348 linker_output = option;
349 seen_o = false;
350 continue;
353 /* If we see -o, skip it and skip and record its argument. */
354 if (option[0] == '-' && option[1] == 'o')
356 if (option[2] == '\0')
357 seen_o = true;
358 else
359 linker_output = &option[2];
360 continue;
363 if (strcmp (option, "-save-temps") == 0)
364 debug = 1;
365 if (strcmp (option, "-v") == 0)
366 verbose = 1;
368 /* We've handled these LTO options, do not pass them on. */
369 if (strcmp (option, "-flto") == 0)
370 lto_mode = LTO_MODE_LTO;
371 else if (strncmp (option, "-fwhopr", 7) == 0)
373 lto_mode = LTO_MODE_WHOPR;
374 if (option[7] == '=')
376 parallel = atoi (option+8);
377 if (parallel <= 1)
378 parallel = 0;
381 else
382 *argv_ptr++ = option;
385 if (linker_output)
387 char *output_dir, *base, *name;
389 output_dir = xstrdup (linker_output);
390 base = output_dir;
391 for (name = base; *name; name++)
392 if (IS_DIR_SEPARATOR (*name))
393 base = name + 1;
394 *base = '\0';
396 linker_output = &linker_output[base - output_dir];
397 if (*output_dir == '\0')
399 static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
400 output_dir = current_dir;
402 *argv_ptr++ = "-dumpdir";
403 *argv_ptr++ = output_dir;
405 *argv_ptr++ = "-dumpbase";
407 else
408 argv_ptr--;
410 if (lto_mode == LTO_MODE_LTO)
412 flto_out = make_temp_file (".lto.o");
413 if (linker_output)
414 argv_ptr[0] = linker_output;
415 argv_ptr[1] = "-o";
416 argv_ptr[2] = flto_out;
417 argv_ptr[3] = "-combine";
419 else if (lto_mode == LTO_MODE_WHOPR)
421 const char *list_option = "-fltrans-output-list=";
422 size_t list_option_len = strlen (list_option);
423 char *tmp;
425 if (linker_output)
427 char *dumpbase = (char *) xmalloc (strlen (linker_output)
428 + sizeof (".wpa") + 1);
429 strcpy (dumpbase, linker_output);
430 strcat (dumpbase, ".wpa");
431 argv_ptr[0] = dumpbase;
434 if (linker_output && debug)
436 ltrans_output_file = (char *) xmalloc (strlen (linker_output)
437 + sizeof (".ltrans.out") + 1);
438 strcpy (ltrans_output_file, linker_output);
439 strcat (ltrans_output_file, ".ltrans.out");
441 else
442 ltrans_output_file = make_temp_file (".ltrans.out");
443 list_option_full = (char *) xmalloc (sizeof (char) *
444 (strlen (ltrans_output_file) + list_option_len + 1));
445 tmp = list_option_full;
447 argv_ptr[1] = tmp;
448 strcpy (tmp, list_option);
449 tmp += list_option_len;
450 strcpy (tmp, ltrans_output_file);
452 argv_ptr[2] = "-fwpa";
453 argv_ptr[3] = "-combine";
455 else
456 fatal ("invalid LTO mode");
458 /* Append the input objects and possible preceeding arguments. */
459 for (i = 1; i < argc; ++i)
460 argv_ptr[3 + i] = argv[i];
461 argv_ptr[3 + i] = NULL;
463 fork_execute (CONST_CAST (char **, new_argv));
465 if (lto_mode == LTO_MODE_LTO)
467 printf("%s\n", flto_out);
468 free (flto_out);
469 flto_out = NULL;
471 else if (lto_mode == LTO_MODE_WHOPR)
473 FILE *stream = fopen (ltrans_output_file, "r");
474 FILE *mstream = NULL;
476 if (!stream)
477 fatal_perror ("fopen: %s", ltrans_output_file);
479 /* Parse the list of LTRANS inputs from the WPA stage. */
480 nr = 0;
481 for (;;)
483 const unsigned piece = 32;
484 char *output_name = NULL;
485 char *buf, *input_name = (char *)xmalloc (piece);
486 size_t len;
488 buf = input_name;
489 cont:
490 if (!fgets (buf, piece, stream))
491 break;
492 len = strlen (input_name);
493 if (input_name[len - 1] != '\n')
495 input_name = (char *)xrealloc (input_name, len + piece);
496 buf = input_name + len;
497 goto cont;
499 input_name[len - 1] = '\0';
501 if (input_name[0] == '*')
502 output_name = &input_name[1];
504 nr++;
505 input_names = (char **)xrealloc (input_names, nr * sizeof (char *));
506 output_names = (char **)xrealloc (output_names, nr * sizeof (char *));
507 input_names[nr-1] = input_name;
508 output_names[nr-1] = output_name;
510 fclose (stream);
511 maybe_unlink_file (ltrans_output_file);
512 ltrans_output_file = NULL;
514 if (parallel)
516 makefile = make_temp_file (".mk");
517 mstream = fopen (makefile, "w");
520 /* Execute the LTRANS stage for each input file (or prepare a
521 makefile to invoke this in parallel). */
522 for (i = 0; i < nr; ++i)
524 char *output_name;
525 char *input_name = input_names[i];
526 /* If it's a pass-through file do nothing. */
527 if (output_names[i])
528 continue;
530 /* Replace the .o suffix with a .ltrans.o suffix and write
531 the resulting name to the LTRANS output list. */
532 obstack_init (&env_obstack);
533 obstack_grow (&env_obstack, input_name, strlen (input_name) - 2);
534 obstack_grow (&env_obstack, ".ltrans.o", sizeof (".ltrans.o"));
535 output_name = XOBFINISH (&env_obstack, char *);
537 /* Adjust the dumpbase if the linker output file was seen. */
538 if (linker_output)
540 char *dumpbase
541 = (char *) xmalloc (strlen (linker_output)
542 + sizeof(DUMPBASE_SUFFIX) + 1);
543 snprintf (dumpbase,
544 strlen (linker_output) + sizeof(DUMPBASE_SUFFIX),
545 "%s.ltrans%u", linker_output, i);
546 argv_ptr[0] = dumpbase;
549 argv_ptr[1] = "-fltrans";
550 argv_ptr[2] = "-o";
551 argv_ptr[3] = output_name;
552 argv_ptr[4] = input_name;
553 argv_ptr[5] = NULL;
554 if (parallel)
556 fprintf (mstream, "%s:\n\t@%s ", output_name, new_argv[0]);
557 for (j = 1; new_argv[j] != NULL; ++j)
558 fprintf (mstream, " '%s'", new_argv[j]);
559 fprintf (mstream, "\n");
561 else
562 fork_execute (CONST_CAST (char **, new_argv));
564 output_names[i] = output_name;
566 if (parallel)
568 struct pex_obj *pex;
569 char jobs[32];
570 fprintf (mstream, "all:");
571 for (i = 0; i < nr; ++i)
572 fprintf (mstream, " \\\n\t%s", output_names[i]);
573 fprintf (mstream, "\n");
574 fclose (mstream);
575 /* Avoid passing --jobserver-fd= and similar flags. */
576 putenv (xstrdup ("MAKEFLAGS="));
577 putenv (xstrdup ("MFLAGS="));
578 new_argv[0] = getenv ("MAKE");
579 if (!new_argv[0])
580 new_argv[0] = "make";
581 new_argv[1] = "-f";
582 new_argv[2] = makefile;
583 snprintf (jobs, 31, "-j%d", parallel);
584 new_argv[3] = jobs;
585 new_argv[4] = "all";
586 new_argv[5] = NULL;
587 pex = collect_execute (CONST_CAST (char **, new_argv));
588 collect_wait (new_argv[0], pex);
589 maybe_unlink_file (makefile);
590 makefile = NULL;
592 for (i = 0; i < nr; ++i)
594 fputs (output_names[i], stdout);
595 putc ('\n', stdout);
596 maybe_unlink_file (input_names[i]);
597 free (input_names[i]);
599 nr = 0;
600 free (output_names);
601 free (input_names);
602 free (list_option_full);
604 else
605 fatal ("invalid LTO mode");
607 obstack_free (&env_obstack, NULL);
611 /* Entry point. */
614 main (int argc, char *argv[])
616 gcc_init_libintl ();
618 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
619 signal (SIGINT, fatal_signal);
620 #ifdef SIGHUP
621 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
622 signal (SIGHUP, fatal_signal);
623 #endif
624 if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
625 signal (SIGTERM, fatal_signal);
626 #ifdef SIGPIPE
627 if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
628 signal (SIGPIPE, fatal_signal);
629 #endif
630 #ifdef SIGCHLD
631 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
632 receive the signal. A different setting is inheritable */
633 signal (SIGCHLD, SIG_DFL);
634 #endif
636 /* We may be called with all the arguments stored in some file and
637 passed with @file. Expand them into argv before processing. */
638 expandargv (&argc, &argv);
639 run_gcc (argc, argv);
641 return 0;