1 | /* Top level of GCC compilers (cc1, cc1plus, etc.) |
2 | Copyright (C) 1987-2023 Free Software Foundation, Inc. |
3 | |
4 | This file is part of GCC. |
5 | |
6 | GCC is free software; you can redistribute it and/or modify it under |
7 | the terms of the GNU General Public License as published by the Free |
8 | Software Foundation; either version 3, or (at your option) any later |
9 | version. |
10 | |
11 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
12 | WARRANTY; without even the implied warranty of MERCHANTABILITY or |
13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
14 | for more details. |
15 | |
16 | You should have received a copy of the GNU General Public License |
17 | along with GCC; see the file COPYING3. If not see |
18 | <http://www.gnu.org/licenses/>. */ |
19 | |
20 | /* This is the top level of cc1/c++. |
21 | It parses command args, opens files, invokes the various passes |
22 | in the proper order, and counts the time used by each. |
23 | Error messages and low-level interface to malloc also handled here. */ |
24 | |
25 | #include "config.h" |
26 | #include "system.h" |
27 | #include "coretypes.h" |
28 | #include "backend.h" |
29 | #include "target.h" |
30 | #include "rtl.h" |
31 | #include "tree.h" |
32 | #include "gimple.h" |
33 | #include "alloc-pool.h" |
34 | #include "timevar.h" |
35 | #include "memmodel.h" |
36 | #include "tm_p.h" |
37 | #include "optabs-libfuncs.h" |
38 | #include "insn-config.h" |
39 | #include "ira.h" |
40 | #include "recog.h" |
41 | #include "cgraph.h" |
42 | #include "coverage.h" |
43 | #include "diagnostic.h" |
44 | #include "varasm.h" |
45 | #include "tree-inline.h" |
46 | #include "realmpfr.h" /* For GMP/MPFR/MPC versions, in print_version. */ |
47 | #include "version.h" |
48 | #include "flags.h" |
49 | #include "insn-attr.h" |
50 | #include "output.h" |
51 | #include "toplev.h" |
52 | #include "expr.h" |
53 | #include "intl.h" |
54 | #include "tree-diagnostic.h" |
55 | #include "reload.h" |
56 | #include "lra.h" |
57 | #include "dwarf2asm.h" |
58 | #include "debug.h" |
59 | #include "common/common-target.h" |
60 | #include "langhooks.h" |
61 | #include "cfgloop.h" /* for init_set_costs */ |
62 | #include "hosthooks.h" |
63 | #include "opts.h" |
64 | #include "opts-diagnostic.h" |
65 | #include "stringpool.h" |
66 | #include "attribs.h" |
67 | #include "asan.h" |
68 | #include "tsan.h" |
69 | #include "plugin.h" |
70 | #include "context.h" |
71 | #include "pass_manager.h" |
72 | #include "auto-profile.h" |
73 | #include "dwarf2out.h" |
74 | #include "ipa-reference.h" |
75 | #include "symbol-summary.h" |
76 | #include "tree-vrp.h" |
77 | #include "ipa-prop.h" |
78 | #include "gcse.h" |
79 | #include "omp-offload.h" |
80 | #include "edit-context.h" |
81 | #include "tree-pass.h" |
82 | #include "dumpfile.h" |
83 | #include "ipa-fnsummary.h" |
84 | #include "dump-context.h" |
85 | #include "print-tree.h" |
86 | #include "optinfo-emit-json.h" |
87 | #include "ipa-modref-tree.h" |
88 | #include "ipa-modref.h" |
89 | #include "ipa-param-manipulation.h" |
90 | #include "dbgcnt.h" |
91 | #include "gcc-urlifier.h" |
92 | |
93 | #include "selftest.h" |
94 | |
95 | #ifdef HAVE_isl |
96 | #include <isl/version.h> |
97 | #endif |
98 | |
99 | static void general_init (const char *, bool); |
100 | static void backend_init (void); |
101 | static int lang_dependent_init (const char *); |
102 | static void init_asm_output (const char *); |
103 | static void finalize (); |
104 | |
105 | static void crash_signal (int) ATTRIBUTE_NORETURN; |
106 | static void compile_file (void); |
107 | |
108 | /* Decoded options, and number of such options. */ |
109 | struct cl_decoded_option *save_decoded_options; |
110 | unsigned int save_decoded_options_count; |
111 | |
112 | /* Vector of saved Optimization decoded command line options. */ |
113 | vec<cl_decoded_option> *save_opt_decoded_options; |
114 | |
115 | /* Debug hooks - dependent upon command line options. */ |
116 | |
117 | const struct gcc_debug_hooks *debug_hooks; |
118 | |
119 | /* The FUNCTION_DECL for the function currently being compiled, |
120 | or 0 if between functions. */ |
121 | tree current_function_decl; |
122 | |
123 | /* Set to the FUNC_BEGIN label of the current function, or NULL |
124 | if none. */ |
125 | const char * current_function_func_begin_label; |
126 | |
127 | /* A random sequence of characters, unless overridden by user. */ |
128 | static const char *flag_random_seed; |
129 | |
130 | /* A local time stamp derived from the time of compilation. It will be |
131 | zero if the system cannot provide a time. It will be -1u, if the |
132 | user has specified a particular random seed. */ |
133 | unsigned local_tick; |
134 | |
135 | /* Random number for this compilation */ |
136 | HOST_WIDE_INT random_seed; |
137 | |
138 | /* -f flags. */ |
139 | |
140 | /* When non-NULL, indicates that whenever space is allocated on the |
141 | stack, the resulting stack pointer must not pass this |
142 | address---that is, for stacks that grow downward, the stack pointer |
143 | must always be greater than or equal to this address; for stacks |
144 | that grow upward, the stack pointer must be less than this address. |
145 | At present, the rtx may be either a REG or a SYMBOL_REF, although |
146 | the support provided depends on the backend. */ |
147 | rtx stack_limit_rtx; |
148 | |
149 | class target_flag_state default_target_flag_state; |
150 | #if SWITCHABLE_TARGET |
151 | class target_flag_state *this_target_flag_state = &default_target_flag_state; |
152 | #else |
153 | #define this_target_flag_state (&default_target_flag_state) |
154 | #endif |
155 | |
156 | /* The user symbol prefix after having resolved same. */ |
157 | const char *user_label_prefix; |
158 | |
159 | /* Output files for assembler code (real compiler output) |
160 | and debugging dumps. */ |
161 | |
162 | FILE *asm_out_file; |
163 | FILE *aux_info_file; |
164 | FILE *callgraph_info_file = NULL; |
165 | static bitmap callgraph_info_external_printed; |
166 | FILE *stack_usage_file = NULL; |
167 | static bool no_backend = false; |
168 | |
169 | /* The current working directory of a translation. It's generally the |
170 | directory from which compilation was initiated, but a preprocessed |
171 | file may specify the original directory in which it was |
172 | created. */ |
173 | |
174 | static const char *src_pwd; |
175 | |
176 | /* Initialize src_pwd with the given string, and return true. If it |
177 | was already initialized, return false. As a special case, it may |
178 | be called with a NULL argument to test whether src_pwd has NOT been |
179 | initialized yet. */ |
180 | |
181 | bool |
182 | set_src_pwd (const char *pwd) |
183 | { |
184 | if (src_pwd) |
185 | { |
186 | if (strcmp (s1: src_pwd, s2: pwd) == 0) |
187 | return true; |
188 | else |
189 | return false; |
190 | } |
191 | |
192 | src_pwd = xstrdup (pwd); |
193 | return true; |
194 | } |
195 | |
196 | /* Return the directory from which the translation unit was initiated, |
197 | in case set_src_pwd() was not called before to assign it a |
198 | different value. */ |
199 | |
200 | const char * |
201 | get_src_pwd (void) |
202 | { |
203 | if (! src_pwd) |
204 | { |
205 | src_pwd = getpwd (); |
206 | if (!src_pwd) |
207 | src_pwd = "." ; |
208 | } |
209 | |
210 | return src_pwd; |
211 | } |
212 | |
213 | /* Called when the start of a function definition is parsed, |
214 | this function prints on stderr the name of the function. */ |
215 | void |
216 | announce_function (tree decl) |
217 | { |
218 | if (!quiet_flag) |
219 | { |
220 | if (rtl_dump_and_exit) |
221 | fprintf (stderr, format: "%s " , |
222 | identifier_to_locale (IDENTIFIER_POINTER (DECL_NAME (decl)))); |
223 | else |
224 | fprintf (stderr, format: " %s" , |
225 | identifier_to_locale (lang_hooks.decl_printable_name (decl, 2))); |
226 | fflush (stderr); |
227 | pp_needs_newline (global_dc->printer) = true; |
228 | diagnostic_set_last_function (global_dc, (diagnostic_info *) NULL); |
229 | } |
230 | } |
231 | |
232 | /* Initialize local_tick with the time of day, or -1 if |
233 | flag_random_seed is set. */ |
234 | |
235 | static void |
236 | init_local_tick (void) |
237 | { |
238 | if (!flag_random_seed) |
239 | { |
240 | #ifdef HAVE_GETTIMEOFDAY |
241 | { |
242 | struct timeval tv; |
243 | |
244 | gettimeofday (tv: &tv, NULL); |
245 | local_tick = (unsigned) tv.tv_sec * 1000 + tv.tv_usec / 1000; |
246 | } |
247 | #else |
248 | { |
249 | time_t now = time (NULL); |
250 | |
251 | if (now != (time_t)-1) |
252 | local_tick = (unsigned) now; |
253 | } |
254 | #endif |
255 | } |
256 | else |
257 | local_tick = -1; |
258 | } |
259 | |
260 | /* Obtain the random_seed. Unless NOINIT, initialize it if |
261 | it's not provided in the command line. */ |
262 | |
263 | HOST_WIDE_INT |
264 | get_random_seed (bool noinit) |
265 | { |
266 | if (!random_seed && !noinit) |
267 | { |
268 | int fd = open (file: "/dev/urandom" , O_RDONLY); |
269 | if (fd >= 0) |
270 | { |
271 | if (read (fd: fd, buf: &random_seed, nbytes: sizeof (random_seed)) |
272 | != sizeof (random_seed)) |
273 | random_seed = 0; |
274 | close (fd: fd); |
275 | } |
276 | if (!random_seed) |
277 | random_seed = local_tick ^ getpid (); |
278 | } |
279 | return random_seed; |
280 | } |
281 | |
282 | /* Set flag_random_seed to VAL, and if non-null, reinitialize random_seed. */ |
283 | |
284 | void |
285 | set_random_seed (const char *val) |
286 | { |
287 | flag_random_seed = val; |
288 | if (flag_random_seed) |
289 | { |
290 | char *endp; |
291 | |
292 | /* When the driver passed in a hex number don't crc it again */ |
293 | random_seed = strtoul (nptr: flag_random_seed, endptr: &endp, base: 0); |
294 | if (!(endp > flag_random_seed && *endp == 0)) |
295 | random_seed = crc32_string (0, flag_random_seed); |
296 | } |
297 | } |
298 | |
299 | /* Handler for fatal signals, such as SIGSEGV. These are transformed |
300 | into ICE messages, which is much more user friendly. In case the |
301 | error printer crashes, reset the signal to prevent infinite recursion. */ |
302 | |
303 | static void |
304 | crash_signal (int signo) |
305 | { |
306 | signal (sig: signo, SIG_DFL); |
307 | |
308 | /* If we crashed while processing an ASM statement, then be a little more |
309 | graceful. It's most likely the user's fault. */ |
310 | if (this_is_asm_operands) |
311 | { |
312 | output_operand_lossage ("unrecoverable error" ); |
313 | exit (FATAL_EXIT_CODE); |
314 | } |
315 | |
316 | internal_error ("%s" , strsignal (sig: signo)); |
317 | } |
318 | |
319 | /* A subroutine of wrapup_global_declarations. We've come to the end of |
320 | the compilation unit. All deferred variables should be undeferred, |
321 | and all incomplete decls should be finalized. */ |
322 | |
323 | void |
324 | wrapup_global_declaration_1 (tree decl) |
325 | { |
326 | /* We're not deferring this any longer. Assignment is conditional to |
327 | avoid needlessly dirtying PCH pages. */ |
328 | if (HAS_DECL_ASSEMBLER_NAME_P (decl) |
329 | && DECL_DEFER_OUTPUT (decl) != 0) |
330 | DECL_DEFER_OUTPUT (decl) = 0; |
331 | |
332 | if (VAR_P (decl) && DECL_SIZE (decl) == 0) |
333 | lang_hooks.finish_incomplete_decl (decl); |
334 | } |
335 | |
336 | /* A subroutine of wrapup_global_declarations. Decide whether or not DECL |
337 | needs to be output. Return true if it is output. */ |
338 | |
339 | bool |
340 | wrapup_global_declaration_2 (tree decl) |
341 | { |
342 | if (TREE_ASM_WRITTEN (decl) || DECL_EXTERNAL (decl) |
343 | || (VAR_P (decl) && DECL_HAS_VALUE_EXPR_P (decl))) |
344 | return false; |
345 | |
346 | /* Don't write out static consts, unless we still need them. |
347 | |
348 | We also keep static consts if not optimizing (for debugging), |
349 | unless the user specified -fno-keep-static-consts. |
350 | ??? They might be better written into the debug information. |
351 | This is possible when using DWARF. |
352 | |
353 | A language processor that wants static constants to be always |
354 | written out (even if it is not used) is responsible for |
355 | calling rest_of_decl_compilation itself. E.g. the C front-end |
356 | calls rest_of_decl_compilation from finish_decl. |
357 | One motivation for this is that is conventional in some |
358 | environments to write things like: |
359 | static const char rcsid[] = "... version string ..."; |
360 | intending to force the string to be in the executable. |
361 | |
362 | A language processor that would prefer to have unneeded |
363 | static constants "optimized away" would just defer writing |
364 | them out until here. E.g. C++ does this, because static |
365 | constants are often defined in header files. |
366 | |
367 | ??? A tempting alternative (for both C and C++) would be |
368 | to force a constant to be written if and only if it is |
369 | defined in a main file, as opposed to an include file. */ |
370 | |
371 | if (VAR_P (decl) && TREE_STATIC (decl)) |
372 | { |
373 | varpool_node *node; |
374 | bool needed = true; |
375 | node = varpool_node::get (decl); |
376 | |
377 | if (!node && flag_ltrans) |
378 | needed = false; |
379 | else if (node && node->definition) |
380 | needed = false; |
381 | else if (node && node->alias) |
382 | needed = false; |
383 | else if (!symtab->global_info_ready |
384 | && (TREE_USED (decl) |
385 | || TREE_USED (DECL_ASSEMBLER_NAME (decl)))) |
386 | /* needed */; |
387 | else if (node && node->analyzed) |
388 | /* needed */; |
389 | else if (DECL_COMDAT (decl)) |
390 | needed = false; |
391 | else if (TREE_READONLY (decl) && !TREE_PUBLIC (decl) |
392 | && (optimize || !flag_keep_static_consts |
393 | || DECL_ARTIFICIAL (decl))) |
394 | needed = false; |
395 | |
396 | if (needed) |
397 | { |
398 | rest_of_decl_compilation (decl, 1, 1); |
399 | return true; |
400 | } |
401 | } |
402 | |
403 | return false; |
404 | } |
405 | |
406 | /* Do any final processing required for the declarations in VEC, of |
407 | which there are LEN. We write out inline functions and variables |
408 | that have been deferred until this point, but which are required. |
409 | Returns nonzero if anything was put out. */ |
410 | |
411 | bool |
412 | wrapup_global_declarations (tree *vec, int len) |
413 | { |
414 | bool reconsider, output_something = false; |
415 | int i; |
416 | |
417 | for (i = 0; i < len; i++) |
418 | wrapup_global_declaration_1 (decl: vec[i]); |
419 | |
420 | /* Now emit any global variables or functions that we have been |
421 | putting off. We need to loop in case one of the things emitted |
422 | here references another one which comes earlier in the list. */ |
423 | do |
424 | { |
425 | reconsider = false; |
426 | for (i = 0; i < len; i++) |
427 | reconsider |= wrapup_global_declaration_2 (decl: vec[i]); |
428 | if (reconsider) |
429 | output_something = true; |
430 | } |
431 | while (reconsider); |
432 | |
433 | return output_something; |
434 | } |
435 | |
436 | /* Compile an entire translation unit. Write a file of assembly |
437 | output and various debugging dumps. */ |
438 | |
439 | static void |
440 | compile_file (void) |
441 | { |
442 | timevar_start (TV_PHASE_PARSING); |
443 | timevar_push (tv: TV_PARSE_GLOBAL); |
444 | |
445 | /* Parse entire file and generate initial debug information. */ |
446 | lang_hooks.parse_file (); |
447 | |
448 | timevar_pop (tv: TV_PARSE_GLOBAL); |
449 | timevar_stop (TV_PHASE_PARSING); |
450 | |
451 | if (flag_dump_locations) |
452 | dump_location_info (stderr); |
453 | |
454 | free_attr_data (); |
455 | |
456 | /* Compilation is now finished except for writing |
457 | what's left of the symbol table output. */ |
458 | |
459 | if (flag_syntax_only || flag_wpa) |
460 | return; |
461 | |
462 | /* Reset maximum_field_alignment, it can be adjusted by #pragma pack |
463 | and this shouldn't influence any types built by the middle-end |
464 | from now on (like gcov_info_type). */ |
465 | maximum_field_alignment = initial_max_fld_align * BITS_PER_UNIT; |
466 | |
467 | ggc_protect_identifiers = false; |
468 | |
469 | /* Run the actual compilation process. */ |
470 | if (!in_lto_p) |
471 | { |
472 | timevar_start (TV_PHASE_OPT_GEN); |
473 | symtab->finalize_compilation_unit (); |
474 | timevar_stop (TV_PHASE_OPT_GEN); |
475 | } |
476 | |
477 | /* Perform any post compilation-proper parser cleanups and |
478 | processing. This is currently only needed for the C++ parser, |
479 | which can be hopefully cleaned up so this hook is no longer |
480 | necessary. */ |
481 | if (lang_hooks.decls.post_compilation_parsing_cleanups) |
482 | lang_hooks.decls.post_compilation_parsing_cleanups (); |
483 | |
484 | dump_context::get ().finish_any_json_writer (); |
485 | |
486 | if (seen_error ()) |
487 | return; |
488 | |
489 | timevar_start (TV_PHASE_LATE_ASM); |
490 | |
491 | /* Compilation unit is finalized. When producing non-fat LTO object, we are |
492 | basically finished. */ |
493 | if ((in_lto_p && flag_incremental_link != INCREMENTAL_LINK_LTO) |
494 | || !flag_lto || flag_fat_lto_objects) |
495 | { |
496 | /* File-scope initialization for AddressSanitizer. */ |
497 | if (flag_sanitize & SANITIZE_ADDRESS) |
498 | asan_finish_file (); |
499 | |
500 | if (flag_sanitize & SANITIZE_THREAD) |
501 | tsan_finish_file (); |
502 | |
503 | if (gate_hwasan ()) |
504 | hwasan_finish_file (); |
505 | |
506 | omp_finish_file (); |
507 | |
508 | output_shared_constant_pool (); |
509 | output_object_blocks (); |
510 | finish_tm_clone_pairs (); |
511 | |
512 | /* Write out any pending weak symbol declarations. */ |
513 | weak_finish (); |
514 | |
515 | /* This must be at the end before unwind and debug info. |
516 | Some target ports emit PIC setup thunks here. */ |
517 | insn_locations_init (); |
518 | targetm.asm_out.code_end (); |
519 | |
520 | /* Do dbx symbols. */ |
521 | timevar_push (tv: TV_SYMOUT); |
522 | |
523 | #if defined DWARF2_DEBUGGING_INFO || defined DWARF2_UNWIND_INFO |
524 | dwarf2out_frame_finish (); |
525 | #endif |
526 | |
527 | debuginfo_start (); |
528 | (*debug_hooks->finish) (main_input_filename); |
529 | debuginfo_stop (); |
530 | timevar_pop (tv: TV_SYMOUT); |
531 | |
532 | /* Output some stuff at end of file if nec. */ |
533 | |
534 | dw2_output_indirect_constants (); |
535 | |
536 | /* Flush any pending external directives. */ |
537 | process_pending_assemble_externals (); |
538 | } |
539 | |
540 | /* Let linker plugin know that this is a slim object and must be LTOed |
541 | even when user did not ask for it. */ |
542 | if (flag_generate_lto && !flag_fat_lto_objects) |
543 | { |
544 | #if defined ASM_OUTPUT_ALIGNED_DECL_COMMON |
545 | ASM_OUTPUT_ALIGNED_DECL_COMMON (asm_out_file, NULL_TREE, "__gnu_lto_slim" , |
546 | HOST_WIDE_INT_1U, 8); |
547 | #elif defined ASM_OUTPUT_ALIGNED_COMMON |
548 | ASM_OUTPUT_ALIGNED_COMMON (asm_out_file, "__gnu_lto_slim" , |
549 | HOST_WIDE_INT_1U, 8); |
550 | #else |
551 | ASM_OUTPUT_COMMON (asm_out_file, "__gnu_lto_slim" , |
552 | HOST_WIDE_INT_1U, |
553 | HOST_WIDE_INT_1U); |
554 | #endif |
555 | } |
556 | |
557 | /* Attach a special .ident directive to the end of the file to identify |
558 | the version of GCC which compiled this code. The format of the .ident |
559 | string is patterned after the ones produced by native SVR4 compilers. */ |
560 | if (!flag_no_ident) |
561 | { |
562 | const char *pkg_version = "(GNU) " ; |
563 | char *ident_str; |
564 | |
565 | if (strcmp (s1: "(GCC) " , pkgversion_string)) |
566 | pkg_version = pkgversion_string; |
567 | |
568 | ident_str = ACONCAT (("GCC: " , pkg_version, version_string, NULL)); |
569 | targetm.asm_out.output_ident (ident_str); |
570 | } |
571 | |
572 | /* Auto profile finalization. */ |
573 | if (flag_auto_profile) |
574 | end_auto_profile (); |
575 | |
576 | /* Invoke registered plugin callbacks. */ |
577 | invoke_plugin_callbacks (event: PLUGIN_FINISH_UNIT, NULL); |
578 | |
579 | /* This must be at the end. Some target ports emit end of file directives |
580 | into the assembly file here, and hence we cannot output anything to the |
581 | assembly file after this point. */ |
582 | targetm.asm_out.file_end (); |
583 | |
584 | timevar_stop (TV_PHASE_LATE_ASM); |
585 | } |
586 | |
587 | /* Print version information to FILE. |
588 | Each line begins with INDENT (for the case where FILE is the |
589 | assembler output file). |
590 | |
591 | If SHOW_GLOBAL_STATE is true (for cc1 etc), we are within the compiler |
592 | proper and can print pertinent state (e.g. params and plugins). |
593 | |
594 | If SHOW_GLOBAL_STATE is false (for use by libgccjit), we are outside the |
595 | compiler, and we don't hold the mutex on the compiler's global state: |
596 | we can't print params and plugins, since they might not be initialized, |
597 | or might be being manipulated by a compile running in another |
598 | thread. */ |
599 | |
600 | void |
601 | print_version (FILE *file, const char *indent, bool show_global_state) |
602 | { |
603 | static const char fmt1[] = |
604 | #ifdef __GNUC__ |
605 | N_("%s%s%s %sversion %s (%s)\n%s\tcompiled by GNU C version %s, " ) |
606 | #else |
607 | N_("%s%s%s %sversion %s (%s) compiled by CC, " ) |
608 | #endif |
609 | ; |
610 | static const char fmt2[] = |
611 | N_("GMP version %s, MPFR version %s, MPC version %s, isl version %s\n" ); |
612 | static const char fmt3[] = |
613 | N_("%s%swarning: %s header version %s differs from library version %s.\n" ); |
614 | static const char fmt4[] = |
615 | N_("%s%sGGC heuristics: --param ggc-min-expand=%d --param ggc-min-heapsize=%d\n" ); |
616 | #ifndef __VERSION__ |
617 | #define __VERSION__ "[?]" |
618 | #endif |
619 | fprintf (file, |
620 | file == stderr ? _(fmt1) : fmt1, |
621 | indent, *indent != 0 ? " " : "" , |
622 | lang_hooks.name, pkgversion_string, version_string, TARGET_NAME, |
623 | indent, __VERSION__); |
624 | |
625 | /* We need to stringify the GMP macro values. Ugh, gmp_version has |
626 | two string formats, "i.j.k" and "i.j" when k is zero. As of |
627 | gmp-4.3.0, GMP always uses the 3 number format. */ |
628 | #define GCC_GMP_STRINGIFY_VERSION3(X) #X |
629 | #define GCC_GMP_STRINGIFY_VERSION2(X) GCC_GMP_STRINGIFY_VERSION3 (X) |
630 | #define GCC_GMP_VERSION_NUM(X,Y,Z) (((X) << 16L) | ((Y) << 8) | (Z)) |
631 | #define GCC_GMP_VERSION \ |
632 | GCC_GMP_VERSION_NUM(__GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL) |
633 | #if GCC_GMP_VERSION < GCC_GMP_VERSION_NUM(4,3,0) && __GNU_MP_VERSION_PATCHLEVEL == 0 |
634 | #define GCC_GMP_STRINGIFY_VERSION \ |
635 | GCC_GMP_STRINGIFY_VERSION2 (__GNU_MP_VERSION) "." \ |
636 | GCC_GMP_STRINGIFY_VERSION2 (__GNU_MP_VERSION_MINOR) |
637 | #else |
638 | #define GCC_GMP_STRINGIFY_VERSION \ |
639 | GCC_GMP_STRINGIFY_VERSION2 (__GNU_MP_VERSION) "." \ |
640 | GCC_GMP_STRINGIFY_VERSION2 (__GNU_MP_VERSION_MINOR) "." \ |
641 | GCC_GMP_STRINGIFY_VERSION2 (__GNU_MP_VERSION_PATCHLEVEL) |
642 | #endif |
643 | fprintf (stream: file, |
644 | format: file == stderr ? _(fmt2) : fmt2, |
645 | GCC_GMP_STRINGIFY_VERSION, MPFR_VERSION_STRING, MPC_VERSION_STRING, |
646 | #ifndef HAVE_isl |
647 | "none" |
648 | #else |
649 | isl_version () |
650 | #endif |
651 | ); |
652 | if (strcmp (GCC_GMP_STRINGIFY_VERSION, gmp_version)) |
653 | fprintf (stream: file, |
654 | format: file == stderr ? _(fmt3) : fmt3, |
655 | indent, *indent != 0 ? " " : "" , |
656 | "GMP" , GCC_GMP_STRINGIFY_VERSION, gmp_version); |
657 | if (strcmp (MPFR_VERSION_STRING, s2: mpfr_get_version ())) |
658 | fprintf (stream: file, |
659 | format: file == stderr ? _(fmt3) : fmt3, |
660 | indent, *indent != 0 ? " " : "" , |
661 | "MPFR" , MPFR_VERSION_STRING, mpfr_get_version ()); |
662 | if (strcmp (MPC_VERSION_STRING, s2: mpc_get_version ())) |
663 | fprintf (stream: file, |
664 | format: file == stderr ? _(fmt3) : fmt3, |
665 | indent, *indent != 0 ? " " : "" , |
666 | "MPC" , MPC_VERSION_STRING, mpc_get_version ()); |
667 | |
668 | if (show_global_state) |
669 | { |
670 | fprintf (stream: file, |
671 | format: file == stderr ? _(fmt4) : fmt4, |
672 | indent, *indent != 0 ? " " : "" , |
673 | param_ggc_min_expand, param_ggc_min_heapsize); |
674 | |
675 | print_plugins_versions (file, indent); |
676 | } |
677 | } |
678 | |
679 | |
680 | |
681 | /* Open assembly code output file. Do this even if -fsyntax-only is |
682 | on, because then the driver will have provided the name of a |
683 | temporary file or bit bucket for us. NAME is the file specified on |
684 | the command line, possibly NULL. */ |
685 | static void |
686 | init_asm_output (const char *name) |
687 | { |
688 | if (name == NULL && asm_file_name == 0) |
689 | asm_out_file = stdout; |
690 | else |
691 | { |
692 | if (asm_file_name == 0) |
693 | { |
694 | int len = strlen (dump_base_name); |
695 | char *dumpname = XNEWVEC (char, len + 6); |
696 | |
697 | memcpy (dest: dumpname, dump_base_name, n: len + 1); |
698 | strip_off_ending (dumpname, len); |
699 | strcat (dest: dumpname, src: ".s" ); |
700 | asm_file_name = dumpname; |
701 | } |
702 | if (!strcmp (asm_file_name, s2: "-" )) |
703 | asm_out_file = stdout; |
704 | else if (!canonical_filename_eq (asm_file_name, b: name) |
705 | || !strcmp (asm_file_name, HOST_BIT_BUCKET)) |
706 | asm_out_file = fopen (asm_file_name, modes: "w" ); |
707 | else |
708 | /* Use UNKOWN_LOCATION to prevent gcc from printing the first |
709 | line in the current file. */ |
710 | fatal_error (UNKNOWN_LOCATION, |
711 | "input file %qs is the same as output file" , |
712 | asm_file_name); |
713 | if (asm_out_file == 0) |
714 | fatal_error (UNKNOWN_LOCATION, |
715 | "cannot open %qs for writing: %m" , asm_file_name); |
716 | } |
717 | |
718 | if (!flag_syntax_only && !(global_dc->m_lang_mask & CL_LTODump)) |
719 | { |
720 | targetm.asm_out.file_start (); |
721 | |
722 | if (flag_record_gcc_switches) |
723 | { |
724 | if (targetm.asm_out.record_gcc_switches) |
725 | { |
726 | const char *str |
727 | = gen_producer_string (language_string: lang_hooks.name, |
728 | options: save_decoded_options, |
729 | options_count: save_decoded_options_count); |
730 | targetm.asm_out.record_gcc_switches (str); |
731 | } |
732 | else |
733 | inform (UNKNOWN_LOCATION, |
734 | "%<-frecord-gcc-switches%> is not supported by " |
735 | "the current target" ); |
736 | } |
737 | |
738 | if (flag_verbose_asm) |
739 | { |
740 | print_version (file: asm_out_file, ASM_COMMENT_START, show_global_state: true); |
741 | fputs (ASM_COMMENT_START, stream: asm_out_file); |
742 | fputs (s: " options passed: " , stream: asm_out_file); |
743 | char *cmdline = gen_command_line_string (options: save_decoded_options, |
744 | options_count: save_decoded_options_count); |
745 | fputs (s: cmdline, stream: asm_out_file); |
746 | free (ptr: cmdline); |
747 | fputc (c: '\n', stream: asm_out_file); |
748 | } |
749 | } |
750 | } |
751 | |
752 | /* A helper function; used as the reallocator function for cpp's line |
753 | table. */ |
754 | static void * |
755 | realloc_for_line_map (void *ptr, size_t len) |
756 | { |
757 | return ggc_realloc (ptr, len); |
758 | } |
759 | |
760 | /* A helper function: used as the allocator function for |
761 | identifier_to_locale. */ |
762 | static void * |
763 | alloc_for_identifier_to_locale (size_t len) |
764 | { |
765 | return ggc_alloc_atomic (s: len); |
766 | } |
767 | |
768 | /* Output stack usage information. */ |
769 | static void |
770 | output_stack_usage_1 (FILE *cf) |
771 | { |
772 | static bool warning_issued = false; |
773 | enum stack_usage_kind_type { STATIC = 0, DYNAMIC, DYNAMIC_BOUNDED }; |
774 | const char *stack_usage_kind_str[] = { |
775 | "static" , |
776 | "dynamic" , |
777 | "dynamic,bounded" |
778 | }; |
779 | HOST_WIDE_INT stack_usage = current_function_static_stack_size; |
780 | enum stack_usage_kind_type stack_usage_kind; |
781 | |
782 | if (stack_usage < 0) |
783 | { |
784 | if (!warning_issued) |
785 | { |
786 | warning (0, "stack usage computation not supported for this target" ); |
787 | warning_issued = true; |
788 | } |
789 | return; |
790 | } |
791 | |
792 | stack_usage_kind = STATIC; |
793 | |
794 | /* Add the maximum amount of space pushed onto the stack. */ |
795 | if (maybe_ne (current_function_pushed_stack_size, b: 0)) |
796 | { |
797 | HOST_WIDE_INT ; |
798 | if (current_function_pushed_stack_size.is_constant (const_value: &extra)) |
799 | { |
800 | stack_usage += extra; |
801 | stack_usage_kind = DYNAMIC_BOUNDED; |
802 | } |
803 | else |
804 | { |
805 | extra = constant_lower_bound (current_function_pushed_stack_size); |
806 | stack_usage += extra; |
807 | stack_usage_kind = DYNAMIC; |
808 | } |
809 | } |
810 | |
811 | /* Now on to the tricky part: dynamic stack allocation. */ |
812 | if (current_function_allocates_dynamic_stack_space) |
813 | { |
814 | if (stack_usage_kind != DYNAMIC) |
815 | { |
816 | if (current_function_has_unbounded_dynamic_stack_size) |
817 | stack_usage_kind = DYNAMIC; |
818 | else |
819 | stack_usage_kind = DYNAMIC_BOUNDED; |
820 | } |
821 | |
822 | /* Add the size even in the unbounded case, this can't hurt. */ |
823 | stack_usage += current_function_dynamic_stack_size; |
824 | } |
825 | |
826 | if (cf && flag_callgraph_info & CALLGRAPH_INFO_STACK_USAGE) |
827 | fprintf (stream: cf, format: "\\n" HOST_WIDE_INT_PRINT_DEC " bytes (%s)" , |
828 | stack_usage, |
829 | stack_usage_kind_str[stack_usage_kind]); |
830 | |
831 | if (stack_usage_file) |
832 | { |
833 | print_decl_identifier (stack_usage_file, current_function_decl, |
834 | PRINT_DECL_ORIGIN | PRINT_DECL_NAME |
835 | | PRINT_DECL_REMAP_DEBUG); |
836 | fprintf (stream: stack_usage_file, format: "\t" HOST_WIDE_INT_PRINT_DEC"\t%s\n" , |
837 | stack_usage, stack_usage_kind_str[stack_usage_kind]); |
838 | } |
839 | |
840 | if (warn_stack_usage >= 0 && warn_stack_usage < HOST_WIDE_INT_MAX) |
841 | { |
842 | const location_t loc = DECL_SOURCE_LOCATION (current_function_decl); |
843 | |
844 | if (stack_usage_kind == DYNAMIC) |
845 | warning_at (loc, OPT_Wstack_usage_, "stack usage might be unbounded" ); |
846 | else if (stack_usage > warn_stack_usage) |
847 | { |
848 | if (stack_usage_kind == DYNAMIC_BOUNDED) |
849 | warning_at (loc, |
850 | OPT_Wstack_usage_, "stack usage might be %wu bytes" , |
851 | stack_usage); |
852 | else |
853 | warning_at (loc, OPT_Wstack_usage_, "stack usage is %wu bytes" , |
854 | stack_usage); |
855 | } |
856 | } |
857 | } |
858 | |
859 | /* Dump placeholder node for indirect calls in VCG format. */ |
860 | |
861 | #define INDIRECT_CALL_NAME "__indirect_call" |
862 | |
863 | static void |
864 | dump_final_node_vcg_start (FILE *f, tree decl) |
865 | { |
866 | fputs (s: "node: { title: \"" , stream: f); |
867 | if (decl) |
868 | print_decl_identifier (f, decl, PRINT_DECL_UNIQUE_NAME); |
869 | else |
870 | fputs (INDIRECT_CALL_NAME, stream: f); |
871 | fputs (s: "\" label: \"" , stream: f); |
872 | if (decl) |
873 | { |
874 | print_decl_identifier (f, decl, PRINT_DECL_NAME); |
875 | fputs (s: "\\n" , stream: f); |
876 | print_decl_identifier (f, decl, PRINT_DECL_ORIGIN); |
877 | } |
878 | else |
879 | fputs (s: "Indirect Call Placeholder" , stream: f); |
880 | } |
881 | |
882 | /* Dump final cgraph edge in VCG format. */ |
883 | |
884 | static void |
885 | dump_final_callee_vcg (FILE *f, location_t location, tree callee) |
886 | { |
887 | if ((!callee || DECL_EXTERNAL (callee)) |
888 | && bitmap_set_bit (callgraph_info_external_printed, |
889 | callee ? DECL_UID (callee) + 1 : 0)) |
890 | { |
891 | dump_final_node_vcg_start (f, decl: callee); |
892 | fputs (s: "\" shape : ellipse }\n" , stream: f); |
893 | } |
894 | |
895 | fputs (s: "edge: { sourcename: \"" , stream: f); |
896 | print_decl_identifier (f, current_function_decl, PRINT_DECL_UNIQUE_NAME); |
897 | fputs (s: "\" targetname: \"" , stream: f); |
898 | if (callee) |
899 | print_decl_identifier (f, callee, PRINT_DECL_UNIQUE_NAME); |
900 | else |
901 | fputs (INDIRECT_CALL_NAME, stream: f); |
902 | if (LOCATION_LOCUS (location) != UNKNOWN_LOCATION) |
903 | { |
904 | expanded_location loc; |
905 | fputs (s: "\" label: \"" , stream: f); |
906 | loc = expand_location (location); |
907 | fprintf (stream: f, format: "%s:%d:%d" , loc.file, loc.line, loc.column); |
908 | } |
909 | fputs (s: "\" }\n" , stream: f); |
910 | } |
911 | |
912 | /* Dump final cgraph node in VCG format. */ |
913 | |
914 | static void |
915 | dump_final_node_vcg (FILE *f) |
916 | { |
917 | dump_final_node_vcg_start (f, decl: current_function_decl); |
918 | |
919 | if (flag_stack_usage_info |
920 | || (flag_callgraph_info & CALLGRAPH_INFO_STACK_USAGE)) |
921 | output_stack_usage_1 (cf: f); |
922 | |
923 | if (flag_callgraph_info & CALLGRAPH_INFO_DYNAMIC_ALLOC) |
924 | { |
925 | fprintf (stream: f, format: "\\n%u dynamic objects" , vec_safe_length (cfun->su->dallocs)); |
926 | |
927 | unsigned i; |
928 | callinfo_dalloc *cda; |
929 | FOR_EACH_VEC_SAFE_ELT (cfun->su->dallocs, i, cda) |
930 | { |
931 | expanded_location loc = expand_location (cda->location); |
932 | fprintf (stream: f, format: "\\n %s" , cda->name); |
933 | fprintf (stream: f, format: " %s:%d:%d" , loc.file, loc.line, loc.column); |
934 | } |
935 | |
936 | vec_free (cfun->su->dallocs); |
937 | cfun->su->dallocs = NULL; |
938 | } |
939 | |
940 | fputs (s: "\" }\n" , stream: f); |
941 | |
942 | unsigned i; |
943 | callinfo_callee *c; |
944 | FOR_EACH_VEC_SAFE_ELT (cfun->su->callees, i, c) |
945 | dump_final_callee_vcg (f, location: c->location, callee: c->decl); |
946 | vec_free (cfun->su->callees); |
947 | cfun->su->callees = NULL; |
948 | } |
949 | |
950 | /* Output stack usage and callgraph info, as requested. */ |
951 | void |
952 | output_stack_usage (void) |
953 | { |
954 | if (flag_callgraph_info) |
955 | dump_final_node_vcg (f: callgraph_info_file); |
956 | else |
957 | output_stack_usage_1 (NULL); |
958 | } |
959 | |
960 | /* Open an auxiliary output file. */ |
961 | static FILE * |
962 | open_auxiliary_file (const char *ext) |
963 | { |
964 | char *filename; |
965 | FILE *file; |
966 | |
967 | filename = concat (aux_base_name, "." , ext, NULL); |
968 | file = fopen (filename: filename, modes: "w" ); |
969 | if (!file) |
970 | fatal_error (input_location, "cannot open %s for writing: %m" , filename); |
971 | free (ptr: filename); |
972 | return file; |
973 | } |
974 | |
975 | /* Alternative diagnostics callback for reentered ICE reporting. */ |
976 | |
977 | static void |
978 | internal_error_reentered (diagnostic_context *, const char *, va_list *) |
979 | { |
980 | /* Flush the dump file if emergency_dump_function itself caused an ICE. */ |
981 | if (dump_file) |
982 | fflush (stream: dump_file); |
983 | } |
984 | |
985 | /* Auxiliary callback for the diagnostics code. */ |
986 | |
987 | static void |
988 | internal_error_function (diagnostic_context *, const char *, va_list *) |
989 | { |
990 | global_dc->m_internal_error = internal_error_reentered; |
991 | warn_if_plugins (); |
992 | emergency_dump_function (); |
993 | } |
994 | |
995 | /* Initialization of the front end environment, before command line |
996 | options are parsed. Signal handlers, internationalization etc. |
997 | ARGV0 is main's argv[0]. */ |
998 | static void |
999 | general_init (const char *argv0, bool init_signals) |
1000 | { |
1001 | const char *p; |
1002 | |
1003 | p = argv0 + strlen (s: argv0); |
1004 | while (p != argv0 && !IS_DIR_SEPARATOR (p[-1])) |
1005 | --p; |
1006 | progname = p; |
1007 | |
1008 | xmalloc_set_program_name (progname); |
1009 | |
1010 | hex_init (); |
1011 | |
1012 | /* Unlock the stdio streams. */ |
1013 | unlock_std_streams (); |
1014 | |
1015 | gcc_init_libintl (); |
1016 | |
1017 | identifier_to_locale_alloc = alloc_for_identifier_to_locale; |
1018 | identifier_to_locale_free = ggc_free; |
1019 | |
1020 | /* Initialize the diagnostics reporting machinery, so option parsing |
1021 | can give warnings and errors. */ |
1022 | diagnostic_initialize (context: global_dc, n_opts: N_OPTS); |
1023 | global_dc->m_lang_mask = lang_hooks.option_lang_mask (); |
1024 | /* Set a default printer. Language specific initializations will |
1025 | override it later. */ |
1026 | tree_diagnostics_defaults (context: global_dc); |
1027 | |
1028 | global_dc->m_source_printing.enabled |
1029 | = global_options_init.x_flag_diagnostics_show_caret; |
1030 | global_dc->m_source_printing.show_labels_p |
1031 | = global_options_init.x_flag_diagnostics_show_labels; |
1032 | global_dc->m_source_printing.show_line_numbers_p |
1033 | = global_options_init.x_flag_diagnostics_show_line_numbers; |
1034 | global_dc->set_show_cwe (global_options_init.x_flag_diagnostics_show_cwe); |
1035 | global_dc->set_show_rules (global_options_init.x_flag_diagnostics_show_rules); |
1036 | global_dc->set_path_format |
1037 | ((enum diagnostic_path_format) |
1038 | global_options_init.x_flag_diagnostics_path_format); |
1039 | global_dc->set_show_path_depths |
1040 | (global_options_init.x_flag_diagnostics_show_path_depths); |
1041 | global_dc->set_show_option_requested |
1042 | (global_options_init.x_flag_diagnostics_show_option); |
1043 | global_dc->m_source_printing.min_margin_width |
1044 | = global_options_init.x_diagnostics_minimum_margin_width; |
1045 | global_dc->m_show_column |
1046 | = global_options_init.x_flag_show_column; |
1047 | global_dc->m_internal_error = internal_error_function; |
1048 | global_dc->m_option_enabled = option_enabled; |
1049 | global_dc->m_option_state = &global_options; |
1050 | global_dc->m_option_name = option_name; |
1051 | global_dc->m_get_option_url = get_option_url; |
1052 | global_dc->set_urlifier (make_gcc_urlifier ()); |
1053 | |
1054 | if (init_signals) |
1055 | { |
1056 | /* Trap fatal signals, e.g. SIGSEGV, and convert them to ICE messages. */ |
1057 | #ifdef SIGSEGV |
1058 | signal (SIGSEGV, handler: crash_signal); |
1059 | #endif |
1060 | #ifdef SIGILL |
1061 | signal (SIGILL, handler: crash_signal); |
1062 | #endif |
1063 | #ifdef SIGBUS |
1064 | signal (SIGBUS, handler: crash_signal); |
1065 | #endif |
1066 | #ifdef SIGABRT |
1067 | signal (SIGABRT, handler: crash_signal); |
1068 | #endif |
1069 | #if defined SIGIOT && (!defined SIGABRT || SIGABRT != SIGIOT) |
1070 | signal (SIGIOT, crash_signal); |
1071 | #endif |
1072 | #ifdef SIGFPE |
1073 | signal (SIGFPE, handler: crash_signal); |
1074 | #endif |
1075 | |
1076 | /* Other host-specific signal setup. */ |
1077 | (*host_hooks.extra_signals)(); |
1078 | } |
1079 | |
1080 | /* Initialize the garbage-collector, string pools and tree type hash |
1081 | table. */ |
1082 | init_ggc (); |
1083 | init_stringpool (); |
1084 | input_location = UNKNOWN_LOCATION; |
1085 | line_table = ggc_alloc<line_maps> (); |
1086 | linemap_init (set: line_table, BUILTINS_LOCATION); |
1087 | line_table->m_reallocator = realloc_for_line_map; |
1088 | line_table->m_round_alloc_size = ggc_round_alloc_size; |
1089 | line_table->default_range_bits = 5; |
1090 | init_ttree (); |
1091 | |
1092 | /* Initialize register usage now so switches may override. */ |
1093 | init_reg_sets (); |
1094 | |
1095 | /* Create the singleton holder for global state. This creates the |
1096 | dump manager. */ |
1097 | g = new gcc::context (); |
1098 | |
1099 | /* Allow languages and middle-end to register their dumps before the |
1100 | optimization passes. */ |
1101 | g->get_dumps ()->register_dumps (); |
1102 | |
1103 | /* Create the passes. */ |
1104 | g->set_passes (new gcc::pass_manager (g)); |
1105 | |
1106 | symtab = new (ggc_alloc <symbol_table> ()) symbol_table (); |
1107 | |
1108 | statistics_early_init (); |
1109 | debuginfo_early_init (); |
1110 | } |
1111 | |
1112 | /* Return true if the current target supports -fsection-anchors. */ |
1113 | |
1114 | static bool |
1115 | target_supports_section_anchors_p (void) |
1116 | { |
1117 | if (targetm.min_anchor_offset == 0 && targetm.max_anchor_offset == 0) |
1118 | return false; |
1119 | |
1120 | if (targetm.asm_out.output_anchor == NULL) |
1121 | return false; |
1122 | |
1123 | return true; |
1124 | } |
1125 | |
1126 | /* Parse "N[:M][:...]" into struct align_flags A. |
1127 | VALUES contains parsed values (in reverse order), all processed |
1128 | values are popped. */ |
1129 | |
1130 | static void |
1131 | read_log_maxskip (auto_vec<unsigned> &values, align_flags_tuple *a) |
1132 | { |
1133 | unsigned n = values.pop (); |
1134 | if (n != 0) |
1135 | a->log = floor_log2 (x: n * 2 - 1); |
1136 | |
1137 | if (values.is_empty ()) |
1138 | a->maxskip = n ? n - 1 : 0; |
1139 | else |
1140 | { |
1141 | unsigned m = values.pop (); |
1142 | /* -falign-foo=N:M means M-1 max bytes of padding, not M. */ |
1143 | if (m > 0) |
1144 | m--; |
1145 | a->maxskip = m; |
1146 | } |
1147 | |
1148 | /* Normalize the tuple. */ |
1149 | a->normalize (); |
1150 | } |
1151 | |
1152 | /* Parse "N[:M[:N2[:M2]]]" string FLAG into a pair of struct align_flags. */ |
1153 | |
1154 | static void |
1155 | parse_N_M (const char *flag, align_flags &a) |
1156 | { |
1157 | if (flag) |
1158 | { |
1159 | static hash_map <nofree_string_hash, align_flags> cache; |
1160 | align_flags *entry = cache.get (k: flag); |
1161 | if (entry) |
1162 | { |
1163 | a = *entry; |
1164 | return; |
1165 | } |
1166 | |
1167 | auto_vec<unsigned> result_values; |
1168 | bool r = parse_and_check_align_values (flag, NULL, result_values, report_error: false, |
1169 | UNKNOWN_LOCATION); |
1170 | if (!r) |
1171 | return; |
1172 | |
1173 | /* Reverse values for easier manipulation. */ |
1174 | result_values.reverse (); |
1175 | |
1176 | read_log_maxskip (values&: result_values, a: &a.levels[0]); |
1177 | if (!result_values.is_empty ()) |
1178 | read_log_maxskip (values&: result_values, a: &a.levels[1]); |
1179 | #ifdef SUBALIGN_LOG |
1180 | else |
1181 | { |
1182 | /* N2[:M2] is not specified. This arch has a default for N2. |
1183 | Before -falign-foo=N:M:N2:M2 was introduced, x86 had a tweak. |
1184 | -falign-functions=N with N > 8 was adding secondary alignment. |
1185 | -falign-functions=10 was emitting this before every function: |
1186 | .p2align 4,,9 |
1187 | .p2align 3 |
1188 | Now this behavior (and more) can be explicitly requested: |
1189 | -falign-functions=16:10:8 |
1190 | Retain old behavior if N2 is missing: */ |
1191 | |
1192 | int align = 1 << a.levels[0].log; |
1193 | int subalign = 1 << SUBALIGN_LOG; |
1194 | |
1195 | if (a.levels[0].log > SUBALIGN_LOG |
1196 | && a.levels[0].maxskip >= subalign - 1) |
1197 | { |
1198 | /* Set N2 unless subalign can never have any effect. */ |
1199 | if (align > a.levels[0].maxskip + 1) |
1200 | { |
1201 | a.levels[1].log = SUBALIGN_LOG; |
1202 | a.levels[1].normalize (); |
1203 | } |
1204 | } |
1205 | } |
1206 | #endif |
1207 | |
1208 | /* Cache seen value. */ |
1209 | cache.put (k: flag, v: a); |
1210 | } |
1211 | } |
1212 | |
1213 | /* Process -falign-foo=N[:M[:N2[:M2]]] options. */ |
1214 | |
1215 | void |
1216 | parse_alignment_opts (void) |
1217 | { |
1218 | parse_N_M (str_align_loops, align_loops); |
1219 | parse_N_M (str_align_jumps, align_jumps); |
1220 | parse_N_M (str_align_labels, align_labels); |
1221 | parse_N_M (str_align_functions, align_functions); |
1222 | } |
1223 | |
1224 | /* Process the options that have been parsed. */ |
1225 | static void |
1226 | process_options () |
1227 | { |
1228 | const char *language_string = lang_hooks.name; |
1229 | |
1230 | maximum_field_alignment = initial_max_fld_align * BITS_PER_UNIT; |
1231 | |
1232 | /* Some machines may reject certain combinations of options. */ |
1233 | location_t saved_location = input_location; |
1234 | input_location = UNKNOWN_LOCATION; |
1235 | targetm.target_option.override (); |
1236 | input_location = saved_location; |
1237 | |
1238 | if (flag_diagnostics_generate_patch) |
1239 | global_dc->create_edit_context (); |
1240 | |
1241 | /* Avoid any informative notes in the second run of -fcompare-debug. */ |
1242 | if (flag_compare_debug) |
1243 | diagnostic_inhibit_notes (context: global_dc); |
1244 | |
1245 | if (flag_section_anchors && !target_supports_section_anchors_p ()) |
1246 | { |
1247 | warning_at (UNKNOWN_LOCATION, OPT_fsection_anchors, |
1248 | "this target does not support %qs" , |
1249 | "-fsection-anchors" ); |
1250 | flag_section_anchors = 0; |
1251 | } |
1252 | |
1253 | if (flag_short_enums == 2) |
1254 | flag_short_enums = targetm.default_short_enums (); |
1255 | |
1256 | /* Set aux_base_name if not already set. */ |
1257 | if (aux_base_name) |
1258 | ; |
1259 | else if (dump_base_name) |
1260 | { |
1261 | const char *name = dump_base_name; |
1262 | int nlen, len; |
1263 | |
1264 | if (dump_base_ext && (len = strlen (dump_base_ext)) |
1265 | && (nlen = strlen (s: name)) && nlen > len |
1266 | && strcmp (s1: name + nlen - len, dump_base_ext) == 0) |
1267 | { |
1268 | char *p = xstrndup (name, nlen - len); |
1269 | name = p; |
1270 | } |
1271 | |
1272 | aux_base_name = name; |
1273 | } |
1274 | else |
1275 | aux_base_name = "gccaux" ; |
1276 | |
1277 | #ifndef HAVE_isl |
1278 | if (flag_graphite |
1279 | || flag_loop_nest_optimize |
1280 | || flag_graphite_identity |
1281 | || flag_loop_parallelize_all) |
1282 | sorry ("Graphite loop optimizations cannot be used (isl is not available) " |
1283 | "(%<-fgraphite%>, %<-fgraphite-identity%>, " |
1284 | "%<-floop-nest-optimize%>, %<-floop-parallelize-all%>)" ); |
1285 | #endif |
1286 | |
1287 | if (flag_cf_protection != CF_NONE |
1288 | && !(flag_cf_protection & CF_SET)) |
1289 | { |
1290 | if (flag_cf_protection == CF_FULL) |
1291 | { |
1292 | error_at (UNKNOWN_LOCATION, |
1293 | "%<-fcf-protection=full%> is not supported for this " |
1294 | "target" ); |
1295 | flag_cf_protection = CF_NONE; |
1296 | } |
1297 | if (flag_cf_protection == CF_BRANCH) |
1298 | { |
1299 | error_at (UNKNOWN_LOCATION, |
1300 | "%<-fcf-protection=branch%> is not supported for this " |
1301 | "target" ); |
1302 | flag_cf_protection = CF_NONE; |
1303 | } |
1304 | if (flag_cf_protection == CF_RETURN) |
1305 | { |
1306 | error_at (UNKNOWN_LOCATION, |
1307 | "%<-fcf-protection=return%> is not supported for this " |
1308 | "target" ); |
1309 | flag_cf_protection = CF_NONE; |
1310 | } |
1311 | } |
1312 | |
1313 | /* One region RA really helps to decrease the code size. */ |
1314 | if (!OPTION_SET_P (flag_ira_region)) |
1315 | flag_ira_region |
1316 | = optimize_size || !optimize ? IRA_REGION_ONE : IRA_REGION_MIXED; |
1317 | |
1318 | if (!abi_version_at_least (2)) |
1319 | { |
1320 | /* -fabi-version=1 support was removed after GCC 4.9. */ |
1321 | error_at (UNKNOWN_LOCATION, |
1322 | "%<-fabi-version=1%> is no longer supported" ); |
1323 | flag_abi_version = 2; |
1324 | } |
1325 | |
1326 | if (flag_non_call_exceptions) |
1327 | flag_asynchronous_unwind_tables = 1; |
1328 | if (flag_asynchronous_unwind_tables) |
1329 | flag_unwind_tables = 1; |
1330 | |
1331 | if (flag_value_profile_transformations) |
1332 | flag_profile_values = 1; |
1333 | |
1334 | /* Warn about options that are not supported on this machine. */ |
1335 | #ifndef INSN_SCHEDULING |
1336 | if (flag_schedule_insns || flag_schedule_insns_after_reload) |
1337 | warning_at (UNKNOWN_LOCATION, 0, |
1338 | "instruction scheduling not supported on this target machine" ); |
1339 | #endif |
1340 | if (!DELAY_SLOTS && flag_delayed_branch) |
1341 | warning_at (UNKNOWN_LOCATION, 0, |
1342 | "this target machine does not have delayed branches" ); |
1343 | |
1344 | user_label_prefix = USER_LABEL_PREFIX; |
1345 | if (flag_leading_underscore != -1) |
1346 | { |
1347 | /* If the default prefix is more complicated than "" or "_", |
1348 | issue a warning and ignore this option. */ |
1349 | if (user_label_prefix[0] == 0 || |
1350 | (user_label_prefix[0] == '_' && user_label_prefix[1] == 0)) |
1351 | { |
1352 | user_label_prefix = flag_leading_underscore ? "_" : "" ; |
1353 | } |
1354 | else |
1355 | warning_at (UNKNOWN_LOCATION, 0, |
1356 | "%<-f%sleading-underscore%> not supported on this " |
1357 | "target machine" , flag_leading_underscore ? "" : "no-" ); |
1358 | } |
1359 | |
1360 | /* If we are in verbose mode, write out the version and maybe all the |
1361 | option flags in use. */ |
1362 | if (version_flag) |
1363 | { |
1364 | /* We already printed the version header in main (). */ |
1365 | if (!quiet_flag) |
1366 | { |
1367 | fputs (s: "options passed: " , stderr); |
1368 | char *cmdline = gen_command_line_string (options: save_decoded_options, |
1369 | options_count: save_decoded_options_count); |
1370 | |
1371 | fputs (s: cmdline, stderr); |
1372 | free (ptr: cmdline); |
1373 | fputc (c: '\n', stderr); |
1374 | } |
1375 | } |
1376 | |
1377 | /* CTF is supported for only C at this time. */ |
1378 | if (!lang_GNU_C () |
1379 | && ctf_debug_info_level > CTFINFO_LEVEL_NONE) |
1380 | { |
1381 | /* Compiling with -flto results in frontend language of GNU GIMPLE. It |
1382 | is not useful to warn in that case. */ |
1383 | if (!startswith (str: lang_hooks.name, prefix: "GNU GIMPLE" )) |
1384 | inform (UNKNOWN_LOCATION, |
1385 | "CTF debug info requested, but not supported for %qs frontend" , |
1386 | language_string); |
1387 | ctf_debug_info_level = CTFINFO_LEVEL_NONE; |
1388 | } |
1389 | |
1390 | if (flag_dump_final_insns && !flag_syntax_only && !no_backend) |
1391 | { |
1392 | FILE *final_output = fopen (flag_dump_final_insns, modes: "w" ); |
1393 | if (!final_output) |
1394 | { |
1395 | error_at (UNKNOWN_LOCATION, |
1396 | "could not open final insn dump file %qs: %m" , |
1397 | flag_dump_final_insns); |
1398 | flag_dump_final_insns = NULL; |
1399 | } |
1400 | else if (fclose (stream: final_output)) |
1401 | { |
1402 | error_at (UNKNOWN_LOCATION, |
1403 | "could not close zeroed insn dump file %qs: %m" , |
1404 | flag_dump_final_insns); |
1405 | flag_dump_final_insns = NULL; |
1406 | } |
1407 | } |
1408 | |
1409 | /* A lot of code assumes write_symbols == NO_DEBUG if the debugging |
1410 | level is 0. */ |
1411 | if (debug_info_level == DINFO_LEVEL_NONE |
1412 | && ctf_debug_info_level == CTFINFO_LEVEL_NONE) |
1413 | write_symbols = NO_DEBUG; |
1414 | |
1415 | if (write_symbols == NO_DEBUG) |
1416 | ; |
1417 | #ifdef DWARF2_DEBUGGING_INFO |
1418 | else if (dwarf_debuginfo_p ()) |
1419 | debug_hooks = &dwarf2_debug_hooks; |
1420 | #endif |
1421 | #ifdef CTF_DEBUGGING_INFO |
1422 | else if (ctf_debuginfo_p ()) |
1423 | debug_hooks = &dwarf2_debug_hooks; |
1424 | #endif |
1425 | #ifdef BTF_DEBUGGING_INFO |
1426 | else if (btf_debuginfo_p ()) |
1427 | debug_hooks = &dwarf2_debug_hooks; |
1428 | #endif |
1429 | #ifdef VMS_DEBUGGING_INFO |
1430 | else if (write_symbols == VMS_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG) |
1431 | debug_hooks = &vmsdbg_debug_hooks; |
1432 | #endif |
1433 | #ifdef DWARF2_LINENO_DEBUGGING_INFO |
1434 | else if (write_symbols == DWARF2_DEBUG) |
1435 | debug_hooks = &dwarf2_lineno_debug_hooks; |
1436 | #endif |
1437 | else |
1438 | { |
1439 | gcc_assert (debug_set_count (write_symbols) <= 1); |
1440 | error_at (UNKNOWN_LOCATION, |
1441 | "target system does not support the %qs debug format" , |
1442 | debug_type_names[debug_set_to_format (write_symbols)]); |
1443 | } |
1444 | |
1445 | /* The debug hooks are used to implement -fdump-go-spec because it |
1446 | gives a simple and stable API for all the information we need to |
1447 | dump. */ |
1448 | if (flag_dump_go_spec != NULL) |
1449 | debug_hooks = dump_go_spec_init (flag_dump_go_spec, debug_hooks); |
1450 | |
1451 | if (!OPTION_SET_P (dwarf2out_as_loc_support)) |
1452 | dwarf2out_as_loc_support = dwarf2out_default_as_loc_support (); |
1453 | if (!OPTION_SET_P (dwarf2out_as_locview_support)) |
1454 | dwarf2out_as_locview_support = dwarf2out_default_as_locview_support (); |
1455 | |
1456 | if (!OPTION_SET_P (debug_variable_location_views)) |
1457 | { |
1458 | debug_variable_location_views |
1459 | = (flag_var_tracking |
1460 | && debug_info_level >= DINFO_LEVEL_NORMAL |
1461 | && dwarf_debuginfo_p () |
1462 | && !dwarf_strict |
1463 | && dwarf2out_as_loc_support |
1464 | && dwarf2out_as_locview_support); |
1465 | } |
1466 | else if (debug_variable_location_views == -1 && dwarf_version != 5) |
1467 | { |
1468 | warning_at (UNKNOWN_LOCATION, 0, |
1469 | "without %<-gdwarf-5%>, " |
1470 | "%<-gvariable-location-views=incompat5%> " |
1471 | "is equivalent to %<-gvariable-location-views%>" ); |
1472 | debug_variable_location_views = 1; |
1473 | } |
1474 | |
1475 | if (debug_internal_reset_location_views == 2) |
1476 | { |
1477 | debug_internal_reset_location_views |
1478 | = (debug_variable_location_views |
1479 | && targetm.reset_location_view); |
1480 | } |
1481 | else if (debug_internal_reset_location_views |
1482 | && !debug_variable_location_views) |
1483 | { |
1484 | warning_at (UNKNOWN_LOCATION, 0, |
1485 | "%<-ginternal-reset-location-views%> is forced disabled " |
1486 | "without %<-gvariable-location-views%>" ); |
1487 | debug_internal_reset_location_views = 0; |
1488 | } |
1489 | |
1490 | if (!OPTION_SET_P (debug_inline_points)) |
1491 | debug_inline_points = debug_variable_location_views; |
1492 | else if (debug_inline_points && !debug_nonbind_markers_p) |
1493 | { |
1494 | warning_at (UNKNOWN_LOCATION, 0, |
1495 | "%<-ginline-points%> is forced disabled without " |
1496 | "%<-gstatement-frontiers%>" ); |
1497 | debug_inline_points = 0; |
1498 | } |
1499 | |
1500 | if (!OPTION_SET_P (flag_tree_cselim)) |
1501 | { |
1502 | if (HAVE_conditional_move) |
1503 | flag_tree_cselim = 1; |
1504 | else |
1505 | flag_tree_cselim = 0; |
1506 | } |
1507 | |
1508 | /* If auxiliary info generation is desired, open the output file. |
1509 | This goes in the same directory as the source file--unlike |
1510 | all the other output files. */ |
1511 | if (flag_gen_aux_info) |
1512 | { |
1513 | aux_info_file = fopen (aux_info_file_name, modes: "w" ); |
1514 | if (aux_info_file == 0) |
1515 | fatal_error (UNKNOWN_LOCATION, |
1516 | "cannot open %s: %m" , aux_info_file_name); |
1517 | } |
1518 | |
1519 | if (!targetm_common.have_named_sections) |
1520 | { |
1521 | if (flag_function_sections) |
1522 | { |
1523 | warning_at (UNKNOWN_LOCATION, 0, |
1524 | "%<-ffunction-sections%> not supported for this target" ); |
1525 | flag_function_sections = 0; |
1526 | } |
1527 | if (flag_data_sections) |
1528 | { |
1529 | warning_at (UNKNOWN_LOCATION, 0, |
1530 | "%<-fdata-sections%> not supported for this target" ); |
1531 | flag_data_sections = 0; |
1532 | } |
1533 | } |
1534 | |
1535 | if (flag_prefetch_loop_arrays > 0 && !targetm.code_for_prefetch) |
1536 | { |
1537 | warning_at (UNKNOWN_LOCATION, 0, |
1538 | "%<-fprefetch-loop-arrays%> not supported for this target" ); |
1539 | flag_prefetch_loop_arrays = 0; |
1540 | } |
1541 | else if (flag_prefetch_loop_arrays > 0 && !targetm.have_prefetch ()) |
1542 | { |
1543 | warning_at (UNKNOWN_LOCATION, 0, |
1544 | "%<-fprefetch-loop-arrays%> not supported for this target " |
1545 | "(try %<-march%> switches)" ); |
1546 | flag_prefetch_loop_arrays = 0; |
1547 | } |
1548 | |
1549 | /* This combination of options isn't handled for i386 targets and doesn't |
1550 | make much sense anyway, so don't allow it. */ |
1551 | if (flag_prefetch_loop_arrays > 0 && optimize_size) |
1552 | { |
1553 | warning_at (UNKNOWN_LOCATION, 0, |
1554 | "%<-fprefetch-loop-arrays%> is not supported with %<-Os%>" ); |
1555 | flag_prefetch_loop_arrays = 0; |
1556 | } |
1557 | |
1558 | /* The presence of IEEE signaling NaNs, implies all math can trap. */ |
1559 | if (flag_signaling_nans) |
1560 | flag_trapping_math = 1; |
1561 | |
1562 | /* We cannot reassociate if we want traps or signed zeros. */ |
1563 | if (flag_associative_math && (flag_trapping_math || flag_signed_zeros)) |
1564 | { |
1565 | warning_at (UNKNOWN_LOCATION, 0, |
1566 | "%<-fassociative-math%> disabled; other options take " |
1567 | "precedence" ); |
1568 | flag_associative_math = 0; |
1569 | } |
1570 | |
1571 | /* -fstack-clash-protection is not currently supported on targets |
1572 | where the stack grows up. */ |
1573 | if (flag_stack_clash_protection && !STACK_GROWS_DOWNWARD) |
1574 | { |
1575 | warning_at (UNKNOWN_LOCATION, 0, |
1576 | "%<-fstack-clash-protection%> is not supported on targets " |
1577 | "where the stack grows from lower to higher addresses" ); |
1578 | flag_stack_clash_protection = 0; |
1579 | } |
1580 | |
1581 | /* We cannot support -fstack-check= and -fstack-clash-protection at |
1582 | the same time. */ |
1583 | if (flag_stack_check != NO_STACK_CHECK && flag_stack_clash_protection) |
1584 | { |
1585 | warning_at (UNKNOWN_LOCATION, 0, |
1586 | "%<-fstack-check=%> and %<-fstack-clash-protection%> are " |
1587 | "mutually exclusive; disabling %<-fstack-check=%>" ); |
1588 | flag_stack_check = NO_STACK_CHECK; |
1589 | } |
1590 | |
1591 | /* Targets must be able to place spill slots at lower addresses. If the |
1592 | target already uses a soft frame pointer, the transition is trivial. */ |
1593 | if (!FRAME_GROWS_DOWNWARD && flag_stack_protect) |
1594 | { |
1595 | warning_at (UNKNOWN_LOCATION, 0, |
1596 | "%<-fstack-protector%> not supported for this target" ); |
1597 | flag_stack_protect = 0; |
1598 | } |
1599 | if (!flag_stack_protect) |
1600 | warn_stack_protect = 0; |
1601 | |
1602 | /* Address Sanitizer needs porting to each target architecture. */ |
1603 | |
1604 | if ((flag_sanitize & SANITIZE_ADDRESS) |
1605 | && !FRAME_GROWS_DOWNWARD) |
1606 | { |
1607 | warning_at (UNKNOWN_LOCATION, 0, |
1608 | "%<-fsanitize=address%> and %<-fsanitize=kernel-address%> " |
1609 | "are not supported for this target" ); |
1610 | flag_sanitize &= ~SANITIZE_ADDRESS; |
1611 | } |
1612 | |
1613 | if ((flag_sanitize & SANITIZE_USER_ADDRESS) |
1614 | && ((targetm.asan_shadow_offset == NULL) |
1615 | || (targetm.asan_shadow_offset () == 0))) |
1616 | { |
1617 | warning_at (UNKNOWN_LOCATION, 0, |
1618 | "%<-fsanitize=address%> not supported for this target" ); |
1619 | flag_sanitize &= ~SANITIZE_ADDRESS; |
1620 | } |
1621 | |
1622 | if ((flag_sanitize & SANITIZE_KERNEL_ADDRESS) |
1623 | && (targetm.asan_shadow_offset == NULL |
1624 | && !asan_shadow_offset_set_p ())) |
1625 | { |
1626 | warning_at (UNKNOWN_LOCATION, 0, |
1627 | "%<-fsanitize=kernel-address%> with stack protection " |
1628 | "is not supported without %<-fasan-shadow-offset=%> " |
1629 | "for this target" ); |
1630 | flag_sanitize &= ~SANITIZE_ADDRESS; |
1631 | } |
1632 | |
1633 | /* HWAsan requires top byte ignore feature in the backend. */ |
1634 | if (flag_sanitize & SANITIZE_HWADDRESS |
1635 | && ! targetm.memtag.can_tag_addresses ()) |
1636 | { |
1637 | warning_at (UNKNOWN_LOCATION, 0, "%qs is not supported for this target" , |
1638 | "-fsanitize=hwaddress" ); |
1639 | flag_sanitize &= ~SANITIZE_HWADDRESS; |
1640 | } |
1641 | |
1642 | if (flag_sanitize & SANITIZE_SHADOW_CALL_STACK) |
1643 | { |
1644 | if (!targetm.have_shadow_call_stack) |
1645 | sorry ("%<-fsanitize=shadow-call-stack%> not supported " |
1646 | "in current platform" ); |
1647 | else if (flag_exceptions) |
1648 | error_at (UNKNOWN_LOCATION, "%<-fsanitize=shadow-call-stack%> " |
1649 | "requires %<-fno-exceptions%>" ); |
1650 | } |
1651 | |
1652 | HOST_WIDE_INT patch_area_size, patch_area_start; |
1653 | parse_and_check_patch_area (flag_patchable_function_entry, report_error: false, |
1654 | patch_area_size: &patch_area_size, patch_area_start: &patch_area_start); |
1655 | |
1656 | /* Do not use IPA optimizations for register allocation if profiler is active |
1657 | or patchable function entries are inserted for run-time instrumentation |
1658 | or port does not emit prologue and epilogue as RTL. */ |
1659 | if (profile_flag || patch_area_size |
1660 | || !targetm.have_prologue () || !targetm.have_epilogue ()) |
1661 | flag_ipa_ra = 0; |
1662 | |
1663 | /* Enable -Werror=coverage-mismatch when -Werror and -Wno-error |
1664 | have not been set. */ |
1665 | if (!OPTION_SET_P (warnings_are_errors)) |
1666 | { |
1667 | if (warn_coverage_mismatch |
1668 | && option_unspecified_p (opt: OPT_Wcoverage_mismatch)) |
1669 | diagnostic_classify_diagnostic (context: global_dc, optidx: OPT_Wcoverage_mismatch, |
1670 | kind: DK_ERROR, UNKNOWN_LOCATION); |
1671 | if (warn_coverage_invalid_linenum |
1672 | && option_unspecified_p (opt: OPT_Wcoverage_invalid_line_number)) |
1673 | diagnostic_classify_diagnostic (context: global_dc, optidx: OPT_Wcoverage_invalid_line_number, |
1674 | kind: DK_ERROR, UNKNOWN_LOCATION); |
1675 | } |
1676 | |
1677 | /* Save the current optimization options. */ |
1678 | optimization_default_node |
1679 | = build_optimization_node (opts: &global_options, opts_set: &global_options_set); |
1680 | optimization_current_node = optimization_default_node; |
1681 | |
1682 | if (flag_checking >= 2) |
1683 | hash_table_sanitize_eq_limit |
1684 | = param_hash_table_verification_limit; |
1685 | |
1686 | if (flag_large_source_files) |
1687 | line_table->default_range_bits = 0; |
1688 | |
1689 | diagnose_options (opts: &global_options, opts_set: &global_options_set, UNKNOWN_LOCATION); |
1690 | |
1691 | /* Please don't change global_options after this point, those changes won't |
1692 | be reflected in optimization_{default,current}_node. */ |
1693 | } |
1694 | |
1695 | /* This function can be called multiple times to reinitialize the compiler |
1696 | back end when register classes or instruction sets have changed, |
1697 | before each function. */ |
1698 | static void |
1699 | backend_init_target (void) |
1700 | { |
1701 | /* This depends on stack_pointer_rtx. */ |
1702 | init_fake_stack_mems (); |
1703 | |
1704 | /* Sets static_base_value[HARD_FRAME_POINTER_REGNUM], which is |
1705 | mode-dependent. */ |
1706 | init_alias_target (); |
1707 | |
1708 | /* Depends on HARD_FRAME_POINTER_REGNUM. */ |
1709 | if (!ira_use_lra_p) |
1710 | init_reload (); |
1711 | |
1712 | /* Depends on the enabled attribute. */ |
1713 | recog_init (); |
1714 | |
1715 | /* The following initialization functions need to generate rtl, so |
1716 | provide a dummy function context for them. */ |
1717 | init_dummy_function_start (); |
1718 | |
1719 | /* rtx_cost is mode-dependent, so cached values need to be recomputed |
1720 | on a mode change. */ |
1721 | init_expmed (); |
1722 | init_lower_subreg (); |
1723 | init_set_costs (); |
1724 | |
1725 | init_expr_target (); |
1726 | ira_init (); |
1727 | |
1728 | /* We may need to recompute regno_save_code[] and regno_restore_code[] |
1729 | after a mode change as well. */ |
1730 | caller_save_initialized_p = false; |
1731 | |
1732 | expand_dummy_function_end (); |
1733 | } |
1734 | |
1735 | /* Initialize the compiler back end. This function is called only once, |
1736 | when starting the compiler. */ |
1737 | static void |
1738 | backend_init (void) |
1739 | { |
1740 | init_emit_once (); |
1741 | |
1742 | init_rtlanal (); |
1743 | init_inline_once (); |
1744 | init_varasm_once (); |
1745 | save_register_info (); |
1746 | |
1747 | /* Middle end needs this initialization for default mem attributes |
1748 | used by early calls to make_decl_rtl. */ |
1749 | init_emit_regs (); |
1750 | |
1751 | /* Middle end needs this initialization for mode tables used to assign |
1752 | modes to vector variables. */ |
1753 | init_regs (); |
1754 | } |
1755 | |
1756 | /* Initialize things that are both lang-dependent and target-dependent. |
1757 | This function can be called more than once if target parameters change. */ |
1758 | static void |
1759 | lang_dependent_init_target (void) |
1760 | { |
1761 | /* This creates various _DECL nodes, so needs to be called after the |
1762 | front end is initialized. It also depends on the HAVE_xxx macros |
1763 | generated from the target machine description. */ |
1764 | init_optabs (); |
1765 | |
1766 | gcc_assert (!this_target_rtl->target_specific_initialized); |
1767 | } |
1768 | |
1769 | /* Perform initializations that are lang-dependent or target-dependent. |
1770 | but matters only for late optimizations and RTL generation. */ |
1771 | |
1772 | static int rtl_initialized; |
1773 | |
1774 | void |
1775 | initialize_rtl (void) |
1776 | { |
1777 | auto_timevar tv (g_timer, TV_INITIALIZE_RTL); |
1778 | |
1779 | /* Initialization done just once per compilation, but delayed |
1780 | till code generation. */ |
1781 | if (!rtl_initialized) |
1782 | ira_init_once (); |
1783 | rtl_initialized = true; |
1784 | |
1785 | /* Target specific RTL backend initialization. */ |
1786 | if (!this_target_rtl->target_specific_initialized) |
1787 | { |
1788 | backend_init_target (); |
1789 | this_target_rtl->target_specific_initialized = true; |
1790 | } |
1791 | } |
1792 | |
1793 | /* Language-dependent initialization. Returns nonzero on success. */ |
1794 | static int |
1795 | lang_dependent_init (const char *name) |
1796 | { |
1797 | location_t save_loc = input_location; |
1798 | if (!dump_base_name) |
1799 | { |
1800 | dump_base_name = name && name[0] ? name : "gccdump" ; |
1801 | |
1802 | /* We do not want to derive a non-empty dumpbase-ext from an |
1803 | explicit -dumpbase argument, only from a defaulted |
1804 | dumpbase. */ |
1805 | if (!dump_base_ext) |
1806 | { |
1807 | const char *base = lbasename (dump_base_name); |
1808 | const char *ext = strrchr (s: base, c: '.'); |
1809 | if (ext) |
1810 | dump_base_ext = ext; |
1811 | } |
1812 | } |
1813 | |
1814 | /* Other front-end initialization. */ |
1815 | input_location = BUILTINS_LOCATION; |
1816 | if (lang_hooks.init () == 0) |
1817 | return 0; |
1818 | input_location = save_loc; |
1819 | |
1820 | if (!flag_wpa) |
1821 | { |
1822 | init_asm_output (name); |
1823 | |
1824 | if (!flag_generate_lto && !flag_compare_debug) |
1825 | { |
1826 | /* If stack usage information is desired, open the output file. */ |
1827 | if (flag_stack_usage) |
1828 | stack_usage_file = open_auxiliary_file (ext: "su" ); |
1829 | |
1830 | /* If call graph information is desired, open the output file. */ |
1831 | if (flag_callgraph_info) |
1832 | { |
1833 | callgraph_info_file = open_auxiliary_file (ext: "ci" ); |
1834 | /* Write the file header. */ |
1835 | fprintf (stream: callgraph_info_file, |
1836 | format: "graph: { title: \"%s\"\n" , main_input_filename); |
1837 | bitmap_obstack_initialize (NULL); |
1838 | callgraph_info_external_printed = BITMAP_ALLOC (NULL); |
1839 | } |
1840 | } |
1841 | else |
1842 | flag_stack_usage = flag_callgraph_info = false; |
1843 | } |
1844 | |
1845 | /* This creates various _DECL nodes, so needs to be called after the |
1846 | front end is initialized. */ |
1847 | init_eh (); |
1848 | |
1849 | /* Do the target-specific parts of the initialization. */ |
1850 | lang_dependent_init_target (); |
1851 | |
1852 | if (!flag_wpa) |
1853 | { |
1854 | /* If dbx symbol table desired, initialize writing it and output the |
1855 | predefined types. */ |
1856 | timevar_push (tv: TV_SYMOUT); |
1857 | |
1858 | /* Now we have the correct original filename, we can initialize |
1859 | debug output. */ |
1860 | (*debug_hooks->init) (name); |
1861 | |
1862 | timevar_pop (tv: TV_SYMOUT); |
1863 | } |
1864 | |
1865 | return 1; |
1866 | } |
1867 | |
1868 | |
1869 | /* Reinitialize everything when target parameters, such as register usage, |
1870 | have changed. */ |
1871 | void |
1872 | target_reinit (void) |
1873 | { |
1874 | if (no_backend) |
1875 | return; |
1876 | |
1877 | struct rtl_data saved_x_rtl; |
1878 | rtx *saved_regno_reg_rtx; |
1879 | tree saved_optimization_current_node; |
1880 | struct target_optabs *saved_this_fn_optabs; |
1881 | |
1882 | /* Temporarily switch to the default optimization node, so that |
1883 | *this_target_optabs is set to the default, not reflecting |
1884 | whatever a previous function used for the optimize |
1885 | attribute. */ |
1886 | saved_optimization_current_node = optimization_current_node; |
1887 | saved_this_fn_optabs = this_fn_optabs; |
1888 | if (saved_optimization_current_node != optimization_default_node) |
1889 | { |
1890 | optimization_current_node = optimization_default_node; |
1891 | cl_optimization_restore |
1892 | (&global_options, &global_options_set, |
1893 | TREE_OPTIMIZATION (optimization_default_node)); |
1894 | } |
1895 | this_fn_optabs = this_target_optabs; |
1896 | |
1897 | /* Save *crtl and regno_reg_rtx around the reinitialization |
1898 | to allow target_reinit being called even after prepare_function_start. */ |
1899 | saved_regno_reg_rtx = regno_reg_rtx; |
1900 | if (saved_regno_reg_rtx) |
1901 | { |
1902 | saved_x_rtl = *crtl; |
1903 | memset (crtl, c: '\0', n: sizeof (*crtl)); |
1904 | regno_reg_rtx = NULL; |
1905 | } |
1906 | |
1907 | this_target_rtl->target_specific_initialized = false; |
1908 | |
1909 | /* This initializes hard_frame_pointer, and calls init_reg_modes_target() |
1910 | to initialize reg_raw_mode[]. */ |
1911 | init_emit_regs (); |
1912 | |
1913 | /* This invokes target hooks to set fixed_reg[] etc, which is |
1914 | mode-dependent. */ |
1915 | init_regs (); |
1916 | |
1917 | /* Reinitialize lang-dependent parts. */ |
1918 | lang_dependent_init_target (); |
1919 | |
1920 | /* Restore the original optimization node. */ |
1921 | if (saved_optimization_current_node != optimization_default_node) |
1922 | { |
1923 | optimization_current_node = saved_optimization_current_node; |
1924 | cl_optimization_restore (&global_options, &global_options_set, |
1925 | TREE_OPTIMIZATION (optimization_current_node)); |
1926 | } |
1927 | this_fn_optabs = saved_this_fn_optabs; |
1928 | |
1929 | /* Restore regno_reg_rtx at the end, as free_after_compilation from |
1930 | expand_dummy_function_end clears it. */ |
1931 | if (saved_regno_reg_rtx) |
1932 | { |
1933 | *crtl = saved_x_rtl; |
1934 | regno_reg_rtx = saved_regno_reg_rtx; |
1935 | saved_regno_reg_rtx = NULL; |
1936 | } |
1937 | } |
1938 | |
1939 | void |
1940 | dump_memory_report (const char *) |
1941 | { |
1942 | /* Print significant header. */ |
1943 | fputc (c: '\n', stderr); |
1944 | for (unsigned i = 0; i < 80; i++) |
1945 | fputc (c: '#', stderr); |
1946 | fprintf (stderr, format: "\n# %-77s#\n" , header); |
1947 | for (unsigned i = 0; i < 80; i++) |
1948 | fputc (c: '#', stderr); |
1949 | fputs (s: "\n\n" , stderr); |
1950 | |
1951 | dump_line_table_statistics (); |
1952 | ggc_print_statistics (); |
1953 | stringpool_statistics (); |
1954 | dump_tree_statistics (); |
1955 | dump_gimple_statistics (); |
1956 | dump_rtx_statistics (); |
1957 | dump_alloc_pool_statistics (); |
1958 | dump_bitmap_statistics (); |
1959 | dump_hash_table_loc_statistics (); |
1960 | dump_vec_loc_statistics (); |
1961 | dump_ggc_loc_statistics (); |
1962 | dump_alias_stats (stderr); |
1963 | dump_pta_stats (stderr); |
1964 | } |
1965 | |
1966 | /* Clean up: close opened files, etc. */ |
1967 | |
1968 | static void |
1969 | finalize () |
1970 | { |
1971 | /* Close the dump files. */ |
1972 | if (flag_gen_aux_info) |
1973 | { |
1974 | fclose (stream: aux_info_file); |
1975 | aux_info_file = NULL; |
1976 | if (seen_error ()) |
1977 | unlink (aux_info_file_name); |
1978 | } |
1979 | |
1980 | /* Close non-debugging input and output files. Take special care to note |
1981 | whether fclose returns an error, since the pages might still be on the |
1982 | buffer chain while the file is open. */ |
1983 | |
1984 | if (asm_out_file) |
1985 | { |
1986 | if (ferror (stream: asm_out_file) != 0) |
1987 | fatal_error (input_location, "error writing to %s: %m" , asm_file_name); |
1988 | if (fclose (stream: asm_out_file) != 0) |
1989 | fatal_error (input_location, "error closing %s: %m" , asm_file_name); |
1990 | asm_out_file = NULL; |
1991 | } |
1992 | |
1993 | if (stack_usage_file) |
1994 | { |
1995 | fclose (stream: stack_usage_file); |
1996 | stack_usage_file = NULL; |
1997 | } |
1998 | |
1999 | if (callgraph_info_file) |
2000 | { |
2001 | fputs (s: "}\n" , stream: callgraph_info_file); |
2002 | fclose (stream: callgraph_info_file); |
2003 | callgraph_info_file = NULL; |
2004 | BITMAP_FREE (callgraph_info_external_printed); |
2005 | bitmap_obstack_release (NULL); |
2006 | } |
2007 | |
2008 | if (seen_error ()) |
2009 | coverage_remove_note_file (); |
2010 | |
2011 | if (!no_backend) |
2012 | { |
2013 | statistics_fini (); |
2014 | debuginfo_fini (); |
2015 | |
2016 | g->get_passes ()->finish_optimization_passes (); |
2017 | |
2018 | lra_finish_once (); |
2019 | } |
2020 | |
2021 | if (mem_report) |
2022 | dump_memory_report (header: "Final" ); |
2023 | |
2024 | if (profile_report) |
2025 | dump_profile_report (); |
2026 | |
2027 | if (flag_dbg_cnt_list) |
2028 | dbg_cnt_list_all_counters (); |
2029 | |
2030 | /* Language-specific end of compilation actions. */ |
2031 | lang_hooks.finish (); |
2032 | } |
2033 | |
2034 | static bool |
2035 | standard_type_bitsize (int bitsize) |
2036 | { |
2037 | /* As a special exception, we always want __int128 enabled if possible. */ |
2038 | if (bitsize == 128) |
2039 | return false; |
2040 | if (bitsize == CHAR_TYPE_SIZE |
2041 | || bitsize == SHORT_TYPE_SIZE |
2042 | || bitsize == INT_TYPE_SIZE |
2043 | || bitsize == LONG_TYPE_SIZE |
2044 | || bitsize == LONG_LONG_TYPE_SIZE) |
2045 | return true; |
2046 | return false; |
2047 | } |
2048 | |
2049 | /* Initialize the compiler, and compile the input file. */ |
2050 | static void |
2051 | do_compile () |
2052 | { |
2053 | /* Don't do any more if an error has already occurred. */ |
2054 | if (!seen_error ()) |
2055 | { |
2056 | int i; |
2057 | |
2058 | timevar_start (TV_PHASE_SETUP); |
2059 | |
2060 | if (flag_save_optimization_record) |
2061 | { |
2062 | dump_context::get ().set_json_writer (new optrecord_json_writer ()); |
2063 | } |
2064 | |
2065 | /* This must be run always, because it is needed to compute the FP |
2066 | predefined macros, such as __LDBL_MAX__, for targets using non |
2067 | default FP formats. */ |
2068 | init_adjust_machine_modes (); |
2069 | init_derived_machine_modes (); |
2070 | |
2071 | /* This must happen after the backend has a chance to process |
2072 | command line options, but before the parsers are |
2073 | initialized. */ |
2074 | for (i = 0; i < NUM_INT_N_ENTS; i ++) |
2075 | if (targetm.scalar_mode_supported_p (int_n_data[i].m) |
2076 | && ! standard_type_bitsize (bitsize: int_n_data[i].bitsize)) |
2077 | int_n_enabled_p[i] = true; |
2078 | else |
2079 | int_n_enabled_p[i] = false; |
2080 | |
2081 | /* Initialize mpfrs exponent range. This is important to get |
2082 | underflow/overflow in a reasonable timeframe. */ |
2083 | machine_mode mode; |
2084 | int min_exp = -1; |
2085 | int max_exp = 1; |
2086 | FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT) |
2087 | if (SCALAR_FLOAT_MODE_P (mode)) |
2088 | { |
2089 | const real_format *fmt = REAL_MODE_FORMAT (mode); |
2090 | if (fmt) |
2091 | { |
2092 | /* fmt->emin - fmt->p + 1 should be enough but the |
2093 | back-and-forth dance in real_to_decimal_for_mode we |
2094 | do for checking fails due to rounding effects then. */ |
2095 | if ((fmt->emin - fmt->p) < min_exp) |
2096 | min_exp = fmt->emin - fmt->p; |
2097 | if (fmt->emax > max_exp) |
2098 | max_exp = fmt->emax; |
2099 | } |
2100 | } |
2101 | /* E.g. mpc_norm assumes it can square a number without bothering with |
2102 | with range scaling, so until that is fixed, double the minimum |
2103 | and maximum exponents, plus add some buffer for arithmetics |
2104 | on the squared numbers. */ |
2105 | if (mpfr_set_emin (2 * (min_exp - 1)) |
2106 | || mpfr_set_emax (2 * (max_exp + 1))) |
2107 | sorry ("mpfr not configured to handle all floating modes" ); |
2108 | |
2109 | /* Set up the back-end if requested. */ |
2110 | if (!no_backend) |
2111 | backend_init (); |
2112 | |
2113 | /* Language-dependent initialization. Returns true on success. */ |
2114 | if (lang_dependent_init (main_input_filename)) |
2115 | { |
2116 | /* Initialize yet another pass. */ |
2117 | |
2118 | ggc_protect_identifiers = true; |
2119 | |
2120 | symtab->initialize (); |
2121 | init_final (main_input_filename); |
2122 | coverage_init (aux_base_name); |
2123 | statistics_init (); |
2124 | debuginfo_init (); |
2125 | invoke_plugin_callbacks (event: PLUGIN_START_UNIT, NULL); |
2126 | |
2127 | timevar_stop (TV_PHASE_SETUP); |
2128 | |
2129 | compile_file (); |
2130 | } |
2131 | else |
2132 | { |
2133 | timevar_stop (TV_PHASE_SETUP); |
2134 | } |
2135 | |
2136 | timevar_start (TV_PHASE_FINALIZE); |
2137 | |
2138 | finalize (); |
2139 | |
2140 | timevar_stop (TV_PHASE_FINALIZE); |
2141 | } |
2142 | } |
2143 | |
2144 | toplev::toplev (timer *external_timer, |
2145 | bool init_signals) |
2146 | : m_use_TV_TOTAL (external_timer == NULL), |
2147 | m_init_signals (init_signals) |
2148 | { |
2149 | if (external_timer) |
2150 | g_timer = external_timer; |
2151 | } |
2152 | |
2153 | toplev::~toplev () |
2154 | { |
2155 | if (g_timer && m_use_TV_TOTAL) |
2156 | { |
2157 | g_timer->stop (tv: TV_TOTAL); |
2158 | g_timer->print (stderr); |
2159 | delete g_timer; |
2160 | g_timer = NULL; |
2161 | } |
2162 | } |
2163 | |
2164 | /* Potentially call timevar_init (which will create g_timevars if it |
2165 | doesn't already exist). */ |
2166 | |
2167 | void |
2168 | toplev::start_timevars () |
2169 | { |
2170 | if (time_report || !quiet_flag || flag_detailed_statistics) |
2171 | timevar_init (); |
2172 | |
2173 | timevar_start (TV_TOTAL); |
2174 | } |
2175 | |
2176 | /* Handle -fself-test. */ |
2177 | |
2178 | void |
2179 | toplev::run_self_tests () |
2180 | { |
2181 | #if CHECKING_P |
2182 | /* Reset some state. */ |
2183 | input_location = UNKNOWN_LOCATION; |
2184 | bitmap_obstack_initialize (NULL); |
2185 | |
2186 | /* Run the tests; any failures will lead to an abort of the process. |
2187 | Use "make selftests-gdb" to run under the debugger. */ |
2188 | ::selftest::run_tests (); |
2189 | |
2190 | /* Cleanup. */ |
2191 | bitmap_obstack_release (NULL); |
2192 | #else |
2193 | inform (UNKNOWN_LOCATION, "self-tests are not enabled in this build" ); |
2194 | #endif /* #if CHECKING_P */ |
2195 | } |
2196 | |
2197 | /* Entry point of cc1, cc1plus, jc1, f771, etc. |
2198 | Exit code is FATAL_EXIT_CODE if can't open files or if there were |
2199 | any errors, or SUCCESS_EXIT_CODE if compilation succeeded. |
2200 | |
2201 | It is not safe to call this function more than once. */ |
2202 | |
2203 | int |
2204 | toplev::main (int argc, char **argv) |
2205 | { |
2206 | /* Parsing and gimplification sometimes need quite large stack. |
2207 | Increase stack size limits if possible. */ |
2208 | stack_limit_increase (64 * 1024 * 1024); |
2209 | |
2210 | expandargv (&argc, &argv); |
2211 | |
2212 | /* Initialization of GCC's environment, and diagnostics. */ |
2213 | general_init (argv0: argv[0], init_signals: m_init_signals); |
2214 | |
2215 | /* One-off initialization of options that does not need to be |
2216 | repeated when options are added for particular functions. */ |
2217 | init_options_once (); |
2218 | init_opts_obstack (); |
2219 | |
2220 | /* Initialize global options structures; this must be repeated for |
2221 | each structure used for parsing options. */ |
2222 | init_options_struct (opts: &global_options, opts_set: &global_options_set); |
2223 | lang_hooks.init_options_struct (&global_options); |
2224 | |
2225 | /* Init GGC heuristics must be caller after we initialize |
2226 | options. */ |
2227 | init_ggc_heuristics (); |
2228 | |
2229 | /* Convert the options to an array. */ |
2230 | decode_cmdline_options_to_array_default_mask (argc, |
2231 | CONST_CAST2 (const char **, |
2232 | char **, argv), |
2233 | decoded_options: &save_decoded_options, |
2234 | decoded_options_count: &save_decoded_options_count); |
2235 | |
2236 | /* Save Optimization decoded options. */ |
2237 | save_opt_decoded_options = new vec<cl_decoded_option> (); |
2238 | for (unsigned i = 1; i < save_decoded_options_count; ++i) |
2239 | if (save_decoded_options[i].opt_index < cl_options_count |
2240 | && cl_options[save_decoded_options[i].opt_index].flags & CL_OPTIMIZATION) |
2241 | save_opt_decoded_options->safe_push (obj: save_decoded_options[i]); |
2242 | |
2243 | /* Perform language-specific options initialization. */ |
2244 | lang_hooks.init_options (save_decoded_options_count, save_decoded_options); |
2245 | |
2246 | /* Parse the options and do minimal processing; basically just |
2247 | enough to default flags appropriately. */ |
2248 | decode_options (opts: &global_options, opts_set: &global_options_set, |
2249 | decoded_options: save_decoded_options, decoded_options_count: save_decoded_options_count, |
2250 | UNKNOWN_LOCATION, dc: global_dc, |
2251 | target_option_override_hook: targetm.target_option.override); |
2252 | |
2253 | handle_common_deferred_options (); |
2254 | |
2255 | init_local_tick (); |
2256 | |
2257 | initialize_plugins (); |
2258 | |
2259 | /* Handle the dump options now that plugins have had a chance to install new |
2260 | passes. */ |
2261 | handle_deferred_dump_options (); |
2262 | |
2263 | if (version_flag) |
2264 | print_version (stderr, indent: "" , show_global_state: true); |
2265 | |
2266 | if (help_flag) |
2267 | print_plugins_help (stderr, indent: "" ); |
2268 | |
2269 | /* Exit early if we can (e.g. -help). */ |
2270 | if (!exit_after_options) |
2271 | { |
2272 | /* Just in case lang_hooks.post_options ends up calling a debug_hook. |
2273 | This can happen with incorrect pre-processed input. */ |
2274 | debug_hooks = &do_nothing_debug_hooks; |
2275 | /* Allow the front end to perform consistency checks and do further |
2276 | initialization based on the command line options. This hook also |
2277 | sets the original filename if appropriate (e.g. foo.i -> foo.c) |
2278 | so we can correctly initialize debug output. */ |
2279 | no_backend = lang_hooks.post_options (&main_input_filename); |
2280 | |
2281 | process_options (); |
2282 | |
2283 | if (m_use_TV_TOTAL) |
2284 | start_timevars (); |
2285 | do_compile (); |
2286 | |
2287 | if (flag_self_test && !seen_error ()) |
2288 | { |
2289 | if (no_backend) |
2290 | error_at (UNKNOWN_LOCATION, "self-tests incompatible with %<-E%>" ); |
2291 | else |
2292 | run_self_tests (); |
2293 | } |
2294 | } |
2295 | |
2296 | if (warningcount || errorcount || werrorcount) |
2297 | print_ignored_options (); |
2298 | |
2299 | /* Invoke registered plugin callbacks if any. Some plugins could |
2300 | emit some diagnostics here. */ |
2301 | invoke_plugin_callbacks (event: PLUGIN_FINISH, NULL); |
2302 | |
2303 | if (flag_diagnostics_generate_patch) |
2304 | { |
2305 | auto edit_context_ptr = global_dc->get_edit_context (); |
2306 | gcc_assert (edit_context_ptr); |
2307 | |
2308 | pretty_printer pp; |
2309 | pp_show_color (&pp) = pp_show_color (global_dc->printer); |
2310 | edit_context_ptr->print_diff (pp: &pp, show_filenames: true); |
2311 | pp_flush (&pp); |
2312 | } |
2313 | |
2314 | diagnostic_finish (context: global_dc); |
2315 | |
2316 | finalize_plugins (); |
2317 | |
2318 | after_memory_report = true; |
2319 | |
2320 | if (seen_error () || werrorcount) |
2321 | return (FATAL_EXIT_CODE); |
2322 | |
2323 | return (SUCCESS_EXIT_CODE); |
2324 | } |
2325 | |
2326 | /* For those that want to, this function aims to clean up enough state that |
2327 | you can call toplev::main again. */ |
2328 | void |
2329 | toplev::finalize (void) |
2330 | { |
2331 | no_backend = false; |
2332 | rtl_initialized = false; |
2333 | this_target_rtl->target_specific_initialized = false; |
2334 | |
2335 | /* Needs to be called before cgraph_cc_finalize since it uses symtab. */ |
2336 | ipa_reference_cc_finalize (); |
2337 | ipa_fnsummary_cc_finalize (); |
2338 | ipa_modref_cc_finalize (); |
2339 | ipa_edge_modifications_finalize (); |
2340 | |
2341 | cgraph_cc_finalize (); |
2342 | cgraphunit_cc_finalize (); |
2343 | symtab_thunks_cc_finalize (); |
2344 | dwarf2cfi_cc_finalize (); |
2345 | dwarf2out_cc_finalize (); |
2346 | gcse_cc_finalize (); |
2347 | ipa_cp_cc_finalize (); |
2348 | ira_costs_cc_finalize (); |
2349 | tree_cc_finalize (); |
2350 | reginfo_cc_finalize (); |
2351 | |
2352 | /* save_decoded_options uses opts_obstack, so these must |
2353 | be cleaned up together. */ |
2354 | obstack_free (&opts_obstack, NULL); |
2355 | XDELETEVEC (save_decoded_options); |
2356 | save_decoded_options = NULL; |
2357 | save_decoded_options_count = 0; |
2358 | |
2359 | ggc_common_finalize (); |
2360 | |
2361 | /* Clean up the context (and pass_manager etc). */ |
2362 | delete g; |
2363 | g = NULL; |
2364 | |
2365 | } |
2366 | |