Mercurial > hg > CbC > CbC_gcc
comparison gcc/lto-opts.c @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 /* LTO IL options. | |
2 | |
3 Copyright 2009 Free Software Foundation, Inc. | |
4 Contributed by Simon Baldwin <simonb@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 "tree.h" | |
26 #include "hashtab.h" | |
27 #include "ggc.h" | |
28 #include "vec.h" | |
29 #include "bitmap.h" | |
30 #include "flags.h" | |
31 #include "opts.h" | |
32 #include "options.h" | |
33 #include "target.h" | |
34 #include "toplev.h" | |
35 #include "lto-streamer.h" | |
36 | |
37 /* When a file is initially compiled, the options used when generating | |
38 the IL are not necessarily the same as those used when linking the | |
39 objects into the final executable. In general, most build systems | |
40 will proceed with something along the lines of: | |
41 | |
42 $ gcc <cc-flags> -flto -c f1.c -o f1.o | |
43 $ gcc <cc-flags> -flto -c f2.c -o f2.o | |
44 ... | |
45 $ gcc <cc-flags> -flto -c fN.c -o fN.o | |
46 | |
47 And the final link may or may not include the same <cc-flags> used | |
48 to generate the initial object files: | |
49 | |
50 $ gcc <ld-flags> -flto -o prog f1.o ... fN.o | |
51 | |
52 Since we will be generating final code during the link step, some | |
53 of the flags used during the compile step need to be re-applied | |
54 during the link step. For instance, flags in the -m family. | |
55 | |
56 The idea is to save a selected set of <cc-flags> in a special | |
57 section of the initial object files. This section is then read | |
58 during linking and the options re-applied. | |
59 | |
60 FIXME lto. Currently the scheme is limited in that only the | |
61 options saved on the first object file (f1.o) are read back during | |
62 the link step. This means that the options used to compile f1.o | |
63 will be applied to ALL the object files in the final link step. | |
64 More work needs to be done to implement a merging and validation | |
65 mechanism, as this will not be enough for all cases. */ | |
66 | |
67 /* Saved options hold the type of the option (currently CL_TARGET or | |
68 CL_COMMON), and the code, argument, and value. */ | |
69 | |
70 typedef struct GTY(()) opt_d | |
71 { | |
72 unsigned int type; | |
73 size_t code; | |
74 char *arg; | |
75 int value; | |
76 } opt_t; | |
77 | |
78 DEF_VEC_O (opt_t); | |
79 DEF_VEC_ALLOC_O (opt_t, heap); | |
80 | |
81 | |
82 /* Options are held in two vectors, one for those registered by | |
83 command line handling code, and the other for those read in from | |
84 any LTO IL input. */ | |
85 static VEC(opt_t, heap) *user_options = NULL; | |
86 static VEC(opt_t, heap) *file_options = NULL; | |
87 | |
88 /* Iterate FROM in reverse, writing option codes not yet in CODES into *TO. | |
89 Mark each new option code encountered in CODES. */ | |
90 | |
91 static void | |
92 reverse_iterate_options (VEC(opt_t, heap) *from, VEC(opt_t, heap) **to, | |
93 bitmap codes) | |
94 { | |
95 int i; | |
96 | |
97 for (i = VEC_length (opt_t, from); i > 0; i--) | |
98 { | |
99 const opt_t *const o = VEC_index (opt_t, from, i - 1); | |
100 | |
101 if (bitmap_set_bit (codes, o->code)) | |
102 VEC_safe_push (opt_t, heap, *to, o); | |
103 } | |
104 } | |
105 | |
106 /* Concatenate options vectors FIRST and SECOND, rationalize so that only the | |
107 final of any given option remains, and return the result. */ | |
108 | |
109 static VEC(opt_t, heap) * | |
110 concatenate_options (VEC(opt_t, heap) *first, VEC(opt_t, heap) *second) | |
111 { | |
112 VEC(opt_t, heap) *results = NULL; | |
113 bitmap codes = lto_bitmap_alloc (); | |
114 | |
115 reverse_iterate_options (second, &results, codes); | |
116 reverse_iterate_options (first, &results, codes); | |
117 | |
118 lto_bitmap_free (codes); | |
119 return results; | |
120 } | |
121 | |
122 /* Clear the options vector in *OPTS_P and set it to NULL. */ | |
123 | |
124 static void | |
125 clear_options (VEC(opt_t, heap) **opts_p) | |
126 { | |
127 int i; | |
128 opt_t *o; | |
129 | |
130 for (i = 0; VEC_iterate (opt_t, *opts_p, i, o); i++) | |
131 free (o->arg); | |
132 | |
133 VEC_free (opt_t, heap, *opts_p); | |
134 } | |
135 | |
136 /* Write LENGTH bytes from ADDR to STREAM. */ | |
137 | |
138 static void | |
139 output_data_stream (struct lto_output_stream *stream, | |
140 const void *addr, size_t length) | |
141 { | |
142 lto_output_data_stream (stream, addr, length); | |
143 } | |
144 | |
145 /* Write string STRING to STREAM. */ | |
146 | |
147 static void | |
148 output_string_stream (struct lto_output_stream *stream, const char *string) | |
149 { | |
150 bool flag = false; | |
151 | |
152 if (string != NULL) | |
153 { | |
154 const size_t length = strlen (string); | |
155 | |
156 flag = true; | |
157 output_data_stream (stream, &flag, sizeof (flag)); | |
158 output_data_stream (stream, &length, sizeof (length)); | |
159 output_data_stream (stream, string, length); | |
160 } | |
161 else | |
162 output_data_stream (stream, &flag, sizeof (flag)); | |
163 } | |
164 | |
165 /* Read LENGTH bytes from STREAM to ADDR. */ | |
166 | |
167 static void | |
168 input_data_block (struct lto_input_block *ib, void *addr, size_t length) | |
169 { | |
170 size_t i; | |
171 unsigned char *const buffer = (unsigned char *const) addr; | |
172 | |
173 for (i = 0; i < length; i++) | |
174 buffer[i] = lto_input_1_unsigned (ib); | |
175 } | |
176 | |
177 /* Return a string from IB. The string is allocated, and the caller is | |
178 responsible for freeing it. */ | |
179 | |
180 static char * | |
181 input_string_block (struct lto_input_block *ib) | |
182 { | |
183 bool flag; | |
184 | |
185 input_data_block (ib, &flag, sizeof (flag)); | |
186 if (flag) | |
187 { | |
188 size_t length; | |
189 char *string; | |
190 | |
191 input_data_block (ib, &length, sizeof (length)); | |
192 string = (char *) xcalloc (1, length + 1); | |
193 input_data_block (ib, string, length); | |
194 | |
195 return string; | |
196 } | |
197 else | |
198 return NULL; | |
199 } | |
200 | |
201 /* Return true if this option is one we need to save in LTO output files. | |
202 At present, we pass along all target options, and common options that | |
203 involve position independent code. | |
204 | |
205 TODO This list of options requires expansion and rationalization. | |
206 Among others, optimization options may well be appropriate here. */ | |
207 | |
208 static bool | |
209 register_user_option_p (size_t code, int type) | |
210 { | |
211 if (type == CL_TARGET) | |
212 return true; | |
213 else if (type == CL_COMMON) | |
214 { | |
215 return (code == OPT_fPIC | |
216 || code == OPT_fpic | |
217 || code == OPT_fPIE | |
218 || code == OPT_fpie | |
219 || code == OPT_fcommon | |
220 || code == OPT_fexceptions); | |
221 } | |
222 | |
223 return false; | |
224 } | |
225 | |
226 /* Note command line option with the given TYPE and CODE, ARG, and VALUE. | |
227 If relevant to LTO, save it in the user options vector. */ | |
228 | |
229 void | |
230 lto_register_user_option (size_t code, const char *arg, int value, int type) | |
231 { | |
232 if (register_user_option_p (code, type)) | |
233 { | |
234 opt_t o; | |
235 | |
236 o.type = type; | |
237 o.code = code; | |
238 if (arg != NULL) | |
239 { | |
240 o.arg = (char *) xmalloc (strlen (arg) + 1); | |
241 strcpy (o.arg, arg); | |
242 } | |
243 else | |
244 o.arg = NULL; | |
245 o.value = value; | |
246 VEC_safe_push (opt_t, heap, user_options, &o); | |
247 } | |
248 } | |
249 | |
250 /* Empty the saved user options vector. */ | |
251 | |
252 void | |
253 lto_clear_user_options (void) | |
254 { | |
255 clear_options (&user_options); | |
256 } | |
257 | |
258 /* Empty the saved file options vector. */ | |
259 | |
260 void | |
261 lto_clear_file_options (void) | |
262 { | |
263 clear_options (&file_options); | |
264 } | |
265 | |
266 /* Concatenate the user options and any file options read from an LTO IL | |
267 file, and serialize them to STREAM. File options precede user options | |
268 so that the latter override the former when reissued. */ | |
269 | |
270 static void | |
271 output_options (struct lto_output_stream *stream) | |
272 { | |
273 VEC(opt_t, heap) *opts = concatenate_options (file_options, user_options); | |
274 const size_t length = VEC_length (opt_t, opts); | |
275 int i; | |
276 opt_t *o; | |
277 | |
278 output_data_stream (stream, &length, sizeof (length)); | |
279 | |
280 for (i = 0; VEC_iterate (opt_t, opts, i, o); i++) | |
281 { | |
282 output_data_stream (stream, &o->type, sizeof (o->type)); | |
283 output_data_stream (stream, &o->code, sizeof (o->code)); | |
284 output_string_stream (stream, o->arg); | |
285 output_data_stream (stream, &o->value, sizeof (o->value)); | |
286 } | |
287 | |
288 VEC_free (opt_t, heap, opts); | |
289 } | |
290 | |
291 /* Write currently held options to an LTO IL section. */ | |
292 | |
293 void | |
294 lto_write_options (void) | |
295 { | |
296 char *const section_name = lto_get_section_name (LTO_section_opts, NULL); | |
297 struct lto_output_stream stream; | |
298 struct lto_simple_header header; | |
299 struct lto_output_stream *header_stream; | |
300 | |
301 lto_begin_section (section_name, !flag_wpa); | |
302 free (section_name); | |
303 | |
304 memset (&stream, 0, sizeof (stream)); | |
305 output_options (&stream); | |
306 | |
307 memset (&header, 0, sizeof (header)); | |
308 header.lto_header.major_version = LTO_major_version; | |
309 header.lto_header.minor_version = LTO_minor_version; | |
310 header.lto_header.section_type = LTO_section_opts; | |
311 | |
312 header.compressed_size = 0; | |
313 header.main_size = stream.total_size; | |
314 | |
315 header_stream = ((struct lto_output_stream *) | |
316 xcalloc (1, sizeof (*header_stream))); | |
317 lto_output_data_stream (header_stream, &header, sizeof (header)); | |
318 lto_write_stream (header_stream); | |
319 free (header_stream); | |
320 | |
321 lto_write_stream (&stream); | |
322 lto_end_section (); | |
323 } | |
324 | |
325 /* Unserialize an options vector from IB, and append to file_options. */ | |
326 | |
327 static void | |
328 input_options (struct lto_input_block *ib) | |
329 { | |
330 size_t length, i; | |
331 | |
332 input_data_block (ib, &length, sizeof (length)); | |
333 | |
334 for (i = 0; i < length; i++) | |
335 { | |
336 opt_t o; | |
337 | |
338 input_data_block (ib, &o.type, sizeof (o.type)); | |
339 input_data_block (ib, &o.code, sizeof (o.code)); | |
340 o.arg = input_string_block (ib); | |
341 input_data_block (ib, &o.value, sizeof (o.value)); | |
342 VEC_safe_push (opt_t, heap, file_options, &o); | |
343 } | |
344 } | |
345 | |
346 /* Read options from an LTO IL section. */ | |
347 | |
348 void | |
349 lto_read_file_options (struct lto_file_decl_data *file_data) | |
350 { | |
351 size_t len; | |
352 const char *data; | |
353 const struct lto_simple_header *header; | |
354 int32_t opts_offset; | |
355 struct lto_input_block ib; | |
356 | |
357 data = lto_get_section_data (file_data, LTO_section_opts, NULL, &len); | |
358 header = (const struct lto_simple_header *) data; | |
359 opts_offset = sizeof (*header); | |
360 | |
361 lto_check_version (header->lto_header.major_version, | |
362 header->lto_header.minor_version); | |
363 | |
364 LTO_INIT_INPUT_BLOCK (ib, data + opts_offset, 0, header->main_size); | |
365 input_options (&ib); | |
366 | |
367 lto_free_section_data (file_data, LTO_section_opts, 0, data, len); | |
368 } | |
369 | |
370 /* Concatenate the user options and any file options read from an LTO IL | |
371 file, and reissue them as if all had just been read in from the command | |
372 line. As with serialization, file options precede user options. */ | |
373 | |
374 void | |
375 lto_reissue_options (void) | |
376 { | |
377 VEC(opt_t, heap) *opts = concatenate_options (file_options, user_options); | |
378 int i; | |
379 opt_t *o; | |
380 | |
381 for (i = 0; VEC_iterate (opt_t, opts, i, o); i++) | |
382 { | |
383 const struct cl_option *option = &cl_options[o->code]; | |
384 | |
385 if (option->flag_var) | |
386 set_option (option, o->value, o->arg); | |
387 | |
388 if (o->type == CL_TARGET) | |
389 targetm.handle_option (o->code, o->arg, o->value); | |
390 else if (o->type == CL_COMMON) | |
391 gcc_assert (option->flag_var); | |
392 else | |
393 gcc_unreachable (); | |
394 } | |
395 | |
396 VEC_free (opt_t, heap, opts); | |
397 } |