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