lto-opts.cc revision 1.1 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