LCOV - code coverage report
Current view: top level - gcc - lto-wrapper.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 56.5 % 1103 623
Test Date: 2026-02-28 14:20:25 Functions: 55.2 % 29 16
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Wrapper to call lto.  Used by collect2 and the linker plugin.
       2              :    Copyright (C) 2009-2026 Free Software Foundation, Inc.
       3              : 
       4              :    Factored out of collect2 by Rafael Espindola <espindola@google.com>
       5              : 
       6              : This file is part of GCC.
       7              : 
       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.
      12              : 
      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.
      17              : 
      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/>.  */
      21              : 
      22              : 
      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.
      27              : 
      28              :    Example:
      29              : 
      30              :    $ lto-wrapper gcc/xgcc -B gcc a.o b.o -o test -flto
      31              : 
      32              :    The above will print something like
      33              :    /tmp/ccwbQ8B2.lto.o
      34              : 
      35              :    If WHOPR is used instead, more than one file might be produced
      36              :    ./ccXj2DTk.lto.ltrans.o
      37              :    ./ccCJuXGv.lto.ltrans.o
      38              : */
      39              : 
      40              : #define INCLUDE_STRING
      41              : #define INCLUDE_ARRAY
      42              : #define INCLUDE_MAP
      43              : #define INCLUDE_VECTOR
      44              : #include "config.h"
      45              : #include "system.h"
      46              : #include "coretypes.h"
      47              : #include "intl.h"
      48              : #include "diagnostic.h"
      49              : #include "obstack.h"
      50              : #include "opts.h"
      51              : #include "options.h"
      52              : #include "simple-object.h"
      53              : #include "lto-section-names.h"
      54              : #include "collect-utils.h"
      55              : #include "opts-diagnostic.h"
      56              : #include "opt-suggestions.h"
      57              : #include "opts-jobserver.h"
      58              : #include "lto-ltrans-cache.h"
      59              : 
      60              : /* Environment variable, used for passing the names of offload targets from GCC
      61              :    driver to lto-wrapper.  */
      62              : #define OFFLOAD_TARGET_NAMES_ENV        "OFFLOAD_TARGET_NAMES"
      63              : #define OFFLOAD_TARGET_DEFAULT_ENV      "OFFLOAD_TARGET_DEFAULT"
      64              : 
      65              : /* By default there is no special suffix for target executables.  */
      66              : #ifdef TARGET_EXECUTABLE_SUFFIX
      67              : #define HAVE_TARGET_EXECUTABLE_SUFFIX
      68              : #else
      69              : #define TARGET_EXECUTABLE_SUFFIX ""
      70              : #endif
      71              : 
      72              : enum lto_mode_d {
      73              :   LTO_MODE_NONE,                        /* Not doing LTO.  */
      74              :   LTO_MODE_LTO,                         /* Normal LTO.  */
      75              :   LTO_MODE_WHOPR                        /* WHOPR.  */
      76              : };
      77              : 
      78              : /* Current LTO mode.  */
      79              : static enum lto_mode_d lto_mode = LTO_MODE_NONE;
      80              : 
      81              : static char *ltrans_output_file;
      82              : static char *flto_out;
      83              : static unsigned int nr;
      84              : static int *ltrans_priorities;
      85              : static char **input_names;
      86              : static char const**output_names;
      87              : static char **offload_names;
      88              : static char *offload_objects_file_name;
      89              : static char *makefile;
      90              : static unsigned int num_deb_objs;
      91              : static const char **early_debug_object_names;
      92              : static bool xassembler_options_error = false;
      93              : 
      94              : const char tool_name[] = "lto-wrapper";
      95              : 
      96              : /* Auxiliary function that frees elements of PTR and PTR itself.
      97              :    N is number of elements to be freed.  If PTR is NULL, nothing is freed.
      98              :    If an element is NULL, subsequent elements are not freed.  */
      99              : 
     100              : static void **
     101            0 : free_array_of_ptrs (void **ptr, unsigned n)
     102              : {
     103            0 :   if (!ptr)
     104              :     return NULL;
     105            0 :   for (unsigned i = 0; i < n; i++)
     106              :     {
     107            0 :       if (!ptr[i])
     108              :         break;
     109            0 :       free (ptr[i]);
     110              :     }
     111            0 :   free (ptr);
     112            0 :   return NULL;
     113              : }
     114              : 
     115              : /* Delete tempfiles.  Called from utils_cleanup.  */
     116              : 
     117              : void
     118        12202 : tool_cleanup (bool)
     119              : {
     120        12202 :   unsigned int i;
     121              : 
     122        12202 :   if (ltrans_output_file)
     123            0 :     maybe_unlink (ltrans_output_file);
     124        12202 :   if (flto_out)
     125            0 :     maybe_unlink (flto_out);
     126        12202 :   if (offload_objects_file_name)
     127            0 :     maybe_unlink (offload_objects_file_name);
     128        12202 :   if (makefile)
     129            0 :     maybe_unlink (makefile);
     130        12202 :   if (early_debug_object_names)
     131            0 :     for (i = 0; i < num_deb_objs; ++i)
     132            0 :       if (early_debug_object_names[i])
     133            0 :         maybe_unlink (early_debug_object_names[i]);
     134        12202 :   for (i = 0; i < nr; ++i)
     135              :     {
     136            0 :       maybe_unlink (input_names[i]);
     137            0 :       if (output_names[i])
     138            0 :         maybe_unlink (output_names[i]);
     139              :     }
     140        12202 :   if (offload_names)
     141              :     {
     142            0 :       for (i = 0; offload_names[i]; i++)
     143            0 :         maybe_unlink (offload_names[i]);
     144            0 :       free_array_of_ptrs ((void **) offload_names, i);
     145              :     }
     146        12202 : }
     147              : 
     148              : static void
     149        12202 : lto_wrapper_cleanup (void)
     150              : {
     151        12202 :   utils_cleanup (false);
     152        12202 : }
     153              : 
     154              : /* Unlink a temporary LTRANS file unless requested otherwise.  */
     155              : 
     156              : void
     157        23746 : maybe_unlink (const char *file)
     158              : {
     159        23746 :   if (!save_temps)
     160              :     {
     161        23717 :       if (unlink_if_ordinary (file)
     162        23717 :           && errno != ENOENT)
     163            0 :         fatal_error (input_location, "deleting LTRANS file %s: %m", file);
     164              :     }
     165           29 :   else if (verbose)
     166            0 :     fprintf (stderr, "[Leaving LTRANS %s]\n", file);
     167        23746 : }
     168              : 
     169              : /* Template of LTRANS dumpbase suffix.  */
     170              : #define DUMPBASE_SUFFIX "ltrans18446744073709551615"
     171              : 
     172              : /* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
     173              :    environment.  */
     174              : 
     175              : static vec<cl_decoded_option>
     176        25459 : get_options_from_collect_gcc_options (const char *collect_gcc,
     177              :                                       const char *collect_gcc_options)
     178              : {
     179        25459 :   cl_decoded_option *decoded_options;
     180        25459 :   unsigned int decoded_options_count;
     181        25459 :   struct obstack argv_obstack;
     182        25459 :   const char **argv;
     183        25459 :   int argc;
     184              : 
     185        25459 :   obstack_init (&argv_obstack);
     186        25459 :   obstack_ptr_grow (&argv_obstack, collect_gcc);
     187              : 
     188        25459 :   parse_options_from_collect_gcc_options (collect_gcc_options,
     189              :                                           &argv_obstack, &argc);
     190        25459 :   argv = XOBFINISH (&argv_obstack, const char **);
     191              : 
     192        25459 :   decode_cmdline_options_to_array (argc, (const char **)argv, CL_DRIVER,
     193              :                                    &decoded_options, &decoded_options_count);
     194        25459 :   vec<cl_decoded_option> decoded;
     195        25459 :   decoded.create (decoded_options_count);
     196       522495 :   for (unsigned i = 0; i < decoded_options_count; ++i)
     197       497036 :     decoded.quick_push (decoded_options[i]);
     198        25459 :   free (decoded_options);
     199              : 
     200        25459 :   obstack_free (&argv_obstack, NULL);
     201              : 
     202        25459 :   return decoded;
     203              : }
     204              : 
     205              : /* Find option in OPTIONS based on OPT_INDEX, starting at START.  -1
     206              :    value is returned if the option is not present.  */
     207              : 
     208              : static int
     209        20432 : find_option (vec<cl_decoded_option> &options, size_t opt_index,
     210              :              unsigned start = 0)
     211              : {
     212       210487 :   for (unsigned i = start; i < options.length (); ++i)
     213       208339 :     if (options[i].opt_index == opt_index)
     214        18284 :       return i;
     215              : 
     216              :   return -1;
     217              : }
     218              : 
     219              : static int
     220        18322 : find_option (vec<cl_decoded_option> &options, cl_decoded_option *option)
     221              : {
     222            0 :   return find_option (options, option->opt_index);
     223              : }
     224              : 
     225              : /* Merge -flto FOPTION into vector of DECODED_OPTIONS.  If FORCE is true
     226              :    then FOPTION overrides previous settings.  */
     227              : 
     228              : static void
     229            5 : merge_flto_options (vec<cl_decoded_option> &decoded_options,
     230              :                     cl_decoded_option *foption, bool force)
     231              : {
     232            5 :   int existing_opt = find_option (decoded_options, foption);
     233            5 :   if (existing_opt == -1)
     234            1 :     decoded_options.safe_push (*foption);
     235            4 :   else if (force)
     236            2 :     decoded_options[existing_opt].arg = foption->arg;
     237              :   else
     238              :     {
     239            2 :       if (strcmp (foption->arg, decoded_options[existing_opt].arg) != 0)
     240              :         {
     241              :           /* -flto=auto is preferred.  */
     242            0 :           if (strcmp (decoded_options[existing_opt].arg, "auto") == 0)
     243              :             ;
     244            0 :           else if (strcmp (foption->arg, "auto") == 0
     245            0 :                    || strcmp (foption->arg, "jobserver") == 0)
     246            0 :             decoded_options[existing_opt].arg = foption->arg;
     247            0 :           else if (strcmp (decoded_options[existing_opt].arg,
     248              :                            "jobserver") != 0)
     249              :             {
     250            0 :               int n = atoi (foption->arg);
     251            0 :               int original_n = atoi (decoded_options[existing_opt].arg);
     252            0 :               if (n > original_n)
     253            0 :                 decoded_options[existing_opt].arg = foption->arg;
     254              :             }
     255              :         }
     256              :     }
     257            5 : }
     258              : 
     259              : /* Try to merge and complain about options FDECODED_OPTIONS when applied
     260              :    ontop of DECODED_OPTIONS.  */
     261              : 
     262              : static void
     263         1055 : merge_and_complain (vec<cl_decoded_option> &decoded_options,
     264              :                     vec<cl_decoded_option> fdecoded_options,
     265              :                     vec<cl_decoded_option> decoded_cl_options)
     266              : {
     267         1055 :   unsigned int i, j;
     268         1055 :   cl_decoded_option *pic_option = NULL;
     269         1055 :   cl_decoded_option *pie_option = NULL;
     270         1055 :   cl_decoded_option *cf_protection_option = NULL;
     271              : 
     272              :   /* ???  Merge options from files.  Most cases can be
     273              :      handled by either unioning or intersecting
     274              :      (for example -fwrapv is a case for unioning,
     275              :      -ffast-math is for intersection).  Most complaints
     276              :      about real conflicts between different options can
     277              :      be deferred to the compiler proper.  Options that
     278              :      we can neither safely handle by intersection nor
     279              :      unioning would need to be complained about here.
     280              :      Ideally we'd have a flag in the opt files that
     281              :      tells whether to union or intersect or reject.
     282              :      In absence of that it's unclear what a good default is.
     283              :      It's also difficult to get positional handling correct.  */
     284              : 
     285              :   /* Look for a -fcf-protection option in the link-time options
     286              :      which overrides any -fcf-protection from the lto sections.  */
     287        51402 :   for (i = 0; i < decoded_cl_options.length (); ++i)
     288              :     {
     289        24646 :       cl_decoded_option *foption = &decoded_cl_options[i];
     290        24646 :       if (foption->opt_index == OPT_fcf_protection_)
     291              :         {
     292            1 :           cf_protection_option = foption;
     293              :         }
     294              :     }
     295              : 
     296              :   /* The following does what the old LTO option code did,
     297              :      union all target and a selected set of common options.  */
     298        38744 :   for (i = 0; i < fdecoded_options.length (); ++i)
     299              :     {
     300        18317 :       cl_decoded_option *foption = &fdecoded_options[i];
     301        18317 :       int existing_opt = find_option (decoded_options, foption);
     302        18317 :       switch (foption->opt_index)
     303              :         {
     304              :         case OPT_SPECIAL_unknown:
     305              :         case OPT_SPECIAL_ignore:
     306              :         case OPT_SPECIAL_warn_removed:
     307              :         case OPT_SPECIAL_program_name:
     308              :         case OPT_SPECIAL_input_file:
     309              :           break;
     310              : 
     311         7745 :         default:
     312         7745 :           if (!(cl_options[foption->opt_index].flags & CL_TARGET))
     313              :             break;
     314              : 
     315              :           /* Fallthru.  */
     316         6402 :         case OPT_fdiagnostics_show_caret:
     317         6402 :         case OPT_fdiagnostics_show_event_links:
     318         6402 :         case OPT_fdiagnostics_show_highlight_colors:
     319         6402 :         case OPT_fdiagnostics_show_labels:
     320         6402 :         case OPT_fdiagnostics_show_line_numbers:
     321         6402 :         case OPT_fdiagnostics_show_option:
     322         6402 :         case OPT_fdiagnostics_show_location_:
     323         6402 :         case OPT_fdiagnostics_show_nesting:
     324         6402 :         case OPT_fdiagnostics_show_nesting_locations:
     325         6402 :         case OPT_fdiagnostics_show_nesting_levels:
     326         6402 :         case OPT_fshow_column:
     327         6402 :         case OPT_fcommon:
     328         6402 :         case OPT_fgnu_tm:
     329         6402 :         case OPT_g:
     330              :           /* Do what the old LTO code did - collect exactly one option
     331              :              setting per OPT code, we pick the first we encounter.
     332              :              ???  This doesn't make too much sense, but when it doesn't
     333              :              then we should complain.  */
     334         6402 :           if (existing_opt == -1)
     335           15 :             decoded_options.safe_push (*foption);
     336              :           break;
     337              : 
     338              :         /* Figure out what PIC/PIE level wins and merge the results.  */
     339              :         case OPT_fPIC:
     340              :         case OPT_fpic:
     341        18317 :           pic_option = foption;
     342              :           break;
     343         1010 :         case OPT_fPIE:
     344         1010 :         case OPT_fpie:
     345         1010 :           pie_option = foption;
     346         1010 :           break;
     347              : 
     348         2111 :         case OPT_fopenmp:
     349         2111 :         case OPT_fopenacc:
     350         2111 :         case OPT_fasynchronous_unwind_tables:
     351         2111 :         case OPT_funwind_tables:
     352              :           /* For selected options we can merge conservatively.  */
     353         2111 :           if (existing_opt == -1)
     354            0 :             decoded_options.safe_push (*foption);
     355              :           /* -fopenmp > -fno-openmp,
     356              :              -fopenacc > -fno-openacc  */
     357         2111 :           else if (foption->value > decoded_options[existing_opt].value)
     358            0 :             decoded_options[existing_opt] = *foption;
     359              :           break;
     360              : 
     361            0 :         case OPT_fopenacc_dim_:
     362              :           /* Append or check identical.  */
     363            0 :           if (existing_opt == -1)
     364            0 :             decoded_options.safe_push (*foption);
     365            0 :           else if (strcmp (decoded_options[existing_opt].arg, foption->arg))
     366            0 :             fatal_error (input_location,
     367              :                          "option %s with different values",
     368              :                          foption->orig_option_with_args_text);
     369              :           break;
     370              : 
     371         1055 :         case OPT_fcf_protection_:
     372              :           /* Default to link-time option, else append or check identical.  */
     373         1055 :           if (!cf_protection_option
     374            1 :               || cf_protection_option->value == CF_CHECK)
     375              :             {
     376         1054 :               if (existing_opt == -1)
     377            0 :                 decoded_options.safe_push (*foption);
     378         1054 :               else if (decoded_options[existing_opt].value != foption->value)
     379              :                 {
     380            0 :                   if (cf_protection_option
     381            0 :                       && cf_protection_option->value == CF_CHECK)
     382            0 :                     fatal_error (input_location,
     383              :                                  "option %qs with mismatching values"
     384              :                                  " (%s, %s)",
     385              :                                  "-fcf-protection",
     386            0 :                                  decoded_options[existing_opt].arg,
     387              :                                  foption->arg);
     388              :                   else
     389              :                     {
     390              :                       /* Merge and update the -fcf-protection option.  */
     391            0 :                       decoded_options[existing_opt].value
     392            0 :                         &= (foption->value & CF_FULL);
     393            0 :                       switch (decoded_options[existing_opt].value)
     394              :                         {
     395            0 :                         case CF_NONE:
     396            0 :                           decoded_options[existing_opt].arg = "none";
     397            0 :                           break;
     398            0 :                         case CF_BRANCH:
     399            0 :                           decoded_options[existing_opt].arg = "branch";
     400            0 :                           break;
     401            0 :                         case CF_RETURN:
     402            0 :                           decoded_options[existing_opt].arg = "return";
     403            0 :                           break;
     404            0 :                         default:
     405            0 :                           gcc_unreachable ();
     406              :                         }
     407              :                     }
     408              :                 }
     409              :             }
     410              :           break;
     411              : 
     412              :         case OPT_O:
     413              :         case OPT_Ofast:
     414              :         case OPT_Og:
     415              :         case OPT_Os:
     416              :         case OPT_Oz:
     417         8215 :           existing_opt = -1;
     418         8215 :           for (j = 0; j < decoded_options.length (); ++j)
     419         8214 :             if (decoded_options[j].opt_index == OPT_O
     420              :                 || decoded_options[j].opt_index == OPT_Ofast
     421              :                 || decoded_options[j].opt_index == OPT_Og
     422              :                 || decoded_options[j].opt_index == OPT_Os
     423              :                 || decoded_options[j].opt_index == OPT_Oz)
     424              :               {
     425         1022 :                 existing_opt = j;
     426         1022 :                 break;
     427              :               }
     428         1023 :           if (existing_opt == -1)
     429            1 :             decoded_options.safe_push (*foption);
     430         1022 :           else if (decoded_options[existing_opt].opt_index == foption->opt_index
     431         1022 :                    && foption->opt_index != OPT_O)
     432              :             /* Exact same options get merged.  */
     433              :             ;
     434              :           else
     435              :             {
     436              :               /* For mismatched option kinds preserve the optimization
     437              :                  level only, thus merge it as -On.  This also handles
     438              :                  merging of same optimization level -On.  */
     439         1018 :               int level = 0;
     440         1018 :               switch (foption->opt_index)
     441              :                 {
     442         1017 :                 case OPT_O:
     443         1017 :                   if (foption->arg[0] == '\0')
     444              :                     level = MAX (level, 1);
     445              :                   else
     446          995 :                     level = MAX (level, atoi (foption->arg));
     447              :                   break;
     448              :                 case OPT_Ofast:
     449              :                   level = MAX (level, 3);
     450              :                   break;
     451              :                 case OPT_Og:
     452           22 :                   level = MAX (level, 1);
     453              :                   break;
     454            1 :                 case OPT_Os:
     455            1 :                 case OPT_Oz:
     456            1 :                   level = MAX (level, 2);
     457            1 :                   break;
     458              :                 default:
     459              :                   gcc_unreachable ();
     460              :                 }
     461         1018 :               switch (decoded_options[existing_opt].opt_index)
     462              :                 {
     463         1018 :                 case OPT_O:
     464         1018 :                   if (decoded_options[existing_opt].arg[0] == '\0')
     465           16 :                     level = MAX (level, 1);
     466              :                   else
     467         1002 :                     level = MAX (level,
     468              :                                  atoi (decoded_options[existing_opt].arg));
     469              :                   break;
     470            0 :                 case OPT_Ofast:
     471            0 :                   level = MAX (level, 3);
     472            0 :                   break;
     473            0 :                 case OPT_Og:
     474            0 :                   level = MAX (level, 1);
     475            0 :                   break;
     476            0 :                 case OPT_Os:
     477            0 :                 case OPT_Oz:
     478            0 :                   level = MAX (level, 2);
     479            0 :                   break;
     480            0 :                 default:
     481            0 :                   gcc_unreachable ();
     482              :                 }
     483         1018 :               decoded_options[existing_opt].opt_index = OPT_O;
     484         1018 :               char *tem;
     485         1018 :               tem = xasprintf ("-O%d", level);
     486         1018 :               decoded_options[existing_opt].arg = &tem[2];
     487         1018 :               decoded_options[existing_opt].canonical_option[0] = tem;
     488         1018 :               decoded_options[existing_opt].value = 1;
     489              :             }
     490              :           break;
     491              : 
     492              : 
     493            0 :         case OPT_foffload_abi_:
     494            0 :         case OPT_foffload_abi_host_opts_:
     495            0 :           if (existing_opt == -1)
     496            0 :             decoded_options.safe_push (*foption);
     497            0 :           else if (foption->value != decoded_options[existing_opt].value)
     498            0 :             fatal_error (input_location,
     499              :                          "option %s not used consistently in all LTO input"
     500              :                          " files", foption->orig_option_with_args_text);
     501              :           break;
     502              : 
     503              : 
     504            0 :         case OPT_foffload_options_:
     505            0 :           decoded_options.safe_push (*foption);
     506            0 :           break;
     507              : 
     508            2 :         case OPT_flto_:
     509            2 :           merge_flto_options (decoded_options, foption, false);
     510            2 :           break;
     511              :         }
     512              :     }
     513              : 
     514              :   /* Merge PIC options:
     515              :       -fPIC + -fpic = -fpic
     516              :       -fPIC + -fno-pic = -fno-pic
     517              :       -fpic/-fPIC + nothing = nothing.
     518              :      It is a common mistake to mix few -fPIC compiled objects into otherwise
     519              :      non-PIC code.  We do not want to build everything with PIC then.
     520              : 
     521              :      Similarly we merge PIE options, however in addition we keep
     522              :       -fPIC + -fPIE = -fPIE
     523              :       -fpic + -fPIE = -fpie
     524              :       -fPIC/-fpic + -fpie = -fpie
     525              : 
     526              :      It would be good to warn on mismatches, but it is bit hard to do as
     527              :      we do not know what nothing translates to.  */
     528              : 
     529        19399 :   for (unsigned int j = 0; j < decoded_options.length ();)
     530        18344 :     if (decoded_options[j].opt_index == OPT_fPIC
     531        18344 :         || decoded_options[j].opt_index == OPT_fpic)
     532              :       {
     533              :         /* -fno-pic in one unit implies -fno-pic everywhere.  */
     534           39 :         if (decoded_options[j].value == 0)
     535            0 :           j++;
     536              :         /* If we have no pic option or merge in -fno-pic, we still may turn
     537              :            existing pic/PIC mode into pie/PIE if -fpie/-fPIE is present.  */
     538           39 :         else if ((pic_option && pic_option->value == 0)
     539              :                  || !pic_option)
     540              :           {
     541            0 :             if (pie_option)
     542              :               {
     543            0 :                 bool big = decoded_options[j].opt_index == OPT_fPIC
     544            0 :                            && pie_option->opt_index == OPT_fPIE;
     545            0 :                 decoded_options[j].opt_index = big ? OPT_fPIE : OPT_fpie;
     546            0 :                 if (pie_option->value)
     547            0 :                   decoded_options[j].canonical_option[0]
     548            0 :                     = big ? "-fPIE" : "-fpie";
     549              :                 else
     550            0 :                   decoded_options[j].canonical_option[0] = "-fno-pie";
     551            0 :                 decoded_options[j].value = pie_option->value;
     552            0 :                 j++;
     553              :               }
     554            0 :             else if (pic_option)
     555              :               {
     556            0 :                 decoded_options[j] = *pic_option;
     557            0 :                 j++;
     558              :               }
     559              :             /* We do not know if target defaults to pic or not, so just remove
     560              :                option if it is missing in one unit but enabled in other.  */
     561              :             else
     562            0 :               decoded_options.ordered_remove (j);
     563              :           }
     564           39 :         else if (pic_option->opt_index == OPT_fpic
     565           39 :                  && decoded_options[j].opt_index == OPT_fPIC)
     566              :           {
     567            0 :             decoded_options[j] = *pic_option;
     568            0 :             j++;
     569              :           }
     570              :         else
     571           39 :           j++;
     572              :       }
     573        18305 :    else if (decoded_options[j].opt_index == OPT_fPIE
     574        18305 :             || decoded_options[j].opt_index == OPT_fpie)
     575              :       {
     576              :         /* -fno-pie in one unit implies -fno-pie everywhere.  */
     577         1016 :         if (decoded_options[j].value == 0)
     578         1015 :           j++;
     579              :         /* If we have no pie option or merge in -fno-pie, we still preserve
     580              :            PIE/pie if pic/PIC is present.  */
     581            1 :         else if ((pie_option && pie_option->value == 0)
     582              :                  || !pie_option)
     583              :           {
     584              :             /* If -fPIC/-fpic is given, merge it with -fPIE/-fpie.  */
     585            0 :             if (pic_option)
     586              :               {
     587            0 :                 if (pic_option->opt_index == OPT_fpic
     588            0 :                     && decoded_options[j].opt_index == OPT_fPIE)
     589              :                   {
     590            0 :                     decoded_options[j].opt_index = OPT_fpie;
     591            0 :                     decoded_options[j].canonical_option[0]
     592            0 :                       = pic_option->value ? "-fpie" : "-fno-pie";
     593              :                   }
     594            0 :                 else if (!pic_option->value)
     595            0 :                   decoded_options[j].canonical_option[0] = "-fno-pie";
     596            0 :                 decoded_options[j].value = pic_option->value;
     597            0 :                 j++;
     598              :               }
     599            0 :             else if (pie_option)
     600              :               {
     601            0 :                 decoded_options[j] = *pie_option;
     602            0 :                 j++;
     603              :               }
     604              :             /* Because we always append pic/PIE options this code path should
     605              :                not happen unless the LTO object was built by old lto1 which
     606              :                did not contain that logic yet.  */
     607              :             else
     608            0 :               decoded_options.ordered_remove (j);
     609              :           }
     610            1 :         else if (pie_option->opt_index == OPT_fpie
     611            1 :                  && decoded_options[j].opt_index == OPT_fPIE)
     612              :           {
     613            0 :             decoded_options[j] = *pie_option;
     614            0 :             j++;
     615              :           }
     616              :         else
     617            1 :           j++;
     618              :       }
     619              :    else
     620        17289 :      j++;
     621              : 
     622         1055 :   int existing_opt_index, existing_opt2_index;
     623         1055 :   if (!xassembler_options_error)
     624            0 :     for (existing_opt_index = existing_opt2_index = 0; ;
     625            0 :          existing_opt_index++, existing_opt2_index++)
     626              :       {
     627         1055 :         existing_opt_index
     628         1055 :           = find_option (decoded_options, OPT_Xassembler, existing_opt_index);
     629         1055 :         existing_opt2_index
     630         1055 :           = find_option (fdecoded_options, OPT_Xassembler,
     631              :                          existing_opt2_index);
     632              : 
     633         1055 :         cl_decoded_option *existing_opt = NULL;
     634         1055 :         cl_decoded_option *existing_opt2 = NULL;
     635         1055 :         if (existing_opt_index != -1)
     636            0 :           existing_opt = &decoded_options[existing_opt_index];
     637         1055 :         if (existing_opt2_index != -1)
     638            0 :           existing_opt2 = &fdecoded_options[existing_opt2_index];
     639              : 
     640         1055 :         if (existing_opt == NULL && existing_opt2 == NULL)
     641              :           break;
     642            0 :         else if (existing_opt != NULL && existing_opt2 == NULL)
     643              :           {
     644            0 :             warning (0, "Extra option to %<-Xassembler%>: %s,"
     645              :                      " dropping all %<-Xassembler%> and %<-Wa%> options.",
     646              :                      existing_opt->arg);
     647            0 :             xassembler_options_error = true;
     648            0 :             break;
     649              :           }
     650            0 :         else if (existing_opt == NULL && existing_opt2 != NULL)
     651              :           {
     652            0 :             warning (0, "Extra option to %<-Xassembler%>: %s,"
     653              :                      " dropping all %<-Xassembler%> and %<-Wa%> options.",
     654              :                      existing_opt2->arg);
     655            0 :             xassembler_options_error = true;
     656            0 :             break;
     657              :           }
     658            0 :         else if (strcmp (existing_opt->arg, existing_opt2->arg) != 0)
     659              :           {
     660            0 :             warning (0, "Options to %<-Xassembler%> do not match: %s, %s,"
     661              :                      " dropping all %<-Xassembler%> and %<-Wa%> options.",
     662              :                      existing_opt->arg, existing_opt2->arg);
     663            0 :             xassembler_options_error = true;
     664            0 :             break;
     665              :           }
     666            0 :       }
     667         1055 : }
     668              : 
     669              : /* Parse STR, saving found tokens into PVALUES and return their number.
     670              :    Tokens are assumed to be delimited by ':'.  If APPEND is non-null,
     671              :    append it to every token we find.  */
     672              : 
     673              : static unsigned
     674            0 : parse_env_var (const char *str, char ***pvalues, const char *append)
     675              : {
     676            0 :   const char *curval, *nextval;
     677            0 :   char **values;
     678            0 :   unsigned num = 1, i;
     679              : 
     680            0 :   curval = strchr (str, ':');
     681            0 :   while (curval)
     682              :     {
     683            0 :       num++;
     684            0 :       curval = strchr (curval + 1, ':');
     685              :     }
     686              : 
     687            0 :   values = (char**) xmalloc (num * sizeof (char*));
     688            0 :   curval = str;
     689            0 :   nextval = strchr (curval, ':');
     690            0 :   if (nextval == NULL)
     691            0 :     nextval = strchr (curval, '\0');
     692              : 
     693            0 :   int append_len = append ? strlen (append) : 0;
     694            0 :   for (i = 0; i < num; i++)
     695              :     {
     696            0 :       int l = nextval - curval;
     697            0 :       values[i] = (char*) xmalloc (l + 1 + append_len);
     698            0 :       memcpy (values[i], curval, l);
     699            0 :       values[i][l] = 0;
     700            0 :       if (append)
     701            0 :         strcat (values[i], append);
     702            0 :       curval = nextval + 1;
     703            0 :       nextval = strchr (curval, ':');
     704            0 :       if (nextval == NULL)
     705            0 :         nextval = strchr (curval, '\0');
     706              :     }
     707            0 :   *pvalues = values;
     708            0 :   return num;
     709              : }
     710              : 
     711              : /* Append options OPTS from lto or offload_lto sections to ARGV_OBSTACK.  */
     712              : 
     713              : static void
     714        12202 : append_compiler_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
     715              : {
     716              :   /* Append compiler driver arguments as far as they were merged.  */
     717       209501 :   for (unsigned int j = 1; j < opts.length (); ++j)
     718              :     {
     719       197299 :       cl_decoded_option *option = &opts[j];
     720              : 
     721              :       /* File options have been properly filtered by lto-opts.cc.  */
     722       197299 :       switch (option->opt_index)
     723              :         {
     724              :         /* Drop arguments that we want to take from the link line.  */
     725        16951 :         case OPT_flto_:
     726        16951 :         case OPT_flto:
     727        16951 :         case OPT_flto_partition_:
     728        16951 :           continue;
     729              : 
     730       180348 :         default:
     731       180348 :           break;
     732              :         }
     733              : 
     734              :       /* For now do what the original LTO option code was doing - pass
     735              :          on any CL_TARGET flag and a few selected others.  */
     736       180348 :       switch (option->opt_index)
     737              :         {
     738              :         case OPT_fdiagnostics_show_caret:
     739              :         case OPT_fdiagnostics_show_event_links:
     740              :         case OPT_fdiagnostics_show_highlight_colors:
     741              :         case OPT_fdiagnostics_show_labels:
     742              :         case OPT_fdiagnostics_show_line_numbers:
     743              :         case OPT_fdiagnostics_show_option:
     744              :         case OPT_fdiagnostics_show_location_:
     745              :         case OPT_fdiagnostics_show_nesting:
     746              :         case OPT_fdiagnostics_show_nesting_locations:
     747              :         case OPT_fdiagnostics_show_nesting_levels:
     748              :         case OPT_fshow_column:
     749              :         case OPT_fPIC:
     750              :         case OPT_fpic:
     751              :         case OPT_fPIE:
     752              :         case OPT_fpie:
     753              :         case OPT_fcommon:
     754              :         case OPT_fgnu_tm:
     755              :         case OPT_fopenmp:
     756              :         case OPT_fopenacc:
     757              :         case OPT_fopenacc_dim_:
     758              :         case OPT_foffload_abi_:
     759              :         case OPT_foffload_abi_host_opts_:
     760              :         case OPT_fcf_protection_:
     761              :         case OPT_fasynchronous_unwind_tables:
     762              :         case OPT_funwind_tables:
     763              :         case OPT_g:
     764              :         case OPT_O:
     765              :         case OPT_Ofast:
     766              :         case OPT_Og:
     767              :         case OPT_Os:
     768              :         case OPT_Oz:
     769              :           break;
     770              : 
     771           16 :         case OPT_Xassembler:
     772              :           /* When we detected a mismatch in assembler options between
     773              :              the input TU's fall back to previous behavior of ignoring them.  */
     774           16 :           if (xassembler_options_error)
     775            0 :             continue;
     776              :           break;
     777              : 
     778        69839 :         default:
     779        69839 :           if (!(cl_options[option->opt_index].flags & CL_TARGET))
     780        42775 :             continue;
     781              :         }
     782              : 
     783              :       /* Pass the option on.  */
     784       275162 :       for (unsigned int i = 0; i < option->canonical_option_num_elements; ++i)
     785       137589 :         obstack_ptr_grow (argv_obstack, option->canonical_option[i]);
     786              :     }
     787        12202 : }
     788              : 
     789              : /* Append diag options in OPTS to ARGV_OBSTACK.  */
     790              : 
     791              : static void
     792            0 : append_diag_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
     793              : {
     794              :   /* Append compiler driver arguments as far as they were merged.  */
     795            0 :   for (unsigned int j = 1; j < opts.length (); ++j)
     796              :     {
     797            0 :       cl_decoded_option *option = &opts[j];
     798              : 
     799            0 :       switch (option->opt_index)
     800              :         {
     801              :         case OPT_fdiagnostics_color_:
     802              :         case OPT_fdiagnostics_format_:
     803              :         case OPT_fdiagnostics_show_caret:
     804              :         case OPT_fdiagnostics_show_event_links:
     805              :         case OPT_fdiagnostics_show_highlight_colors:
     806              :         case OPT_fdiagnostics_show_labels:
     807              :         case OPT_fdiagnostics_show_line_numbers:
     808              :         case OPT_fdiagnostics_show_option:
     809              :         case OPT_fdiagnostics_show_location_:
     810              :         case OPT_fdiagnostics_show_nesting:
     811              :         case OPT_fdiagnostics_show_nesting_locations:
     812              :         case OPT_fdiagnostics_show_nesting_levels:
     813              :         case OPT_fshow_column:
     814              :           break;
     815            0 :         default:
     816            0 :           continue;
     817              :         }
     818              : 
     819              :       /* Pass the option on.  */
     820            0 :       for (unsigned int i = 0; i < option->canonical_option_num_elements; ++i)
     821            0 :         obstack_ptr_grow (argv_obstack, option->canonical_option[i]);
     822              :     }
     823            0 : }
     824              : 
     825              : 
     826              : /* Append linker options OPTS to ARGV_OBSTACK.  */
     827              : 
     828              : static void
     829        12202 : append_linker_options (obstack *argv_obstack, vec<cl_decoded_option> opts)
     830              : {
     831              :   /* Append linker driver arguments.  Compiler options from the linker
     832              :      driver arguments will override / merge with those from the compiler.  */
     833       269234 :   for (unsigned int j = 1; j < opts.length (); ++j)
     834              :     {
     835       257032 :       cl_decoded_option *option = &opts[j];
     836              : 
     837              :       /* Do not pass on frontend specific flags not suitable for lto.  */
     838       270070 :       if (!(cl_options[option->opt_index].flags
     839       257032 :             & (CL_COMMON|CL_TARGET|CL_DRIVER|CL_LTO)))
     840        13038 :         continue;
     841              : 
     842       243994 :       switch (option->opt_index)
     843              :         {
     844        24372 :         case OPT_o:
     845        24372 :         case OPT_flto_:
     846        24372 :         case OPT_flto:
     847              :           /* We've handled these LTO options, do not pass them on.  */
     848        24372 :           continue;
     849              : 
     850           61 :         case OPT_fopenmp:
     851           61 :         case OPT_fopenacc:
     852              :           /* Ignore -fno-XXX form of these options, as otherwise
     853              :              corresponding builtins will not be enabled.  */
     854           61 :           if (option->value == 0)
     855            0 :             continue;
     856              :           break;
     857              : 
     858              :         default:
     859              :           break;
     860              :         }
     861              : 
     862              :       /* Pass the option on.  */
     863       479320 :       for (unsigned int i = 0; i < option->canonical_option_num_elements; ++i)
     864       259698 :         obstack_ptr_grow (argv_obstack, option->canonical_option[i]);
     865              :     }
     866        12202 : }
     867              : 
     868              : /* Extract options for TARGET offload compiler from OPTIONS and append
     869              :    them to ARGV_OBSTACK.  */
     870              : 
     871              : static void
     872            0 : append_offload_options (obstack *argv_obstack, const char *target,
     873              :                         vec<cl_decoded_option> options)
     874              : {
     875            0 :   for (unsigned i = 0; i < options.length (); i++)
     876              :     {
     877            0 :       const char *cur, *next, *opts;
     878            0 :       char **argv;
     879            0 :       unsigned argc;
     880            0 :       cl_decoded_option *option = &options[i];
     881              : 
     882            0 :       if (option->opt_index != OPT_foffload_options_)
     883            0 :         continue;
     884              : 
     885              :       /* If option argument starts with '-' then no target is specified.  That
     886              :          means offload options are specified for all targets, so we need to
     887              :          append them.  */
     888            0 :       if (option->arg[0] == '-')
     889              :         opts = option->arg;
     890              :       else
     891              :         {
     892            0 :           opts = strchr (option->arg, '=');
     893            0 :           gcc_assert (opts);
     894              :           cur = option->arg;
     895              : 
     896            0 :           while (cur < opts)
     897              :             {
     898            0 :               next = strchr (cur, ',');
     899            0 :               if (next == NULL)
     900            0 :                 next = opts;
     901            0 :               next = (next > opts) ? opts : next;
     902              : 
     903              :               /* Are we looking for this offload target?  */
     904            0 :               if (strlen (target) == (size_t) (next - cur)
     905            0 :                   && strncmp (target, cur, next - cur) == 0)
     906              :                 break;
     907              : 
     908              :               /* Skip the comma or equal sign.  */
     909            0 :               cur = next + 1;
     910              :             }
     911              : 
     912            0 :           if (cur >= opts)
     913            0 :             continue;
     914              : 
     915            0 :           opts++;
     916              :         }
     917              : 
     918            0 :       argv = buildargv (opts);
     919            0 :       for (argc = 0; argv[argc]; argc++)
     920            0 :         obstack_ptr_grow (argv_obstack, argv[argc]);
     921              :     }
     922            0 : }
     923              : 
     924              : /* Check whether NAME can be accessed in MODE.  This is like access,
     925              :    except that it never considers directories to be executable.  */
     926              : 
     927              : static int
     928            0 : access_check (const char *name, int mode)
     929              : {
     930            0 :   if (mode == X_OK)
     931              :     {
     932            0 :       struct stat st;
     933              : 
     934            0 :       if (stat (name, &st) < 0
     935            0 :           || S_ISDIR (st.st_mode))
     936            0 :         return -1;
     937              :     }
     938              : 
     939            0 :   return access (name, mode);
     940              : }
     941              : 
     942              : /* Prepare a target image for offload TARGET, using mkoffload tool from
     943              :    COMPILER_PATH.  Return the name of the resultant object file.  */
     944              : 
     945              : static const char *
     946            0 : compile_offload_image (const char *target, const char *compiler_path,
     947              :                        unsigned in_argc, char *in_argv[],
     948              :                        vec<cl_decoded_option> compiler_opts,
     949              :                        vec<cl_decoded_option> linker_opts,
     950              :                        char **filename)
     951              : {
     952            0 :   char *dumpbase;
     953            0 :   char **argv;
     954            0 :   char *suffix
     955            0 :     = XALLOCAVEC (char, sizeof ("/accel//mkoffload") + strlen (target));
     956            0 :   strcpy (suffix, "/accel/");
     957            0 :   strcat (suffix, target);
     958            0 :   strcat (suffix, "/mkoffload");
     959            0 :   *filename = NULL;
     960              : 
     961            0 :   char **paths = NULL;
     962            0 :   unsigned n_paths = parse_env_var (compiler_path, &paths, suffix);
     963              : 
     964            0 :   const char *compiler = NULL;
     965            0 :   for (unsigned i = 0; i < n_paths; i++)
     966            0 :     if (access_check (paths[i], X_OK) == 0)
     967              :       {
     968            0 :         compiler = paths[i];
     969            0 :         break;
     970              :       }
     971              : #if OFFLOAD_DEFAULTED
     972              :   if (!compiler && getenv (OFFLOAD_TARGET_DEFAULT_ENV))
     973              :     {
     974              :       free_array_of_ptrs ((void **) paths, n_paths);
     975              :       return NULL;
     976              :     }
     977              : #endif
     978              : 
     979            0 :   if (!compiler)
     980            0 :     fatal_error (input_location,
     981              :                  "could not find %s in %s (consider using %<-B%>)",
     982              :                  suffix + 1, compiler_path);
     983              : 
     984            0 :   dumpbase = concat (dumppfx, "x", target, NULL);
     985              : 
     986              :   /* Generate temporary output file name.  */
     987            0 :   if (save_temps)
     988            0 :     *filename = concat (dumpbase, ".o", NULL);
     989              :   else
     990            0 :     *filename = make_temp_file (".target.o");
     991              : 
     992            0 :   struct obstack argv_obstack;
     993            0 :   obstack_init (&argv_obstack);
     994            0 :   obstack_ptr_grow (&argv_obstack, compiler);
     995            0 :   if (save_temps)
     996            0 :     obstack_ptr_grow (&argv_obstack, "-save-temps");
     997            0 :   if (verbose)
     998            0 :     obstack_ptr_grow (&argv_obstack, "-v");
     999            0 :   obstack_ptr_grow (&argv_obstack, "-o");
    1000            0 :   obstack_ptr_grow (&argv_obstack, *filename);
    1001              : 
    1002              :   /* Append names of input object files.  */
    1003            0 :   for (unsigned i = 0; i < in_argc; i++)
    1004            0 :     obstack_ptr_grow (&argv_obstack, in_argv[i]);
    1005              : 
    1006              :   /* Append options from offload_lto sections.  */
    1007            0 :   append_compiler_options (&argv_obstack, compiler_opts);
    1008            0 :   append_diag_options (&argv_obstack, linker_opts);
    1009              : 
    1010            0 :   obstack_ptr_grow (&argv_obstack, "-dumpbase");
    1011            0 :   obstack_ptr_grow (&argv_obstack, dumpbase);
    1012              : 
    1013              :   /* Append options specified by -foffload last.  In case of conflicting
    1014              :      options we expect offload compiler to choose the latest.  */
    1015            0 :   append_offload_options (&argv_obstack, target, compiler_opts);
    1016            0 :   append_offload_options (&argv_obstack, target, linker_opts);
    1017              : 
    1018            0 :   obstack_ptr_grow (&argv_obstack, NULL);
    1019            0 :   argv = XOBFINISH (&argv_obstack, char **);
    1020            0 :   suffix = concat (target, ".offload_args", NULL);
    1021            0 :   fork_execute (argv[0], argv, true, suffix);
    1022            0 :   obstack_free (&argv_obstack, NULL);
    1023              : 
    1024            0 :   free_array_of_ptrs ((void **) paths, n_paths);
    1025            0 :   return *filename;
    1026              : }
    1027              : 
    1028              : 
    1029              : /* The main routine dealing with offloading.
    1030              :    The routine builds a target image for each offload target.  IN_ARGC and
    1031              :    IN_ARGV specify options and input object files.  As all of them could contain
    1032              :    target sections, we pass them all to target compilers.  */
    1033              : 
    1034              : static void
    1035            0 : compile_images_for_offload_targets (unsigned in_argc, char *in_argv[],
    1036              :                                     vec<cl_decoded_option> compiler_opts,
    1037              :                                     vec<cl_decoded_option> linker_opts)
    1038              : {
    1039            0 :   char **names = NULL;
    1040            0 :   const char *target_names = getenv (OFFLOAD_TARGET_NAMES_ENV);
    1041            0 :   if (!target_names)
    1042            0 :     return;
    1043            0 :   unsigned num_targets = parse_env_var (target_names, &names, NULL);
    1044            0 :   int next_name_entry = 0;
    1045              : 
    1046            0 :   const char *compiler_path = getenv ("COMPILER_PATH");
    1047            0 :   if (!compiler_path)
    1048            0 :     goto out;
    1049              : 
    1050              :   /* Prepare an image for each target and save the name of the resultant object
    1051              :      file to the OFFLOAD_NAMES array.  It is terminated by a NULL entry.  */
    1052            0 :   offload_names = XCNEWVEC (char *, num_targets + 1);
    1053            0 :   for (unsigned i = 0; i < num_targets; i++)
    1054              :     {
    1055            0 :       if (!compile_offload_image (names[i], compiler_path, in_argc, in_argv,
    1056              :                                   compiler_opts, linker_opts,
    1057            0 :                                   &offload_names[next_name_entry]))
    1058              : #if OFFLOAD_DEFAULTED
    1059              :         continue;
    1060              : #else
    1061            0 :         fatal_error (input_location,
    1062              :                      "problem with building target image for %s", names[i]);
    1063              : #endif
    1064            0 :       next_name_entry++;
    1065              :     }
    1066              : 
    1067              : #if OFFLOAD_DEFAULTED
    1068              :   if (next_name_entry == 0)
    1069              :     {
    1070              :       free (offload_names);
    1071              :       offload_names = NULL;
    1072              :     }
    1073              : #endif
    1074              : 
    1075            0 :  out:
    1076            0 :   free_array_of_ptrs ((void **) names, num_targets);
    1077              : }
    1078              : 
    1079              : /* Copy a file from SRC to DEST.  */
    1080              : 
    1081              : static void
    1082            0 : copy_file (const char *dest, const char *src)
    1083              : {
    1084            0 :   FILE *d = fopen (dest, "wb");
    1085            0 :   FILE *s = fopen (src, "rb");
    1086            0 :   char buffer[512];
    1087            0 :   while (!feof (s))
    1088              :     {
    1089            0 :       size_t len = fread (buffer, 1, 512, s);
    1090            0 :       if (ferror (s) != 0)
    1091            0 :         fatal_error (input_location, "reading input file");
    1092            0 :       if (len > 0)
    1093              :         {
    1094            0 :           fwrite (buffer, 1, len, d);
    1095            0 :           if (ferror (d) != 0)
    1096            0 :             fatal_error (input_location, "writing output file");
    1097              :         }
    1098              :     }
    1099            0 :   fclose (d);
    1100            0 :   fclose (s);
    1101            0 : }
    1102              : 
    1103              : /* Find the crtoffloadtable.o file in LIBRARY_PATH, make copy and pass name of
    1104              :    the copy to the linker.  */
    1105              : 
    1106              : static void
    1107            0 : find_crtoffloadtable (int save_temps, bool pie_or_shared, const char *dumppfx)
    1108              : {
    1109            0 :   char **paths = NULL;
    1110            0 :   const char *library_path = getenv ("LIBRARY_PATH");
    1111            0 :   if (!library_path)
    1112            0 :     return;
    1113            0 :   unsigned n_paths = parse_env_var (library_path, &paths,
    1114              :                                     pie_or_shared
    1115              :                                     ? "/crtoffloadtableS.o"
    1116              :                                     : "/crtoffloadtable.o");
    1117              : 
    1118            0 :   unsigned i;
    1119            0 :   for (i = 0; i < n_paths; i++)
    1120            0 :     if (access_check (paths[i], R_OK) == 0)
    1121              :       {
    1122              :         /* The linker will delete the filename we give it, so make a copy.  */
    1123            0 :         char *crtoffloadtable;
    1124            0 :         if (!save_temps)
    1125            0 :           crtoffloadtable = make_temp_file (".crtoffloadtable.o");
    1126              :         else
    1127            0 :           crtoffloadtable = concat (dumppfx, "crtoffloadtable.o", NULL);
    1128            0 :         copy_file (crtoffloadtable, paths[i]);
    1129            0 :         printf ("%s\n", crtoffloadtable);
    1130            0 :         XDELETEVEC (crtoffloadtable);
    1131            0 :         break;
    1132              :       }
    1133            0 :   if (i == n_paths)
    1134            0 :     fatal_error (input_location,
    1135              :                  "installation error, cannot find %<crtoffloadtable%s.o%>",
    1136              :                  pie_or_shared ? "S" : "");
    1137              : 
    1138            0 :   free_array_of_ptrs ((void **) paths, n_paths);
    1139              : }
    1140              : 
    1141              : /* A subroutine of run_gcc.  Examine the open file FD for lto sections with
    1142              :    name prefix PREFIX, at FILE_OFFSET, and store any options we find in OPTS.
    1143              :    Return true if we found a matching section, false
    1144              :    otherwise.  COLLECT_GCC holds the value of the environment variable with
    1145              :    the same name.  */
    1146              : 
    1147              : static bool
    1148        13257 : find_and_merge_options (int fd, off_t file_offset, const char *prefix,
    1149              :                         vec<cl_decoded_option> decoded_cl_options, bool first,
    1150              :                         vec<cl_decoded_option> *opts, const char *collect_gcc)
    1151              : {
    1152        13257 :   off_t offset, length;
    1153        13257 :   char *data;
    1154        13257 :   char *fopts;
    1155        13257 :   const char *errmsg;
    1156        13257 :   int err;
    1157        13257 :   vec<cl_decoded_option> fdecoded_options;
    1158              : 
    1159        13257 :   if (!first)
    1160         1055 :     fdecoded_options = *opts;
    1161              : 
    1162        13257 :   simple_object_read *sobj;
    1163        13257 :   sobj = simple_object_start_read (fd, file_offset, "__GNU_LTO",
    1164              :                                    &errmsg, &err);
    1165        13257 :   if (!sobj)
    1166              :     return false;
    1167              : 
    1168        13257 :   char *secname = XALLOCAVEC (char, strlen (prefix) + sizeof (".opts"));
    1169        13257 :   strcpy (secname, prefix);
    1170        13257 :   strcat (secname, ".opts");
    1171        13257 :   if (!simple_object_find_section (sobj, secname, &offset, &length,
    1172              :                                    &errmsg, &err))
    1173              :     {
    1174            0 :       simple_object_release_read (sobj);
    1175            0 :       return false;
    1176              :     }
    1177              : 
    1178        13257 :   lseek (fd, file_offset + offset, SEEK_SET);
    1179        13257 :   data = (char *)xmalloc (length);
    1180        13257 :   read (fd, data, length);
    1181        13257 :   fopts = data;
    1182        13257 :   do
    1183              :     {
    1184        13257 :       vec<cl_decoded_option> f2decoded_options
    1185        13257 :         = get_options_from_collect_gcc_options (collect_gcc, fopts);
    1186        13257 :       if (first)
    1187              :         {
    1188        12202 :           fdecoded_options = f2decoded_options;
    1189        12202 :           first = false;
    1190              :         }
    1191              :       else
    1192         1055 :         merge_and_complain (fdecoded_options, f2decoded_options,
    1193              :                             decoded_cl_options);
    1194              : 
    1195        13257 :       fopts += strlen (fopts) + 1;
    1196              :     }
    1197        13257 :   while (fopts - data < length);
    1198              : 
    1199        13257 :   free (data);
    1200        13257 :   simple_object_release_read (sobj);
    1201        13257 :   *opts = fdecoded_options;
    1202        13257 :   return true;
    1203              : }
    1204              : 
    1205              : /* Copy early debug info sections from INFILE to a new file whose name
    1206              :    is returned.  Return NULL on error.  */
    1207              : 
    1208              : const char *
    1209        13257 : debug_objcopy (const char *infile, bool rename)
    1210              : {
    1211        13257 :   char *outfile;
    1212        13257 :   const char *errmsg;
    1213        13257 :   int err;
    1214              : 
    1215        13257 :   const char *p;
    1216        13257 :   const char *orig_infile = infile;
    1217        13257 :   int64_t inoff = 0;
    1218        13257 :   int consumed;
    1219        13257 :   if ((p = strrchr (infile, '@'))
    1220            1 :       && p != infile
    1221            1 :       && sscanf (p, "@%" PRIi64 "%n", &inoff, &consumed) >= 1
    1222        13258 :       && strlen (p) == (unsigned int) consumed)
    1223              :     {
    1224            1 :       char *fname = xstrdup (infile);
    1225            1 :       fname[p - infile] = '\0';
    1226            1 :       infile = fname;
    1227              :     }
    1228        13257 :   int infd = open (infile, O_RDONLY | O_BINARY);
    1229        13257 :   if (infd == -1)
    1230              :     return NULL;
    1231        13257 :   simple_object_read *inobj = simple_object_start_read (infd, inoff,
    1232              :                                                         "__GNU_LTO",
    1233              :                                                         &errmsg, &err);
    1234        13257 :   if (!inobj)
    1235              :     return NULL;
    1236              : 
    1237        13257 :   off_t off, len;
    1238        13257 :   if (simple_object_find_section (inobj, ".gnu.debuglto_.debug_info",
    1239              :                                   &off, &len, &errmsg, &err) != 1)
    1240              :     {
    1241        12485 :       if (errmsg)
    1242            0 :         fatal_error (0, "%s: %s", errmsg, xstrerror (err));
    1243              : 
    1244        12485 :       simple_object_release_read (inobj);
    1245        12485 :       close (infd);
    1246        12485 :       return NULL;
    1247              :     }
    1248              : 
    1249          772 :   if (save_temps)
    1250            0 :     outfile = concat (orig_infile, ".debug.temp.o", NULL);
    1251              :   else
    1252          772 :     outfile = make_temp_file (".debug.temp.o");
    1253          772 :   errmsg = simple_object_copy_lto_debug_sections (inobj, outfile, &err, rename);
    1254          772 :   if (errmsg)
    1255              :     {
    1256            0 :       unlink_if_ordinary (outfile);
    1257            0 :       fatal_error (0, "%s: %s", errmsg, xstrerror (err));
    1258              :     }
    1259              : 
    1260          772 :   simple_object_release_read (inobj);
    1261          772 :   close (infd);
    1262              : 
    1263          772 :   return outfile;
    1264              : }
    1265              : 
    1266              : /* Helper for qsort: compare priorities for parallel compilation.  */
    1267              : 
    1268              : int
    1269         4138 : cmp_priority (const void *a, const void *b)
    1270              : {
    1271         4138 :   return *((const int *)b)-*((const int *)a);
    1272              : }
    1273              : 
    1274              : /* Number of CPUs that can be used for parallel LTRANS phase.  */
    1275              : 
    1276              : static unsigned long nthreads_var = 0;
    1277              : 
    1278              : #ifdef HAVE_PTHREAD_AFFINITY_NP
    1279              : unsigned long cpuset_size;
    1280              : static unsigned long get_cpuset_size;
    1281              : cpu_set_t *cpusetp;
    1282              : 
    1283              : unsigned long
    1284              : static cpuset_popcount (unsigned long cpusetsize, cpu_set_t *cpusetp)
    1285              : {
    1286              : #ifdef CPU_COUNT_S
    1287              :   /* glibc 2.7 and above provide a macro for this.  */
    1288              :   return CPU_COUNT_S (cpusetsize, cpusetp);
    1289              : #else
    1290              : #ifdef CPU_COUNT
    1291              :   if (cpusetsize == sizeof (cpu_set_t))
    1292              :     /* glibc 2.6 and above provide a macro for this.  */
    1293              :     return CPU_COUNT (cpusetp);
    1294              : #endif
    1295              :   size_t i;
    1296              :   unsigned long ret = 0;
    1297              :   STATIC_ASSERT (sizeof (cpusetp->__bits[0]) == sizeof (unsigned long int));
    1298              :   for (i = 0; i < cpusetsize / sizeof (cpusetp->__bits[0]); i++)
    1299              :     {
    1300              :       unsigned long int mask = cpusetp->__bits[i];
    1301              :       if (mask == 0)
    1302              :         continue;
    1303              :       ret += __builtin_popcountl (mask);
    1304              :     }
    1305              :   return ret;
    1306              : #endif
    1307              : }
    1308              : #endif
    1309              : 
    1310              : /* At startup, determine the default number of threads.  It would seem
    1311              :    this should be related to the number of cpus online.  */
    1312              : 
    1313              : static void
    1314            0 : init_num_threads (void)
    1315              : {
    1316              : #ifdef HAVE_PTHREAD_AFFINITY_NP
    1317              : #if defined (_SC_NPROCESSORS_CONF) && defined (CPU_ALLOC_SIZE)
    1318              :   cpuset_size = sysconf (_SC_NPROCESSORS_CONF);
    1319              :   cpuset_size = CPU_ALLOC_SIZE (cpuset_size);
    1320              : #else
    1321              :   cpuset_size = sizeof (cpu_set_t);
    1322              : #endif
    1323              : 
    1324              :   cpusetp = (cpu_set_t *) xmalloc (gomp_cpuset_size);
    1325              :   do
    1326              :     {
    1327              :       int ret = pthread_getaffinity_np (pthread_self (), gomp_cpuset_size,
    1328              :                                         cpusetp);
    1329              :       if (ret == 0)
    1330              :         {
    1331              :           /* Count only the CPUs this process can use.  */
    1332              :           nthreads_var = cpuset_popcount (cpuset_size, cpusetp);
    1333              :           if (nthreads_var == 0)
    1334              :             break;
    1335              :           get_cpuset_size = cpuset_size;
    1336              : #ifdef CPU_ALLOC_SIZE
    1337              :           unsigned long i;
    1338              :           for (i = cpuset_size * 8; i; i--)
    1339              :             if (CPU_ISSET_S (i - 1, cpuset_size, cpusetp))
    1340              :               break;
    1341              :           cpuset_size = CPU_ALLOC_SIZE (i);
    1342              : #endif
    1343              :           return;
    1344              :         }
    1345              :       if (ret != EINVAL)
    1346              :         break;
    1347              : #ifdef CPU_ALLOC_SIZE
    1348              :       if (cpuset_size < sizeof (cpu_set_t))
    1349              :         cpuset_size = sizeof (cpu_set_t);
    1350              :       else
    1351              :         cpuset_size = cpuset_size * 2;
    1352              :       if (cpuset_size < 8 * sizeof (cpu_set_t))
    1353              :         cpusetp
    1354              :           = (cpu_set_t *) realloc (cpusetp, cpuset_size);
    1355              :       else
    1356              :         {
    1357              :           /* Avoid fatal if too large memory allocation would be
    1358              :              requested, e.g. kernel returning EINVAL all the time.  */
    1359              :           void *p = realloc (cpusetp, cpuset_size);
    1360              :           if (p == NULL)
    1361              :             break;
    1362              :           cpusetp = (cpu_set_t *) p;
    1363              :         }
    1364              : #else
    1365              :       break;
    1366              : #endif
    1367              :     }
    1368              :   while (1);
    1369              :   cpuset_size = 0;
    1370              :   nthreads_var = 1;
    1371              :   free (cpusetp);
    1372              :   cpusetp = NULL;
    1373              : #endif
    1374              : #ifdef _SC_NPROCESSORS_ONLN
    1375            0 :   nthreads_var = sysconf (_SC_NPROCESSORS_ONLN);
    1376              : #endif
    1377            0 : }
    1378              : 
    1379              : /* Print link to -flto documentation with a hint message.  */
    1380              : 
    1381              : void
    1382            0 : print_lto_docs_link ()
    1383              : {
    1384            0 :   label_text url = label_text::take (global_dc->make_option_url (OPT_flto));
    1385            0 :   inform (UNKNOWN_LOCATION,
    1386              :           "see the %{%<-flto%> option documentation%} for more information",
    1387              :           url.get ());
    1388            0 : }
    1389              : 
    1390              : /* Test that a make command is present and working, return true if so.  */
    1391              : 
    1392              : static bool
    1393         7739 : make_exists (void)
    1394              : {
    1395         7739 :   const char *make = "make";
    1396         7739 :   char **make_argv = buildargv (getenv ("MAKE"));
    1397         7739 :   if (make_argv)
    1398         7739 :     make = make_argv[0];
    1399         7739 :   const char *make_args[] = {make, "--version", NULL};
    1400              : 
    1401         7739 :   int exit_status = 0;
    1402         7739 :   int err = 0;
    1403         7739 :   const char *errmsg
    1404         7739 :     = pex_one (PEX_SEARCH, make_args[0], const_cast<char **> (make_args),
    1405              :                "make", NULL, NULL, &exit_status, &err);
    1406         7739 :   freeargv (make_argv);
    1407         7739 :   return errmsg == NULL && exit_status == 0 && err == 0;
    1408              : }
    1409              : 
    1410              : /* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
    1411              : 
    1412              : static void
    1413        12202 : run_gcc (unsigned argc, char *argv[])
    1414              : {
    1415        12202 :   unsigned i, j;
    1416        12202 :   const char **new_argv;
    1417        12202 :   const char **argv_ptr;
    1418        12202 :   char *list_option_full = NULL;
    1419        12202 :   const char *linker_output = NULL;
    1420        12202 :   const char *collect_gcc;
    1421        12202 :   char *collect_gcc_options;
    1422        12202 :   int parallel = 0;
    1423        12202 :   int jobserver = 0;
    1424        12202 :   bool jobserver_requested = false;
    1425        12202 :   int auto_parallel = 0;
    1426        12202 :   bool no_partition = false;
    1427        12202 :   bool fdecoded_options_first = true;
    1428        12202 :   vec<cl_decoded_option> fdecoded_options;
    1429        12202 :   fdecoded_options.create (16);
    1430        12202 :   bool offload_fdecoded_options_first = true;
    1431        12202 :   vec<cl_decoded_option> offload_fdecoded_options = vNULL;
    1432        12202 :   struct obstack argv_obstack;
    1433        12202 :   int new_head_argc;
    1434        12202 :   bool have_lto = false;
    1435        12202 :   bool have_offload = false;
    1436        12202 :   unsigned lto_argc = 0, ltoobj_argc = 0;
    1437        12202 :   char **lto_argv, **ltoobj_argv;
    1438        12202 :   bool linker_output_rel = false;
    1439        12202 :   bool skip_debug = false;
    1440              : #ifdef ENABLE_DEFAULT_PIE
    1441              :   bool pie_or_shared = true;
    1442              : #else
    1443        12202 :   bool pie_or_shared = false;
    1444              : #endif
    1445        12202 :   const char *incoming_dumppfx = dumppfx = NULL;
    1446        12202 :   static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
    1447        12202 :   const char *ltrans_cache_dir = NULL;
    1448        12202 :   size_t ltrans_cache_size = 4096;
    1449              : 
    1450              :   /* Get the driver and options.  */
    1451        12202 :   collect_gcc = getenv ("COLLECT_GCC");
    1452        12202 :   if (!collect_gcc)
    1453            0 :     fatal_error (input_location,
    1454              :                  "environment variable %<COLLECT_GCC%> must be set");
    1455        12202 :   collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
    1456        12202 :   if (!collect_gcc_options)
    1457            0 :     fatal_error (input_location,
    1458              :                  "environment variable %<COLLECT_GCC_OPTIONS%> must be set");
    1459              : 
    1460        12202 :   char *collect_as_options = getenv ("COLLECT_AS_OPTIONS");
    1461              : 
    1462              :   /* Prepend -Xassembler to each option, and append the string
    1463              :      to collect_gcc_options.  */
    1464        12202 :   if (collect_as_options)
    1465              :     {
    1466            1 :       obstack temporary_obstack;
    1467            1 :       obstack_init (&temporary_obstack);
    1468              : 
    1469            1 :       prepend_xassembler_to_collect_as_options (collect_as_options,
    1470              :                                                 &temporary_obstack);
    1471            1 :       obstack_1grow (&temporary_obstack, '\0');
    1472              : 
    1473            1 :       char *xassembler_opts_string
    1474            1 :         = XOBFINISH (&temporary_obstack, char *);
    1475            1 :       collect_gcc_options = concat (collect_gcc_options, xassembler_opts_string,
    1476              :                                     NULL);
    1477              :     }
    1478              : 
    1479        12202 :   vec<cl_decoded_option> decoded_options
    1480        12202 :     = get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options);
    1481              : 
    1482              :   /* Allocate array for input object files with LTO IL,
    1483              :      and for possible preceding arguments.  */
    1484        12202 :   lto_argv = XNEWVEC (char *, argc);
    1485        12202 :   ltoobj_argv = XNEWVEC (char *, argc);
    1486              : 
    1487              :   /* Look at saved options in the IL files.  */
    1488        41044 :   for (i = 1; i < argc; ++i)
    1489              :     {
    1490        28842 :       char *p;
    1491        28842 :       int fd;
    1492        28842 :       int64_t file_offset = 0;
    1493        28842 :       int consumed;
    1494        28842 :       char *filename = argv[i];
    1495              : 
    1496        28842 :       if (startswith (argv[i], "-foffload-objects="))
    1497              :         {
    1498            0 :           have_offload = true;
    1499            0 :           offload_objects_file_name
    1500            0 :             = argv[i] + sizeof ("-foffload-objects=") - 1;
    1501        15585 :           continue;
    1502              :         }
    1503              : 
    1504        28842 :       if ((p = strrchr (argv[i], '@'))
    1505            1 :           && p != argv[i]
    1506            1 :           && sscanf (p, "@%" PRIi64 "%n", &file_offset, &consumed) >= 1
    1507        28843 :           && strlen (p) == (unsigned int) consumed)
    1508              :         {
    1509            1 :           filename = XNEWVEC (char, p - argv[i] + 1);
    1510            1 :           memcpy (filename, argv[i], p - argv[i]);
    1511            1 :           filename[p - argv[i]] = '\0';
    1512              :         }
    1513        28842 :       fd = open (filename, O_RDONLY | O_BINARY);
    1514              :       /* Linker plugin passes -fresolution and -flinker-output options.
    1515              :          -flinker-output is passed only when user did not specify one and thus
    1516              :          we do not need to worry about duplicities with the option handling
    1517              :          below. */
    1518        28842 :       if (fd == -1)
    1519              :         {
    1520        15585 :           lto_argv[lto_argc++] = argv[i];
    1521        15585 :           if (strcmp (argv[i], "-flinker-output=rel") == 0)
    1522           33 :             linker_output_rel = true;
    1523        15585 :           continue;
    1524              :         }
    1525              : 
    1526        13257 :       if (find_and_merge_options (fd, file_offset, LTO_SECTION_NAME_PREFIX,
    1527              :                                   decoded_options, fdecoded_options_first,
    1528              :                                   &fdecoded_options,
    1529              :                                   collect_gcc))
    1530              :         {
    1531        13257 :           have_lto = true;
    1532        13257 :           ltoobj_argv[ltoobj_argc++] = argv[i];
    1533        13257 :           fdecoded_options_first = false;
    1534              :         }
    1535        13257 :       close (fd);
    1536              :     }
    1537              : 
    1538              :   /* Initalize the common arguments for the driver.  */
    1539        12202 :   obstack_init (&argv_obstack);
    1540        12202 :   obstack_ptr_grow (&argv_obstack, collect_gcc);
    1541        12202 :   obstack_ptr_grow (&argv_obstack, "-xlto");
    1542        12202 :   obstack_ptr_grow (&argv_obstack, "-c");
    1543              : 
    1544        12202 :   append_compiler_options (&argv_obstack, fdecoded_options);
    1545        12202 :   append_linker_options (&argv_obstack, decoded_options);
    1546              : 
    1547              :   /* Scan linker driver arguments for things that are of relevance to us.  */
    1548       538468 :   for (j = 1; j < decoded_options.length (); ++j)
    1549              :     {
    1550       257032 :       cl_decoded_option *option = &decoded_options[j];
    1551       257032 :       switch (option->opt_index)
    1552              :         {
    1553        12179 :         case OPT_o:
    1554        12179 :           linker_output = option->arg;
    1555        12179 :           break;
    1556              : 
    1557              :           /* We don't have to distinguish between -save-temps=* and
    1558              :              -save-temps, -dumpdir already carries that
    1559              :              information.  */
    1560           14 :         case OPT_save_temps_:
    1561           14 :         case OPT_save_temps:
    1562           14 :           save_temps = 1;
    1563           14 :           break;
    1564              : 
    1565            0 :         case OPT_v:
    1566            0 :           verbose = 1;
    1567            0 :           break;
    1568              : 
    1569         4757 :         case OPT_flto_partition_:
    1570         4757 :           if (strcmp (option->arg, "none") == 0)
    1571       257032 :             no_partition = true;
    1572              :           break;
    1573              : 
    1574            0 :         case OPT_flto_incremental_:
    1575              :           /* Exists.  */
    1576            0 :           if (access (option->arg, W_OK) == 0)
    1577            0 :             ltrans_cache_dir = option->arg;
    1578              :           else
    1579            0 :             fatal_error (input_location, "missing directory: %s", option->arg);
    1580            0 :           break;
    1581              : 
    1582            0 :         case OPT_flto_incremental_cache_size_:
    1583            0 :           ltrans_cache_size = atoi (option->arg);
    1584            0 :           break;
    1585              : 
    1586            3 :         case OPT_flto_:
    1587              :           /* Override IL file settings with a linker -flto= option.  */
    1588            3 :           merge_flto_options (fdecoded_options, option, true);
    1589            3 :           if (strcmp (option->arg, "jobserver") == 0)
    1590       257032 :             jobserver_requested = true;
    1591              :           break;
    1592              : 
    1593          127 :         case OPT_flinker_output_:
    1594          127 :           linker_output_rel = !strcmp (option->arg, "rel");
    1595          127 :           break;
    1596              : 
    1597          763 :         case OPT_g:
    1598              :           /* Recognize -g0.  */
    1599          763 :           skip_debug = option->arg && !strcmp (option->arg, "0");
    1600              :           break;
    1601              : 
    1602              :         case OPT_gbtf:
    1603              :         case OPT_gctf:
    1604              :         case OPT_gdwarf:
    1605              :         case OPT_gdwarf_:
    1606              :         case OPT_ggdb:
    1607              :         case OPT_gvms:
    1608              :           /* Negative forms, if allowed, enable debug info as well.  */
    1609          774 :           skip_debug = false;
    1610              :           break;
    1611              : 
    1612        12202 :         case OPT_dumpdir:
    1613        12202 :           incoming_dumppfx = dumppfx = option->arg;
    1614        12202 :           break;
    1615              : 
    1616        12201 :         case OPT_fdiagnostics_urls_:
    1617        12201 :           diagnostic_urls_init (global_dc, option->value);
    1618        12201 :           break;
    1619              : 
    1620        12201 :         case OPT_fdiagnostics_color_:
    1621        12201 :           diagnostic_color_init (global_dc, option->value);
    1622        12201 :           break;
    1623              : 
    1624            0 :         case OPT_fdiagnostics_show_highlight_colors:
    1625            0 :           global_dc->set_show_highlight_colors (option->value);
    1626            0 :           break;
    1627              : 
    1628              :         case OPT_pie:
    1629              :         case OPT_shared:
    1630              :         case OPT_static_pie:
    1631       257032 :           pie_or_shared = true;
    1632              :           break;
    1633              : 
    1634            0 :         case OPT_no_pie:
    1635            0 :           pie_or_shared = false;
    1636            0 :           break;
    1637              : 
    1638              :         default:
    1639              :           break;
    1640              :         }
    1641              :     }
    1642              : 
    1643              :   /* Process LTO-related options on merged options.  */
    1644       209502 :   for (j = 1; j < fdecoded_options.length (); ++j)
    1645              :     {
    1646       197300 :       cl_decoded_option *option = &fdecoded_options[j];
    1647       197300 :       switch (option->opt_index)
    1648              :         {
    1649            3 :         case OPT_flto_:
    1650            3 :           if (strcmp (option->arg, "jobserver") == 0)
    1651              :             {
    1652              :               parallel = 1;
    1653              :               jobserver = 1;
    1654              :             }
    1655            3 :           else if (strcmp (option->arg, "auto") == 0)
    1656              :             {
    1657              :               parallel = 1;
    1658              :               auto_parallel = 1;
    1659              :             }
    1660              :           else
    1661              :             {
    1662            0 :               parallel = atoi (option->arg);
    1663            0 :               if (parallel <= 1)
    1664            0 :                 parallel = 0;
    1665              :             }
    1666              :           /* Fallthru.  */
    1667              : 
    1668        12203 :         case OPT_flto:
    1669        12203 :           lto_mode = LTO_MODE_WHOPR;
    1670        12203 :           break;
    1671              :         }
    1672              :     }
    1673              : 
    1674              :   /* Output lto-wrapper invocation command.  */
    1675        12202 :   if (verbose)
    1676              :     {
    1677            0 :       for (i = 0; i < argc; ++i)
    1678              :         {
    1679            0 :           fputs (argv[i], stderr);
    1680            0 :           fputc (' ', stderr);
    1681              :         }
    1682            0 :       fputc ('\n', stderr);
    1683              :     }
    1684              : 
    1685        12202 :   if (linker_output_rel)
    1686              :     no_partition = true;
    1687              : 
    1688        12169 :   if (no_partition)
    1689              :     {
    1690         4385 :       lto_mode = LTO_MODE_LTO;
    1691         4385 :       jobserver = 0;
    1692         4385 :       jobserver_requested = false;
    1693         4385 :       auto_parallel = 0;
    1694         4385 :       parallel = 0;
    1695              :     }
    1696              :   else
    1697              :     {
    1698         7817 :       jobserver_info jinfo;
    1699         7817 :       if (jobserver && !jinfo.is_active)
    1700              :         {
    1701              :           /* Fall back to auto parallelism.  */
    1702              :           jobserver = 0;
    1703              :           auto_parallel = 1;
    1704              :         }
    1705         7817 :       else if (!jobserver && jinfo.is_active)
    1706              :         {
    1707         7739 :           parallel = 1;
    1708         7739 :           jobserver = 1;
    1709              :         }
    1710         7817 :     }
    1711              : 
    1712              :   /* We need make working for a parallel execution.  */
    1713        12202 :   if (parallel && !make_exists ())
    1714              :     parallel = 0;
    1715              : 
    1716        12202 :   if (!dumppfx)
    1717              :     {
    1718            0 :       if (!linker_output
    1719            0 :           || strcmp (linker_output, HOST_BIT_BUCKET) == 0)
    1720            0 :         dumppfx = "a.";
    1721              :       else
    1722              :         {
    1723            0 :           const char *obase = lbasename (linker_output), *temp;
    1724              : 
    1725              :           /* Strip the executable extension.  */
    1726            0 :           size_t blen = strlen (obase), xlen;
    1727            0 :           if ((temp = strrchr (obase + 1, '.'))
    1728            0 :               && (xlen = strlen (temp))
    1729            0 :               && (strcmp (temp, ".exe") == 0
    1730              : #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
    1731              :                   || strcmp (temp, TARGET_EXECUTABLE_SUFFIX) == 0
    1732              : #endif
    1733            0 :                   || strcmp (obase, "a.out") == 0))
    1734            0 :             dumppfx = xstrndup (linker_output,
    1735            0 :                                 obase - linker_output + blen - xlen + 1);
    1736              :           else
    1737            0 :             dumppfx = concat (linker_output, ".", NULL);
    1738              :         }
    1739              :     }
    1740              : 
    1741              :   /* If there's no directory component in the dumppfx, add one, so
    1742              :      that, when it is used as -dumpbase, it overrides any occurrence
    1743              :      of -dumpdir that might have been passed in.  */
    1744        12202 :   if (!dumppfx || lbasename (dumppfx) == dumppfx)
    1745         2634 :     dumppfx = concat (current_dir, dumppfx, NULL);
    1746              : 
    1747              :   /* Make sure some -dumpdir is passed, so as to get predictable
    1748              :      -dumpbase overriding semantics.  If we got an incoming -dumpdir
    1749              :      argument, we'll pass it on, so don't bother with another one
    1750              :      then.  */
    1751        12202 :   if (!incoming_dumppfx)
    1752              :     {
    1753            0 :       obstack_ptr_grow (&argv_obstack, "-dumpdir");
    1754            0 :       obstack_ptr_grow (&argv_obstack, "");
    1755              :     }
    1756        12202 :   obstack_ptr_grow (&argv_obstack, "-dumpbase");
    1757              : 
    1758              :   /* Remember at which point we can scrub args to re-use the commons.  */
    1759        12202 :   new_head_argc = obstack_object_size (&argv_obstack) / sizeof (void *);
    1760              : 
    1761        12202 :   if (have_offload)
    1762              :     {
    1763            0 :       unsigned i, num_offload_files;
    1764            0 :       char **offload_argv;
    1765            0 :       FILE *f;
    1766              : 
    1767            0 :       f = fopen (offload_objects_file_name, "r");
    1768            0 :       if (f == NULL)
    1769            0 :         fatal_error (input_location, "cannot open %s: %m",
    1770              :                      offload_objects_file_name);
    1771            0 :       if (fscanf (f, "%u ", &num_offload_files) != 1)
    1772            0 :         fatal_error (input_location, "cannot read %s: %m",
    1773              :                      offload_objects_file_name);
    1774            0 :       offload_argv = XCNEWVEC (char *, num_offload_files);
    1775              : 
    1776              :       /* Read names of object files with offload.  */
    1777            0 :       for (i = 0; i < num_offload_files; i++)
    1778              :         {
    1779            0 :           const unsigned piece = 32;
    1780            0 :           char *buf, *filename = XNEWVEC (char, piece);
    1781            0 :           size_t len;
    1782              : 
    1783            0 :           buf = filename;
    1784            0 : cont1:
    1785            0 :           if (!fgets (buf, piece, f))
    1786              :             break;
    1787            0 :           len = strlen (filename);
    1788            0 :           if (filename[len - 1] != '\n')
    1789              :             {
    1790            0 :               filename = XRESIZEVEC (char, filename, len + piece);
    1791            0 :               buf = filename + len;
    1792            0 :               goto cont1;
    1793              :             }
    1794            0 :           filename[len - 1] = '\0';
    1795            0 :           offload_argv[i] = filename;
    1796              :         }
    1797            0 :       fclose (f);
    1798            0 :       if (offload_argv[num_offload_files - 1] == NULL)
    1799            0 :         fatal_error (input_location, "invalid format of %s",
    1800              :                      offload_objects_file_name);
    1801            0 :       maybe_unlink (offload_objects_file_name);
    1802            0 :       offload_objects_file_name = NULL;
    1803              : 
    1804              :       /* Look at saved offload options in files.  */
    1805            0 :       for (i = 0; i < num_offload_files; i++)
    1806              :         {
    1807            0 :           char *p;
    1808            0 :           int fd, consumed;
    1809            0 :           int64_t file_offset = 0;
    1810            0 :           char *filename = offload_argv[i];
    1811              : 
    1812            0 :           if ((p = strrchr (offload_argv[i], '@'))
    1813            0 :               && p != offload_argv[i]
    1814            0 :               && sscanf (p, "@%" PRIi64 "%n", &file_offset, &consumed) >= 1
    1815            0 :               && strlen (p) == (unsigned int) consumed)
    1816              :             {
    1817            0 :               filename = XNEWVEC (char, p - offload_argv[i] + 1);
    1818            0 :               memcpy (filename, offload_argv[i], p - offload_argv[i]);
    1819            0 :               filename[p - offload_argv[i]] = '\0';
    1820              :             }
    1821            0 :           fd = open (filename, O_RDONLY | O_BINARY);
    1822            0 :           if (fd == -1)
    1823            0 :             fatal_error (input_location, "cannot open %s: %m", filename);
    1824            0 :           if (!find_and_merge_options (fd, file_offset,
    1825              :                                        OFFLOAD_SECTION_NAME_PREFIX,
    1826              :                                        decoded_options,
    1827              :                                        offload_fdecoded_options_first,
    1828              :                                        &offload_fdecoded_options,
    1829              :                                        collect_gcc))
    1830            0 :             fatal_error (input_location, "cannot read %s: %m", filename);
    1831            0 :           offload_fdecoded_options_first = false;
    1832            0 :           close (fd);
    1833            0 :           if (filename != offload_argv[i])
    1834            0 :             XDELETEVEC (filename);
    1835              :         }
    1836              : 
    1837            0 :       compile_images_for_offload_targets (num_offload_files, offload_argv,
    1838              :                                           offload_fdecoded_options, decoded_options);
    1839              : 
    1840            0 :       free_array_of_ptrs ((void **) offload_argv, num_offload_files);
    1841              : 
    1842            0 :       if (offload_names)
    1843              :         {
    1844            0 :           find_crtoffloadtable (save_temps, pie_or_shared, dumppfx);
    1845            0 :           for (i = 0; offload_names[i]; i++)
    1846            0 :             printf ("%s\n", offload_names[i]);
    1847            0 :           free_array_of_ptrs ((void **) offload_names, i);
    1848            0 :           offload_names = NULL;
    1849              :         }
    1850              :     }
    1851              : 
    1852              :   /* If object files contain offload sections, but do not contain LTO sections,
    1853              :      then there is no need to perform a link-time recompilation, i.e.
    1854              :      lto-wrapper is used only for a compilation of offload images.  */
    1855        12202 :   if (have_offload && !have_lto)
    1856            0 :     goto finish;
    1857              : 
    1858        12202 :   if (lto_mode == LTO_MODE_LTO)
    1859              :     {
    1860              :       /* -dumpbase argument for LTO.  */
    1861         4385 :       flto_out = concat (dumppfx, "lto.o", NULL);
    1862         4385 :       obstack_ptr_grow (&argv_obstack, flto_out);
    1863              : 
    1864         4385 :       if (!save_temps)
    1865         4385 :         flto_out = make_temp_file (".lto.o");
    1866         4385 :       obstack_ptr_grow (&argv_obstack, "-o");
    1867         4385 :       obstack_ptr_grow (&argv_obstack, flto_out);
    1868              :     }
    1869              :   else
    1870              :     {
    1871         7817 :       const char *list_option = "-fltrans-output-list=";
    1872              : 
    1873              :       /* -dumpbase argument for WPA.  */
    1874         7817 :       char *dumpbase = concat (dumppfx, "wpa", NULL);
    1875         7817 :       obstack_ptr_grow (&argv_obstack, dumpbase);
    1876              : 
    1877         7817 :       if (ltrans_cache_dir)
    1878              :         {
    1879              :           /* Results of wpa phase must be on the same disk partition as
    1880              :              cache.  */
    1881            0 :           char* file = concat (ltrans_cache_dir, "/ccXXXXXX.ltrans.out", NULL);
    1882            0 :           int fd = mkstemps (file, strlen (".ltrans.out"));
    1883            0 :           gcc_assert (fd != -1 && !close (fd));
    1884              : 
    1885            0 :           ltrans_output_file = file;
    1886              :         }
    1887         7817 :       else if (save_temps)
    1888           14 :         ltrans_output_file = concat (dumppfx, "ltrans.out", NULL);
    1889              :       else
    1890         7803 :         ltrans_output_file = make_temp_file (".ltrans.out");
    1891         7817 :       list_option_full = concat (list_option, ltrans_output_file, NULL);
    1892         7817 :       obstack_ptr_grow (&argv_obstack, list_option_full);
    1893              : 
    1894         7817 :       if (jobserver)
    1895              :         {
    1896         7739 :           if (verbose)
    1897            0 :             fprintf (stderr, "Using make jobserver\n");
    1898         7739 :           obstack_ptr_grow (&argv_obstack, xstrdup ("-fwpa=jobserver"));
    1899              :         }
    1900           78 :       else if (auto_parallel)
    1901              :         {
    1902            0 :           char buf[256];
    1903            0 :           init_num_threads ();
    1904            0 :           if (nthreads_var == 0)
    1905            0 :             nthreads_var = 1;
    1906            0 :           if (verbose)
    1907            0 :             fprintf (stderr, "LTO parallelism level set to %ld\n",
    1908              :                      nthreads_var);
    1909            0 :           sprintf (buf, "-fwpa=%ld", nthreads_var);
    1910            0 :           obstack_ptr_grow (&argv_obstack, xstrdup (buf));
    1911              :         }
    1912           78 :       else if (parallel > 1)
    1913              :         {
    1914            0 :           char buf[256];
    1915            0 :           sprintf (buf, "-fwpa=%i", parallel);
    1916            0 :           obstack_ptr_grow (&argv_obstack, xstrdup (buf));
    1917              :         }
    1918              :       else
    1919           78 :         obstack_ptr_grow (&argv_obstack, "-fwpa");
    1920              :     }
    1921              : 
    1922              :   /* Append input arguments.  */
    1923        27787 :   for (i = 0; i < lto_argc; ++i)
    1924        15585 :     obstack_ptr_grow (&argv_obstack, lto_argv[i]);
    1925              :   /* Append the input objects.  */
    1926        25459 :   for (i = 0; i < ltoobj_argc; ++i)
    1927        13257 :     obstack_ptr_grow (&argv_obstack, ltoobj_argv[i]);
    1928        12202 :   obstack_ptr_grow (&argv_obstack, NULL);
    1929              : 
    1930        12202 :   new_argv = XOBFINISH (&argv_obstack, const char **);
    1931        12202 :   argv_ptr = &new_argv[new_head_argc];
    1932        12202 :   fork_execute (new_argv[0], const_cast<char **> (new_argv), true,
    1933              :                 "ltrans_args");
    1934              : 
    1935              :   /* Copy the early generated debug info from the objects to temporary
    1936              :      files and append those to the partial link commandline.  */
    1937        12202 :   early_debug_object_names = NULL;
    1938        12202 :   if (! skip_debug)
    1939              :     {
    1940        12202 :       early_debug_object_names = XCNEWVEC (const char *, ltoobj_argc+ 1);
    1941        12202 :       num_deb_objs = ltoobj_argc;
    1942        25459 :       for (i = 0; i < ltoobj_argc; ++i)
    1943              :         {
    1944        13257 :           const char *tem;
    1945        13257 :           if ((tem = debug_objcopy (ltoobj_argv[i], !linker_output_rel)))
    1946          772 :             early_debug_object_names[i] = tem;
    1947              :         }
    1948              :     }
    1949              : 
    1950        12202 :   if (lto_mode == LTO_MODE_LTO)
    1951              :     {
    1952         4385 :       printf ("%s\n", flto_out);
    1953         4385 :       if (!skip_debug)
    1954              :         {
    1955         9094 :           for (i = 0; i < ltoobj_argc; ++i)
    1956         4709 :             if (early_debug_object_names[i] != NULL)
    1957          272 :               printf ("%s\n", early_debug_object_names[i]);
    1958              :         }
    1959              :       /* These now belong to collect2.  */
    1960         4385 :       free (flto_out);
    1961         4385 :       flto_out = NULL;
    1962         4385 :       free (early_debug_object_names);
    1963         4385 :       early_debug_object_names = NULL;
    1964              :     }
    1965              :   else
    1966              :     {
    1967         7817 :       FILE *stream = fopen (ltrans_output_file, "r");
    1968         7817 :       FILE *mstream = NULL;
    1969         7817 :       struct obstack env_obstack;
    1970         7817 :       int priority;
    1971              : 
    1972         7817 :       if (!stream)
    1973            0 :         fatal_error (input_location, "%<fopen%>: %s: %m", ltrans_output_file);
    1974              : 
    1975              :       /* Parse the list of LTRANS inputs from the WPA stage.  */
    1976         7817 :       obstack_init (&env_obstack);
    1977         7817 :       nr = 0;
    1978        24197 :       for (;;)
    1979              :         {
    1980        16007 :           const unsigned piece = 32;
    1981        16007 :           char *output_name = NULL;
    1982        16007 :           char *buf, *input_name = (char *)xmalloc (piece);
    1983        16007 :           size_t len;
    1984              : 
    1985        16007 :           buf = input_name;
    1986        16007 :           if (fscanf (stream, "%i\n", &priority) != 1)
    1987              :             {
    1988         7817 :               if (!feof (stream))
    1989            0 :                 fatal_error (input_location,
    1990              :                              "corrupted ltrans output file %s",
    1991              :                              ltrans_output_file);
    1992              :               break;
    1993              :             }
    1994         8190 : cont:
    1995         8191 :           if (!fgets (buf, piece, stream))
    1996              :             break;
    1997         8191 :           len = strlen (input_name);
    1998         8191 :           if (input_name[len - 1] != '\n')
    1999              :             {
    2000            1 :               input_name = (char *)xrealloc (input_name, len + piece);
    2001            1 :               buf = input_name + len;
    2002            1 :               goto cont;
    2003              :             }
    2004         8190 :           input_name[len - 1] = '\0';
    2005              : 
    2006         8190 :           if (input_name[0] == '*')
    2007            0 :             output_name = &input_name[1];
    2008              : 
    2009         8190 :           nr++;
    2010         8190 :           ltrans_priorities
    2011         8190 :              = (int *)xrealloc (ltrans_priorities, nr * sizeof (int) * 2);
    2012         8190 :           input_names = (char **)xrealloc (input_names, nr * sizeof (char *));
    2013        16380 :           output_names = (char const**)
    2014         8190 :             xrealloc (output_names, nr * sizeof (char const*));
    2015         8190 :           ltrans_priorities[(nr-1)*2] = priority;
    2016         8190 :           ltrans_priorities[(nr-1)*2+1] = nr-1;
    2017         8190 :           input_names[nr-1] = input_name;
    2018         8190 :           output_names[nr-1] = output_name;
    2019         8190 :         }
    2020         7817 :       fclose (stream);
    2021         7817 :       maybe_unlink (ltrans_output_file);
    2022         7817 :       ltrans_output_file = NULL;
    2023              : 
    2024         7817 :       if (nr > 1)
    2025              :         {
    2026          201 :           jobserver_info jinfo;
    2027          201 :           if (jobserver_requested && !jinfo.is_active)
    2028              :             {
    2029            0 :               warning (0, jinfo.error_msg.c_str ());
    2030            0 :               print_lto_docs_link ();
    2031              :             }
    2032          201 :           else if (parallel == 0)
    2033              :             {
    2034            0 :               warning (0, "using serial compilation of %d LTRANS jobs", nr);
    2035            0 :               print_lto_docs_link ();
    2036              :             }
    2037          201 :         }
    2038              : 
    2039         7817 :       if (parallel)
    2040              :         {
    2041         7739 :           if (save_temps)
    2042            1 :             makefile = concat (dumppfx, "ltrans.mk", NULL);
    2043              :           else
    2044         7738 :             makefile = make_temp_file (".mk");
    2045         7739 :           mstream = fopen (makefile, "w");
    2046         7739 :           qsort (ltrans_priorities, nr, sizeof (int) * 2, cmp_priority);
    2047              :         }
    2048              : 
    2049         7817 :       ltrans_file_cache ltrans_cache (ltrans_cache_dir, "ltrans", ".o",
    2050        15634 :                                       ltrans_cache_size);
    2051              : 
    2052         7817 :       if (ltrans_cache)
    2053              :         {
    2054            0 :           if (!lockfile::lockfile_supported ())
    2055              :             {
    2056            0 :               warning (0, "using ltrans cache without file locking support,"
    2057              :                        " do not use in parallel");
    2058              :             }
    2059            0 :           ltrans_cache.deletion_lock.lock_read ();
    2060            0 :           ltrans_cache.creation_lock.lock_write ();
    2061              : 
    2062            0 :           ltrans_cache.load_cache ();
    2063              : 
    2064            0 :           int recompiling = 0;
    2065              : 
    2066            0 :           for (i = 0; i < nr; ++i)
    2067              :             {
    2068              :               /* If it's a pass-through file do nothing.  */
    2069            0 :               if (output_names[i])
    2070            0 :                 continue;
    2071              : 
    2072            0 :               ltrans_file_cache::item* item;
    2073            0 :               bool existed = ltrans_cache.add_to_cache (input_names[i], item);
    2074            0 :               free (input_names[i]);
    2075            0 :               input_names[i] = xstrdup (item->input.c_str ());
    2076              : 
    2077            0 :               if (existed)
    2078              :                 {
    2079              :                   /* Fill the output_name to skip compilation.  */
    2080            0 :                   output_names[i] = item->output.c_str ();
    2081              :                 }
    2082              :               else
    2083              :                 {
    2084              :                   /* Lock so no other process can access until the file is
    2085              :                      compiled.  */
    2086            0 :                   item->lock.lock_write ();
    2087            0 :                   recompiling++;
    2088              :                 }
    2089              :             }
    2090            0 :           if (verbose)
    2091            0 :             fprintf (stderr, "LTRANS: recompiling %d/%d\n", recompiling, nr);
    2092              : 
    2093            0 :           ltrans_cache.save_cache ();
    2094            0 :           ltrans_cache.creation_lock.unlock ();
    2095              :         }
    2096              : 
    2097              :       /* Execute the LTRANS stage for each input file (or prepare a
    2098              :          makefile to invoke this in parallel).  */
    2099        16007 :       for (i = 0; i < nr; ++i)
    2100              :         {
    2101         8190 :           char const* output_name;
    2102         8190 :           char *input_name = input_names[i];
    2103              :           /* If it's a pass-through or cached file do nothing.  */
    2104         8190 :           if (output_names[i])
    2105            0 :             continue;
    2106              : 
    2107         8190 :           if (ltrans_cache)
    2108              :             {
    2109            0 :               ltrans_file_cache::item* item;
    2110            0 :               item = ltrans_cache.get_item (input_name);
    2111            0 :               gcc_assert (item);
    2112              : 
    2113            0 :               output_name = item->output.c_str ();
    2114              :             }
    2115              :           else
    2116              :             {
    2117              :               /* Replace the .o suffix with a .ltrans.o suffix and write
    2118              :                  the resulting name to the LTRANS output list.  */
    2119         8190 :               obstack_grow (&env_obstack, input_name, strlen (input_name) - 2);
    2120         8190 :               obstack_grow (&env_obstack, ".ltrans.o", sizeof (".ltrans.o"));
    2121         8190 :               output_name = XOBFINISH (&env_obstack, char const*);
    2122              :             }
    2123              : 
    2124              :           /* Adjust the dumpbase if the linker output file was seen.  */
    2125         8190 :           int dumpbase_len = (strlen (dumppfx)
    2126              :                               + sizeof (DUMPBASE_SUFFIX)
    2127         8190 :                               + sizeof (".ltrans"));
    2128         8190 :           char *dumpbase = (char *) xmalloc (dumpbase_len + 1);
    2129         8190 :           snprintf (dumpbase, dumpbase_len, "%sltrans%u.ltrans", dumppfx, i);
    2130         8190 :           argv_ptr[0] = dumpbase;
    2131              : 
    2132         8190 :           argv_ptr[1] = "-fltrans";
    2133         8190 :           argv_ptr[2] = "-o";
    2134         8190 :           argv_ptr[3] = output_name;
    2135         8190 :           argv_ptr[4] = input_name;
    2136         8190 :           argv_ptr[5] = NULL;
    2137         8190 :           if (parallel)
    2138              :             {
    2139         8112 :               fprintf (mstream, "%s:\n\t@%s ", output_name, new_argv[0]);
    2140       348938 :               for (j = 1; new_argv[j] != NULL; ++j)
    2141       332714 :                 fprintf (mstream, " '%s'", new_argv[j]);
    2142              :               /* If we are not preserving the ltrans input files then
    2143              :                  truncate them as soon as we have processed it.  This
    2144              :                  reduces temporary disk-space usage.  */
    2145         8112 :               if (!ltrans_cache && !save_temps)
    2146         8111 :                 fprintf (mstream, " -truncate '%s'", input_name);
    2147         8112 :               fprintf (mstream, "\n");
    2148              :             }
    2149              :           else
    2150              :             {
    2151           78 :               char argsuffix[sizeof (DUMPBASE_SUFFIX)
    2152              :                              + sizeof (".ltrans_args") + 1];
    2153           78 :               if (save_temps)
    2154           13 :                 snprintf (argsuffix,
    2155              :                           sizeof (DUMPBASE_SUFFIX) + sizeof (".ltrans_args"),
    2156              :                           "ltrans%u.ltrans_args", i);
    2157          143 :               fork_execute (new_argv[0], const_cast<char **> (new_argv),
    2158              :                             true, save_temps ? argsuffix : NULL);
    2159           78 :               if (!ltrans_cache)
    2160           78 :                 maybe_unlink (input_names[i]);
    2161              :             }
    2162              : 
    2163         8190 :           output_names[i] = output_name;
    2164              :         }
    2165         7817 :       if (parallel)
    2166              :         {
    2167         7739 :           struct pex_obj *pex;
    2168         7739 :           char jobs[32];
    2169              : 
    2170         7739 :           fprintf (mstream,
    2171              :                    ".PHONY: all\n"
    2172              :                    "all:");
    2173        15851 :           for (i = 0; i < nr; ++i)
    2174              :             {
    2175         8112 :               int j = ltrans_priorities[i*2 + 1];
    2176         8112 :               fprintf (mstream, " \\\n\t%s", output_names[j]);
    2177              :             }
    2178         7739 :           fprintf (mstream, "\n");
    2179         7739 :           fclose (mstream);
    2180         7739 :           if (!jobserver)
    2181              :             {
    2182              :               /* Avoid passing --jobserver-fd= and similar flags
    2183              :                  unless jobserver mode is explicitly enabled.  */
    2184            0 :               putenv (xstrdup ("MAKEFLAGS="));
    2185            0 :               putenv (xstrdup ("MFLAGS="));
    2186              :             }
    2187              : 
    2188         7739 :           char **make_argv = buildargv (getenv ("MAKE"));
    2189         7739 :           if (make_argv)
    2190              :             {
    2191        15478 :               for (unsigned argc = 0; make_argv[argc]; argc++)
    2192         7739 :                 obstack_ptr_grow (&argv_obstack, make_argv[argc]);
    2193              :             }
    2194              :           else
    2195            0 :             obstack_ptr_grow (&argv_obstack, "make");
    2196              : 
    2197         7739 :           obstack_ptr_grow (&argv_obstack, "-f");
    2198         7739 :           obstack_ptr_grow (&argv_obstack, makefile);
    2199         7739 :           if (!jobserver)
    2200              :             {
    2201            0 :               snprintf (jobs, 31, "-j%ld",
    2202              :                         auto_parallel ? nthreads_var : parallel);
    2203            0 :               obstack_ptr_grow (&argv_obstack, jobs);
    2204              :             }
    2205         7739 :           obstack_ptr_grow (&argv_obstack, "all");
    2206         7739 :           obstack_ptr_grow (&argv_obstack, NULL);
    2207         7739 :           new_argv = XOBFINISH (&argv_obstack, const char **);
    2208              : 
    2209         7739 :           pex = collect_execute (new_argv[0], const_cast<char **> (new_argv),
    2210              :                                  NULL, NULL, PEX_SEARCH, false, NULL);
    2211         7739 :           do_wait (new_argv[0], pex);
    2212         7739 :           freeargv (make_argv);
    2213         7739 :           maybe_unlink (makefile);
    2214         7739 :           makefile = NULL;
    2215              : 
    2216         7739 :           if (!ltrans_cache)
    2217        15851 :             for (i = 0; i < nr; ++i)
    2218         8112 :               maybe_unlink (input_names[i]);
    2219              :         }
    2220              : 
    2221         7817 :       if (ltrans_cache)
    2222              :         {
    2223            0 :           for (i = 0; i < nr; ++i)
    2224              :             {
    2225            0 :               ltrans_file_cache::item* item;
    2226            0 :               item = ltrans_cache.get_item (input_names[i]);
    2227              : 
    2228            0 :               if (item)
    2229              :                 {
    2230              :                   /* Ensure LTRANS for this item finished.  */
    2231            0 :                   item->lock.lock_read ();
    2232            0 :                   item->lock.unlock ();
    2233              :                 }
    2234              :             }
    2235              : 
    2236            0 :           ltrans_cache.deletion_lock.unlock ();
    2237              :         }
    2238              : 
    2239        16007 :       for (i = 0; i < nr; ++i)
    2240              :         {
    2241         8190 :           fputs (output_names[i], stdout);
    2242         8190 :           putc ('\n', stdout);
    2243         8190 :           free (input_names[i]);
    2244              :         }
    2245              : 
    2246         7817 :       if (ltrans_cache && !save_temps)
    2247            0 :         ltrans_cache.try_prune ();
    2248              : 
    2249         7817 :       if (!skip_debug)
    2250              :         {
    2251        16365 :           for (i = 0; i < ltoobj_argc; ++i)
    2252         8548 :             if (early_debug_object_names[i] != NULL)
    2253          500 :               printf ("%s\n", early_debug_object_names[i]);
    2254              :         }
    2255         7817 :       nr = 0;
    2256         7817 :       free (ltrans_priorities);
    2257         7817 :       free (output_names);
    2258         7817 :       output_names = NULL;
    2259         7817 :       free (early_debug_object_names);
    2260         7817 :       early_debug_object_names = NULL;
    2261         7817 :       free (input_names);
    2262         7817 :       free (list_option_full);
    2263         7817 :       obstack_free (&env_obstack, NULL);
    2264              :     }
    2265              : 
    2266        12202 :  finish:
    2267        12202 :   XDELETE (lto_argv);
    2268        12202 :   obstack_free (&argv_obstack, NULL);
    2269        12202 : }
    2270              : 
    2271              : /* Concrete implementation of diagnostics::option_id_manager for LTO.  */
    2272              : 
    2273              : class lto_diagnostic_option_id_manager
    2274              :   : public gcc_diagnostic_option_id_manager
    2275              : {
    2276              : public:
    2277        12202 :   lto_diagnostic_option_id_manager ()
    2278        12202 :   : gcc_diagnostic_option_id_manager (0 /* lang_mask */)
    2279              :   {
    2280              :   }
    2281            0 :   int option_enabled_p (diagnostics::option_id) const final override
    2282              :   {
    2283            0 :     return true;
    2284              :   }
    2285            0 :   char *make_option_name (diagnostics::option_id,
    2286              :                           enum diagnostics::kind,
    2287              :                           enum diagnostics::kind) const final override
    2288              :   {
    2289            0 :     return nullptr;
    2290              :   }
    2291              : };
    2292              : 
    2293              : /* Entry point.  */
    2294              : 
    2295              : int
    2296        12202 : main (int argc, char *argv[])
    2297              : {
    2298        12202 :   const char *p;
    2299              : 
    2300        12202 :   init_opts_obstack ();
    2301              : 
    2302        12202 :   p = argv[0] + strlen (argv[0]);
    2303       146424 :   while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
    2304       134222 :     --p;
    2305        12202 :   progname = p;
    2306              : 
    2307        12202 :   xmalloc_set_program_name (progname);
    2308              : 
    2309        12202 :   gcc_init_libintl ();
    2310              : 
    2311        12202 :   diagnostic_initialize (global_dc, 0);
    2312        12202 :   diagnostic_color_init (global_dc);
    2313        12202 :   diagnostic_urls_init (global_dc);
    2314        12202 :   global_dc->set_option_id_manager
    2315        12202 :     (::make_unique<lto_diagnostic_option_id_manager> (), 0);
    2316              : 
    2317        12202 :   if (atexit (lto_wrapper_cleanup) != 0)
    2318            0 :     fatal_error (input_location, "%<atexit%> failed");
    2319              : 
    2320        12202 :   setup_signals ();
    2321              : 
    2322              :   /* We may be called with all the arguments stored in some file and
    2323              :      passed with @file.  Expand them into argv before processing.  */
    2324        12202 :   expandargv (&argc, &argv);
    2325              : 
    2326        12202 :   run_gcc (argc, argv);
    2327              : 
    2328        12202 :   return 0;
    2329              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.