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