2011-01-30 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / gcc / lto-wrapper.c
blob6f106a31f453e8d11b34d6e2c67c22e40f74d0ed
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 WHOPR 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 "intl.h"
44 #include "obstack.h"
46 int debug; /* true if -save-temps. */
47 int verbose; /* true if -v. */
49 enum lto_mode_d {
50 LTO_MODE_NONE, /* Not doing LTO. */
51 LTO_MODE_LTO, /* Normal LTO. */
52 LTO_MODE_WHOPR /* WHOPR. */
55 /* Current LTO mode. */
56 static enum lto_mode_d lto_mode = LTO_MODE_NONE;
58 static char *ltrans_output_file;
59 static char *flto_out;
60 static char *args_name;
61 static unsigned int nr;
62 static char **input_names;
63 static char **output_names;
64 static char *makefile;
66 static void maybe_unlink_file (const char *);
68 /* Delete tempfiles. */
70 static void
71 lto_wrapper_cleanup (void)
73 static bool cleanup_done = false;
74 unsigned int i;
76 if (cleanup_done)
77 return;
79 /* Setting cleanup_done prevents an infinite loop if one of the
80 calls to maybe_unlink_file fails. */
81 cleanup_done = true;
83 if (ltrans_output_file)
84 maybe_unlink_file (ltrans_output_file);
85 if (flto_out)
86 maybe_unlink_file (flto_out);
87 if (args_name)
88 maybe_unlink_file (args_name);
89 if (makefile)
90 maybe_unlink_file (makefile);
91 for (i = 0; i < nr; ++i)
93 maybe_unlink_file (input_names[i]);
94 if (output_names[i])
95 maybe_unlink_file (output_names[i]);
99 static void
100 fatal_signal (int signum)
102 signal (signum, SIG_DFL);
103 lto_wrapper_cleanup ();
104 /* Get the same signal again, this time not handled,
105 so its normal effect occurs. */
106 kill (getpid (), signum);
109 /* Just die. CMSGID is the error message. */
111 static void __attribute__ ((format (printf, 1, 2)))
112 fatal (const char * cmsgid, ...)
114 va_list ap;
116 va_start (ap, cmsgid);
117 fprintf (stderr, "lto-wrapper: ");
118 vfprintf (stderr, _(cmsgid), ap);
119 fprintf (stderr, "\n");
120 va_end (ap);
122 lto_wrapper_cleanup ();
123 exit (FATAL_EXIT_CODE);
127 /* Die when sys call fails. CMSGID is the error message. */
129 static void __attribute__ ((format (printf, 1, 2)))
130 fatal_perror (const char *cmsgid, ...)
132 int e = errno;
133 va_list ap;
135 va_start (ap, cmsgid);
136 fprintf (stderr, "lto-wrapper: ");
137 vfprintf (stderr, _(cmsgid), ap);
138 fprintf (stderr, ": %s\n", xstrerror (e));
139 va_end (ap);
141 lto_wrapper_cleanup ();
142 exit (FATAL_EXIT_CODE);
146 /* Execute a program, and wait for the reply. ARGV are the arguments. The
147 last one must be NULL. */
149 static struct pex_obj *
150 collect_execute (char **argv)
152 struct pex_obj *pex;
153 const char *errmsg;
154 int err;
156 if (verbose)
158 char **p_argv;
159 const char *str;
161 for (p_argv = argv; (str = *p_argv) != (char *) 0; p_argv++)
162 fprintf (stderr, " %s", str);
164 fprintf (stderr, "\n");
167 fflush (stdout);
168 fflush (stderr);
170 pex = pex_init (0, "lto-wrapper", NULL);
171 if (pex == NULL)
172 fatal_perror ("pex_init failed");
174 /* Do not use PEX_LAST here, we use our stdout for communicating with
175 collect2 or the linker-plugin. Any output from the sub-process
176 will confuse that. */
177 errmsg = pex_run (pex, PEX_SEARCH, argv[0], argv, NULL,
178 NULL, &err);
179 if (errmsg != NULL)
181 if (err != 0)
183 errno = err;
184 fatal_perror (errmsg);
186 else
187 fatal (errmsg);
190 return pex;
194 /* Wait for a process to finish, and exit if a nonzero status is found.
195 PROG is the program name. PEX is the process we should wait for. */
197 static int
198 collect_wait (const char *prog, struct pex_obj *pex)
200 int status;
202 if (!pex_get_status (pex, 1, &status))
203 fatal_perror ("can't get program status");
204 pex_free (pex);
206 if (status)
208 if (WIFSIGNALED (status))
210 int sig = WTERMSIG (status);
211 if (WCOREDUMP (status))
212 fatal ("%s terminated with signal %d [%s], core dumped",
213 prog, sig, strsignal (sig));
214 else
215 fatal ("%s terminated with signal %d [%s]",
216 prog, sig, strsignal (sig));
219 if (WIFEXITED (status))
220 fatal ("%s returned %d exit status", prog, WEXITSTATUS (status));
223 return 0;
227 /* Unlink a temporary LTRANS file unless requested otherwise. */
229 static void
230 maybe_unlink_file (const char *file)
232 if (! debug)
234 if (unlink_if_ordinary (file)
235 && errno != ENOENT)
236 fatal_perror ("deleting LTRANS file %s", file);
238 else
239 fprintf (stderr, "[Leaving LTRANS %s]\n", file);
243 /* Execute program ARGV[0] with arguments ARGV. Wait for it to finish. */
245 static void
246 fork_execute (char **argv)
248 struct pex_obj *pex;
249 char *new_argv[3];
250 char *at_args;
251 FILE *args;
252 int status;
254 args_name = make_temp_file (".args");
255 at_args = concat ("@", args_name, NULL);
256 args = fopen (args_name, "w");
257 if (args == NULL)
258 fatal ("failed to open %s", args_name);
260 status = writeargv (&argv[1], args);
262 if (status)
263 fatal ("could not write to temporary file %s", args_name);
265 fclose (args);
267 new_argv[0] = argv[0];
268 new_argv[1] = at_args;
269 new_argv[2] = NULL;
271 pex = collect_execute (new_argv);
272 collect_wait (new_argv[0], pex);
274 maybe_unlink_file (args_name);
275 args_name = NULL;
276 free (at_args);
279 /* Template of LTRANS dumpbase suffix. */
280 #define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
282 /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
284 static void
285 run_gcc (unsigned argc, char *argv[])
287 unsigned i, j;
288 const char **new_argv;
289 const char **argv_ptr;
290 char *list_option_full = NULL;
291 const char *linker_output = NULL;
292 const char *collect_gcc_options, *collect_gcc;
293 struct obstack env_obstack;
294 bool seen_o = false;
295 int parallel = 0;
296 int jobserver = 0;
297 bool no_partition = false;
299 /* Get the driver and options. */
300 collect_gcc = getenv ("COLLECT_GCC");
301 if (!collect_gcc)
302 fatal ("environment variable COLLECT_GCC must be set");
304 /* Set the CFLAGS environment variable. */
305 collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
306 if (!collect_gcc_options)
307 fatal ("environment variable COLLECT_GCC_OPTIONS must be set");
309 /* Count arguments. */
310 i = 0;
311 for (j = 0; collect_gcc_options[j] != '\0'; ++j)
312 if (collect_gcc_options[j] == '\'')
313 ++i;
315 if (i % 2 != 0)
316 fatal ("malformed COLLECT_GCC_OPTIONS");
318 /* Initalize the common arguments for the driver. */
319 new_argv = (const char **) xmalloc ((15 + i / 2 + argc) * sizeof (char *));
320 argv_ptr = new_argv;
321 *argv_ptr++ = collect_gcc;
322 *argv_ptr++ = "-xlto";
323 *argv_ptr++ = "-c";
324 for (j = 0; collect_gcc_options[j] != '\0'; ++j)
325 if (collect_gcc_options[j] == '\'')
327 char *option;
329 ++j;
330 i = j;
331 while (collect_gcc_options[j] != '\'')
332 ++j;
334 obstack_init (&env_obstack);
335 obstack_grow (&env_obstack, &collect_gcc_options[i], j - i);
336 obstack_1grow (&env_obstack, 0);
337 option = XOBFINISH (&env_obstack, char *);
338 if (seen_o)
340 linker_output = option;
341 seen_o = false;
342 continue;
345 /* If we see -o, skip it and skip and record its argument. */
346 if (option[0] == '-' && option[1] == 'o')
348 if (option[2] == '\0')
349 seen_o = true;
350 else
351 linker_output = &option[2];
352 continue;
355 if (strcmp (option, "-save-temps") == 0)
356 debug = 1;
357 if (strcmp (option, "-v") == 0)
358 verbose = 1;
360 if (strcmp (option, "-flto-partition=none") == 0)
361 no_partition = true;
362 /* We've handled these LTO options, do not pass them on. */
363 if (strncmp (option, "-flto=", 6) == 0
364 || !strcmp (option, "-flto"))
366 lto_mode = LTO_MODE_WHOPR;
367 if (option[5] == '=')
369 if (!strcmp (option + 6, "jobserver"))
371 jobserver = 1;
372 parallel = 1;
374 else
376 parallel = atoi (option + 6);
377 if (parallel <= 1)
378 parallel = 0;
382 else
383 *argv_ptr++ = option;
385 if (no_partition)
387 lto_mode = LTO_MODE_LTO;
388 jobserver = 0;
389 parallel = 0;
392 if (linker_output)
394 char *output_dir, *base, *name;
396 output_dir = xstrdup (linker_output);
397 base = output_dir;
398 for (name = base; *name; name++)
399 if (IS_DIR_SEPARATOR (*name))
400 base = name + 1;
401 *base = '\0';
403 linker_output = &linker_output[base - output_dir];
404 if (*output_dir == '\0')
406 static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
407 output_dir = current_dir;
409 *argv_ptr++ = "-dumpdir";
410 *argv_ptr++ = output_dir;
412 *argv_ptr++ = "-dumpbase";
414 else
415 argv_ptr--;
417 if (lto_mode == LTO_MODE_LTO)
419 flto_out = make_temp_file (".lto.o");
420 if (linker_output)
421 argv_ptr[0] = linker_output;
422 argv_ptr[1] = "-o";
423 argv_ptr[2] = flto_out;
425 else
427 const char *list_option = "-fltrans-output-list=";
428 size_t list_option_len = strlen (list_option);
429 char *tmp;
431 if (linker_output)
433 char *dumpbase = (char *) xmalloc (strlen (linker_output)
434 + sizeof (".wpa") + 1);
435 strcpy (dumpbase, linker_output);
436 strcat (dumpbase, ".wpa");
437 argv_ptr[0] = dumpbase;
440 if (linker_output && debug)
442 ltrans_output_file = (char *) xmalloc (strlen (linker_output)
443 + sizeof (".ltrans.out") + 1);
444 strcpy (ltrans_output_file, linker_output);
445 strcat (ltrans_output_file, ".ltrans.out");
447 else
448 ltrans_output_file = make_temp_file (".ltrans.out");
449 list_option_full = (char *) xmalloc (sizeof (char) *
450 (strlen (ltrans_output_file) + list_option_len + 1));
451 tmp = list_option_full;
453 argv_ptr[1] = tmp;
454 strcpy (tmp, list_option);
455 tmp += list_option_len;
456 strcpy (tmp, ltrans_output_file);
458 argv_ptr[2] = "-fwpa";
461 /* Append the input objects and possible preceeding arguments. */
462 for (i = 1; i < argc; ++i)
463 argv_ptr[2 + i] = argv[i];
464 argv_ptr[2 + i] = NULL;
466 fork_execute (CONST_CAST (char **, new_argv));
468 if (lto_mode == LTO_MODE_LTO)
470 printf("%s\n", flto_out);
471 free (flto_out);
472 flto_out = NULL;
474 else
476 FILE *stream = fopen (ltrans_output_file, "r");
477 FILE *mstream = NULL;
479 if (!stream)
480 fatal_perror ("fopen: %s", ltrans_output_file);
482 /* Parse the list of LTRANS inputs from the WPA stage. */
483 nr = 0;
484 for (;;)
486 const unsigned piece = 32;
487 char *output_name = NULL;
488 char *buf, *input_name = (char *)xmalloc (piece);
489 size_t len;
491 buf = input_name;
492 cont:
493 if (!fgets (buf, piece, stream))
494 break;
495 len = strlen (input_name);
496 if (input_name[len - 1] != '\n')
498 input_name = (char *)xrealloc (input_name, len + piece);
499 buf = input_name + len;
500 goto cont;
502 input_name[len - 1] = '\0';
504 if (input_name[0] == '*')
505 output_name = &input_name[1];
507 nr++;
508 input_names = (char **)xrealloc (input_names, nr * sizeof (char *));
509 output_names = (char **)xrealloc (output_names, nr * sizeof (char *));
510 input_names[nr-1] = input_name;
511 output_names[nr-1] = output_name;
513 fclose (stream);
514 maybe_unlink_file (ltrans_output_file);
515 ltrans_output_file = NULL;
517 if (parallel)
519 makefile = make_temp_file (".mk");
520 mstream = fopen (makefile, "w");
523 /* Execute the LTRANS stage for each input file (or prepare a
524 makefile to invoke this in parallel). */
525 for (i = 0; i < nr; ++i)
527 char *output_name;
528 char *input_name = input_names[i];
529 /* If it's a pass-through file do nothing. */
530 if (output_names[i])
531 continue;
533 /* Replace the .o suffix with a .ltrans.o suffix and write
534 the resulting name to the LTRANS output list. */
535 obstack_init (&env_obstack);
536 obstack_grow (&env_obstack, input_name, strlen (input_name) - 2);
537 obstack_grow (&env_obstack, ".ltrans.o", sizeof (".ltrans.o"));
538 output_name = XOBFINISH (&env_obstack, char *);
540 /* Adjust the dumpbase if the linker output file was seen. */
541 if (linker_output)
543 char *dumpbase
544 = (char *) xmalloc (strlen (linker_output)
545 + sizeof(DUMPBASE_SUFFIX) + 1);
546 snprintf (dumpbase,
547 strlen (linker_output) + sizeof(DUMPBASE_SUFFIX),
548 "%s.ltrans%u", linker_output, i);
549 argv_ptr[0] = dumpbase;
552 argv_ptr[1] = "-fltrans";
553 argv_ptr[2] = "-o";
554 argv_ptr[3] = output_name;
555 argv_ptr[4] = input_name;
556 argv_ptr[5] = NULL;
557 if (parallel)
559 fprintf (mstream, "%s:\n\t@%s ", output_name, new_argv[0]);
560 for (j = 1; new_argv[j] != NULL; ++j)
561 fprintf (mstream, " '%s'", new_argv[j]);
562 fprintf (mstream, "\n");
564 else
565 fork_execute (CONST_CAST (char **, new_argv));
567 output_names[i] = output_name;
569 if (parallel)
571 struct pex_obj *pex;
572 char jobs[32];
574 fprintf (mstream, "all:");
575 for (i = 0; i < nr; ++i)
576 fprintf (mstream, " \\\n\t%s", output_names[i]);
577 fprintf (mstream, "\n");
578 fclose (mstream);
579 if (!jobserver)
581 /* Avoid passing --jobserver-fd= and similar flags
582 unless jobserver mode is explicitly enabled. */
583 putenv (xstrdup ("MAKEFLAGS="));
584 putenv (xstrdup ("MFLAGS="));
586 new_argv[0] = getenv ("MAKE");
587 if (!new_argv[0])
588 new_argv[0] = "make";
589 new_argv[1] = "-f";
590 new_argv[2] = makefile;
591 i = 3;
592 if (!jobserver)
594 snprintf (jobs, 31, "-j%d", parallel);
595 new_argv[i++] = jobs;
597 new_argv[i++] = "all";
598 new_argv[i++] = NULL;
599 pex = collect_execute (CONST_CAST (char **, new_argv));
600 collect_wait (new_argv[0], pex);
601 maybe_unlink_file (makefile);
602 makefile = NULL;
604 for (i = 0; i < nr; ++i)
606 fputs (output_names[i], stdout);
607 putc ('\n', stdout);
608 maybe_unlink_file (input_names[i]);
609 free (input_names[i]);
611 nr = 0;
612 free (output_names);
613 free (input_names);
614 free (list_option_full);
617 obstack_free (&env_obstack, NULL);
621 /* Entry point. */
624 main (int argc, char *argv[])
626 gcc_init_libintl ();
628 if (signal (SIGINT, SIG_IGN) != SIG_IGN)
629 signal (SIGINT, fatal_signal);
630 #ifdef SIGHUP
631 if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
632 signal (SIGHUP, fatal_signal);
633 #endif
634 if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
635 signal (SIGTERM, fatal_signal);
636 #ifdef SIGPIPE
637 if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
638 signal (SIGPIPE, fatal_signal);
639 #endif
640 #ifdef SIGCHLD
641 /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
642 receive the signal. A different setting is inheritable */
643 signal (SIGCHLD, SIG_DFL);
644 #endif
646 /* We may be called with all the arguments stored in some file and
647 passed with @file. Expand them into argv before processing. */
648 expandargv (&argc, &argv);
649 run_gcc (argc, argv);
651 return 0;