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