Home | History | Annotate | Line # | Download | only in gcc
      1  1.1  mrg /* LTO IL options.
      2  1.1  mrg 
      3  1.1  mrg    Copyright (C) 2009-2022 Free Software Foundation, Inc.
      4  1.1  mrg    Contributed by Simon Baldwin <simonb (at) google.com>
      5  1.1  mrg 
      6  1.1  mrg This file is part of GCC.
      7  1.1  mrg 
      8  1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      9  1.1  mrg the terms of the GNU General Public License as published by the Free
     10  1.1  mrg Software Foundation; either version 3, or (at your option) any later
     11  1.1  mrg version.
     12  1.1  mrg 
     13  1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     14  1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     15  1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     16  1.1  mrg for more details.
     17  1.1  mrg 
     18  1.1  mrg You should have received a copy of the GNU General Public License
     19  1.1  mrg along with GCC; see the file COPYING3.  If not see
     20  1.1  mrg <http://www.gnu.org/licenses/>.  */
     21  1.1  mrg 
     22  1.1  mrg #include "config.h"
     23  1.1  mrg #include "system.h"
     24  1.1  mrg #include "coretypes.h"
     25  1.1  mrg #include "backend.h"
     26  1.1  mrg #include "target.h"
     27  1.1  mrg #include "tree.h"
     28  1.1  mrg #include "gimple.h"
     29  1.1  mrg #include "cgraph.h"
     30  1.1  mrg #include "lto-streamer.h"
     31  1.1  mrg #include "opts.h"
     32  1.1  mrg #include "toplev.h"
     33  1.1  mrg 
     34  1.1  mrg /* Append the option piece OPT to the COLLECT_GCC_OPTIONS string
     35  1.1  mrg    set up by OB, appropriately quoted and separated by spaces
     36  1.1  mrg    (if !*FIRST_P).  */
     37  1.1  mrg 
     38  1.1  mrg static void
     39  1.1  mrg append_to_collect_gcc_options (struct obstack *ob,
     40  1.1  mrg 			       bool *first_p, const char *opt)
     41  1.1  mrg {
     42  1.1  mrg   const char *p, *q = opt;
     43  1.1  mrg   if (!*first_p)
     44  1.1  mrg     obstack_grow (ob, " ", 1);
     45  1.1  mrg   obstack_grow (ob, "'", 1);
     46  1.1  mrg   while ((p = strchr (q, '\'')))
     47  1.1  mrg     {
     48  1.1  mrg       obstack_grow (ob, q, p - q);
     49  1.1  mrg       obstack_grow (ob, "'\\''", 4);
     50  1.1  mrg       q = ++p;
     51  1.1  mrg     }
     52  1.1  mrg   obstack_grow (ob, q, strlen (q));
     53  1.1  mrg   obstack_grow (ob, "'", 1);
     54  1.1  mrg   *first_p = false;
     55  1.1  mrg }
     56  1.1  mrg 
     57  1.1  mrg /* Write currently held options to an LTO IL section.  */
     58  1.1  mrg 
     59  1.1  mrg void
     60  1.1  mrg lto_write_options (void)
     61  1.1  mrg {
     62  1.1  mrg   char *section_name;
     63  1.1  mrg   struct obstack temporary_obstack;
     64  1.1  mrg   unsigned int i, j;
     65  1.1  mrg   char *args;
     66  1.1  mrg   bool first_p = true;
     67  1.1  mrg 
     68  1.1  mrg   section_name = lto_get_section_name (LTO_section_opts, NULL, 0, NULL);
     69  1.1  mrg   lto_begin_section (section_name, false);
     70  1.1  mrg 
     71  1.1  mrg   obstack_init (&temporary_obstack);
     72  1.1  mrg 
     73  1.1  mrg   if (!OPTION_SET_P (flag_openmp)
     74  1.1  mrg       && !global_options.x_flag_openmp)
     75  1.1  mrg     append_to_collect_gcc_options (&temporary_obstack, &first_p,
     76  1.1  mrg 				   "-fno-openmp");
     77  1.1  mrg   if (!OPTION_SET_P (flag_openacc)
     78  1.1  mrg       && !global_options.x_flag_openacc)
     79  1.1  mrg     append_to_collect_gcc_options (&temporary_obstack, &first_p,
     80  1.1  mrg 				   "-fno-openacc");
     81  1.1  mrg   /* Append PIC/PIE mode because its default depends on target and it is
     82  1.1  mrg      subject of merging in lto-wrapper.  */
     83  1.1  mrg   if (!OPTION_SET_P (flag_pic) && !OPTION_SET_P (flag_pie))
     84  1.1  mrg     {
     85  1.1  mrg       const char *pic = "-fno-pie";
     86  1.1  mrg       if (global_options.x_flag_pie == 2)
     87  1.1  mrg 	pic = "-fPIE";
     88  1.1  mrg       else if (global_options.x_flag_pie == 1)
     89  1.1  mrg 	pic = "-fpie";
     90  1.1  mrg       else if (global_options.x_flag_pic == 2)
     91  1.1  mrg 	pic = "-fPIC";
     92  1.1  mrg       else if (global_options.x_flag_pic == 1)
     93  1.1  mrg 	pic = "-fpic";
     94  1.1  mrg       append_to_collect_gcc_options (&temporary_obstack, &first_p, pic);
     95  1.1  mrg     }
     96  1.1  mrg 
     97  1.1  mrg   if (!OPTION_SET_P (flag_cf_protection))
     98  1.1  mrg     {
     99  1.1  mrg       const char *cf_protection = NULL;
    100  1.1  mrg       switch (global_options.x_flag_cf_protection)
    101  1.1  mrg 	{
    102  1.1  mrg 	case CF_NONE: cf_protection = "-fcf-protection=none"; break;
    103  1.1  mrg 	case CF_FULL: cf_protection = "-fcf-protection=full"; break;
    104  1.1  mrg 	case CF_BRANCH: cf_protection = "-fcf-protection=branch"; break;
    105  1.1  mrg 	case CF_RETURN: cf_protection = "-fcf-protection=return"; break;
    106  1.1  mrg 	default: break;
    107  1.1  mrg 	}
    108  1.1  mrg       if (cf_protection)
    109  1.1  mrg 	append_to_collect_gcc_options (&temporary_obstack, &first_p,
    110  1.1  mrg 				       cf_protection);
    111  1.1  mrg     }
    112  1.1  mrg 
    113  1.1  mrg   /* If debug info is enabled append -g.  */
    114  1.1  mrg   if (debug_info_level > DINFO_LEVEL_NONE)
    115  1.1  mrg     append_to_collect_gcc_options (&temporary_obstack, &first_p, "-g");
    116  1.1  mrg 
    117  1.1  mrg   /* Append options from target hook and store them to offload_lto section.  */
    118  1.1  mrg   if (lto_stream_offload_p)
    119  1.1  mrg     {
    120  1.1  mrg       char *offload_opts = targetm.offload_options ();
    121  1.1  mrg       char *offload_ptr = offload_opts;
    122  1.1  mrg       while (offload_ptr)
    123  1.1  mrg        {
    124  1.1  mrg 	 char *next = strchr (offload_ptr, ' ');
    125  1.1  mrg 	 if (next)
    126  1.1  mrg 	   *next++ = '\0';
    127  1.1  mrg 	 append_to_collect_gcc_options (&temporary_obstack, &first_p,
    128  1.1  mrg 					offload_ptr);
    129  1.1  mrg 	 offload_ptr = next;
    130  1.1  mrg        }
    131  1.1  mrg       free (offload_opts);
    132  1.1  mrg     }
    133  1.1  mrg 
    134  1.1  mrg   /* Output explicitly passed options.  */
    135  1.1  mrg   for (i = 1; i < save_decoded_options_count; ++i)
    136  1.1  mrg     {
    137  1.1  mrg       struct cl_decoded_option *option = &save_decoded_options[i];
    138  1.1  mrg 
    139  1.1  mrg       /* Skip explicitly some common options that we do not need.  */
    140  1.1  mrg       switch (option->opt_index)
    141  1.1  mrg       {
    142  1.1  mrg 	case OPT_dumpbase:
    143  1.1  mrg 	case OPT_SPECIAL_unknown:
    144  1.1  mrg 	case OPT_SPECIAL_ignore:
    145  1.1  mrg 	case OPT_SPECIAL_warn_removed:
    146  1.1  mrg 	case OPT_SPECIAL_program_name:
    147  1.1  mrg 	case OPT_SPECIAL_input_file:
    148  1.1  mrg 	case OPT_dumpdir:
    149  1.1  mrg 	case OPT_fresolution_:
    150  1.1  mrg 	case OPT_fdebug_prefix_map_:
    151  1.1  mrg 	case OPT_ffile_prefix_map_:
    152  1.1  mrg 	case OPT_fmacro_prefix_map_:
    153  1.1  mrg 	case OPT_fprofile_prefix_map_:
    154  1.1  mrg 	  continue;
    155  1.1  mrg 
    156  1.1  mrg 	default:
    157  1.1  mrg 	  break;
    158  1.1  mrg       }
    159  1.1  mrg 
    160  1.1  mrg       /* Skip frontend and driver specific options here.  */
    161  1.1  mrg       if (!(cl_options[option->opt_index].flags & (CL_COMMON|CL_TARGET|CL_LTO)))
    162  1.1  mrg 	continue;
    163  1.1  mrg 
    164  1.1  mrg       /* Do not store target-specific options in offload_lto section.  */
    165  1.1  mrg       if ((cl_options[option->opt_index].flags & CL_TARGET)
    166  1.1  mrg 	  && lto_stream_offload_p)
    167  1.1  mrg        continue;
    168  1.1  mrg 
    169  1.1  mrg       /* Drop options created from the gcc driver that will be rejected
    170  1.1  mrg 	 when passed on to the driver again.  */
    171  1.1  mrg       if (cl_options[option->opt_index].cl_reject_driver)
    172  1.1  mrg 	continue;
    173  1.1  mrg 
    174  1.1  mrg       /* Also drop all options that are handled by the driver as well,
    175  1.1  mrg 	 which includes things like -o and -v or -fhelp for example.
    176  1.1  mrg 	 We do not need those.  The only exception is -foffload option, if we
    177  1.1  mrg 	 write it in offload_lto section.  Also drop all diagnostic options.  */
    178  1.1  mrg       if ((cl_options[option->opt_index].flags & (CL_DRIVER|CL_WARNING))
    179  1.1  mrg 	  && (!lto_stream_offload_p
    180  1.1  mrg 	      || option->opt_index != OPT_foffload_options_))
    181  1.1  mrg 	continue;
    182  1.1  mrg 
    183  1.1  mrg       for (j = 0; j < option->canonical_option_num_elements; ++j)
    184  1.1  mrg 	append_to_collect_gcc_options (&temporary_obstack, &first_p,
    185  1.1  mrg 				       option->canonical_option[j]);
    186  1.1  mrg     }
    187  1.1  mrg 
    188  1.1  mrg   const char *collect_as_options = getenv ("COLLECT_AS_OPTIONS");
    189  1.1  mrg   if (collect_as_options)
    190  1.1  mrg     prepend_xassembler_to_collect_as_options (collect_as_options,
    191  1.1  mrg 					      &temporary_obstack);
    192  1.1  mrg 
    193  1.1  mrg   obstack_grow (&temporary_obstack, "\0", 1);
    194  1.1  mrg   args = XOBFINISH (&temporary_obstack, char *);
    195  1.1  mrg   lto_write_data (args, strlen (args) + 1);
    196  1.1  mrg   lto_end_section ();
    197  1.1  mrg 
    198  1.1  mrg   obstack_free (&temporary_obstack, NULL);
    199  1.1  mrg   free (section_name);
    200  1.1  mrg }
    201