]> gcc.gnu.org Git - gcc.git/blame - gcc/passes.c
Fix a typo.
[gcc.git] / gcc / passes.c
CommitLineData
f6db1481
RH
1/* Top level of GCC compilers (cc1, cc1plus, etc.)
2 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
cd280abb 3 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
f6db1481
RH
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 2, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA
2002111-1307, USA. */
21
22/* This is the top level of cc1/c++.
23 It parses command args, opens files, invokes the various passes
24 in the proper order, and counts the time used by each.
25 Error messages and low-level interface to malloc also handled here. */
26
27#include "config.h"
28#undef FLOAT /* This is for hpux. They should change hpux. */
29#undef FFS /* Some systems define this in param.h. */
30#include "system.h"
31#include "coretypes.h"
32#include "tm.h"
33#include <signal.h>
34
35#ifdef HAVE_SYS_RESOURCE_H
36# include <sys/resource.h>
37#endif
38
39#ifdef HAVE_SYS_TIMES_H
40# include <sys/times.h>
41#endif
42
43#include "line-map.h"
44#include "input.h"
45#include "tree.h"
46#include "rtl.h"
47#include "tm_p.h"
48#include "flags.h"
49#include "insn-attr.h"
50#include "insn-config.h"
51#include "insn-flags.h"
52#include "hard-reg-set.h"
53#include "recog.h"
54#include "output.h"
55#include "except.h"
56#include "function.h"
57#include "toplev.h"
58#include "expr.h"
59#include "basic-block.h"
60#include "intl.h"
61#include "ggc.h"
62#include "graph.h"
f6db1481
RH
63#include "regs.h"
64#include "timevar.h"
65#include "diagnostic.h"
66#include "params.h"
67#include "reload.h"
68#include "dwarf2asm.h"
69#include "integrate.h"
70#include "real.h"
71#include "debug.h"
72#include "target.h"
73#include "langhooks.h"
74#include "cfglayout.h"
75#include "cfgloop.h"
76#include "hosthooks.h"
77#include "cgraph.h"
78#include "opts.h"
79#include "coverage.h"
80#include "value-prof.h"
81#include "alloc-pool.h"
2f8e398b 82#include "tree-pass.h"
9f8628ba 83#include "tree-dump.h"
f6db1481
RH
84
85#if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO)
86#include "dwarf2out.h"
87#endif
88
97b0ade3 89#if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO)
f6db1481
RH
90#include "dbxout.h"
91#endif
92
93#ifdef SDB_DEBUGGING_INFO
94#include "sdbout.h"
95#endif
96
97#ifdef XCOFF_DEBUGGING_INFO
98#include "xcoffout.h" /* Needed for external data
99 declarations for e.g. AIX 4.x. */
100#endif
101
102#ifndef HAVE_conditional_execution
103#define HAVE_conditional_execution 0
104#endif
105
106/* Format to use to print dumpfile index value */
107#ifndef DUMPFILE_FORMAT
108#define DUMPFILE_FORMAT ".%02d."
109#endif
110
9f8628ba 111static int initializing_dump = 0;
f6db1481
RH
112
113/* Routine to open a dump file. Return true if the dump file is enabled. */
114
115static int
9f8628ba 116open_dump_file (enum tree_dump_index index, tree decl)
f6db1481 117{
9f8628ba 118 if (! dump_enabled_p (index))
f6db1481
RH
119 return 0;
120
121 timevar_push (TV_DUMP);
f6db1481 122
8127d0e0
NS
123 if (dump_file != NULL || dump_file_name != NULL)
124 abort ();
f6db1481 125
9f8628ba
PB
126 dump_file_name = get_dump_file_name (index);
127 initializing_dump = !dump_initialized_p (index);
128 dump_file = dump_begin (index, NULL);
f6db1481 129
f6db1481 130 if (dump_file == NULL)
9f8628ba 131 fatal_error ("can't open %s: %m", dump_file_name);
f6db1481
RH
132
133 if (decl)
134 fprintf (dump_file, "\n;; Function %s%s\n\n",
ae2bcd98 135 lang_hooks.decl_printable_name (decl, 2),
f6db1481
RH
136 cfun->function_frequency == FUNCTION_FREQUENCY_HOT
137 ? " (hot)"
138 : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED
139 ? " (unlikely executed)"
140 : "");
141
142 timevar_pop (TV_DUMP);
143 return 1;
144}
145
146/* Routine to close a dump file. */
147
148static void
9f8628ba 149close_dump_file (enum tree_dump_index index,
f6db1481
RH
150 void (*func) (FILE *, rtx),
151 rtx insns)
152{
153 if (! dump_file)
154 return;
155
156 timevar_push (TV_DUMP);
157 if (insns
9f8628ba 158 && graph_dump_format != no_graph)
f6db1481 159 {
9f8628ba
PB
160 /* If we've not initialized the files, do so now. */
161 if (initializing_dump)
162 clean_graph_dump_file (dump_file_name);
f6db1481 163
9f8628ba 164 print_rtl_graph_with_bb (dump_file_name, insns);
f6db1481
RH
165 }
166
167 if (func && insns)
168 func (dump_file, insns);
169
9f8628ba
PB
170 dump_end (index, dump_file);
171 free ((char *) dump_file_name);
f6db1481
RH
172
173 dump_file = NULL;
9f8628ba 174 dump_file_name = NULL;
f6db1481
RH
175 timevar_pop (TV_DUMP);
176}
177
178/* This is called from various places for FUNCTION_DECL, VAR_DECL,
179 and TYPE_DECL nodes.
180
181 This does nothing for local (non-static) variables, unless the
0e6df31e
GK
182 variable is a register variable with DECL_ASSEMBLER_NAME set. In
183 that case, or if the variable is not an automatic, it sets up the
184 RTL and outputs any assembler code (label definition, storage
185 allocation and initialization).
f6db1481 186
0e6df31e 187 DECL is the declaration. TOP_LEVEL is nonzero
f6db1481
RH
188 if this declaration is not within a function. */
189
190void
191rest_of_decl_compilation (tree decl,
f6db1481
RH
192 int top_level,
193 int at_end)
194{
195 /* We deferred calling assemble_alias so that we could collect
196 other attributes such as visibility. Emit the alias now. */
197 {
198 tree alias;
199 alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
200 if (alias)
201 {
202 alias = TREE_VALUE (TREE_VALUE (alias));
203 alias = get_identifier (TREE_STRING_POINTER (alias));
204 assemble_alias (decl, alias);
205 }
206 }
207
0e6df31e
GK
208 /* Can't defer this, because it needs to happen before any
209 later function definitions are processed. */
210 if (DECL_REGISTER (decl) && DECL_ASSEMBLER_NAME_SET_P (decl))
211 make_decl_rtl (decl);
212
f6db1481
RH
213 /* Forward declarations for nested functions are not "external",
214 but we need to treat them as if they were. */
215 if (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
216 || TREE_CODE (decl) == FUNCTION_DECL)
217 {
218 timevar_push (TV_VARCONST);
219
f6db1481
RH
220 /* Don't output anything when a tentative file-scope definition
221 is seen. But at end of compilation, do output code for them.
222
223 We do output all variables when unit-at-a-time is active and rely on
224 callgraph code to defer them except for forward declarations
225 (see gcc.c-torture/compile/920624-1.c) */
226 if ((at_end
227 || !DECL_DEFER_OUTPUT (decl)
228 || (flag_unit_at_a_time && DECL_INITIAL (decl)))
229 && !DECL_EXTERNAL (decl))
230 {
231 if (flag_unit_at_a_time && !cgraph_global_info_ready
0a2695db 232 && TREE_CODE (decl) != FUNCTION_DECL && top_level)
f6db1481
RH
233 cgraph_varpool_finalize_decl (decl);
234 else
235 assemble_variable (decl, top_level, at_end, 0);
236 }
237
238#ifdef ASM_FINISH_DECLARE_OBJECT
239 if (decl == last_assemble_variable_decl)
240 {
241 ASM_FINISH_DECLARE_OBJECT (asm_out_file, decl,
242 top_level, at_end);
243 }
244#endif
245
246 timevar_pop (TV_VARCONST);
247 }
f6db1481
RH
248 else if (TREE_CODE (decl) == TYPE_DECL)
249 {
250 timevar_push (TV_SYMOUT);
251 debug_hooks->type_decl (decl, !top_level);
252 timevar_pop (TV_SYMOUT);
253 }
254}
255
256/* Called after finishing a record, union or enumeral type. */
257
258void
259rest_of_type_compilation (tree type, int toplev)
260{
261 /* Avoid confusing the debug information machinery when there are
262 errors. */
263 if (errorcount != 0 || sorrycount != 0)
264 return;
265
266 timevar_push (TV_SYMOUT);
267 debug_hooks->type_decl (TYPE_STUB_DECL (type), !toplev);
268 timevar_pop (TV_SYMOUT);
269}
270
271/* Turn the RTL into assembly. */
272static void
fd743bc1 273rest_of_handle_final (void)
f6db1481
RH
274{
275 timevar_push (TV_FINAL);
276 {
277 rtx x;
278 const char *fnname;
279
280 /* Get the function's name, as described by its RTL. This may be
281 different from the DECL_NAME name used in the source file. */
282
fd743bc1 283 x = DECL_RTL (current_function_decl);
8127d0e0
NS
284 if (!MEM_P (x))
285 abort ();
f6db1481 286 x = XEXP (x, 0);
8127d0e0
NS
287 if (GET_CODE (x) != SYMBOL_REF)
288 abort ();
f6db1481
RH
289 fnname = XSTR (x, 0);
290
fd743bc1
PB
291 assemble_start_function (current_function_decl, fnname);
292 final_start_function (get_insns (), asm_out_file, optimize);
293 final (get_insns (), asm_out_file, optimize, 0);
f6db1481
RH
294 final_end_function ();
295
951120ea 296#ifdef TARGET_UNWIND_INFO
f6db1481
RH
297 /* ??? The IA-64 ".handlerdata" directive must be issued before
298 the ".endp" directive that closes the procedure descriptor. */
299 output_function_exception_table ();
300#endif
301
fd743bc1 302 assemble_end_function (current_function_decl, fnname);
f6db1481 303
951120ea 304#ifndef TARGET_UNWIND_INFO
f6db1481
RH
305 /* Otherwise, it feels unclean to switch sections in the middle. */
306 output_function_exception_table ();
307#endif
308
9fb32434
CT
309 user_defined_section_attribute = false;
310
f6db1481
RH
311 if (! quiet_flag)
312 fflush (asm_out_file);
313
314 /* Release all memory allocated by flow. */
bb8a619e 315 free_basic_block_vars ();
f6db1481 316 }
97b0ade3
PB
317
318 /* Write DBX symbols if requested. */
319
320 /* Note that for those inline functions where we don't initially
321 know for certain that we will be generating an out-of-line copy,
322 the first invocation of this routine (rest_of_compilation) will
323 skip over this code by doing a `goto exit_rest_of_compilation;'.
324 Later on, wrapup_global_declarations will (indirectly) call
325 rest_of_compilation again for those inline functions that need
326 to have out-of-line copies generated. During that call, we
327 *will* be routed past here. */
328
329 timevar_push (TV_SYMOUT);
330 (*debug_hooks->function_decl) (current_function_decl);
331 timevar_pop (TV_SYMOUT);
f6db1481
RH
332
333 ggc_collect ();
97b0ade3 334 timevar_pop (TV_FINAL);
f6db1481
RH
335}
336
337#ifdef DELAY_SLOTS
338/* Run delay slot optimization. */
339static void
fd743bc1 340rest_of_handle_delay_slots (void)
f6db1481
RH
341{
342 timevar_push (TV_DBR_SCHED);
fd743bc1 343 open_dump_file (DFI_dbr, current_function_decl);
f6db1481 344
fd743bc1 345 dbr_schedule (get_insns (), dump_file);
f6db1481 346
fd743bc1 347 close_dump_file (DFI_dbr, print_rtl, get_insns ());
f6db1481
RH
348
349 ggc_collect ();
97b0ade3
PB
350
351 timevar_pop (TV_DBR_SCHED);
f6db1481
RH
352}
353#endif
354
355#ifdef STACK_REGS
356/* Convert register usage from flat register file usage to a stack
357 register file. */
358static void
fd743bc1 359rest_of_handle_stack_regs (void)
f6db1481
RH
360{
361#if defined (HAVE_ATTR_length)
362 /* If flow2 creates new instructions which need splitting
363 and scheduling after reload is not done, they might not be
364 split until final which doesn't allow splitting
365 if HAVE_ATTR_length. */
366#ifdef INSN_SCHEDULING
367 if (optimize && !flag_schedule_insns_after_reload)
368#else
369 if (optimize)
370#endif
371 {
372 timevar_push (TV_SHORTEN_BRANCH);
373 split_all_insns (1);
374 timevar_pop (TV_SHORTEN_BRANCH);
375 }
376#endif
377
378 timevar_push (TV_REG_STACK);
fd743bc1 379 open_dump_file (DFI_stack, current_function_decl);
f6db1481 380
827c06b6 381 if (reg_to_stack (dump_file) && optimize)
f6db1481
RH
382 {
383 if (cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK
384 | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0))
750054a2 385 && (flag_reorder_blocks || flag_reorder_blocks_and_partition))
f6db1481 386 {
35b6b437 387 reorder_basic_blocks (0);
f6db1481
RH
388 cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK);
389 }
390 }
391
fd743bc1 392 close_dump_file (DFI_stack, print_rtl_with_bb, get_insns ());
f6db1481
RH
393
394 ggc_collect ();
97b0ade3 395 timevar_pop (TV_REG_STACK);
f6db1481
RH
396}
397#endif
398
89dbed81 399/* Track the variables, i.e. compute where the variable is stored at each position in function. */
f6db1481 400static void
fd743bc1 401rest_of_handle_variable_tracking (void)
f6db1481
RH
402{
403 timevar_push (TV_VAR_TRACKING);
fd743bc1 404 open_dump_file (DFI_vartrack, current_function_decl);
f6db1481
RH
405
406 variable_tracking_main ();
407
fd743bc1 408 close_dump_file (DFI_vartrack, print_rtl_with_bb, get_insns ());
f6db1481
RH
409 timevar_pop (TV_VAR_TRACKING);
410}
411
97b0ade3 412/* Machine dependent reorg pass. */
f6db1481 413static void
fd743bc1 414rest_of_handle_machine_reorg (void)
f6db1481
RH
415{
416 timevar_push (TV_MACH_DEP);
fd743bc1 417 open_dump_file (DFI_mach, current_function_decl);
f6db1481 418
5fd9b178 419 targetm.machine_dependent_reorg ();
f6db1481 420
fd743bc1 421 close_dump_file (DFI_mach, print_rtl, get_insns ());
f6db1481
RH
422
423 ggc_collect ();
97b0ade3 424 timevar_pop (TV_MACH_DEP);
f6db1481
RH
425}
426
427
f6db1481
RH
428/* Run old register allocator. Return TRUE if we must exit
429 rest_of_compilation upon return. */
430static bool
fd743bc1 431rest_of_handle_old_regalloc (void)
f6db1481
RH
432{
433 int failure;
434 int rebuild_notes;
435
97b0ade3
PB
436 timevar_push (TV_LOCAL_ALLOC);
437 open_dump_file (DFI_lreg, current_function_decl);
438
f6db1481
RH
439 /* Allocate the reg_renumber array. */
440 allocate_reg_info (max_regno, FALSE, TRUE);
441
442 /* And the reg_equiv_memory_loc array. */
965ccc5a
R
443 VARRAY_GROW (reg_equiv_memory_loc_varray, max_regno);
444 reg_equiv_memory_loc = &VARRAY_RTX (reg_equiv_memory_loc_varray, 0);
f6db1481
RH
445
446 allocate_initial_values (reg_equiv_memory_loc);
447
fd743bc1 448 regclass (get_insns (), max_reg_num (), dump_file);
f6db1481
RH
449 rebuild_notes = local_alloc ();
450
451 timevar_pop (TV_LOCAL_ALLOC);
452
453 /* Local allocation may have turned an indirect jump into a direct
454 jump. If so, we must rebuild the JUMP_LABEL fields of jumping
455 instructions. */
456 if (rebuild_notes)
457 {
458 timevar_push (TV_JUMP);
459
fd743bc1 460 rebuild_jump_labels (get_insns ());
f6db1481 461 purge_all_dead_edges (0);
9b09c842 462 delete_unreachable_blocks ();
f6db1481
RH
463
464 timevar_pop (TV_JUMP);
465 }
466
9f8628ba 467 if (dump_enabled_p (DFI_lreg))
f6db1481
RH
468 {
469 timevar_push (TV_DUMP);
f6db1481
RH
470 dump_flow_info (dump_file);
471 dump_local_alloc (dump_file);
f6db1481
RH
472 timevar_pop (TV_DUMP);
473 }
474
97b0ade3
PB
475 close_dump_file (DFI_lreg, print_rtl_with_bb, get_insns ());
476
f6db1481
RH
477 ggc_collect ();
478
479 timevar_push (TV_GLOBAL_ALLOC);
fd743bc1 480 open_dump_file (DFI_greg, current_function_decl);
f6db1481
RH
481
482 /* If optimizing, allocate remaining pseudo-regs. Do the reload
483 pass fixing up any insns that are invalid. */
484
485 if (optimize)
486 failure = global_alloc (dump_file);
487 else
488 {
fd743bc1
PB
489 build_insn_chain (get_insns ());
490 failure = reload (get_insns (), 0);
f6db1481
RH
491 }
492
9f8628ba 493 if (dump_enabled_p (DFI_greg))
f6db1481
RH
494 {
495 timevar_push (TV_DUMP);
f6db1481 496 dump_global_regs (dump_file);
97b0ade3 497 timevar_pop (TV_DUMP);
f6db1481 498
fd743bc1 499 close_dump_file (DFI_greg, print_rtl_with_bb, get_insns ());
f6db1481
RH
500 }
501
97b0ade3
PB
502 ggc_collect ();
503
504 timevar_pop (TV_GLOBAL_ALLOC);
505
f6db1481
RH
506 return failure;
507}
508
509/* Run the regrename and cprop passes. */
510static void
fd743bc1 511rest_of_handle_regrename (void)
f6db1481
RH
512{
513 timevar_push (TV_RENAME_REGISTERS);
fd743bc1 514 open_dump_file (DFI_rnreg, current_function_decl);
f6db1481
RH
515
516 if (flag_rename_registers)
517 regrename_optimize ();
518 if (flag_cprop_registers)
519 copyprop_hardreg_forward ();
520
fd743bc1 521 close_dump_file (DFI_rnreg, print_rtl_with_bb, get_insns ());
f6db1481
RH
522 timevar_pop (TV_RENAME_REGISTERS);
523}
524
525/* Reorder basic blocks. */
526static void
fd743bc1 527rest_of_handle_reorder_blocks (void)
f6db1481
RH
528{
529 bool changed;
35b6b437
RS
530 unsigned int liveness_flags;
531
fd743bc1 532 open_dump_file (DFI_bbro, current_function_decl);
2f8e398b 533
f6db1481
RH
534 /* Last attempt to optimize CFG, as scheduling, peepholing and insn
535 splitting possibly introduced more crossjumping opportunities. */
35b6b437
RS
536 liveness_flags = (!HAVE_conditional_execution ? CLEANUP_UPDATE_LIFE : 0);
537 changed = cleanup_cfg (CLEANUP_EXPENSIVE | liveness_flags);
f6db1481
RH
538
539 if (flag_sched2_use_traces && flag_schedule_insns_after_reload)
35b6b437 540 tracer (liveness_flags);
750054a2 541 if (flag_reorder_blocks || flag_reorder_blocks_and_partition)
35b6b437 542 reorder_basic_blocks (liveness_flags);
750054a2 543 if (flag_reorder_blocks || flag_reorder_blocks_and_partition
f6db1481 544 || (flag_sched2_use_traces && flag_schedule_insns_after_reload))
35b6b437 545 changed |= cleanup_cfg (CLEANUP_EXPENSIVE | liveness_flags);
f6db1481
RH
546
547 /* On conditional execution targets we can not update the life cheaply, so
548 we deffer the updating to after both cleanups. This may lose some cases
549 but should not be terribly bad. */
550 if (changed && HAVE_conditional_execution)
551 update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
552 PROP_DEATH_NOTES);
fd743bc1 553 close_dump_file (DFI_bbro, print_rtl_with_bb, get_insns ());
f6db1481
RH
554}
555
97b0ade3
PB
556/* Partition hot and cold basic blocks. */
557static void
558rest_of_handle_partition_blocks (void)
559{
560 no_new_pseudos = 0;
561 partition_hot_cold_basic_blocks ();
562 allocate_reg_life_data ();
563 update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
564 PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES);
565 no_new_pseudos = 1;
566}
567
f6db1481
RH
568#ifdef INSN_SCHEDULING
569/* Run instruction scheduler. */
97b0ade3 570/* Perform SMS module scheduling. */
f6db1481 571static void
97b0ade3 572rest_of_handle_sms (void)
f6db1481 573{
e5626198 574 timevar_push (TV_SMS);
97b0ade3 575 open_dump_file (DFI_sms, current_function_decl);
e5626198 576
97b0ade3
PB
577 /* We want to be able to create new pseudos. */
578 no_new_pseudos = 0;
579 sms_schedule (dump_file);
580 close_dump_file (DFI_sms, print_rtl, get_insns ());
e5626198 581
e5626198 582
97b0ade3
PB
583 /* Update the life information, because we add pseudos. */
584 max_regno = max_reg_num ();
585 allocate_reg_info (max_regno, FALSE, FALSE);
586 update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
587 (PROP_DEATH_NOTES
588 | PROP_KILL_DEAD_CODE
589 | PROP_SCAN_DEAD_CODE));
590 no_new_pseudos = 1;
e5626198 591
97b0ade3 592 ggc_collect ();
e5626198 593 timevar_pop (TV_SMS);
97b0ade3
PB
594}
595
596/* Run instruction scheduler. */
597static void
598rest_of_handle_sched (void)
599{
f6db1481
RH
600 timevar_push (TV_SCHED);
601
602 /* Print function header into sched dump now
603 because doing the sched analysis makes some of the dump. */
97b0ade3 604 open_dump_file (DFI_sched, current_function_decl);
f6db1481 605
97b0ade3
PB
606 /* Do control and data sched analysis,
607 and write some of the results to dump file. */
f6db1481 608
97b0ade3 609 schedule_insns (dump_file);
f6db1481 610
97b0ade3 611 close_dump_file (DFI_sched, print_rtl_with_bb, get_insns ());
f6db1481
RH
612
613 ggc_collect ();
97b0ade3 614 timevar_pop (TV_SCHED);
f6db1481
RH
615}
616
617/* Run second scheduling pass after reload. */
618static void
fd743bc1 619rest_of_handle_sched2 (void)
f6db1481
RH
620{
621 timevar_push (TV_SCHED2);
fd743bc1 622 open_dump_file (DFI_sched2, current_function_decl);
f6db1481
RH
623
624 /* Do control and data sched analysis again,
625 and write some more of the results to dump file. */
626
627 split_all_insns (1);
628
629 if (flag_sched2_use_superblocks || flag_sched2_use_traces)
630 {
631 schedule_ebbs (dump_file);
632 /* No liveness updating code yet, but it should be easy to do.
4ee31f1e 633 reg-stack recomputes the liveness when needed for now. */
f6db1481
RH
634 count_or_remove_death_notes (NULL, 1);
635 cleanup_cfg (CLEANUP_EXPENSIVE);
636 }
637 else
638 schedule_insns (dump_file);
639
fd743bc1 640 close_dump_file (DFI_sched2, print_rtl_with_bb, get_insns ());
f6db1481
RH
641
642 ggc_collect ();
97b0ade3
PB
643
644 timevar_pop (TV_SCHED2);
f6db1481
RH
645}
646#endif
647
f9957958 648static void
fd743bc1 649rest_of_handle_gcse2 (void)
f9957958 650{
0516f6fe 651 timevar_push (TV_GCSE_AFTER_RELOAD);
fd743bc1 652 open_dump_file (DFI_gcse2, current_function_decl);
f9957958 653
0516f6fe 654 gcse_after_reload_main (get_insns ());
fd743bc1
PB
655 rebuild_jump_labels (get_insns ());
656 delete_trivially_dead_insns (get_insns (), max_reg_num ());
657 close_dump_file (DFI_gcse2, print_rtl_with_bb, get_insns ());
f9957958
MH
658
659 ggc_collect ();
660
661#ifdef ENABLE_CHECKING
662 verify_flow_info ();
663#endif
97b0ade3 664
0516f6fe 665 timevar_pop (TV_GCSE_AFTER_RELOAD);
f9957958
MH
666}
667
f6db1481
RH
668/* Register allocation pre-pass, to reduce number of moves necessary
669 for two-address machines. */
670static void
fd743bc1 671rest_of_handle_regmove (void)
f6db1481
RH
672{
673 timevar_push (TV_REGMOVE);
fd743bc1 674 open_dump_file (DFI_regmove, current_function_decl);
f6db1481 675
fd743bc1 676 regmove_optimize (get_insns (), max_reg_num (), dump_file);
f6db1481
RH
677
678 cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
fd743bc1 679 close_dump_file (DFI_regmove, print_rtl_with_bb, get_insns ());
f6db1481
RH
680
681 ggc_collect ();
97b0ade3 682 timevar_pop (TV_REGMOVE);
f6db1481
RH
683}
684
685/* Run tracer. */
686static void
fd743bc1 687rest_of_handle_tracer (void)
f6db1481 688{
fd743bc1 689 open_dump_file (DFI_tracer, current_function_decl);
f6db1481
RH
690 if (dump_file)
691 dump_flow_info (dump_file);
35b6b437 692 tracer (0);
f6db1481 693 cleanup_cfg (CLEANUP_EXPENSIVE);
c80a0f26 694 reg_scan (get_insns (), max_reg_num ());
f6db1481
RH
695 close_dump_file (DFI_tracer, print_rtl_with_bb, get_insns ());
696}
697
698/* If-conversion and CFG cleanup. */
699static void
fd743bc1 700rest_of_handle_if_conversion (void)
f6db1481 701{
97b0ade3 702 timevar_push (TV_IFCVT);
fd743bc1 703 open_dump_file (DFI_ce1, current_function_decl);
97b0ade3 704
f6db1481
RH
705 if (flag_if_conversion)
706 {
f6db1481
RH
707 if (dump_file)
708 dump_flow_info (dump_file);
709 cleanup_cfg (CLEANUP_EXPENSIVE);
c80a0f26 710 reg_scan (get_insns (), max_reg_num ());
f6db1481 711 if_convert (0);
f6db1481 712 }
97b0ade3 713
f6db1481
RH
714 timevar_push (TV_JUMP);
715 cleanup_cfg (CLEANUP_EXPENSIVE);
c80a0f26 716 reg_scan (get_insns (), max_reg_num ());
f6db1481 717 timevar_pop (TV_JUMP);
97b0ade3 718
f6db1481 719 close_dump_file (DFI_ce1, print_rtl_with_bb, get_insns ());
97b0ade3 720 timevar_pop (TV_IFCVT);
f6db1481
RH
721}
722
723/* Rerun if-conversion, as combine may have simplified things enough
724 to now meet sequence length restrictions. */
725static void
fd743bc1 726rest_of_handle_if_after_combine (void)
f6db1481
RH
727{
728 timevar_push (TV_IFCVT);
fd743bc1 729 open_dump_file (DFI_ce2, current_function_decl);
f6db1481
RH
730
731 no_new_pseudos = 0;
732 if_convert (1);
733 no_new_pseudos = 1;
734
fd743bc1 735 close_dump_file (DFI_ce2, print_rtl_with_bb, get_insns ());
f6db1481
RH
736 timevar_pop (TV_IFCVT);
737}
738
97b0ade3
PB
739static void
740rest_of_handle_if_after_reload (void)
741{
742 timevar_push (TV_IFCVT2);
743 open_dump_file (DFI_ce3, current_function_decl);
744
745 /* Last attempt to optimize CFG, as scheduling, peepholing and insn
746 splitting possibly introduced more crossjumping opportunities. */
747 cleanup_cfg (CLEANUP_EXPENSIVE
748 | CLEANUP_UPDATE_LIFE
749 | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
750 if (flag_if_conversion2)
751 if_convert (1);
752 close_dump_file (DFI_ce3, print_rtl_with_bb, get_insns ());
753 timevar_pop (TV_IFCVT2);
754}
755
f6db1481 756static void
fd743bc1 757rest_of_handle_web (void)
f6db1481 758{
fd743bc1 759 open_dump_file (DFI_web, current_function_decl);
f6db1481
RH
760 timevar_push (TV_WEB);
761 web_main ();
fd743bc1 762 delete_trivially_dead_insns (get_insns (), max_reg_num ());
f6db1481
RH
763 cleanup_cfg (CLEANUP_EXPENSIVE);
764
765 timevar_pop (TV_WEB);
fd743bc1 766 close_dump_file (DFI_web, print_rtl_with_bb, get_insns ());
c80a0f26 767 reg_scan (get_insns (), max_reg_num ());
f6db1481
RH
768}
769
770/* Do branch profiling and static profile estimation passes. */
771static void
fd743bc1 772rest_of_handle_branch_prob (void)
f6db1481
RH
773{
774 struct loops loops;
97b0ade3 775
f6db1481 776 timevar_push (TV_BRANCH_PROB);
fd743bc1 777 open_dump_file (DFI_bp, current_function_decl);
f6db1481
RH
778
779 if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
780 branch_prob ();
781
782 /* Discover and record the loop depth at the head of each basic
783 block. The loop infrastructure does the real job for us. */
784 flow_loops_find (&loops, LOOP_TREE);
785
786 if (dump_file)
787 flow_loops_dump (&loops, dump_file, NULL, 0);
788
789 /* Estimate using heuristics if no profiling info is available. */
790 if (flag_guess_branch_prob)
791 estimate_probability (&loops);
792
793 flow_loops_free (&loops);
794 free_dominance_info (CDI_DOMINATORS);
fd743bc1 795 close_dump_file (DFI_bp, print_rtl_with_bb, get_insns ());
f6db1481
RH
796 timevar_pop (TV_BRANCH_PROB);
797}
798
799/* Do optimizations based on expression value profiles. */
800static void
fd743bc1 801rest_of_handle_value_profile_transformations (void)
f6db1481 802{
fd743bc1 803 open_dump_file (DFI_vpt, current_function_decl);
f6db1481
RH
804 timevar_push (TV_VPT);
805
806 if (value_profile_transformations ())
807 cleanup_cfg (CLEANUP_EXPENSIVE);
808
809 timevar_pop (TV_VPT);
fd743bc1 810 close_dump_file (DFI_vpt, print_rtl_with_bb, get_insns ());
f6db1481
RH
811}
812
813/* Do control and data flow analysis; write some of the results to the
814 dump file. */
815static void
fd743bc1 816rest_of_handle_cfg (void)
f6db1481 817{
fd743bc1 818 open_dump_file (DFI_cfg, current_function_decl);
f6db1481
RH
819 if (dump_file)
820 dump_flow_info (dump_file);
821 if (optimize)
822 cleanup_cfg (CLEANUP_EXPENSIVE
823 | (flag_thread_jumps ? CLEANUP_THREADING : 0));
824
825 /* It may make more sense to mark constant functions after dead code is
826 eliminated by life_analysis, but we need to do it early, as -fprofile-arcs
827 may insert code making function non-constant, but we still must consider
828 it as constant, otherwise -fbranch-probabilities will not read data back.
829
830 life_analysis rarely eliminates modification of external memory.
70f3cc30
JH
831
832 FIXME: now with tree based profiling we are in the trap described above
833 again. It seems to be easiest to disable the optimization for time
834 being before the problem is either solved by moving the transformation
835 to the IPA level (we need the CFG for this) or the very early optimization
836 passes are made to ignore the const/pure flags so code does not change. */
837 if (optimize
838 && (!flag_tree_based_profiling
839 || (!profile_arc_flag && !flag_branch_probabilities)))
f6db1481
RH
840 {
841 /* Alias analysis depends on this information and mark_constant_function
842 depends on alias analysis. */
c80a0f26 843 reg_scan (get_insns (), max_reg_num ());
f6db1481
RH
844 mark_constant_function ();
845 }
846
fd743bc1 847 close_dump_file (DFI_cfg, print_rtl_with_bb, get_insns ());
f6db1481
RH
848}
849
f6db1481
RH
850/* Perform jump bypassing and control flow optimizations. */
851static void
fd743bc1 852rest_of_handle_jump_bypass (void)
f6db1481
RH
853{
854 timevar_push (TV_BYPASS);
fd743bc1 855 open_dump_file (DFI_bypass, current_function_decl);
f6db1481
RH
856
857 cleanup_cfg (CLEANUP_EXPENSIVE);
c80a0f26 858 reg_scan (get_insns (), max_reg_num ());
f6db1481
RH
859
860 if (bypass_jumps (dump_file))
861 {
fd743bc1 862 rebuild_jump_labels (get_insns ());
f6db1481 863 cleanup_cfg (CLEANUP_EXPENSIVE);
fd743bc1 864 delete_trivially_dead_insns (get_insns (), max_reg_num ());
f6db1481
RH
865 }
866
fd743bc1 867 close_dump_file (DFI_bypass, print_rtl_with_bb, get_insns ());
f6db1481
RH
868 timevar_pop (TV_BYPASS);
869
870 ggc_collect ();
871
872#ifdef ENABLE_CHECKING
873 verify_flow_info ();
874#endif
875}
876
f6db1481
RH
877/* Try combining insns through substitution. */
878static void
fd743bc1 879rest_of_handle_combine (void)
f6db1481
RH
880{
881 int rebuild_jump_labels_after_combine = 0;
882
883 timevar_push (TV_COMBINE);
fd743bc1 884 open_dump_file (DFI_combine, current_function_decl);
f6db1481
RH
885
886 rebuild_jump_labels_after_combine
fd743bc1 887 = combine_instructions (get_insns (), max_reg_num ());
f6db1481 888
97b0ade3 889 /* Combining insns may have turned an indirect jump into a
f6db1481
RH
890 direct jump. Rebuild the JUMP_LABEL fields of jumping
891 instructions. */
892 if (rebuild_jump_labels_after_combine)
893 {
894 timevar_push (TV_JUMP);
fd743bc1 895 rebuild_jump_labels (get_insns ());
f6db1481
RH
896 timevar_pop (TV_JUMP);
897
898 cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE);
899 }
900
fd743bc1 901 close_dump_file (DFI_combine, print_rtl_with_bb, get_insns ());
f6db1481
RH
902 timevar_pop (TV_COMBINE);
903
904 ggc_collect ();
905}
906
907/* Perform life analysis. */
908static void
fd743bc1 909rest_of_handle_life (void)
f6db1481 910{
fd743bc1 911 open_dump_file (DFI_life, current_function_decl);
f6db1481
RH
912 regclass_init ();
913
914#ifdef ENABLE_CHECKING
915 verify_flow_info ();
916#endif
827c06b6 917 life_analysis (dump_file, PROP_FINAL);
f6db1481 918 if (optimize)
c80a0f26 919 cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE | CLEANUP_LOG_LINKS
f6db1481 920 | (flag_thread_jumps ? CLEANUP_THREADING : 0));
f6db1481 921
6de9cd9a 922 if (extra_warnings)
f6db1481 923 {
fd743bc1 924 setjmp_vars_warning (DECL_INITIAL (current_function_decl));
6de9cd9a 925 setjmp_args_warning ();
f6db1481
RH
926 }
927
928 if (optimize)
929 {
cd280abb 930 if (initialize_uninitialized_subregs ())
f6db1481
RH
931 {
932 /* Insns were inserted, and possibly pseudos created, so
933 things might look a bit different. */
f6db1481
RH
934 allocate_reg_life_data ();
935 update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
936 PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES);
937 }
938 }
939
940 no_new_pseudos = 1;
941
fd743bc1 942 close_dump_file (DFI_life, print_rtl_with_bb, get_insns ());
f6db1481
RH
943
944 ggc_collect ();
945}
946
947/* Perform common subexpression elimination. Nonzero value from
948 `cse_main' means that jumps were simplified and some code may now
949 be unreachable, so do jump optimization again. */
950static void
fd743bc1 951rest_of_handle_cse (void)
f6db1481
RH
952{
953 int tem;
97b0ade3 954
fd743bc1 955 open_dump_file (DFI_cse, current_function_decl);
f6db1481
RH
956 if (dump_file)
957 dump_flow_info (dump_file);
958 timevar_push (TV_CSE);
959
c80a0f26 960 reg_scan (get_insns (), max_reg_num ());
f6db1481 961
5affca01 962 tem = cse_main (get_insns (), max_reg_num (), dump_file);
f6db1481 963 if (tem)
fd743bc1 964 rebuild_jump_labels (get_insns ());
f6db1481
RH
965 if (purge_all_dead_edges (0))
966 delete_unreachable_blocks ();
967
fd743bc1 968 delete_trivially_dead_insns (get_insns (), max_reg_num ());
f6db1481
RH
969
970 /* If we are not running more CSE passes, then we are no longer
971 expecting CSE to be run. But always rerun it in a cheap mode. */
972 cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse;
973
974 if (tem || optimize > 1)
975 cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
f6db1481
RH
976
977 timevar_pop (TV_CSE);
fd743bc1 978 close_dump_file (DFI_cse, print_rtl_with_bb, get_insns ());
97b0ade3
PB
979
980 ggc_collect ();
f6db1481
RH
981}
982
983/* Run second CSE pass after loop optimizations. */
984static void
fd743bc1 985rest_of_handle_cse2 (void)
f6db1481
RH
986{
987 int tem;
97b0ade3 988
f6db1481 989 timevar_push (TV_CSE2);
fd743bc1 990 open_dump_file (DFI_cse2, current_function_decl);
f6db1481
RH
991 if (dump_file)
992 dump_flow_info (dump_file);
993 /* CFG is no longer maintained up-to-date. */
5affca01 994 tem = cse_main (get_insns (), max_reg_num (), dump_file);
f6db1481
RH
995
996 /* Run a pass to eliminate duplicated assignments to condition code
997 registers. We have to run this after bypass_jumps, because it
998 makes it harder for that pass to determine whether a jump can be
999 bypassed safely. */
1000 cse_condition_code_reg ();
1001
1002 purge_all_dead_edges (0);
fd743bc1 1003 delete_trivially_dead_insns (get_insns (), max_reg_num ());
f6db1481
RH
1004
1005 if (tem)
1006 {
1007 timevar_push (TV_JUMP);
fd743bc1 1008 rebuild_jump_labels (get_insns ());
f6db1481
RH
1009 cleanup_cfg (CLEANUP_EXPENSIVE);
1010 timevar_pop (TV_JUMP);
1011 }
c80a0f26 1012 reg_scan (get_insns (), max_reg_num ());
fd743bc1 1013 close_dump_file (DFI_cse2, print_rtl_with_bb, get_insns ());
f6db1481 1014 timevar_pop (TV_CSE2);
97b0ade3
PB
1015
1016 ggc_collect ();
f6db1481
RH
1017}
1018
1019/* Perform global cse. */
1020static void
fd743bc1 1021rest_of_handle_gcse (void)
f6db1481
RH
1022{
1023 int save_csb, save_cfj;
1024 int tem2 = 0, tem;
97b0ade3 1025
f6db1481 1026 timevar_push (TV_GCSE);
fd743bc1 1027 open_dump_file (DFI_gcse, current_function_decl);
f6db1481 1028
fd743bc1
PB
1029 tem = gcse_main (get_insns (), dump_file);
1030 rebuild_jump_labels (get_insns ());
1031 delete_trivially_dead_insns (get_insns (), max_reg_num ());
f6db1481
RH
1032
1033 save_csb = flag_cse_skip_blocks;
1034 save_cfj = flag_cse_follow_jumps;
1035 flag_cse_skip_blocks = flag_cse_follow_jumps = 0;
1036
f6db1481
RH
1037 /* If -fexpensive-optimizations, re-run CSE to clean up things done
1038 by gcse. */
1039 if (flag_expensive_optimizations)
1040 {
1041 timevar_push (TV_CSE);
c80a0f26 1042 reg_scan (get_insns (), max_reg_num ());
5affca01 1043 tem2 = cse_main (get_insns (), max_reg_num (), dump_file);
f6db1481 1044 purge_all_dead_edges (0);
fd743bc1 1045 delete_trivially_dead_insns (get_insns (), max_reg_num ());
f6db1481
RH
1046 timevar_pop (TV_CSE);
1047 cse_not_expected = !flag_rerun_cse_after_loop;
1048 }
1049
1050 /* If gcse or cse altered any jumps, rerun jump optimizations to clean
1051 things up. Then possibly re-run CSE again. */
1052 while (tem || tem2)
1053 {
1054 tem = tem2 = 0;
1055 timevar_push (TV_JUMP);
fd743bc1 1056 rebuild_jump_labels (get_insns ());
f6db1481
RH
1057 cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
1058 timevar_pop (TV_JUMP);
1059
1060 if (flag_expensive_optimizations)
1061 {
1062 timevar_push (TV_CSE);
c80a0f26 1063 reg_scan (get_insns (), max_reg_num ());
5affca01 1064 tem2 = cse_main (get_insns (), max_reg_num (), dump_file);
f6db1481 1065 purge_all_dead_edges (0);
fd743bc1 1066 delete_trivially_dead_insns (get_insns (), max_reg_num ());
f6db1481
RH
1067 timevar_pop (TV_CSE);
1068 }
1069 }
1070
fd743bc1 1071 close_dump_file (DFI_gcse, print_rtl_with_bb, get_insns ());
f6db1481
RH
1072 timevar_pop (TV_GCSE);
1073
1074 ggc_collect ();
1075 flag_cse_skip_blocks = save_csb;
1076 flag_cse_follow_jumps = save_cfj;
1077#ifdef ENABLE_CHECKING
1078 verify_flow_info ();
1079#endif
1080}
1081
1082/* Move constant computations out of loops. */
1083static void
fd743bc1 1084rest_of_handle_loop_optimize (void)
f6db1481 1085{
c94583fe 1086 int do_prefetch;
f6db1481
RH
1087
1088 timevar_push (TV_LOOP);
1089 delete_dead_jumptables ();
1090 cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
fd743bc1 1091 open_dump_file (DFI_loop, current_function_decl);
f6db1481
RH
1092
1093 /* CFG is no longer maintained up-to-date. */
1094 free_bb_for_insn ();
e53de54d 1095 profile_status = PROFILE_ABSENT;
f6db1481 1096
f6db1481
RH
1097 do_prefetch = flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0;
1098
1099 if (flag_rerun_loop_opt)
1100 {
1101 cleanup_barriers ();
1102
1103 /* We only want to perform unrolling once. */
c94583fe 1104 loop_optimize (get_insns (), dump_file, 0);
f6db1481
RH
1105
1106 /* The first call to loop_optimize makes some instructions
1107 trivially dead. We delete those instructions now in the
1108 hope that doing so will make the heuristics in loop work
1109 better and possibly speed up compilation. */
fd743bc1 1110 delete_trivially_dead_insns (get_insns (), max_reg_num ());
f6db1481
RH
1111
1112 /* The regscan pass is currently necessary as the alias
1113 analysis code depends on this information. */
c80a0f26 1114 reg_scan (get_insns (), max_reg_num ());
f6db1481
RH
1115 }
1116 cleanup_barriers ();
c94583fe 1117 loop_optimize (get_insns (), dump_file, do_prefetch);
f6db1481
RH
1118
1119 /* Loop can create trivially dead instructions. */
fd743bc1 1120 delete_trivially_dead_insns (get_insns (), max_reg_num ());
97b0ade3 1121 find_basic_blocks (get_insns (), max_reg_num (), dump_file);
fd743bc1 1122 close_dump_file (DFI_loop, print_rtl, get_insns ());
f6db1481 1123 timevar_pop (TV_LOOP);
f6db1481
RH
1124
1125 ggc_collect ();
1126}
1127
1128/* Perform loop optimizations. It might be better to do them a bit
1129 sooner, but we want the profile feedback to work more
1130 efficiently. */
1131static void
fd743bc1 1132rest_of_handle_loop2 (void)
f6db1481
RH
1133{
1134 struct loops *loops;
1135 basic_block bb;
1136
5e962776
ZD
1137 if (!flag_move_loop_invariants
1138 && !flag_unswitch_loops
689ba89d
ZD
1139 && !flag_peel_loops
1140 && !flag_unroll_loops
1141 && !flag_branch_on_count_reg)
1142 return;
1143
f6db1481 1144 timevar_push (TV_LOOP);
fd743bc1 1145 open_dump_file (DFI_loop2, current_function_decl);
f6db1481
RH
1146 if (dump_file)
1147 dump_flow_info (dump_file);
1148
1149 /* Initialize structures for layout changes. */
35b6b437 1150 cfg_layout_initialize (0);
f6db1481
RH
1151
1152 loops = loop_optimizer_init (dump_file);
1153
1154 if (loops)
1155 {
1156 /* The optimizations: */
5e962776
ZD
1157 if (flag_move_loop_invariants)
1158 move_loop_invariants (loops);
1159
f6db1481
RH
1160 if (flag_unswitch_loops)
1161 unswitch_loops (loops);
1162
1163 if (flag_peel_loops || flag_unroll_loops)
1164 unroll_and_peel_loops (loops,
1165 (flag_peel_loops ? UAP_PEEL : 0) |
1166 (flag_unroll_loops ? UAP_UNROLL : 0) |
1167 (flag_unroll_all_loops ? UAP_UNROLL_ALL : 0));
1168
689ba89d
ZD
1169#ifdef HAVE_doloop_end
1170 if (flag_branch_on_count_reg && HAVE_doloop_end)
1171 doloop_optimize_loops (loops);
1172#endif /* HAVE_doloop_end */
1173
f6db1481
RH
1174 loop_optimizer_finalize (loops, dump_file);
1175 }
1176
8a807136
ZD
1177 free_dominance_info (CDI_DOMINATORS);
1178
f6db1481
RH
1179 /* Finalize layout changes. */
1180 FOR_EACH_BB (bb)
1181 if (bb->next_bb != EXIT_BLOCK_PTR)
1182 bb->rbi->next = bb->next_bb;
1183 cfg_layout_finalize ();
1184
1185 cleanup_cfg (CLEANUP_EXPENSIVE);
fd743bc1 1186 delete_trivially_dead_insns (get_insns (), max_reg_num ());
c80a0f26 1187 reg_scan (get_insns (), max_reg_num ());
f6db1481
RH
1188 if (dump_file)
1189 dump_flow_info (dump_file);
1190 close_dump_file (DFI_loop2, print_rtl_with_bb, get_insns ());
1191 timevar_pop (TV_LOOP);
1192 ggc_collect ();
1193}
1194
97b0ade3
PB
1195static void
1196rest_of_handle_branch_target_load_optimize (void)
f6db1481 1197{
97b0ade3
PB
1198 static int warned = 0;
1199
1200 /* Leave this a warning for now so that it is possible to experiment
1201 with running this pass twice. In 3.6, we should either make this
1202 an error, or use separate dump files. */
1203 if (flag_branch_target_load_optimize
1204 && flag_branch_target_load_optimize2
1205 && !warned)
1206 {
1207 warning ("branch target register load optimization is not intended "
1208 "to be run twice");
f6db1481 1209
97b0ade3
PB
1210 warned = 1;
1211 }
f6db1481 1212
97b0ade3
PB
1213 open_dump_file (DFI_branch_target_load, current_function_decl);
1214 branch_target_load_optimize (epilogue_completed);
1215 close_dump_file (DFI_branch_target_load, print_rtl_with_bb, get_insns ());
f6db1481 1216 ggc_collect ();
97b0ade3 1217}
f6db1481 1218
97b0ade3
PB
1219#ifdef OPTIMIZE_MODE_SWITCHING
1220static void
1221rest_of_handle_mode_switching (void)
1222{
1223 timevar_push (TV_MODE_SWITCH);
f6db1481 1224
97b0ade3
PB
1225 no_new_pseudos = 0;
1226 optimize_mode_switching (NULL);
1227 no_new_pseudos = 1;
f6db1481 1228
97b0ade3
PB
1229 timevar_pop (TV_MODE_SWITCH);
1230}
1231#endif
f6db1481 1232
97b0ade3
PB
1233static void
1234rest_of_handle_jump (void)
1235{
1236 ggc_collect ();
f6db1481
RH
1237
1238 timevar_push (TV_JUMP);
fd743bc1 1239 open_dump_file (DFI_sibling, current_function_decl);
f6db1481
RH
1240
1241 delete_unreachable_blocks ();
242229bb 1242#ifdef ENABLE_CHECKING
97b0ade3 1243 verify_flow_info ();
242229bb 1244#endif
9f8628ba
PB
1245
1246 if (cfun->tail_call_emit)
1247 fixup_tail_calls ();
1248
1249 close_dump_file (DFI_sibling, print_rtl, get_insns ());
97b0ade3
PB
1250 timevar_pop (TV_JUMP);
1251}
f6db1481 1252
97b0ade3
PB
1253static void
1254rest_of_handle_eh (void)
1255{
f6db1481
RH
1256 insn_locators_initialize ();
1257 /* Complete generation of exception handling code. */
1258 if (doing_eh (0))
1259 {
1260 timevar_push (TV_JUMP);
fd743bc1 1261 open_dump_file (DFI_eh, current_function_decl);
f6db1481 1262
3fbd86b1
SB
1263 cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL);
1264
f6db1481
RH
1265 finish_eh_generation ();
1266
3fbd86b1
SB
1267 cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL);
1268
f6db1481
RH
1269 close_dump_file (DFI_eh, print_rtl, get_insns ());
1270 timevar_pop (TV_JUMP);
1271 }
97b0ade3 1272}
f6db1481 1273
97b0ade3
PB
1274static void
1275rest_of_handle_stack_adjustments (void)
1276{
1277 life_analysis (dump_file, PROP_POSTRELOAD);
1278 cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE
1279 | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0));
1280
1281 /* This is kind of a heuristic. We need to run combine_stack_adjustments
1282 even for machines with possibly nonzero RETURN_POPS_ARGS
1283 and ACCUMULATE_OUTGOING_ARGS. We expect that only ports having
1284 push instructions will have popping returns. */
1285#ifndef PUSH_ROUNDING
1286 if (!ACCUMULATE_OUTGOING_ARGS)
f6db1481 1287#endif
97b0ade3
PB
1288 combine_stack_adjustments ();
1289}
f6db1481 1290
97b0ade3
PB
1291static void
1292rest_of_handle_flow2 (void)
1293{
1294 timevar_push (TV_FLOW2);
1295 open_dump_file (DFI_flow2, current_function_decl);
f6db1481 1296
97b0ade3
PB
1297 /* Re-create the death notes which were deleted during reload. */
1298#ifdef ENABLE_CHECKING
1299 verify_flow_info ();
1300#endif
1301
1302 /* If optimizing, then go ahead and split insns now. */
1303#ifndef STACK_REGS
1304 if (optimize > 0)
1305#endif
1306 split_all_insns (0);
1307
1308 if (flag_branch_target_load_optimize)
1309 rest_of_handle_branch_target_load_optimize ();
1310
033797e2
EB
1311 if (optimize)
1312 cleanup_cfg (CLEANUP_EXPENSIVE);
1313
1314 /* On some machines, the prologue and epilogue code, or parts thereof,
1315 can be represented as RTL. Doing so lets us schedule insns between
1316 it and the rest of the code and also allows delayed branch
1317 scheduling to operate in the epilogue. */
1318 thread_prologue_and_epilogue_insns (get_insns ());
1319 epilogue_completed = 1;
97b0ade3
PB
1320
1321 if (optimize)
1322 rest_of_handle_stack_adjustments ();
1323
1324 flow2_completed = 1;
1325
1326 close_dump_file (DFI_flow2, print_rtl_with_bb, get_insns ());
1327 timevar_pop (TV_FLOW2);
1328
1329 ggc_collect ();
1330}
1331
1332
1333static void
1334rest_of_handle_jump2 (void)
1335{
fd743bc1 1336 open_dump_file (DFI_jump, current_function_decl);
f6db1481
RH
1337
1338 /* Always do one jump optimization pass to ensure that JUMP_LABEL fields
1339 are initialized and to compute whether control can drop off the end
1340 of the function. */
1341
1342 timevar_push (TV_JUMP);
1343 /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB. Do this
1344 before jump optimization switches branch directions. */
1345 if (flag_guess_branch_prob)
1346 expected_value_to_br_prob ();
1347
fd743bc1 1348 delete_trivially_dead_insns (get_insns (), max_reg_num ());
c80a0f26 1349 reg_scan (get_insns (), max_reg_num ());
f6db1481
RH
1350 if (dump_file)
1351 dump_flow_info (dump_file);
1352 cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP
1353 | (flag_thread_jumps ? CLEANUP_THREADING : 0));
1354
6de9cd9a
DN
1355 create_loop_notes ();
1356
fd743bc1 1357 purge_line_number_notes (get_insns ());
f6db1481 1358
f6db1481
RH
1359 if (optimize)
1360 cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP);
1361
f6db1481
RH
1362 /* Jump optimization, and the removal of NULL pointer checks, may
1363 have reduced the number of instructions substantially. CSE, and
1364 future passes, allocate arrays whose dimensions involve the
1365 maximum instruction UID, so if we can reduce the maximum UID
1366 we'll save big on memory. */
1367 renumber_insns (dump_file);
f6db1481 1368
fd743bc1 1369 close_dump_file (DFI_jump, print_rtl_with_bb, get_insns ());
97b0ade3 1370 timevar_pop (TV_JUMP);
f6db1481
RH
1371
1372 ggc_collect ();
97b0ade3
PB
1373}
1374
1375#ifdef HAVE_peephole2
1376static void
1377rest_of_handle_peephole2 (void)
1378{
1379 timevar_push (TV_PEEPHOLE2);
1380 open_dump_file (DFI_peephole2, current_function_decl);
1381
1382 peephole2_optimize (dump_file);
1383
1384 close_dump_file (DFI_peephole2, print_rtl_with_bb, get_insns ());
1385 timevar_pop (TV_PEEPHOLE2);
1386}
1387#endif
1388
1389static void
1390rest_of_handle_postreload (void)
1391{
1392 timevar_push (TV_RELOAD_CSE_REGS);
1393 open_dump_file (DFI_postreload, current_function_decl);
1394
1395 /* Do a very simple CSE pass over just the hard registers. */
1396 reload_cse_regs (get_insns ());
1397 /* reload_cse_regs can eliminate potentially-trapping MEMs.
1398 Remove any EH edges associated with them. */
1399 if (flag_non_call_exceptions)
1400 purge_all_dead_edges (0);
1401
1402 close_dump_file (DFI_postreload, print_rtl_with_bb, get_insns ());
1403 timevar_pop (TV_RELOAD_CSE_REGS);
1404}
1405
1406static void
1407rest_of_handle_shorten_branches (void)
1408{
1409 /* Shorten branches. */
1410 timevar_push (TV_SHORTEN_BRANCH);
1411 shorten_branches (get_insns ());
1412 timevar_pop (TV_SHORTEN_BRANCH);
1413}
1414
1415static void
1416rest_of_clean_state (void)
1417{
0a9aeefd 1418 rtx insn, next;
8d168c24 1419 coverage_end_function ();
0a9aeefd
JH
1420
1421 /* It is very important to decompose the RTL instruction chain here:
1422 debug information keeps pointing into CODE_LABEL insns inside the function
1423 body. If these remain pointing to the other insns, we end up preserving
1424 whole RTL chain and attached detailed debug info in memory. */
1425 for (insn = get_insns (); insn; insn = next)
1426 {
1427 next = NEXT_INSN (insn);
1428 NEXT_INSN (insn) = NULL;
1429 PREV_INSN (insn) = NULL;
1430 }
97b0ade3
PB
1431
1432 /* In case the function was not output,
1433 don't leave any temporary anonymous types
1434 queued up for sdb output. */
1435#ifdef SDB_DEBUGGING_INFO
1436 if (write_symbols == SDB_DEBUG)
1437 sdbout_types (NULL_TREE);
1438#endif
1439
1440 reload_completed = 0;
1441 epilogue_completed = 0;
1442 flow2_completed = 0;
1443 no_new_pseudos = 0;
1444
1445 timevar_push (TV_FINAL);
1446
1447 /* Clear out the insn_length contents now that they are no
1448 longer valid. */
1449 init_insn_lengths ();
1450
1451 /* Show no temporary slots allocated. */
1452 init_temp_slots ();
1453
1454 free_basic_block_vars ();
1455 free_bb_for_insn ();
1456
1457 timevar_pop (TV_FINAL);
1458
1459 if (targetm.binds_local_p (current_function_decl))
1460 {
1461 int pref = cfun->preferred_stack_boundary;
b3f332c6 1462 if (cfun->stack_alignment_needed > cfun->preferred_stack_boundary)
97b0ade3
PB
1463 pref = cfun->stack_alignment_needed;
1464 cgraph_rtl_info (current_function_decl)->preferred_incoming_stack_boundary
1465 = pref;
1466 }
1467
1468 /* Make sure volatile mem refs aren't considered valid operands for
1469 arithmetic insns. We must call this here if this is a nested inline
1470 function, since the above code leaves us in the init_recog state
1471 (from final.c), and the function context push/pop code does not
1472 save/restore volatile_ok.
1473
1474 ??? Maybe it isn't necessary for expand_start_function to call this
1475 anymore if we do it here? */
1476
1477 init_recog_no_volatile ();
1478
1479 /* We're done with this function. Free up memory if we can. */
1480 free_after_parsing (cfun);
80d8221e 1481 free_after_compilation (cfun);
97b0ade3
PB
1482}
1483\f
1484
3fbd86b1
SB
1485/* This function is called from the pass manager in tree-optimize.c
1486 after all tree passes have finished for a single function, and we
1487 have expanded the function body from trees to RTL.
1488 Once we are here, we have decided that we're supposed to output
89dbed81 1489 that function, i.e. that we should write assembler code for it.
3fbd86b1
SB
1490
1491 We run a series of low-level passes here on the function's RTL
1492 representation. Each pass is called via a rest_of_* function. */
97b0ade3 1493
73dcf3b5 1494static void
97b0ade3
PB
1495rest_of_compilation (void)
1496{
97b0ade3
PB
1497 /* If we're emitting a nested function, make sure its parent gets
1498 emitted as well. Doing otherwise confuses debug info. */
1499 {
1500 tree parent;
1501 for (parent = DECL_CONTEXT (current_function_decl);
1502 parent != NULL_TREE;
1503 parent = get_containing_scope (parent))
1504 if (TREE_CODE (parent) == FUNCTION_DECL)
1505 TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (parent)) = 1;
1506 }
1507
1508 /* We are now committed to emitting code for this function. Do any
1509 preparation, such as emitting abstract debug info for the inline
1510 before it gets mangled by optimization. */
1511 if (cgraph_function_possibly_inlined_p (current_function_decl))
1512 (*debug_hooks->outlining_inline_function) (current_function_decl);
1513
1514 /* Remove any notes we don't need. That will make iterating
1515 over the instruction sequence faster, and allow the garbage
1516 collector to reclaim the memory used by the notes. */
1517 remove_unnecessary_notes ();
1518
1519 /* Initialize some variables used by the optimizers. */
1520 init_function_for_compilation ();
1521
1522 TREE_ASM_WRITTEN (current_function_decl) = 1;
1523
97b0ade3
PB
1524 /* Early return if there were errors. We can run afoul of our
1525 consistency checks, and there's not really much point in fixing them. */
1526 if (rtl_dump_and_exit || flag_syntax_only || errorcount || sorrycount)
1527 goto exit_rest_of_compilation;
1528
1529 rest_of_handle_jump ();
97b0ade3 1530
97b0ade3
PB
1531 rest_of_handle_eh ();
1532
1533 /* Delay emitting hard_reg_initial_value sets until after EH landing pad
1534 generation, which might create new sets. */
1535 emit_initial_value_sets ();
1536
1537#ifdef FINALIZE_PIC
1538 /* If we are doing position-independent code generation, now
1539 is the time to output special prologues and epilogues.
1540 We do not want to do this earlier, because it just clutters
1541 up inline functions with meaningless insns. */
1542 if (flag_pic)
1543 FINALIZE_PIC;
1544#endif
1545
1546 /* Copy any shared structure that should not be shared. */
1547 unshare_all_rtl ();
1548
1549#ifdef SETJMP_VIA_SAVE_AREA
1550 /* This must be performed before virtual register instantiation.
1551 Please be aware that everything in the compiler that can look
1552 at the RTL up to this point must understand that REG_SAVE_AREA
1553 is just like a use of the REG contained inside. */
1554 if (current_function_calls_alloca)
1555 optimize_save_area_alloca ();
1556#endif
1557
1558 /* Instantiate all virtual registers. */
1559 instantiate_virtual_regs ();
1560
1561 rest_of_handle_jump2 ();
f6db1481
RH
1562
1563 if (optimize > 0)
fd743bc1 1564 rest_of_handle_cse ();
f6db1481 1565
f6db1481
RH
1566 if (optimize > 0)
1567 {
1568 if (flag_gcse)
fd743bc1 1569 rest_of_handle_gcse ();
f6db1481
RH
1570
1571 if (flag_loop_optimize)
fd743bc1 1572 rest_of_handle_loop_optimize ();
f6db1481
RH
1573
1574 if (flag_gcse)
fd743bc1 1575 rest_of_handle_jump_bypass ();
f6db1481
RH
1576 }
1577
1578 timevar_push (TV_FLOW);
fd743bc1 1579 rest_of_handle_cfg ();
f6db1481 1580
6de9cd9a
DN
1581 if (!flag_tree_based_profiling
1582 && (optimize > 0 || profile_arc_flag
1583 || flag_test_coverage || flag_branch_probabilities))
f6db1481 1584 {
6de9cd9a
DN
1585 rtl_register_profile_hooks ();
1586 rtl_register_value_prof_hooks ();
fd743bc1 1587 rest_of_handle_branch_prob ();
f6db1481
RH
1588
1589 if (flag_branch_probabilities
1590 && flag_profile_values
6d9901e7
ZD
1591 && (flag_value_profile_transformations
1592 || flag_speculative_prefetching))
fd743bc1 1593 rest_of_handle_value_profile_transformations ();
f6db1481
RH
1594
1595 /* Remove the death notes created for vpt. */
1596 if (flag_profile_values)
1597 count_or_remove_death_notes (NULL, 1);
1598 }
1599
1600 if (optimize > 0)
fd743bc1 1601 rest_of_handle_if_conversion ();
f6db1481 1602
97b0ade3 1603 if (optimize > 0 && flag_tracer)
fd743bc1 1604 rest_of_handle_tracer ();
f6db1481 1605
5e962776
ZD
1606 if (optimize > 0
1607 && flag_loop_optimize2)
fd743bc1 1608 rest_of_handle_loop2 ();
f6db1481 1609
97b0ade3 1610 if (optimize > 0 && flag_web)
fd743bc1 1611 rest_of_handle_web ();
f6db1481 1612
97b0ade3 1613 if (optimize > 0 && flag_rerun_cse_after_loop)
fd743bc1 1614 rest_of_handle_cse2 ();
f6db1481
RH
1615
1616 cse_not_expected = 1;
1617
fd743bc1 1618 rest_of_handle_life ();
97b0ade3 1619 timevar_pop (TV_FLOW);
f6db1481
RH
1620
1621 if (optimize > 0)
fd743bc1 1622 rest_of_handle_combine ();
f6db1481 1623
97b0ade3 1624 if (optimize > 0 && flag_if_conversion)
fd743bc1 1625 rest_of_handle_if_after_combine ();
f6db1481 1626
750054a2 1627 /* The optimization to partition hot/cold basic blocks into separate
8e8d5162
CT
1628 sections of the .o file does not work well with linkonce or with
1629 user defined section attributes. Don't call it if either case
1630 arises. */
750054a2 1631
9fb32434
CT
1632 if (flag_reorder_blocks_and_partition
1633 && !DECL_ONE_ONLY (current_function_decl)
1634 && !user_defined_section_attribute)
97b0ade3 1635 rest_of_handle_partition_blocks ();
750054a2 1636
1ab219d3 1637 if (optimize > 0 && flag_regmove)
fd743bc1 1638 rest_of_handle_regmove ();
f6db1481
RH
1639
1640 /* Do unconditional splitting before register allocation to allow machine
1641 description to add extra information not needed previously. */
1642 split_all_insns (1);
1643
1644#ifdef OPTIMIZE_MODE_SWITCHING
97b0ade3 1645 rest_of_handle_mode_switching ();
f6db1481
RH
1646#endif
1647
1648 /* Any of the several passes since flow1 will have munged register
1649 lifetime data a bit. We need it to be up to date for scheduling
1650 (see handling of reg_known_equiv in init_alias_analysis). */
fd743bc1 1651 recompute_reg_usage (get_insns (), !optimize_size);
f6db1481
RH
1652
1653#ifdef INSN_SCHEDULING
97b0ade3
PB
1654 if (optimize > 0 && flag_modulo_sched)
1655 rest_of_handle_sms ();
1656
1657 if (flag_schedule_insns)
1658 rest_of_handle_sched ();
f6db1481
RH
1659#endif
1660
1661 /* Determine if the current function is a leaf before running reload
1662 since this can impact optimizations done by the prologue and
1663 epilogue thus changing register elimination offsets. */
1664 current_function_is_leaf = leaf_function_p ();
1665
cd280abb
PB
1666 if (rest_of_handle_old_regalloc ())
1667 goto exit_rest_of_compilation;
f6db1481 1668
f6db1481 1669 if (optimize > 0)
97b0ade3 1670 rest_of_handle_postreload ();
f6db1481 1671
f9957958 1672 if (optimize > 0 && flag_gcse_after_reload)
fd743bc1 1673 rest_of_handle_gcse2 ();
f9957958 1674
97b0ade3 1675 rest_of_handle_flow2 ();
f6db1481
RH
1676
1677#ifdef HAVE_peephole2
1678 if (optimize > 0 && flag_peephole2)
97b0ade3 1679 rest_of_handle_peephole2 ();
f6db1481
RH
1680#endif
1681
97b0ade3
PB
1682 if (optimize > 0)
1683 rest_of_handle_if_after_reload ();
f6db1481
RH
1684
1685 if (optimize > 0)
1686 {
1687 if (flag_rename_registers || flag_cprop_registers)
fd743bc1 1688 rest_of_handle_regrename ();
f6db1481 1689
fd743bc1 1690 rest_of_handle_reorder_blocks ();
f6db1481
RH
1691 }
1692
1693 if (flag_branch_target_load_optimize2)
97b0ade3 1694 rest_of_handle_branch_target_load_optimize ();
f6db1481 1695
f6db1481
RH
1696#ifdef LEAF_REGISTERS
1697 current_function_uses_only_leaf_regs
1698 = optimize > 0 && only_leaf_regs_used () && leaf_function_p ();
1699#endif
1700
9ac617d4
EB
1701#ifdef INSN_SCHEDULING
1702 if (optimize > 0 && flag_schedule_insns_after_reload)
1703 rest_of_handle_sched2 ();
1704#endif
1705
f6db1481 1706#ifdef STACK_REGS
fd743bc1 1707 rest_of_handle_stack_regs ();
f6db1481
RH
1708#endif
1709
1710 compute_alignments ();
1711
1712 if (flag_var_tracking)
fd743bc1 1713 rest_of_handle_variable_tracking ();
f6db1481
RH
1714
1715 /* CFG is no longer maintained up-to-date. */
1716 free_bb_for_insn ();
1717
1718 if (targetm.machine_dependent_reorg != 0)
fd743bc1 1719 rest_of_handle_machine_reorg ();
f6db1481 1720
fd743bc1 1721 purge_line_number_notes (get_insns ());
f6db1481
RH
1722 cleanup_barriers ();
1723
1724#ifdef DELAY_SLOTS
97b0ade3 1725 if (flag_delayed_branch)
fd743bc1 1726 rest_of_handle_delay_slots ();
f6db1481
RH
1727#endif
1728
1729#if defined (HAVE_ATTR_length) && !defined (STACK_REGS)
1730 timevar_push (TV_SHORTEN_BRANCH);
1731 split_all_insns_noflow ();
1732 timevar_pop (TV_SHORTEN_BRANCH);
1733#endif
1734
1735 convert_to_eh_region_ranges ();
1736
97b0ade3 1737 rest_of_handle_shorten_branches ();
f6db1481
RH
1738
1739 set_nothrow_function_flags ();
f6db1481 1740
fd743bc1 1741 rest_of_handle_final ();
f6db1481 1742
f6db1481
RH
1743 exit_rest_of_compilation:
1744
97b0ade3 1745 rest_of_clean_state ();
f6db1481
RH
1746}
1747
f6db1481
RH
1748void
1749finish_optimization_passes (void)
1750{
9f8628ba
PB
1751 enum tree_dump_index i;
1752 struct dump_file_info *dfi;
1753 char *name;
1754
97b0ade3 1755 timevar_push (TV_DUMP);
f6db1481
RH
1756 if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
1757 {
f6db1481 1758 open_dump_file (DFI_bp, NULL);
f6db1481 1759 end_branch_prob ();
f6db1481 1760 close_dump_file (DFI_bp, NULL, NULL_RTX);
f6db1481
RH
1761 }
1762
1763 if (optimize > 0 && open_dump_file (DFI_combine, NULL))
1764 {
f6db1481
RH
1765 dump_combine_total_stats (dump_file);
1766 close_dump_file (DFI_combine, NULL, NULL_RTX);
f6db1481
RH
1767 }
1768
f6db1481
RH
1769 /* Do whatever is necessary to finish printing the graphs. */
1770 if (graph_dump_format != no_graph)
9f8628ba
PB
1771 for (i = DFI_MIN; (dfi = get_dump_file_info (i)) != NULL; ++i)
1772 if (dump_initialized_p (i)
1773 && (dfi->flags & TDF_RTL) != 0
1774 && (name = get_dump_file_name (i)) != NULL)
1775 {
1776 finish_graph_dump_file (name);
1777 free (name);
1778 }
f6db1481 1779
97b0ade3 1780 timevar_pop (TV_DUMP);
f6db1481
RH
1781}
1782
2f8e398b
PB
1783struct tree_opt_pass pass_rest_of_compilation =
1784{
9f8628ba 1785 NULL, /* name */
2f8e398b
PB
1786 NULL, /* gate */
1787 rest_of_compilation, /* execute */
1788 NULL, /* sub */
1789 NULL, /* next */
1790 0, /* static_pass_number */
1791 TV_REST_OF_COMPILATION, /* tv_id */
1792 PROP_rtl, /* properties_required */
1793 0, /* properties_provided */
1794 PROP_rtl, /* properties_destroyed */
1795 0, /* todo_flags_start */
9f8628ba
PB
1796 TODO_ggc_collect, /* todo_flags_finish */
1797 0 /* letter */
2f8e398b
PB
1798};
1799
1800
This page took 0.75005 seconds and 5 git commands to generate.