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