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