2010-05-28 Segher Boessenkool <segher@kernel.crashing.org>
[official-gcc.git] / gcc / lto-wrapper.c
blob7454b54af79b61a6187db0eda1b5c5b45a010fd0
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 <errno.h>
43 #include "coretypes.h"
44 #include "tm.h"
45 #include "intl.h"
46 #include "libiberty.h"
47 #include "obstack.h"
49 int debug; /* true if -save-temps. */
50 int verbose; /* true if -v. */
52 enum lto_mode_d {
53 LTO_MODE_NONE, /* Not doing LTO. */
54 LTO_MODE_LTO, /* Normal LTO. */
55 LTO_MODE_WHOPR /* WHOPR. */
58 /* Current LTO mode. */
59 static enum lto_mode_d lto_mode = LTO_MODE_NONE;
61 static char *ltrans_output_file;
62 static char *flto_out;
63 static char *args_name;
64 static unsigned int nr;
65 static char **input_names;
66 static char **output_names;
67 static char *makefile;
69 static void maybe_unlink_file (const char *);
71 /* Delete tempfiles and exit function. */
73 static void
74 lto_wrapper_exit (int status)
76 static bool cleanup_done = false;
77 if (!cleanup_done)
79 unsigned int i;
81 /* Setting cleanup_done prevents an infinite loop if one of the
82 calls to maybe_unlink_file fails. */
83 cleanup_done = true;
85 if (ltrans_output_file)
86 maybe_unlink_file (ltrans_output_file);
87 if (flto_out)
88 maybe_unlink_file (flto_out);
89 if (args_name)
90 maybe_unlink_file (args_name);
91 if (makefile)
92 maybe_unlink_file (makefile);
93 for (i = 0; i < nr; ++i)
95 maybe_unlink_file (input_names[i]);
96 if (output_names[i])
97 maybe_unlink_file (output_names[i]);
100 exit (status);
103 /* Just die. CMSGID is the error message. */
105 static void __attribute__ ((format (printf, 1, 2)))
106 fatal (const char * cmsgid, ...)
108 va_list ap;
110 va_start (ap, cmsgid);
111 fprintf (stderr, "lto-wrapper: ");
112 vfprintf (stderr, _(cmsgid), ap);
113 fprintf (stderr, "\n");
114 va_end (ap);
116 lto_wrapper_exit (FATAL_EXIT_CODE);
120 /* Die when sys call fails. CMSGID is the error message. */
122 static void __attribute__ ((format (printf, 1, 2)))
123 fatal_perror (const char *cmsgid, ...)
125 int e = errno;
126 va_list ap;
128 va_start (ap, cmsgid);
129 fprintf (stderr, "lto-wrapper: ");
130 vfprintf (stderr, _(cmsgid), ap);
131 fprintf (stderr, ": %s\n", xstrerror (e));
132 va_end (ap);
134 lto_wrapper_exit (FATAL_EXIT_CODE);
138 /* Execute a program, and wait for the reply. ARGV are the arguments. The
139 last one must be NULL. */
141 static struct pex_obj *
142 collect_execute (char **argv)
144 struct pex_obj *pex;
145 const char *errmsg;
146 int err;
148 if (verbose)
150 char **p_argv;
151 const char *str;
153 for (p_argv = argv; (str = *p_argv) != (char *) 0; p_argv++)
154 fprintf (stderr, " %s", str);
156 fprintf (stderr, "\n");
159 fflush (stdout);
160 fflush (stderr);
162 pex = pex_init (0, "lto-wrapper", NULL);
163 if (pex == NULL)
164 fatal_perror ("pex_init failed");
166 /* Do not use PEX_LAST here, we use our stdout for communicating with
167 collect2 or the linker-plugin. Any output from the sub-process
168 will confuse that. */
169 errmsg = pex_run (pex, PEX_SEARCH, argv[0], argv, NULL,
170 NULL, &err);
171 if (errmsg != NULL)
173 if (err != 0)
175 errno = err;
176 fatal_perror (errmsg);
178 else
179 fatal (errmsg);
182 return pex;
186 /* Wait for a process to finish, and exit if a nonzero status is found.
187 PROG is the program name. PEX is the process we should wait for. */
189 static int
190 collect_wait (const char *prog, struct pex_obj *pex)
192 int status;
194 if (!pex_get_status (pex, 1, &status))
195 fatal_perror ("can't get program status");
196 pex_free (pex);
198 if (status)
200 if (WIFSIGNALED (status))
202 int sig = WTERMSIG (status);
203 if (WCOREDUMP (status))
204 fatal ("%s terminated with signal %d [%s], core dumped",
205 prog, sig, strsignal (sig));
206 else
207 fatal ("%s terminated with signal %d [%s]",
208 prog, sig, strsignal (sig));
211 if (WIFEXITED (status))
212 fatal ("%s returned %d exit status", prog, WEXITSTATUS (status));
215 return 0;
219 /* Unlink a temporary LTRANS file unless requested otherwise. */
221 static void
222 maybe_unlink_file (const char *file)
224 if (! debug)
226 if (unlink_if_ordinary (file)
227 && errno != ENOENT)
228 fatal_perror ("deleting LTRANS file %s", file);
230 else
231 fprintf (stderr, "[Leaving LTRANS %s]\n", file);
235 /* Execute program ARGV[0] with arguments ARGV. Wait for it to finish. */
237 static void
238 fork_execute (char **argv)
240 struct pex_obj *pex;
241 char *new_argv[3];
242 char *at_args;
243 FILE *args;
244 int status;
246 args_name = make_temp_file (".args");
247 at_args = concat ("@", args_name, NULL);
248 args = fopen (args_name, "w");
249 if (args == NULL)
250 fatal ("failed to open %s", args_name);
252 status = writeargv (&argv[1], args);
254 if (status)
255 fatal ("could not write to temporary file %s", args_name);
257 fclose (args);
259 new_argv[0] = argv[0];
260 new_argv[1] = at_args;
261 new_argv[2] = NULL;
263 pex = collect_execute (new_argv);
264 collect_wait (new_argv[0], pex);
266 maybe_unlink_file (args_name);
267 args_name = NULL;
268 free (at_args);
271 /* Template of LTRANS dumpbase suffix. */
272 #define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
274 /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
276 static void
277 run_gcc (unsigned argc, char *argv[])
279 unsigned i, j;
280 const char **new_argv;
281 const char **argv_ptr;
282 char *list_option_full = NULL;
283 const char *linker_output = NULL;
284 const char *collect_gcc_options, *collect_gcc;
285 struct obstack env_obstack;
286 bool seen_o = false;
287 int parallel = 0;
289 /* Get the driver and options. */
290 collect_gcc = getenv ("COLLECT_GCC");
291 if (!collect_gcc)
292 fatal ("environment variable COLLECT_GCC must be set");
294 /* Set the CFLAGS environment variable. */
295 collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
296 if (!collect_gcc_options)
297 fatal ("environment variable COLLECT_GCC_OPTIONS must be set");
299 /* Count arguments. */
300 i = 0;
301 for (j = 0; collect_gcc_options[j] != '\0'; ++j)
302 if (collect_gcc_options[j] == '\'')
303 ++i;
305 if (i % 2 != 0)
306 fatal ("malformed COLLECT_GCC_OPTIONS");
308 /* Initalize the common arguments for the driver. */
309 new_argv = (const char **) xmalloc ((15 + i / 2 + argc) * sizeof (char *));
310 argv_ptr = new_argv;
311 *argv_ptr++ = collect_gcc;
312 *argv_ptr++ = "-xlto";
313 *argv_ptr++ = "-c";
314 for (j = 0; collect_gcc_options[j] != '\0'; ++j)
315 if (collect_gcc_options[j] == '\'')
317 char *option;
319 ++j;
320 i = j;
321 while (collect_gcc_options[j] != '\'')
322 ++j;
324 obstack_init (&env_obstack);
325 obstack_grow (&env_obstack, &collect_gcc_options[i], j - i);
326 obstack_1grow (&env_obstack, 0);
327 option = XOBFINISH (&env_obstack, char *);
328 if (seen_o)
330 linker_output = option;
331 seen_o = false;
332 continue;
335 /* If we see -o, skip it and skip and record its argument. */
336 if (option[0] == '-' && option[1] == 'o')
338 if (option[2] == '\0')
339 seen_o = true;
340 else
341 linker_output = &option[2];
342 continue;
345 if (strcmp (option, "-save-temps") == 0)
346 debug = 1;
347 if (strcmp (option, "-v") == 0)
348 verbose = 1;
350 /* We've handled these LTO options, do not pass them on. */
351 if (strcmp (option, "-flto") == 0)
352 lto_mode = LTO_MODE_LTO;
353 else if (strncmp (option, "-fwhopr", 7) == 0)
355 lto_mode = LTO_MODE_WHOPR;
356 if (option[7] == '=')
358 parallel = atoi (option+8);
359 if (parallel <= 1)
360 parallel = 0;
363 else
364 *argv_ptr++ = option;
367 if (linker_output)
369 char *output_dir, *base, *name;
371 output_dir = xstrdup (linker_output);
372 base = output_dir;
373 for (name = base; *name; name++)
374 if (IS_DIR_SEPARATOR (*name))
375 base = name + 1;
376 *base = '\0';
378 linker_output = &linker_output[base - output_dir];
379 if (*output_dir == '\0')
381 static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
382 output_dir = current_dir;
384 *argv_ptr++ = "-dumpdir";
385 *argv_ptr++ = output_dir;
387 *argv_ptr++ = "-dumpbase";
389 else
390 argv_ptr--;
392 if (lto_mode == LTO_MODE_LTO)
394 flto_out = make_temp_file (".lto.o");
395 if (linker_output)
396 argv_ptr[0] = linker_output;
397 argv_ptr[1] = "-o";
398 argv_ptr[2] = flto_out;
399 argv_ptr[3] = "-combine";
401 else if (lto_mode == LTO_MODE_WHOPR)
403 const char *list_option = "-fltrans-output-list=";
404 size_t list_option_len = strlen (list_option);
405 char *tmp;
407 if (linker_output)
409 char *dumpbase = (char *) xmalloc (strlen (linker_output)
410 + sizeof(".wpa") + 1);
411 strcpy (dumpbase, linker_output);
412 strcat (dumpbase, ".wpa");
413 argv_ptr[0] = dumpbase;
416 ltrans_output_file = make_temp_file (".ltrans.out");
417 list_option_full = (char *) xmalloc (sizeof (char) *
418 (strlen (ltrans_output_file) + list_option_len + 1));
419 tmp = list_option_full;
421 argv_ptr[1] = tmp;
422 strcpy (tmp, list_option);
423 tmp += list_option_len;
424 strcpy (tmp, ltrans_output_file);
426 argv_ptr[2] = "-fwpa";
427 argv_ptr[3] = "-combine";
429 else
430 fatal ("invalid LTO mode");
432 /* Append the input objects and possible preceeding arguments. */
433 for (i = 1; i < argc; ++i)
434 argv_ptr[3 + i] = argv[i];
435 argv_ptr[3 + i] = NULL;
437 fork_execute (CONST_CAST (char **, new_argv));
439 if (lto_mode == LTO_MODE_LTO)
441 printf("%s\n", flto_out);
442 free (flto_out);
443 flto_out = NULL;
445 else if (lto_mode == LTO_MODE_WHOPR)
447 FILE *stream = fopen (ltrans_output_file, "r");
448 FILE *mstream = NULL;
450 if (!stream)
451 fatal_perror ("fopen: %s", ltrans_output_file);
453 /* Parse the list of LTRANS inputs from the WPA stage. */
454 nr = 0;
455 for (;;)
457 const unsigned piece = 32;
458 char *output_name = NULL;
459 char *buf, *input_name = (char *)xmalloc (piece);
460 size_t len;
462 buf = input_name;
463 cont:
464 if (!fgets (buf, piece, stream))
465 break;
466 len = strlen (input_name);
467 if (input_name[len - 1] != '\n')
469 input_name = (char *)xrealloc (input_name, len + piece);
470 buf = input_name + len;
471 goto cont;
473 input_name[len - 1] = '\0';
475 if (input_name[0] == '*')
476 output_name = &input_name[1];
478 nr++;
479 input_names = (char **)xrealloc (input_names, nr * sizeof (char *));
480 output_names = (char **)xrealloc (output_names, nr * sizeof (char *));
481 input_names[nr-1] = input_name;
482 output_names[nr-1] = output_name;
484 fclose (stream);
485 maybe_unlink_file (ltrans_output_file);
486 ltrans_output_file = NULL;
488 if (parallel)
490 makefile = make_temp_file (".mk");
491 mstream = fopen (makefile, "w");
494 /* Execute the LTRANS stage for each input file (or prepare a
495 makefile to invoke this in parallel). */
496 for (i = 0; i < nr; ++i)
498 char *output_name;
499 char *input_name = input_names[i];
500 /* If it's a pass-through file do nothing. */
501 if (output_names[i])
502 continue;
504 /* Replace the .o suffix with a .ltrans.o suffix and write
505 the resulting name to the LTRANS output list. */
506 obstack_init (&env_obstack);
507 obstack_grow (&env_obstack, input_name, strlen (input_name) - 2);
508 obstack_grow (&env_obstack, ".ltrans.o", sizeof (".ltrans.o"));
509 output_name = XOBFINISH (&env_obstack, char *);
511 /* Adjust the dumpbase if the linker output file was seen. */
512 if (linker_output)
514 char *dumpbase
515 = (char *) xmalloc (strlen (linker_output)
516 + sizeof(DUMPBASE_SUFFIX) + 1);
517 snprintf (dumpbase,
518 strlen (linker_output) + sizeof(DUMPBASE_SUFFIX),
519 "%s.ltrans%u", linker_output, nr);
520 argv_ptr[0] = dumpbase;
523 argv_ptr[1] = "-fltrans";
524 argv_ptr[2] = "-o";
525 argv_ptr[3] = output_name;
526 argv_ptr[4] = input_name;
527 argv_ptr[5] = NULL;
528 if (parallel)
530 fprintf (mstream, "%s:\n\t@%s ", output_name, new_argv[0]);
531 for (j = 1; new_argv[j] != NULL; ++j)
532 fprintf (mstream, " '%s'", new_argv[j]);
533 fprintf (mstream, "\n");
535 else
536 fork_execute (CONST_CAST (char **, new_argv));
538 output_names[i] = output_name;
540 if (parallel)
542 struct pex_obj *pex;
543 char jobs[32];
544 fprintf (mstream, "all:");
545 for (i = 0; i < nr; ++i)
546 fprintf (mstream, " \\\n\t%s", output_names[i]);
547 fprintf (mstream, "\n");
548 fclose (mstream);
549 /* Avoid passing --jobserver-fd= and similar flags. */
550 putenv (xstrdup ("MAKEFLAGS="));
551 putenv (xstrdup ("MFLAGS="));
552 new_argv[0] = getenv ("MAKE");
553 if (!new_argv[0])
554 new_argv[0] = "make";
555 new_argv[1] = "-f";
556 new_argv[2] = makefile;
557 snprintf (jobs, 31, "-j%d", parallel);
558 new_argv[3] = jobs;
559 new_argv[4] = "all";
560 new_argv[5] = NULL;
561 pex = collect_execute (CONST_CAST (char **, new_argv));
562 collect_wait (new_argv[0], pex);
563 maybe_unlink_file (makefile);
564 makefile = NULL;
566 for (i = 0; i < nr; ++i)
568 fputs (output_names[i], stdout);
569 putc ('\n', stdout);
570 maybe_unlink_file (input_names[i]);
571 free (input_names[i]);
573 nr = 0;
574 free (output_names);
575 free (input_names);
576 free (list_option_full);
578 else
579 fatal ("invalid LTO mode");
581 obstack_free (&env_obstack, NULL);
585 /* Entry point. */
588 main (int argc, char *argv[])
590 gcc_init_libintl ();
592 /* We may be called with all the arguments stored in some file and
593 passed with @file. Expand them into argv before processing. */
594 expandargv (&argc, &argv);
595 run_gcc (argc, argv);
597 return 0;