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