From 9f8628bacdb26f5c6f63aa305f29212b0d766199 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 6 Sep 2004 10:08:17 +0000 Subject: [PATCH] Unify the management of RTL and tree-level dump files. 2004-09-06 Paolo Bonzini Unify the management of RTL and tree-level dump files. * cfgexpand.c (tree_expand_cfg): Fix incorrect comment. Don't print function name to the dump file, the pass manager would do this for us. Add code from the top of rest_of_compilation, up to the initial RTL dump. * passes.c (rest_of_handle_jump): Call fixup_tail_calls and close the DFI_sibling dump file. (rest_of_compilation): Don't do that here. Remove code up to the initial RTL dump. (init_optimization_passes): Remove. (pass_rest_of_compilation): Change pass name to NULL. * toplev.c (lang_dependent_init): Do not use an empty dump file prefix. Do not call init_optimization_passes. * toplev.h (init_optimization_passes): Remove. * graph.c (print_rtl_graph_with_bb, clean_graph_dump_file, finish_graph_dump_file): Remove SUFFIX parameter. * graph.h (print_rtl_graph_with_bb, clean_graph_dump_file, finish_graph_dump_file): Likewise. * tree-pass.h (struct tree_opt_pass): Add `letter' field. * cfgexpand.c (pass_expand): Adjust. * gimple-low.c (pass_lower_cf, pass_remove_useless_vars): Adjust. * passes.c (pass_rest_of_compilation): Adjust. * predict.c (pass_profile): Adjust. * tree-alias-common.c (pass_build_pta, pass_del_pta): Adjust. * tree-cfg.c (pass_build_cfg, pass_remove_useless_stmts, pass_split_crit_edges, pass_warn_function_return): Adjust. * tree-complex.c (pass_lower_vector_ssa, pass_pre_expand): Adjust. * tree-dfa.c (pass_referenced_vars): Adjust. * tree-eh.c (pass_lower_eh): Adjust. * tree-if-conv.c (pass_build_ssa): Adjust. * tree-into-ssa.c (pass_build_ssa): Adjust. * tree-mudflap.c (pass_mudflap_1, pass_mudflap_2): Adjust. * tree-nomudflap.c (pass_mudflap_1, pass_mudflap_2): Adjust. * tree-nrv.c (pass_nrv): Adjust. * tree-optimize.c (pass_gimple, pass_all_optimizations, pass_cleanup_cfg_post_optimizing, pass_free_datastructures, pass_init_datastructures): Adjust. * tree-outof-ssa.c (pass_del_ssa): Adjust. * tree-profile.c (pass_tree_profile): Adjust. * tree-sra.c (pass_sra): Adjust. * tree-ssa-alias.c (pass_may_alias): Adjust. * tree-ssa-ccp.c (pass_ccp, pass_fold_builtins): Adjust. * tree-ssa-copyrename.c (pass_rename_ssa_copies): Adjust. * tree-ssa-dce.c (pass_dce, pass_cd_dce): Adjust. * tree-ssa-dom.c (pass_dominator): Adjust. * tree-ssa-dse.c (pass_dse): Adjust. * tree-ssa-forwprop.c (pass_forwprop): Adjust. * tree-ssa-if-conv.c (pass_if_conversion): Adjust. * tree-ssa-loop-ch.c (pass_ch): Adjust. * tree-ssa-loop.c (pass_loop, pass_loop_init, pass_lim, pass_loop_done, pass_complete_unroll, pass_iv_canon, pass_iv_optimize, pass_vectorize): Adjust. * tree-ssa-phiopt.c (pass_phiopt): Adjust. * tree-ssa-pre.c (pass_pre, pass_fre): Adjust. * tree-ssa.c (pass_redundant_phi, pass_early_warn_uninitialized, pass_late_warn_uninnitialized): Adjust. * tree-tailcall.c (pass_tail_recursion, pass_tail_calls): Adjust. * Makefile.in (tree-dump.o): Add new dependencies. * cgraph.c (cgraph_remove_node): TDF_all -> TDF_tree_all. * cgraphunit.c (cgraph_preserve_function_body_p, cgraph_optimize): Likewise. * toplev.c (dump_file_name): New. * tree-dump.c (dump_enable_all): Add LETTER parameter. (struct dump_file_info): Add NUM and LETTER fields. (dump_files): Adjust and add RTL dump files. (dump_register): Add NUM and LETTER fields. (get_dump_file_name, dump_initialized_p, enable_rtl_dump_file): New. (dump_begin): Use get_dump_file_name. (dump_switch_p_1): Adjust call to dump_enable_all. * tree-dump.h (dump_register): Adjust prototype. * tree-optimize.c (register_one_dump_file): Take dump file index. Support flags for RTL dumps. (register_dump_files): Fill in NUM field of struct dump_file_info. Track properties both when the gate is executed and when it is not. (execute_todo): Dump RTL. Add PROPERTIES parameter. (execute_one_pass): Pass properties to execute_todo. Handle VCG dumps of RTL. * tree-pass.h (dump_file_name): New. * tree.h (TDF_TREE, TDF_RTL, get_dump_file_name, dump_initialized_p): New. * Makefile.in (passes.o): Add new dependencies. * passes.c (struct dump_file_info, enum dump_file_index, dump_file_tbl, init_optimization_passes): Remove. (open_dump_file, close_dump_file): Use tree-dumping infrastructure. (rest_of_handle_new_regalloc, rest_of_handle_old_regalloc): Use dump_enabled_p. (finish_optimization_passes): Update finish_graph_dump_file loop. (enable_rtl_dump_file): Remove. * tree-dump.c (dump_files): Adjust and add RTL dump files. (enable_rtl_dump_file): Add here. * tree.h (enum tree_dump_index): Add RTL dump file indices. * doc/invoke.texi (Debugging options): Document new RTL debugging options. Update. From-SVN: r87113 --- gcc/ChangeLog | 101 ++++++++++++ gcc/Makefile.in | 5 +- gcc/cfgexpand.c | 24 +-- gcc/cgraph.c | 4 +- gcc/cgraphunit.c | 4 +- gcc/doc/invoke.texi | 312 ++++++++++++++++++++++++++------------ gcc/gimple-low.c | 6 +- gcc/graph.c | 24 ++- gcc/graph.h | 6 +- gcc/passes.c | 282 ++++++---------------------------- gcc/predict.c | 3 +- gcc/toplev.c | 4 +- gcc/toplev.h | 1 - gcc/tree-alias-common.c | 6 +- gcc/tree-cfg.c | 12 +- gcc/tree-complex.c | 6 +- gcc/tree-dfa.c | 3 +- gcc/tree-dump.c | 180 ++++++++++++++++------ gcc/tree-dump.h | 2 +- gcc/tree-eh.c | 3 +- gcc/tree-if-conv.c | 3 +- gcc/tree-into-ssa.c | 3 +- gcc/tree-mudflap.c | 6 +- gcc/tree-nomudflap.c | 6 +- gcc/tree-nrv.c | 3 +- gcc/tree-optimize.c | 111 ++++++++++---- gcc/tree-outof-ssa.c | 3 +- gcc/tree-pass.h | 18 +++ gcc/tree-profile.c | 3 +- gcc/tree-sra.c | 3 +- gcc/tree-ssa-alias.c | 3 +- gcc/tree-ssa-ccp.c | 7 +- gcc/tree-ssa-copyrename.c | 3 +- gcc/tree-ssa-dce.c | 6 +- gcc/tree-ssa-dom.c | 3 +- gcc/tree-ssa-dse.c | 3 +- gcc/tree-ssa-forwprop.c | 3 +- gcc/tree-ssa-loop-ch.c | 3 +- gcc/tree-ssa-loop.c | 24 ++- gcc/tree-ssa-phiopt.c | 3 +- gcc/tree-ssa-pre.c | 6 +- gcc/tree-ssa.c | 9 +- gcc/tree-tailcall.c | 6 +- gcc/tree.h | 50 +++++- 44 files changed, 771 insertions(+), 505 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 77cdac9e450..0852f2980b6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,104 @@ +2004-09-06 Paolo Bonzini + + Unify the management of RTL and tree-level dump files. + + * cfgexpand.c (tree_expand_cfg): Fix incorrect comment. + Don't print function name to the dump file, the pass manager + would do this for us. Add code from the top of + rest_of_compilation, up to the initial RTL dump. + * passes.c (rest_of_handle_jump): Call fixup_tail_calls and + close the DFI_sibling dump file. + (rest_of_compilation): Don't do that here. Remove code up to the + initial RTL dump. + (init_optimization_passes): Remove. + (pass_rest_of_compilation): Change pass name to NULL. + * toplev.c (lang_dependent_init): Do not use an empty dump file prefix. + Do not call init_optimization_passes. + * toplev.h (init_optimization_passes): Remove. + + * graph.c (print_rtl_graph_with_bb, clean_graph_dump_file, + finish_graph_dump_file): Remove SUFFIX parameter. + * graph.h (print_rtl_graph_with_bb, clean_graph_dump_file, + finish_graph_dump_file): Likewise. + + * tree-pass.h (struct tree_opt_pass): Add `letter' field. + * cfgexpand.c (pass_expand): Adjust. + * gimple-low.c (pass_lower_cf, pass_remove_useless_vars): Adjust. + * passes.c (pass_rest_of_compilation): Adjust. + * predict.c (pass_profile): Adjust. + * tree-alias-common.c (pass_build_pta, pass_del_pta): Adjust. + * tree-cfg.c (pass_build_cfg, pass_remove_useless_stmts, + pass_split_crit_edges, pass_warn_function_return): Adjust. + * tree-complex.c (pass_lower_vector_ssa, pass_pre_expand): Adjust. + * tree-dfa.c (pass_referenced_vars): Adjust. + * tree-eh.c (pass_lower_eh): Adjust. + * tree-if-conv.c (pass_build_ssa): Adjust. + * tree-into-ssa.c (pass_build_ssa): Adjust. + * tree-mudflap.c (pass_mudflap_1, pass_mudflap_2): Adjust. + * tree-nomudflap.c (pass_mudflap_1, pass_mudflap_2): Adjust. + * tree-nrv.c (pass_nrv): Adjust. + * tree-optimize.c (pass_gimple, pass_all_optimizations, + pass_cleanup_cfg_post_optimizing, pass_free_datastructures, + pass_init_datastructures): Adjust. + * tree-outof-ssa.c (pass_del_ssa): Adjust. + * tree-profile.c (pass_tree_profile): Adjust. + * tree-sra.c (pass_sra): Adjust. + * tree-ssa-alias.c (pass_may_alias): Adjust. + * tree-ssa-ccp.c (pass_ccp, pass_fold_builtins): Adjust. + * tree-ssa-copyrename.c (pass_rename_ssa_copies): Adjust. + * tree-ssa-dce.c (pass_dce, pass_cd_dce): Adjust. + * tree-ssa-dom.c (pass_dominator): Adjust. + * tree-ssa-dse.c (pass_dse): Adjust. + * tree-ssa-forwprop.c (pass_forwprop): Adjust. + * tree-ssa-if-conv.c (pass_if_conversion): Adjust. + * tree-ssa-loop-ch.c (pass_ch): Adjust. + * tree-ssa-loop.c (pass_loop, pass_loop_init, pass_lim, + pass_loop_done, pass_complete_unroll, pass_iv_canon, + pass_iv_optimize, pass_vectorize): Adjust. + * tree-ssa-phiopt.c (pass_phiopt): Adjust. + * tree-ssa-pre.c (pass_pre, pass_fre): Adjust. + * tree-ssa.c (pass_redundant_phi, pass_early_warn_uninitialized, + pass_late_warn_uninnitialized): Adjust. + * tree-tailcall.c (pass_tail_recursion, pass_tail_calls): Adjust. + + * Makefile.in (tree-dump.o): Add new dependencies. + * cgraph.c (cgraph_remove_node): TDF_all -> TDF_tree_all. + * cgraphunit.c (cgraph_preserve_function_body_p, cgraph_optimize): + Likewise. + * toplev.c (dump_file_name): New. + * tree-dump.c (dump_enable_all): Add LETTER parameter. + (struct dump_file_info): Add NUM and LETTER fields. + (dump_files): Adjust and add RTL dump files. + (dump_register): Add NUM and LETTER fields. + (get_dump_file_name, dump_initialized_p, enable_rtl_dump_file): New. + (dump_begin): Use get_dump_file_name. + (dump_switch_p_1): Adjust call to dump_enable_all. + * tree-dump.h (dump_register): Adjust prototype. + * tree-optimize.c (register_one_dump_file): Take dump file index. + Support flags for RTL dumps. + (register_dump_files): Fill in NUM field of struct dump_file_info. + Track properties both when the gate is executed and when it is not. + (execute_todo): Dump RTL. Add PROPERTIES parameter. + (execute_one_pass): Pass properties to execute_todo. Handle VCG + dumps of RTL. + * tree-pass.h (dump_file_name): New. + * tree.h (TDF_TREE, TDF_RTL, get_dump_file_name, dump_initialized_p): + New. + + * Makefile.in (passes.o): Add new dependencies. + * passes.c (struct dump_file_info, enum dump_file_index, + dump_file_tbl, init_optimization_passes): Remove. + (open_dump_file, close_dump_file): Use tree-dumping infrastructure. + (rest_of_handle_new_regalloc, rest_of_handle_old_regalloc): Use + dump_enabled_p. + (finish_optimization_passes): Update finish_graph_dump_file loop. + (enable_rtl_dump_file): Remove. + * tree-dump.c (dump_files): Adjust and add RTL dump files. + (enable_rtl_dump_file): Add here. + * tree.h (enum tree_dump_index): Add RTL dump file indices. + * doc/invoke.texi (Debugging options): Document new RTL debugging + options. Update. + 2004-09-05 Kazu Hirata * c-common.c, c-decl.c, combine.c, defaults.h, fold-const.c, diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 71c11ebc43a..efaa7a311ac 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1587,7 +1587,7 @@ tree.o : tree.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ real.h gt-tree.h tree-iterator.h $(BASIC_BLOCK_H) $(TREE_FLOW_H) tree-dump.o: tree-dump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ $(C_TREE_H) $(FLAGS_H) langhooks.h toplev.h output.h $(C_PRAGMA_H) $(RTL_H) \ - $(GGC_H) $(EXPR_H) $(SPLAY_TREE_H) $(TREE_DUMP_H) tree-iterator.h + $(GGC_H) $(EXPR_H) $(SPLAY_TREE_H) $(TREE_DUMP_H) tree-iterator.h tree-pass.h tree-inline.o : tree-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(RTL_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) input.h insn-config.h \ $(INTEGRATE_H) $(VARRAY_H) $(HASHTAB_H) $(SPLAY_TREE_H) toplev.h \ @@ -1818,7 +1818,8 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ graph.h $(LOOP_H) except.h $(REGS_H) $(TIMEVAR_H) value-prof.h \ $(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \ langhooks.h insn-flags.h $(CFGLAYOUT_H) real.h $(CFGLOOP_H) \ - hosthooks.h $(LANGHOOKS_DEF_H) cgraph.h $(COVERAGE_H) alloc-pool.h + hosthooks.h $(LANGHOOKS_DEF_H) cgraph.h $(COVERAGE_H) alloc-pool.h \ + tree-pass.h tree-dump.h main.o : main.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index d4456e3d525..122c11b37b8 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -1188,14 +1188,6 @@ tree_expand_cfg (void) basic_block bb, init_block; sbitmap blocks; - if (dump_file) - { - fprintf (dump_file, "\n;; Function %s", - (*lang_hooks.decl_printable_name) (current_function_decl, 2)); - fprintf (dump_file, " (%s)\n", - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); - } - profile_status = PROFILE_ABSENT; /* Some backends want to know that we are expanding to RTL. */ @@ -1231,8 +1223,7 @@ tree_expand_cfg (void) currently_expanding_to_rtl = 0; /* Convert from NOTE_INSN_EH_REGION style notes, and do other - sorts of eh initialization. Delay this until after the - initial rtl dump so that we can see the original nesting. */ + sorts of eh initialization. */ convert_from_eh_region_ranges (); rebuild_jump_labels (get_insns ()); @@ -1248,6 +1239,16 @@ tree_expand_cfg (void) #ifdef ENABLE_CHECKING verify_flow_info(); #endif + + /* There's no need to defer outputting this function any more; we + know we want to output it. */ + DECL_DEFER_OUTPUT (current_function_decl) = 0; + + /* Now that we're done expanding trees to RTL, we shouldn't have any + more CONCATs anywhere. */ + generating_concat_p = 0; + + finalize_block_changes (); } struct tree_opt_pass pass_expand = @@ -1264,5 +1265,6 @@ struct tree_opt_pass pass_expand = PROP_rtl, /* properties_provided */ PROP_gimple_leh, /* properties_destroyed */ 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ + 0, /* todo_flags_finish */ + 'r' /* letter */ }; diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 9f00f609dee..84cd4b1b607 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -328,7 +328,7 @@ cgraph_remove_node (struct cgraph_node *node) else { htab_clear_slot (cgraph_hash, slot); - if (!dump_enabled_p (TDI_all)) + if (!dump_enabled_p (TDI_tree_all)) { DECL_SAVED_TREE (node->decl) = NULL; DECL_STRUCT_FUNCTION (node->decl) = NULL; @@ -356,7 +356,7 @@ cgraph_remove_node (struct cgraph_node *node) || (!n->global.inlined_to && !TREE_ASM_WRITTEN (n->decl) && !DECL_EXTERNAL (n->decl))) break; - if (!n && !dump_enabled_p (TDI_all)) + if (!n && !dump_enabled_p (TDI_tree_all)) { DECL_SAVED_TREE (node->decl) = NULL; DECL_STRUCT_FUNCTION (node->decl) = NULL; diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 48cb2398f72..66a97a92b5d 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1712,7 +1712,7 @@ cgraph_preserve_function_body_p (tree decl) { struct cgraph_node *node; /* Keep the body; we're going to dump it. */ - if (dump_enabled_p (TDI_all)) + if (dump_enabled_p (TDI_tree_all)) return true; if (!cgraph_global_info_ready) return (DECL_INLINE (decl) && !flag_really_no_inline); @@ -1771,7 +1771,7 @@ cgraph_optimize (void) /* Double check that all inline clones are gone and that all function bodies have been released from memory. */ if (flag_unit_at_a_time - && !dump_enabled_p (TDI_all) + && !dump_enabled_p (TDI_tree_all) && !(sorrycount || errorcount)) { struct cgraph_node *node; diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index ade9d2c27bc..ea5f983a768 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -3349,160 +3349,280 @@ generate test coverage data. Coverage data will match the source files more closely, if you do not optimize. @item -d@var{letters} +@item -fdump-rtl-@var{pass} @opindex d Says to make debugging dumps during compilation at times specified by -@var{letters}. This is used for debugging the compiler. The file names -for most of the dumps are made by appending a pass number and a word to -the @var{dumpname}. @var{dumpname} is generated from the name of the -output file, if explicitly specified and it is not an executable, -otherwise it is the basename of the source file. In both cases any -suffix is removed (e.g. @file{foo.01.rtl} or @file{foo.02.sibling}). -Here are the possible letters for use in @var{letters}, and their -meanings: +@var{letters}. This is used for debugging the RTL-based passes of the +compiler. The file names for most of the dumps are made by appending a +pass number and a word to the @var{dumpname}. @var{dumpname} is generated +from the name of the output file, if explicitly specified and it is not +an executable, otherwise it is the basename of the source file. -@table @samp -@item A +Most debug dumps can be enabled either passing a letter to the @option{-d} +option, or with a long @option{-fdump-rtl} switch; here are the possible +letters for use in @var{letters} and @var{pass}, and their meanings: + +@table @gcctabopt +@item -dA @opindex dA Annotate the assembler output with miscellaneous debugging information. -@item b + +@item -db +@itemx -fdump-rtl-bp @opindex db -Dump after computing branch probabilities, to @file{@var{file}.12.bp}. -@item B +@opindex fdump-rtl-bp +Dump after computing branch probabilities, to @file{@var{file}.09.bp}. + +@item -dB +@itemx -fdump-rtl-bbro @opindex dB -Dump after block reordering, to @file{@var{file}.32.bbro}. -@item c +@opindex fdump-rtl-bbro +Dump after block reordering, to @file{@var{file}.30.bbro}. + +@item -dc +@itemx -fdump-rtl-combine @opindex dc -Dump after instruction combination, to the file @file{@var{file}.20.combine}. -@item C +@opindex fdump-rtl-combine +Dump after instruction combination, to the file @file{@var{file}.17.combine}. + +@item -dC +@itemx -fdump-rtl-ce1 +@itemx -fdump-rtl-ce2 @opindex dC -Dump after the first if conversion, to the file @file{@var{file}.14.ce1}. -Also dump after the second if conversion, to the file @file{@var{file}.21.ce2}. -@item d +@opindex fdump-rtl-ce1 +@opindex fdump-rtl-ce2 +@option{-dC} and @option{-fdump-rtl-ce1} enable dumping after the +first if conversion, to the file @file{@var{file}.11.ce1}. @option{-dC} +and @option{-fdump-rtl-ce2} enable dumping after the second if +conversion, to the file @file{@var{file}.18.ce2}. + +@item -dd +@itemx -fdump-rtl-btl +@itemx -fdump-rtl-dbr @opindex dd -Dump after branch target load optimization, to to @file{@var{file}.33.btl}. -Also dump after delayed branch scheduling, to @file{@var{file}.37.dbr}. -@item D +@opindex fdump-rtl-btl +@opindex fdump-rtl-dbr +@option{-dd} and @option{-fdump-rtl-btl} enable dumping after branch +target load optimization, to to @file{@var{file}.31.btl}. @option{-dd} +and @option{-fdump-rtl-dbr} enable dumping after delayed branch +scheduling, to @file{@var{file}.36.dbr}. + +@item -dD @opindex dD Dump all macro definitions, at the end of preprocessing, in addition to normal output. -@item E + +@item -dE +@itemx -fdump-rtl-ce3 @opindex dE -Dump after the third if conversion, to @file{@var{file}.31.ce3}. -@item f +@opindex fdump-rtl-ce3 +Dump after the third if conversion, to @file{@var{file}.28.ce3}. + +@item -df +@itemx -fdump-rtl-cfg +@itemx -fdump-rtl-life @opindex df -Dump after control and data flow analysis, to @file{@var{file}.11.cfg}. -Also dump after life analysis, to @file{@var{file}.19.life}. -@item g +@opindex fdump-rtl-cfg +@opindex fdump-rtl-life +@option{-df} and @option{-fdump-rtl-cfg} enable dumping after control +and data flow analysis, to @file{@var{file}.08.cfg}. @option{-df} +and @option{-fdump-rtl-cfg} enable dumping dump after life analysis, +to @file{@var{file}.16.life}. + +@item -dg +@itemx -fdump-rtl-greg @opindex dg -Dump after global register allocation, to @file{@var{file}.26.greg}. -@item G +@opindex fdump-rtl-greg +Dump after global register allocation, to @file{@var{file}.23.greg}. + +@item -dG +@itemx -fdump-rtl-gcse +@itemx -fdump-rtl-bypass @opindex dG -Dump after GCSE, to @file{@var{file}.08.gcse}. -Also dump after jump bypassing and control flow optimizations, to -@file{@var{file}.10.bypass}. -@item h +@opindex fdump-rtl-gcse +@opindex fdump-rtl-bypass +@option{-dG} and @option{-fdump-rtl-gcse} enable dumping after GCSE, to +@file{@var{file}.05.gcse}. @option{-dG} and @option{-fdump-rtl-bypass} +enable dumping after jump bypassing and control flow optimizations, to +@file{@var{file}.07.bypass}. + +@item -dh +@itemx -fdump-rtl-eh @opindex dh -Dump after finalization of EH handling code, to @file{@var{file}.03.eh}. -@item i +@opindex fdump-rtl-eh +Dump after finalization of EH handling code, to @file{@var{file}.02.eh}. + +@item -di +@itemx -fdump-rtl-sibling @opindex di -Dump after sibling call optimizations, to @file{@var{file}.02.sibling}. -@item j +@opindex fdump-rtl-sibling +Dump after sibling call optimizations, to @file{@var{file}.01.sibling}. + +@item -dj +@itemx -fdump-rtl-jump @opindex dj -Dump after the first jump optimization, to @file{@var{file}.04.jump}. -@item k +@opindex fdump-rtl-jump +Dump after the first jump optimization, to @file{@var{file}.03.jump}. + +@item -dk +@itemx -fdump-rtl-stack @opindex dk -Dump after conversion from registers to stack, to @file{@var{file}.35.stack}. -@item l +@opindex fdump-rtl-stack +Dump after conversion from registers to stack, to @file{@var{file}.33.stack}. + +@item -dl +@itemx -fdump-rtl-lreg @opindex dl -Dump after local register allocation, to @file{@var{file}.25.lreg}. -@item L +@opindex fdump-rtl-lreg +Dump after local register allocation, to @file{@var{file}.22.lreg}. + +@item -dL +@itemx -fdump-rtl-loop +@itemx -fdump-rtl-loop2 @opindex dL -Dump after loop optimization passes, to @file{@var{file}.09.loop} and -@file{@var{file}.16.loop2}. -@item m +@opindex fdump-rtl-loop +@opindex fdump-rtl-loop2 +@option{-dL} and @option{-fdump-rtl-loop} enable dumping after the first +loop optimization pass, to @file{@var{file}.06.loop}. @option{-dL} and +@option{-fdump-rtl-loop2} enable dumping after the second pass, to +@file{@var{file}.13.loop2}. + +@item -dm +@itemx -fdump-rtl-sms @opindex dm -Dump after modulo scheduling, to @file{@var{file}.23.sms}. -@item M +@opindex fdump-rtl-sms +Dump after modulo scheduling, to @file{@var{file}.20.sms}. + +@item -dM +@itemx -fdump-rtl-mach @opindex dM +@opindex fdump-rtl-mach Dump after performing the machine dependent reorganization pass, to -@file{@var{file}.36.mach}. -@item n +@file{@var{file}.35.mach}. + +@item -dn +@itemx -fdump-rtl-rnreg @opindex dn -Dump after register renumbering, to @file{@var{file}.30.rnreg}. -@item N +@opindex fdump-rtl-rnreg +Dump after register renumbering, to @file{@var{file}.29.rnreg}. + +@item -dN +@itemx -fdump-rtl-regmove @opindex dN -Dump after the register move pass, to @file{@var{file}.22.regmove}. -@item o +@opindex fdump-rtl-regmove +Dump after the register move pass, to @file{@var{file}.19.regmove}. + +@item -do +@itemx -fdump-rtl-postreload @opindex do -Dump after post-reload optimizations, to @file{@var{file}.27.postreload}. -@item r +@opindex fdump-rtl-postreload +Dump after post-reload optimizations, to @file{@var{file}.24.postreload}. + +@item -dr +@itemx -fdump-rtl-expand @opindex dr -Dump after RTL generation, to @file{@var{file}.01.rtl}. -@item R +@opindex fdump-rtl-expand +Dump after RTL generation, to @file{@var{file}.00.expand}. + +@item -dR +@itemx -fdump-rtl-sched2 @opindex dR -Dump after the second scheduling pass, to @file{@var{file}.34.sched2}. -@item s +@opindex fdump-rtl-sched2 +Dump after the second scheduling pass, to @file{@var{file}.32.sched2}. + +@item -ds +@itemx -fdump-rtl-cse @opindex ds +@opindex fdump-rtl-cse Dump after CSE (including the jump optimization that sometimes follows -CSE), to @file{@var{file}.06.cse}. -@item S +CSE), to @file{@var{file}.04.cse}. + +@item -dS +@itemx -fdump-rtl-sched @opindex dS -Dump after the first scheduling pass, to @file{@var{file}.24.sched}. -@item t +@opindex fdump-rtl-sched +Dump after the first scheduling pass, to @file{@var{file}.21.sched}. + +@item -dt +@itemx -fdump-rtl-cse2 @opindex dt +@opindex fdump-rtl-cse2 Dump after the second CSE pass (including the jump optimization that -sometimes follows CSE), to @file{@var{file}.18.cse2}. -@item T +sometimes follows CSE), to @file{@var{file}.15.cse2}. + +@item -dT +@itemx -fdump-rtl-tracer @opindex dT -Dump after running tracer, to @file{@var{file}.15.tracer}. -@item u -@opindex du -Dump after null pointer elimination pass to @file{@var{file}.05.null}. -@item U -@opindex dU -Dump callgraph and unit-at-a-time optimization @file{@var{file}.00.unit}. -@item V +@opindex fdump-rtl-tracer +Dump after running tracer, to @file{@var{file}.12.tracer}. + +@item -dV +@itemx -fdump-rtl-vpt +@itemx -fdump-rtl-vartrack @opindex dV -Dump after the value profile transformations, to @file{@var{file}.13.vpt}. -Also dump after variable tracking, to @file{@var{file}.35.vartrack}. -@item w +@opindex fdump-rtl-vpt +@opindex fdump-rtl-vartrack +@option{-dV} and @option{-fdump-rtl-vpt} enable dumping after the value +profile transformations, to @file{@var{file}.10.vpt}. @option{-dV} +and @option{-fdump-rtl-vartrack} enable dumping after variable tracking, +to @file{@var{file}.34.vartrack}. + +@item -dw +@itemx -fdump-rtl-flow2 @opindex dw -Dump after the second flow pass, to @file{@var{file}.28.flow2}. -@item z +@opindex fdump-rtl-flow2 +Dump after the second flow pass, to @file{@var{file}.26.flow2}. + +@item -dz +@itemx -fdump-rtl-peephole2 @opindex dz -Dump after the peephole pass, to @file{@var{file}.29.peephole2}. -@item Z +@opindex fdump-rtl-peephole2 +Dump after the peephole pass, to @file{@var{file}.27.peephole2}. + +@item -dZ +@itemx -fdump-rtl-web @opindex dZ -Dump after constructing the web, to @file{@var{file}.17.web}. -@item a +@opindex fdump-rtl-web +Dump after live range splitting, to @file{@var{file}.14.web}. + +@item -da +@itemx -fdump-rtl-all @opindex da +@opindex fdump-rtl-all Produce all the dumps listed above. -@item H + +@item -dH @opindex dH Produce a core dump whenever an error occurs. -@item m + +@item -dm @opindex dm Print statistics on memory usage, at the end of the run, to standard error. -@item p + +@item -dp @opindex dp Annotate the assembler output with a comment indicating which pattern and alternative was used. The length of each instruction is also printed. -@item P + +@item -dP @opindex dP Dump the RTL in the assembler output as a comment before each instruction. Also turns on @option{-dp} annotation. -@item v + +@item -dv @opindex dv -For each of the other indicated dump files (except for -@file{@var{file}.01.rtl}), dump a representation of the control flow graph -suitable for viewing with VCG to @file{@var{file}.@var{pass}.vcg}. -@item x +For each of the other indicated dump files (either with @option{-d} or +@option{-fdump-rtl-@var{pass}}), dump a representation of the control flow +graph suitable for viewing with VCG to @file{@var{file}.@var{pass}.vcg}. + +@item -dx @opindex dx Just generate RTL for a function instead of compiling it. Usually used -with @samp{r}. -@item y +with @samp{r} (@option{-fdump-rtl-expand}). + +@item -dy @opindex dy Dump debugging information during parsing, to standard error. @end table diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index 828a36fa756..5544a18468d 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -138,7 +138,8 @@ struct tree_opt_pass pass_lower_cf = PROP_gimple_lcf, /* properties_provided */ PROP_gimple_any, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; @@ -538,5 +539,6 @@ struct tree_opt_pass pass_remove_useless_vars = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/graph.c b/gcc/graph.c index d751bd0bf4f..62c35d71c67 100644 --- a/gcc/graph.c +++ b/gcc/graph.c @@ -220,21 +220,19 @@ end_fct (FILE *fp) /* Like print_rtl, but also print out live information for the start of each basic block. */ void -print_rtl_graph_with_bb (const char *base, const char *suffix, rtx rtx_first) +print_rtl_graph_with_bb (const char *base, rtx rtx_first) { rtx tmp_rtx; size_t namelen = strlen (base); - size_t suffixlen = strlen (suffix); size_t extlen = strlen (graph_ext[graph_dump_format]) + 1; - char *buf = alloca (namelen + suffixlen + extlen); + char *buf = alloca (namelen + extlen); FILE *fp; if (basic_block_info == NULL) return; memcpy (buf, base, namelen); - memcpy (buf + namelen, suffix, suffixlen); - memcpy (buf + namelen + suffixlen, graph_ext[graph_dump_format], extlen); + memcpy (buf + namelen, graph_ext[graph_dump_format], extlen); fp = fopen (buf, "a"); if (fp == NULL) @@ -385,17 +383,15 @@ print_rtl_graph_with_bb (const char *base, const char *suffix, rtx rtx_first) /* Similar as clean_dump_file, but this time for graph output files. */ void -clean_graph_dump_file (const char *base, const char *suffix) +clean_graph_dump_file (const char *base) { size_t namelen = strlen (base); - size_t suffixlen = strlen (suffix); size_t extlen = strlen (graph_ext[graph_dump_format]) + 1; - char *buf = alloca (namelen + extlen + suffixlen); + char *buf = alloca (namelen + extlen); FILE *fp; memcpy (buf, base, namelen); - memcpy (buf + namelen, suffix, suffixlen); - memcpy (buf + namelen + suffixlen, graph_ext[graph_dump_format], extlen); + memcpy (buf + namelen, graph_ext[graph_dump_format], extlen); fp = fopen (buf, "w"); @@ -417,17 +413,15 @@ clean_graph_dump_file (const char *base, const char *suffix) /* Do final work on the graph output file. */ void -finish_graph_dump_file (const char *base, const char *suffix) +finish_graph_dump_file (const char *base) { size_t namelen = strlen (base); - size_t suffixlen = strlen (suffix); size_t extlen = strlen (graph_ext[graph_dump_format]) + 1; - char *buf = alloca (namelen + suffixlen + extlen); + char *buf = alloca (namelen + extlen); FILE *fp; memcpy (buf, base, namelen); - memcpy (buf + namelen, suffix, suffixlen); - memcpy (buf + namelen + suffixlen, graph_ext[graph_dump_format], extlen); + memcpy (buf + namelen, graph_ext[graph_dump_format], extlen); fp = fopen (buf, "a"); if (fp != NULL) diff --git a/gcc/graph.h b/gcc/graph.h index e69f3361660..b96188c3381 100644 --- a/gcc/graph.h +++ b/gcc/graph.h @@ -21,8 +21,8 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #ifndef GCC_GRAPH_H #define GCC_GRAPH_H -extern void print_rtl_graph_with_bb (const char *, const char *, rtx); -extern void clean_graph_dump_file (const char *, const char *); -extern void finish_graph_dump_file (const char *, const char *); +extern void print_rtl_graph_with_bb (const char *, rtx); +extern void clean_graph_dump_file (const char *); +extern void finish_graph_dump_file (const char *); #endif /* ! GCC_GRAPH_H */ diff --git a/gcc/passes.c b/gcc/passes.c index d55e9b91062..0beac3206f6 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -81,6 +81,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "value-prof.h" #include "alloc-pool.h" #include "tree-pass.h" +#include "tree-dump.h" #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO) #include "dwarf2out.h" @@ -108,166 +109,27 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #define DUMPFILE_FORMAT ".%02d." #endif -/* Describes a dump file. */ - -struct dump_file_info -{ - /* The unique extension to apply, e.g. ".jump". */ - const char *const extension; - - /* The -d character that enables this dump file. */ - char const debug_switch; - - /* True if there is a corresponding graph dump file. */ - char const graph_dump_p; - - /* True if the user selected this dump. */ - char enabled; - - /* True if the files have been initialized (ie truncated). */ - char initialized; -}; - -/* Enumerate the extant dump files. */ - -enum dump_file_index -{ - DFI_cgraph, - DFI_rtl, - DFI_sibling, - DFI_eh, - DFI_jump, - DFI_null, - DFI_cse, - DFI_gcse, - DFI_loop, - DFI_bypass, - DFI_cfg, - DFI_bp, - DFI_vpt, - DFI_ce1, - DFI_tracer, - DFI_loop2, - DFI_web, - DFI_cse2, - DFI_life, - DFI_combine, - DFI_ce2, - DFI_regmove, - DFI_sms, - DFI_sched, - DFI_lreg, - DFI_greg, - DFI_postreload, - DFI_gcse2, - DFI_flow2, - DFI_peephole2, - DFI_ce3, - DFI_rnreg, - DFI_bbro, - DFI_branch_target_load, - DFI_sched2, - DFI_stack, - DFI_vartrack, - DFI_mach, - DFI_dbr, - DFI_MAX -}; - -/* Describes all the dump files. Should be kept in order of the - pass and in sync with dump_file_index above. - - Remaining -d letters: - - " e q " - " F K O Q WXY " -*/ - -static struct dump_file_info dump_file_tbl[DFI_MAX] = -{ - { "cgraph", 'U', 0, 0, 0 }, - { "rtl", 'r', 0, 0, 0 }, - { "sibling", 'i', 0, 0, 0 }, - { "eh", 'h', 0, 0, 0 }, - { "jump", 'j', 0, 0, 0 }, - { "null", 'u', 0, 0, 0 }, - { "cse", 's', 0, 0, 0 }, - { "gcse", 'G', 1, 0, 0 }, - { "loop", 'L', 1, 0, 0 }, - { "bypass", 'G', 1, 0, 0 }, /* Yes, duplicate enable switch. */ - { "cfg", 'f', 1, 0, 0 }, - { "bp", 'b', 1, 0, 0 }, - { "vpt", 'V', 1, 0, 0 }, - { "ce1", 'C', 1, 0, 0 }, - { "tracer", 'T', 1, 0, 0 }, - { "loop2", 'L', 1, 0, 0 }, - { "web", 'Z', 0, 0, 0 }, - { "cse2", 't', 1, 0, 0 }, - { "life", 'f', 1, 0, 0 }, /* Yes, duplicate enable switch. */ - { "combine", 'c', 1, 0, 0 }, - { "ce2", 'C', 1, 0, 0 }, - { "regmove", 'N', 1, 0, 0 }, - { "sms", 'm', 0, 0, 0 }, - { "sched", 'S', 1, 0, 0 }, - { "lreg", 'l', 1, 0, 0 }, - { "greg", 'g', 1, 0, 0 }, - { "postreload", 'o', 1, 0, 0 }, - { "gcse2", 'J', 0, 0, 0 }, - { "flow2", 'w', 1, 0, 0 }, - { "peephole2", 'z', 1, 0, 0 }, - { "ce3", 'E', 1, 0, 0 }, - { "rnreg", 'n', 1, 0, 0 }, - { "bbro", 'B', 1, 0, 0 }, - { "btl", 'd', 1, 0, 0 }, /* Yes, duplicate enable switch. */ - { "sched2", 'R', 1, 0, 0 }, - { "stack", 'k', 1, 0, 0 }, - { "vartrack", 'V', 1, 0, 0 }, /* Yes, duplicate enable switch. */ - { "mach", 'M', 1, 0, 0 }, - { "dbr", 'd', 0, 0, 0 }, -}; +static int initializing_dump = 0; /* Routine to open a dump file. Return true if the dump file is enabled. */ static int -open_dump_file (enum dump_file_index index, tree decl) +open_dump_file (enum tree_dump_index index, tree decl) { - char *dump_name; - const char *open_arg; - char seq[16]; - - if (! dump_file_tbl[index].enabled) + if (! dump_enabled_p (index)) return 0; timevar_push (TV_DUMP); - if (dump_file != NULL) - fclose (dump_file); - - sprintf (seq, DUMPFILE_FORMAT, index); - if (! dump_file_tbl[index].initialized) - { - /* If we've not initialized the files, do so now. */ - if (graph_dump_format != no_graph - && dump_file_tbl[index].graph_dump_p) - { - dump_name = concat (seq, dump_file_tbl[index].extension, NULL); - clean_graph_dump_file (dump_base_name, dump_name); - free (dump_name); - } - dump_file_tbl[index].initialized = 1; - open_arg = "w"; - } - else - open_arg = "a"; + if (dump_file != NULL || dump_file_name != NULL) + abort (); - dump_name = concat (dump_base_name, seq, - dump_file_tbl[index].extension, NULL); + dump_file_name = get_dump_file_name (index); + initializing_dump = !dump_initialized_p (index); + dump_file = dump_begin (index, NULL); - dump_file = fopen (dump_name, open_arg); if (dump_file == NULL) - fatal_error ("can't open %s: %m", dump_name); - - free (dump_name); + fatal_error ("can't open %s: %m", dump_file_name); if (decl) fprintf (dump_file, "\n;; Function %s%s\n\n", @@ -285,7 +147,7 @@ open_dump_file (enum dump_file_index index, tree decl) /* Routine to close a dump file. */ static void -close_dump_file (enum dump_file_index index, +close_dump_file (enum tree_dump_index index, void (*func) (FILE *, rtx), rtx insns) { @@ -294,25 +156,23 @@ close_dump_file (enum dump_file_index index, timevar_push (TV_DUMP); if (insns - && graph_dump_format != no_graph - && dump_file_tbl[index].graph_dump_p) + && graph_dump_format != no_graph) { - char seq[16]; - char *suffix; + /* If we've not initialized the files, do so now. */ + if (initializing_dump) + clean_graph_dump_file (dump_file_name); - sprintf (seq, DUMPFILE_FORMAT, index); - suffix = concat (seq, dump_file_tbl[index].extension, NULL); - print_rtl_graph_with_bb (dump_base_name, suffix, insns); - free (suffix); + print_rtl_graph_with_bb (dump_file_name, insns); } if (func && insns) func (dump_file, insns); - fflush (dump_file); - fclose (dump_file); + dump_end (index, dump_file); + free ((char *) dump_file_name); dump_file = NULL; + dump_file_name = NULL; timevar_pop (TV_DUMP); } @@ -603,7 +463,7 @@ rest_of_handle_new_regalloc (void) ggc_collect (); - if (dump_file_tbl[DFI_greg].enabled) + if (dump_enabled_p (DFI_greg)) { timevar_push (TV_DUMP); dump_global_regs (dump_file); @@ -657,7 +517,7 @@ rest_of_handle_old_regalloc (void) timevar_pop (TV_JUMP); } - if (dump_file_tbl[DFI_lreg].enabled) + if (dump_enabled_p (DFI_lreg)) { timevar_push (TV_DUMP); dump_flow_info (dump_file); @@ -683,7 +543,7 @@ rest_of_handle_old_regalloc (void) failure = reload (get_insns (), 0); } - if (dump_file_tbl[DFI_greg].enabled) + if (dump_enabled_p (DFI_greg)) { timevar_push (TV_DUMP); dump_global_regs (dump_file); @@ -1454,6 +1314,11 @@ rest_of_handle_jump (void) #ifdef ENABLE_CHECKING verify_flow_info (); #endif + + if (cfun->tail_call_emit) + fixup_tail_calls (); + + close_dump_file (DFI_sibling, print_rtl, get_insns ()); timevar_pop (TV_JUMP); } @@ -1713,27 +1578,8 @@ rest_of_clean_state (void) void rest_of_compilation (void) { - /* There's no need to defer outputting this function any more; we - know we want to output it. */ - DECL_DEFER_OUTPUT (current_function_decl) = 0; - - /* Now that we're done expanding trees to RTL, we shouldn't have any - more CONCATs anywhere. */ - generating_concat_p = 0; - - /* When processing delayed functions, prepare_function_start () won't - have been run to re-initialize it. */ - cse_not_expected = ! optimize; - - finalize_block_changes (); - - /* Dump the rtl code if we are dumping rtl. */ - if (open_dump_file (DFI_rtl, current_function_decl)) - close_dump_file (DFI_rtl, print_rtl, get_insns ()); - /* Convert from NOTE_INSN_EH_REGION style notes, and do other - sorts of eh initialization. Delay this until after the - initial rtl dump so that we can see the original nesting. */ + sorts of eh initialization. */ convert_from_eh_region_ranges (); /* If we're emitting a nested function, make sure its parent gets @@ -1770,9 +1616,6 @@ rest_of_compilation (void) rest_of_handle_jump (); - if (cfun->tail_call_emit) - fixup_tail_calls (); - rest_of_handle_eh (); /* Delay emitting hard_reg_initial_value sets until after EH landing pad @@ -2001,17 +1844,13 @@ rest_of_compilation (void) rest_of_clean_state (); } -void -init_optimization_passes (void) -{ - open_dump_file (DFI_cgraph, NULL); - cgraph_dump_file = dump_file; - dump_file = NULL; -} - void finish_optimization_passes (void) { + enum tree_dump_index i; + struct dump_file_info *dfi; + char *name; + timevar_push (TV_DUMP); if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) { @@ -2026,59 +1865,23 @@ finish_optimization_passes (void) close_dump_file (DFI_combine, NULL, NULL_RTX); } - dump_file = cgraph_dump_file; - cgraph_dump_file = NULL; - close_dump_file (DFI_cgraph, NULL, NULL_RTX); - /* Do whatever is necessary to finish printing the graphs. */ if (graph_dump_format != no_graph) - { - int i; - - for (i = 0; i < (int) DFI_MAX; ++i) - if (dump_file_tbl[i].initialized && dump_file_tbl[i].graph_dump_p) - { - char seq[16]; - char *suffix; - - sprintf (seq, DUMPFILE_FORMAT, i); - suffix = concat (seq, dump_file_tbl[i].extension, NULL); - finish_graph_dump_file (dump_base_name, suffix); - free (suffix); - } - } + for (i = DFI_MIN; (dfi = get_dump_file_info (i)) != NULL; ++i) + if (dump_initialized_p (i) + && (dfi->flags & TDF_RTL) != 0 + && (name = get_dump_file_name (i)) != NULL) + { + finish_graph_dump_file (name); + free (name); + } timevar_pop (TV_DUMP); } -bool -enable_rtl_dump_file (int letter) -{ - bool matched = false; - int i; - - if (letter == 'a') - { - for (i = 0; i < (int) DFI_MAX; ++i) - dump_file_tbl[i].enabled = 1; - matched = true; - } - else - { - for (i = 0; i < (int) DFI_MAX; ++i) - if (letter == dump_file_tbl[i].debug_switch) - { - dump_file_tbl[i].enabled = 1; - matched = true; - } - } - - return matched; -} - struct tree_opt_pass pass_rest_of_compilation = { - "rest of compilation", /* name */ + NULL, /* name */ NULL, /* gate */ rest_of_compilation, /* execute */ NULL, /* sub */ @@ -2089,7 +1892,8 @@ struct tree_opt_pass pass_rest_of_compilation = 0, /* properties_provided */ PROP_rtl, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_ggc_collect /* todo_flags_finish */ + TODO_ggc_collect, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/predict.c b/gcc/predict.c index d0ab77015ac..e4e077658c9 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -1471,5 +1471,6 @@ struct tree_opt_pass pass_profile = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ + TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/toplev.c b/gcc/toplev.c index 90409b97050..eb4a0c69027 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -423,6 +423,7 @@ FILE *asm_out_file; FILE *aux_info_file; FILE *dump_file = NULL; FILE *cgraph_dump_file = NULL; +char *dump_file_name; /* The current working directory of a translation. It's generally the directory from which compilation was initiated, but a preprocessed @@ -1984,7 +1985,7 @@ lang_dependent_init (const char *name) { location_t save_loc = input_location; if (dump_base_name == 0) - dump_base_name = name ? name : "gccdump"; + dump_base_name = name && name[0] ? name : "gccdump"; /* Other front-end initialization. */ #ifdef USE_MAPPED_LOCATION @@ -2003,7 +2004,6 @@ lang_dependent_init (const char *name) front end is initialized. */ init_eh (); init_optabs (); - init_optimization_passes (); /* The following initialization functions need to generate rtl, so provide a dummy function context for them. */ diff --git a/gcc/toplev.h b/gcc/toplev.h index fe588762a7d..a657036548e 100644 --- a/gcc/toplev.h +++ b/gcc/toplev.h @@ -78,7 +78,6 @@ extern void rest_of_type_compilation (tree, int); extern void rest_of_compilation (void); extern void tree_rest_of_compilation (tree, bool); extern void init_tree_optimization_passes (void); -extern void init_optimization_passes (void); extern void finish_optimization_passes (void); extern bool enable_rtl_dump_file (int); diff --git a/gcc/tree-alias-common.c b/gcc/tree-alias-common.c index eac77463c40..fa47ce6cda0 100644 --- a/gcc/tree-alias-common.c +++ b/gcc/tree-alias-common.c @@ -1052,7 +1052,8 @@ struct tree_opt_pass pass_build_pta = PROP_pta, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ + 0, /* todo_flags_finish */ + 0 /* letter */ }; @@ -1097,7 +1098,8 @@ struct tree_opt_pass pass_del_pta = 0, /* properties_provided */ PROP_pta, /* properties_destroyed */ 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ + 0, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 2be194794dc..ce0be966592 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -207,7 +207,8 @@ struct tree_opt_pass pass_build_cfg = PROP_cfg, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_verify_stmts /* todo_flags_finish */ + TODO_verify_stmts, /* todo_flags_finish */ + 0 /* letter */ }; /* Search the CFG for any computed gotos. If found, factor them to a @@ -1647,7 +1648,8 @@ struct tree_opt_pass pass_remove_useless_stmts = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; @@ -4765,7 +4767,8 @@ struct tree_opt_pass pass_split_crit_edges = PROP_no_crit_edges, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; @@ -4959,7 +4962,8 @@ struct tree_opt_pass pass_warn_function_return = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ + 0, /* todo_flags_finish */ + 0 /* letter */ }; #include "gt-tree-cfg.h" diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c index 68302e87db9..d0c6c637384 100644 --- a/gcc/tree-complex.c +++ b/gcc/tree-complex.c @@ -935,7 +935,8 @@ struct tree_opt_pass pass_lower_vector_ssa = 0, /* todo_flags_start */ TODO_dump_func | TODO_rename_vars /* todo_flags_finish */ | TODO_ggc_collect | TODO_verify_ssa - | TODO_verify_stmts | TODO_verify_flow + | TODO_verify_stmts | TODO_verify_flow, + 0 /* letter */ }; struct tree_opt_pass pass_pre_expand = @@ -952,5 +953,6 @@ struct tree_opt_pass pass_pre_expand = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_dump_func | TODO_ggc_collect - | TODO_verify_stmts /* todo_flags_finish */ + | TODO_verify_stmts, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index 8e7dec5825c..87e0ac865f6 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -135,7 +135,8 @@ struct tree_opt_pass pass_referenced_vars = PROP_referenced_vars, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ + 0, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-dump.c b/gcc/tree-dump.c index c42e33f32f7..dfe2ebbae6e 100644 --- a/gcc/tree-dump.c +++ b/gcc/tree-dump.c @@ -28,6 +28,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "diagnostic.h" #include "toplev.h" #include "tree-dump.h" +#include "tree-pass.h" #include "langhooks.h" #include "tree-iterator.h" @@ -37,7 +38,7 @@ static void dequeue_and_dump (dump_info_p); static void dump_new_line (dump_info_p); static void dump_maybe_newline (dump_info_p); static void dump_string_field (dump_info_p, const char *, const char *); -static void dump_enable_all (int); +static int dump_enable_all (int, int); /* Add T to the end of the queue of nodes to dump. Returns the index assigned to T. */ @@ -658,30 +659,61 @@ dump_node (tree t, int flags, FILE *stream) } splay_tree_delete (di.nodes); } - -/* Define a tree dump switch. */ -struct dump_file_info -{ - const char *suffix; /* suffix to give output file. */ - const char *swtch; /* command line switch */ - int flags; /* user flags */ - int state; /* state of play */ -}; + /* Table of tree dump switches. This must be consistent with the TREE_DUMP_INDEX enumeration in tree.h */ static struct dump_file_info dump_files[TDI_end] = { - {NULL, NULL, 0, 0}, - {".tu", "translation-unit", 0, 0}, - {".class", "class-hierarchy", 0, 0}, - {".original", "tree-original", 0, 0}, - {".generic", "tree-generic", 0, 0}, - {".nested", "tree-nested", 0, 0}, - {".inlined", "tree-inlined", 0, 0}, - {".vcg", "tree-vcg", 0, 0}, - {".xml", "call-graph", 0, 0}, - {NULL, "tree-all", 0, 0}, + {NULL, NULL, 0, 0, 0, 0}, + {".tu", "translation-unit", TDF_TREE, 0, 0, 0}, + {".class", "class-hierarchy", TDF_TREE, 0, 1, 0}, + {".original", "tree-original", TDF_TREE, 0, 2, 0}, + {".generic", "tree-generic", TDF_TREE, 0, 3, 0}, + {".nested", "tree-nested", TDF_TREE, 0, 4, 0}, + {".inlined", "tree-inlined", TDF_TREE, 0, 5, 0}, + {".vcg", "tree-vcg", TDF_TREE, 0, 6, 0}, + /* FIXME -fdump-call-graph is broken. Set TDF_TREE when it is fixed. */ + {".xml", "call-graph", 0, 0, 7, 0}, + {NULL, "tree-all", TDF_TREE, 0, 0, 0}, + {NULL, "rtl-all", TDF_RTL, 0, 0, 0}, + + { ".sibling", "rtl-sibling", TDF_RTL, 0, 1, 'i'}, + { ".eh", "rtl-eh", TDF_RTL, 0, 2, 'h'}, + { ".jump", "rtl-jump", TDF_RTL, 0, 3, 'j'}, + { ".cse", "rtl-cse", TDF_RTL, 0, 4, 's'}, + { ".gcse", "rtl-gcse", TDF_RTL, 0, 5, 'G'}, + { ".loop", "rtl-loop", TDF_RTL, 0, 6, 'L'}, + { ".bypass", "rtl-bypass", TDF_RTL, 0, 7, 'G'}, + { ".cfg", "rtl-cfg", TDF_RTL, 0, 8, 'f'}, + { ".bp", "rtl-bp", TDF_RTL, 0, 9, 'b'}, + { ".vpt", "rtl-vpt", TDF_RTL, 0, 10, 'V'}, + { ".ce1", "rtl-ce1", TDF_RTL, 0, 11, 'C'}, + { ".tracer", "rtl-tracer", TDF_RTL, 0, 12, 'T'}, + { ".loop2", "rtl-loop2", TDF_RTL, 0, 13, 'L'}, + { ".web", "rtl-web", TDF_RTL, 0, 14, 'Z'}, + { ".cse2", "rtl-cse2", TDF_RTL, 0, 15, 't'}, + { ".life", "rtl-life", TDF_RTL, 0, 16, 'f'}, + { ".combine", "rtl-combine", TDF_RTL, 0, 17, 'c'}, + { ".ce2", "rtl-ce2", TDF_RTL, 0, 18, 'C'}, + { ".regmove", "rtl-regmove", TDF_RTL, 0, 19, 'N'}, + { ".sms", "rtl-sms", TDF_RTL, 0, 20, 'm'}, + { ".sched", "rtl-sched", TDF_RTL, 0, 21, 'S'}, + { ".lreg", "rtl-lreg", TDF_RTL, 0, 22, 'l'}, + { ".greg", "rtl-greg", TDF_RTL, 0, 23, 'g'}, + { ".postreload", "rtl-postreload", TDF_RTL, 0, 24, 'o'}, + { ".gcse2", "rtl-gcse2", TDF_RTL, 0, 25, 'J'}, + { ".flow2", "rtl-flow2", TDF_RTL, 0, 26, 'w'}, + { ".peephole2", "rtl-peephole2", TDF_RTL, 0, 27, 'z'}, + { ".ce3", "rtl-ce3", TDF_RTL, 0, 28, 'E'}, + { ".rnreg", "rtl-rnreg", TDF_RTL, 0, 29, 'n'}, + { ".bbro", "rtl-bbro", TDF_RTL, 0, 30, 'B'}, + { ".btl", "rtl-btl", TDF_RTL, 0, 31, 'd'}, + { ".sched2", "rtl-sched2", TDF_RTL, 0, 32, 'R'}, + { ".stack", "rtl-stack", TDF_RTL, 0, 33, 'k'}, + { ".vartrack", "rtl-vartrack", TDF_RTL, 0, 34, 'V'}, + { ".mach", "rtl-mach", TDF_RTL, 0, 35, 'M'}, + { ".dbr", "rtl-dbr", TDF_RTL, 0, 36, 'd'} }; /* Dynamically registered tree dump files and switches. */ @@ -714,7 +746,8 @@ static const struct dump_option_value_info dump_options[] = }; unsigned int -dump_register (const char *suffix, const char *swtch) +dump_register (const char *suffix, const char *swtch, int flags, + unsigned int num, int letter) { size_t this = extra_dump_files_in_use++; @@ -732,24 +765,52 @@ dump_register (const char *suffix, const char *swtch) memset (&extra_dump_files[this], 0, sizeof (struct dump_file_info)); extra_dump_files[this].suffix = suffix; extra_dump_files[this].swtch = swtch; + extra_dump_files[this].flags = flags; + extra_dump_files[this].num = num; + extra_dump_files[this].letter = letter; return this + TDI_end; } + /* Return the dump_file_info for the given phase. */ -static struct dump_file_info * +struct dump_file_info * get_dump_file_info (enum tree_dump_index phase) { if (phase < TDI_end) return &dump_files[phase]; else if (phase - TDI_end >= extra_dump_files_in_use) - abort (); + return NULL; else return extra_dump_files + (phase - TDI_end); } +/* Return the name of the dump file for the given phase. + If the dump is not enabled, returns NULL. */ + +char * +get_dump_file_name (enum tree_dump_index phase) +{ + char dump_id[7]; + struct dump_file_info *dfi; + + if (phase == TDI_none) + return NULL; + + dfi = get_dump_file_info (phase); + if (dfi->state == 0) + return NULL; + + if (dfi->num < 0 + || snprintf (dump_id, sizeof (dump_id), ".%s%02d", + (dfi->flags & TDF_TREE) ? "t" : "", dfi->num) < 0) + dump_id[0] = '\0'; + + return concat (dump_base_name, dump_id, dfi->suffix, NULL); +} + /* Begin a tree dump for PHASE. Stores any user supplied flag in *FLAG_PTR and returns a stream to write to. If the dump is not enabled, returns NULL. @@ -758,22 +819,15 @@ get_dump_file_info (enum tree_dump_index phase) FILE * dump_begin (enum tree_dump_index phase, int *flag_ptr) { - FILE *stream; char *name; - char dump_id[10]; struct dump_file_info *dfi; + FILE *stream; - if (phase == TDI_none) + if (phase == TDI_none || !dump_enabled_p (phase)) return NULL; + name = get_dump_file_name (phase); dfi = get_dump_file_info (phase); - if (dfi->state == 0) - return NULL; - - if (snprintf (dump_id, sizeof (dump_id), ".t%02d", phase) < 0) - dump_id[0] = '\0'; - - name = concat (dump_base_name, dump_id, dfi->suffix, NULL); stream = fopen (name, dfi->state < 0 ? "w" : "a"); if (!stream) error ("could not open dump file `%s': %s", name, strerror (errno)); @@ -796,6 +850,15 @@ dump_enabled_p (enum tree_dump_index phase) return dfi->state; } +/* Returns nonzero if tree dump PHASE has been initialized. */ + +int +dump_initialized_p (enum tree_dump_index phase) +{ + struct dump_file_info *dfi = get_dump_file_info (phase); + return dfi->state > 0; +} + /* Returns the switch name of PHASE. */ const char * @@ -814,28 +877,33 @@ dump_end (enum tree_dump_index phase ATTRIBUTE_UNUSED, FILE *stream) fclose (stream); } -/* Enable all tree dumps. */ +/* Enable all tree dumps. Return number of enabled tree dumps. */ -static void -dump_enable_all (int flags) +static int +dump_enable_all (int flags, int letter) { + int n = 0; size_t i; for (i = TDI_none + 1; i < (size_t) TDI_end; i++) - { - dump_files[i].state = -1; - dump_files[i].flags = flags; - } + if ((dump_files[i].flags & flags) + && (letter == 0 || letter == dump_files[i].letter)) + { + dump_files[i].state = -1; + dump_files[i].flags = flags; + n++; + } for (i = 0; i < extra_dump_files_in_use; i++) - { - extra_dump_files[i].state = -1; - extra_dump_files[i].flags = flags; - } + if ((extra_dump_files[i].flags & flags) + && (letter == 0 || letter == extra_dump_files[i].letter)) + { + extra_dump_files[i].state = -1; + extra_dump_files[i].flags = flags; + n++; + } - /* FIXME -fdump-call-graph is broken. */ - dump_files[TDI_xml].state = 0; - dump_files[TDI_xml].flags = 0; + return n; } /* Parse ARG as a dump switch. Return nonzero if it is, and store the @@ -882,11 +950,12 @@ dump_switch_p_1 (const char *arg, struct dump_file_info *dfi) } dfi->state = -1; - dfi->flags = flags; + dfi->flags |= flags; - /* Process -fdump-tree-all by enabling all the known dumps. */ + /* Process -fdump-tree-all and -fdump-rtl-all, by enabling all the + known dumps. */ if (dfi->suffix == NULL) - dump_enable_all (flags); + dump_enable_all (dfi->flags, 0); return 1; } @@ -921,3 +990,14 @@ dump_function (enum tree_dump_index phase, tree fn) dump_end (phase, stream); } } + +bool +enable_rtl_dump_file (int letter) +{ + if (letter == 'a') + letter = 0; + + return dump_enable_all (TDF_RTL, letter) > 0; +} + + diff --git a/gcc/tree-dump.h b/gcc/tree-dump.h index 8a0dcabe47d..8c05f1c87c5 100644 --- a/gcc/tree-dump.h +++ b/gcc/tree-dump.h @@ -88,6 +88,6 @@ extern void queue_and_dump_type (dump_info_p, tree); extern void dump_function (enum tree_dump_index, tree); extern void dump_function_to_file (tree, FILE *, int); -extern unsigned int dump_register (const char *, const char *); +extern unsigned int dump_register (const char *, const char *, int, unsigned int, int); #endif /* ! GCC_TREE_DUMP_H */ diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 6103aa69c17..212604768a5 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -1660,7 +1660,8 @@ struct tree_opt_pass pass_lower_eh = PROP_gimple_leh, /* properties_provided */ PROP_gimple_lcf, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 86e1bb0ce8b..daca885f64a 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -1097,5 +1097,6 @@ struct tree_opt_pass pass_if_conversion = TODO_dump_func | TODO_verify_ssa | TODO_verify_stmts - | TODO_verify_flow /* todo_flags_finish */ + | TODO_verify_flow, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 5df92ff94a0..735d71fe0c4 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -1723,5 +1723,6 @@ struct tree_opt_pass pass_build_ssa = PROP_ssa, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + TODO_dump_func | TODO_verify_ssa, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c index 5ee7e1bfba1..a03ae879d28 100644 --- a/gcc/tree-mudflap.c +++ b/gcc/tree-mudflap.c @@ -1253,7 +1253,8 @@ struct tree_opt_pass pass_mudflap_1 = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; struct tree_opt_pass pass_mudflap_2 = @@ -1270,7 +1271,8 @@ struct tree_opt_pass pass_mudflap_2 = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_verify_flow | TODO_verify_stmts - | TODO_dump_func /* todo_flags_finish */ + | TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; #include "gt-tree-mudflap.h" diff --git a/gcc/tree-nomudflap.c b/gcc/tree-nomudflap.c index 1e30194f77e..e47ebaca947 100644 --- a/gcc/tree-nomudflap.c +++ b/gcc/tree-nomudflap.c @@ -98,7 +98,8 @@ struct tree_opt_pass pass_mudflap_1 = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ + 0, /* todo_flags_finish */ + 0 /* letter */ }; struct tree_opt_pass pass_mudflap_2 = @@ -114,7 +115,8 @@ struct tree_opt_pass pass_mudflap_2 = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ + 0, /* todo_flags_finish */ + 0 /* letter */ }; /* Instead of: diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c index 761bb03c94a..0df0712d19c 100644 --- a/gcc/tree-nrv.c +++ b/gcc/tree-nrv.c @@ -214,5 +214,6 @@ struct tree_opt_pass pass_nrv = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ + TODO_dump_func | TODO_ggc_collect, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c index 71b66c87e6f..701b1043087 100644 --- a/gcc/tree-optimize.c +++ b/gcc/tree-optimize.c @@ -47,6 +47,7 @@ Boston, MA 02111-1307, USA. */ #include "tree-alias-common.h" #include "ggc.h" #include "cgraph.h" +#include "graph.h" /* Global variables used to communicate with passes. */ @@ -72,7 +73,8 @@ static struct tree_opt_pass pass_gimple = PROP_gimple_any, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; /* Gate: execute, or not, all of the non-trivial optimizations. */ @@ -98,7 +100,8 @@ static struct tree_opt_pass pass_all_optimizations = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ + 0, /* todo_flags_finish */ + 0 /* letter */ }; /* Pass: cleanup the CFG just before expanding trees to RTL. @@ -127,7 +130,8 @@ static struct tree_opt_pass pass_cleanup_cfg_post_optimizing = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ + 0, /* todo_flags_finish */ + 0 /* letter */ }; /* Pass: do the actions required to finish with tree-ssa optimization @@ -170,7 +174,8 @@ static struct tree_opt_pass pass_free_datastructures = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ + 0, /* todo_flags_finish */ + 0 /* letter */ }; @@ -197,7 +202,8 @@ static struct tree_opt_pass pass_init_datastructures = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ + 0, /* todo_flags_finish */ + 0 /* letter */ }; /* Iterate over the pass tree allocating dump file numbers. We want @@ -205,14 +211,11 @@ static struct tree_opt_pass pass_init_datastructures = enabled or not. */ static void -register_one_dump_file (struct tree_opt_pass *pass) +register_one_dump_file (struct tree_opt_pass *pass, int n) { char *dot_name, *flag_name; char num[10]; - if (!pass->name) - return; - /* See below in next_pass_1. */ num[0] = '\0'; if (pass->static_pass_number != -1) @@ -220,31 +223,55 @@ register_one_dump_file (struct tree_opt_pass *pass) ? 1 : pass->static_pass_number)); dot_name = concat (".", pass->name, num, NULL); - flag_name = concat ("tree-", pass->name, num, NULL); - - pass->static_pass_number = dump_register (dot_name, flag_name); + if (pass->properties_provided & PROP_trees) + { + flag_name = concat ("tree-", pass->name, num, NULL); + pass->static_pass_number = dump_register (dot_name, flag_name, + TDF_TREE, n + TDI_tree_all, 0); + } + else + { + flag_name = concat ("rtl-", pass->name, num, NULL); + pass->static_pass_number = dump_register (dot_name, flag_name, + TDF_RTL, n, pass->letter); + } } static int register_dump_files (struct tree_opt_pass *pass, int properties) { + static int n = 0; do { - /* Verify that all required properties are present. */ - if (pass->properties_required & ~properties) - abort (); - - if (pass->properties_destroyed & pass->properties_provided) - abort (); + int new_properties; + int pass_number; pass->properties_required = properties; - pass->properties_provided = properties = + new_properties = (properties | pass->properties_provided) & ~pass->properties_destroyed; - if (properties & PROP_trees) - register_one_dump_file (pass); + /* Reset the counter when we reach RTL-based passes. */ + if ((pass->properties_provided ^ pass->properties_required) & PROP_rtl) + n = 0; + + pass_number = n; + if (pass->name) + n++; + if (pass->sub) - properties = register_dump_files (pass->sub, properties); + new_properties = register_dump_files (pass->sub, new_properties); + + /* If we have a gate, combine the properties that we could have with + and without the pass being examined. */ + if (pass->gate) + properties &= new_properties; + else + properties = new_properties; + + pass->properties_provided = properties; + if (pass->name) + register_one_dump_file (pass, pass_number); + pass = pass->next; } while (pass); @@ -386,7 +413,7 @@ static void execute_pass_list (struct tree_opt_pass *); static unsigned int last_verified; static void -execute_todo (unsigned int flags) +execute_todo (int properties, unsigned int flags) { if (flags & TODO_rename_vars) { @@ -396,8 +423,13 @@ execute_todo (unsigned int flags) if ((flags & TODO_dump_func) && dump_file) { - dump_function_to_file (current_function_decl, - dump_file, dump_flags); + if (properties & PROP_trees) + dump_function_to_file (current_function_decl, + dump_file, dump_flags); + else if (properties & PROP_cfg) + print_rtl_with_bb (dump_file, get_insns ()); + else + print_rtl (dump_file, get_insns ()); /* Flush the file. If verification fails, we won't be able to close the file before aborting. */ @@ -433,11 +465,13 @@ execute_one_pass (struct tree_opt_pass *pass) /* Run pre-pass verification. */ todo = pass->todo_flags_start & ~last_verified; if (todo) - execute_todo (todo); + execute_todo (pass->properties_required, todo); /* If a dump file name is present, open it if enabled. */ if (pass->static_pass_number != -1) { + bool initializing_dump = !dump_initialized_p (pass->static_pass_number); + dump_file_name = get_dump_file_name (pass->static_pass_number); dump_file = dump_begin (pass->static_pass_number, &dump_flags); if (dump_file) { @@ -445,8 +479,19 @@ execute_one_pass (struct tree_opt_pass *pass) dname = lang_hooks.decl_printable_name (current_function_decl, 2); aname = (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); - fprintf (dump_file, "\n;; Function %s (%s)\n\n", dname, aname); + fprintf (dump_file, "\n;; Function %s (%s)%s\n\n", dname, aname, + cfun->function_frequency == FUNCTION_FREQUENCY_HOT + ? " (hot)" + : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED + ? " (unlikely executed)" + : ""); } + + if (initializing_dump + && graph_dump_format != no_graph + && (pass->properties_provided & (PROP_cfg | PROP_rtl)) + == (PROP_cfg | PROP_rtl)) + clean_graph_dump_file (dump_file_name); } /* If a timevar is present, start it. */ @@ -457,15 +502,25 @@ execute_one_pass (struct tree_opt_pass *pass) if (pass->execute) pass->execute (); + if (dump_file + && (pass->properties_provided & (PROP_cfg | PROP_rtl)) + == (PROP_cfg | PROP_rtl)) + print_rtl_graph_with_bb (dump_file_name, get_insns ()); + /* Run post-pass cleanup and verification. */ todo = pass->todo_flags_finish; last_verified = todo & TODO_verify_all; if (todo) - execute_todo (todo); + execute_todo (pass->properties_provided, todo); /* Close down timevar and dump file. */ if (pass->tv_id) timevar_pop (pass->tv_id); + if (dump_file_name) + { + free ((char *) dump_file_name); + dump_file_name = NULL; + } if (dump_file) { dump_end (pass->static_pass_number, dump_file); diff --git a/gcc/tree-outof-ssa.c b/gcc/tree-outof-ssa.c index 0245494690a..c9403f0dd35 100644 --- a/gcc/tree-outof-ssa.c +++ b/gcc/tree-outof-ssa.c @@ -2102,5 +2102,6 @@ struct tree_opt_pass pass_del_ssa = PROP_ssa, /* properties_destroyed */ TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts, /* todo_flags_start */ - TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ + TODO_dump_func | TODO_ggc_collect, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 2f340a9c7c4..29877180b7d 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -26,9 +26,13 @@ Boston, MA 02111-1307, USA. */ /* Global variables used to communicate with passes. */ extern FILE *dump_file; extern int dump_flags; +extern const char *dump_file_name; extern struct bitmap_head_def *vars_to_rename; +/* Return the dump_file_info for the given phase. */ +extern struct dump_file_info *get_dump_file_info (enum tree_dump_index); + /* Describe one pass. */ struct tree_opt_pass { @@ -64,6 +68,20 @@ struct tree_opt_pass /* Flags indicating common sets things to do before and after. */ unsigned int todo_flags_start; unsigned int todo_flags_finish; + + /* Letter for RTL dumps. */ + char letter; +}; + +/* Define a tree dump switch. */ +struct dump_file_info +{ + const char *suffix; /* suffix to give output file. */ + const char *swtch; /* command line switch */ + int flags; /* user flags */ + int state; /* state of play */ + int num; /* dump file number */ + int letter; /* enabling letter for RTL dumps */ }; /* Pass properties. */ diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index 7f184152cb7..582a6ec1d44 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.c @@ -175,7 +175,8 @@ struct tree_opt_pass pass_tree_profile = PROP_gimple_leh | PROP_cfg, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_verify_stmts /* todo_flags_finish */ + TODO_verify_stmts, /* todo_flags_finish */ + 0 /* letter */ }; struct profile_hooks tree_profile_hooks = diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index dd5d9e500ed..c96ecfd7ce8 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -2107,5 +2107,6 @@ struct tree_opt_pass pass_sra = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_dump_func | TODO_rename_vars - | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ + | TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 3569023ad78..8b49699961c 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -359,7 +359,8 @@ struct tree_opt_pass pass_may_alias = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_dump_func | TODO_rename_vars - | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ + | TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index e3577c1da18..b1b74b1e68f 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -181,7 +181,6 @@ get_default_value (tree var) return val; } - /* Get the constant value associated with variable VAR. */ static value * @@ -1220,7 +1219,8 @@ struct tree_opt_pass pass_ccp = 0, /* todo_flags_start */ TODO_dump_func | TODO_rename_vars | TODO_ggc_collect | TODO_verify_ssa - | TODO_verify_stmts /* todo_flags_finish */ + | TODO_verify_stmts, /* todo_flags_finish */ + 0 /* letter */ }; @@ -2164,5 +2164,6 @@ struct tree_opt_pass pass_fold_builtins = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + TODO_dump_func | TODO_verify_ssa, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c index a05935f5742..db85d9c0162 100644 --- a/gcc/tree-ssa-copyrename.c +++ b/gcc/tree-ssa-copyrename.c @@ -391,6 +391,7 @@ struct tree_opt_pass pass_rename_ssa_copies = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + TODO_dump_func | TODO_verify_ssa, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index 3b08aa32de4..b1d9365a8cb 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -943,7 +943,8 @@ struct tree_opt_pass pass_dce = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ + TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */ + 0 /* letter */ }; struct tree_opt_pass pass_cd_dce = @@ -959,7 +960,8 @@ struct tree_opt_pass pass_cd_dce = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_ggc_collect | TODO_verify_ssa | TODO_verify_flow + TODO_ggc_collect | TODO_verify_ssa | TODO_verify_flow, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index 0660cc6952d..697d8d49971 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -432,7 +432,8 @@ struct tree_opt_pass pass_dominator = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_dump_func | TODO_rename_vars - | TODO_verify_ssa /* todo_flags_finish */ + | TODO_verify_ssa, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index 26aae0cb143..558d50d75c7 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -443,5 +443,6 @@ struct tree_opt_pass pass_dse = { 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ - | TODO_verify_ssa + | TODO_verify_ssa, + 0 /* letter */ }; diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 2cb3b9bd20b..9343ec2f50a 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -523,5 +523,6 @@ struct tree_opt_pass pass_forwprop = { 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ - | TODO_verify_ssa + | TODO_verify_ssa, + 0 /* letter */ }; diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c index f10ec75e1cc..f815c3c938e 100644 --- a/gcc/tree-ssa-loop-ch.c +++ b/gcc/tree-ssa-loop-ch.c @@ -284,5 +284,6 @@ struct tree_opt_pass pass_ch = 0, /* properties_destroyed */ 0, /* todo_flags_start */ (TODO_dump_func - | TODO_verify_ssa) /* todo_flags_finish */ + | TODO_verify_ssa), /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c index 55cce5548e6..01dc7675159 100644 --- a/gcc/tree-ssa-loop.c +++ b/gcc/tree-ssa-loop.c @@ -89,7 +89,8 @@ struct tree_opt_pass pass_loop = 0, /* properties_provided */ 0, /* properties_destroyed */ TODO_ggc_collect, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa | TODO_ggc_collect /* todo_flags_finish */ + TODO_dump_func | TODO_verify_ssa | TODO_ggc_collect, /* todo_flags_finish */ + 0 /* letter */ }; /* Loop optimizer initialization. */ @@ -120,7 +121,8 @@ struct tree_opt_pass pass_loop_init = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; /* Loop invariant motion pass. */ @@ -153,7 +155,8 @@ struct tree_opt_pass pass_lim = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; /* Loop autovectorization. */ @@ -187,7 +190,8 @@ struct tree_opt_pass pass_vectorize = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; /* Canonical induction variable creation pass. */ @@ -220,7 +224,8 @@ struct tree_opt_pass pass_iv_canon = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; /* Complete unrolling of loops. */ @@ -253,7 +258,8 @@ struct tree_opt_pass pass_complete_unroll = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; /* Induction variable optimizations. */ @@ -286,7 +292,8 @@ struct tree_opt_pass pass_iv_optimize = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; /* Loop optimizer finalization. */ @@ -322,6 +329,7 @@ struct tree_opt_pass pass_loop_done = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 220c391598e..bbdccf43777 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -674,7 +674,8 @@ struct tree_opt_pass pass_phiopt = 0, /* todo_flags_start */ TODO_dump_func | TODO_ggc_collect /* todo_flags_finish */ | TODO_verify_ssa | TODO_rename_vars - | TODO_verify_flow + | TODO_verify_flow, + 0 /* letter */ }; diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 2bdf8853ca5..870a0300757 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -2087,7 +2087,8 @@ struct tree_opt_pass pass_pre = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ + TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */ + 0 /* letter */ }; @@ -2118,5 +2119,6 @@ struct tree_opt_pass pass_fre = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ + TODO_dump_func | TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index f6037c2b5f9..2f077856538 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1164,7 +1164,8 @@ struct tree_opt_pass pass_redundant_phi = 0, /* properties_destroyed */ 0, /* todo_flags_start */ TODO_dump_func | TODO_rename_vars - | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */ + | TODO_ggc_collect | TODO_verify_ssa, /* todo_flags_finish */ + 0 /* letter */ }; /* Emit warnings for uninitialized variables. This is done in two passes. @@ -1304,7 +1305,8 @@ struct tree_opt_pass pass_early_warn_uninitialized = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ + 0, /* todo_flags_finish */ + 0 /* letter */ }; struct tree_opt_pass pass_late_warn_uninitialized = @@ -1320,5 +1322,6 @@ struct tree_opt_pass pass_late_warn_uninitialized = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - 0 /* todo_flags_finish */ + 0, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index 8c1aabcabb5..21582848a34 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -952,7 +952,8 @@ struct tree_opt_pass pass_tail_recursion = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + TODO_dump_func | TODO_verify_ssa, /* todo_flags_finish */ + 0 /* letter */ }; struct tree_opt_pass pass_tail_calls = @@ -968,5 +969,6 @@ struct tree_opt_pass pass_tail_calls = 0, /* properties_provided */ 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_dump_func | TODO_verify_ssa /* todo_flags_finish */ + TODO_dump_func | TODO_verify_ssa, /* todo_flags_finish */ + 0 /* letter */ }; diff --git a/gcc/tree.h b/gcc/tree.h index c078fdb55c7..7d6d87c0dee 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -3714,12 +3714,52 @@ enum tree_dump_index TDI_vcg, /* create a VCG graph file for each function's flowgraph. */ TDI_xml, /* dump function call graph. */ - TDI_all, /* enable all the dumps. */ + TDI_tree_all, /* enable all the GENERIC/GIMPLE dumps. */ + TDI_rtl_all, /* enable all the RTL dumps. */ + + DFI_MIN, /* For now, RTL dumps are placed here. */ + DFI_sibling = DFI_MIN, + DFI_eh, + DFI_jump, + DFI_cse, + DFI_gcse, + DFI_loop, + DFI_bypass, + DFI_cfg, + DFI_bp, + DFI_vpt, + DFI_ce1, + DFI_tracer, + DFI_loop2, + DFI_web, + DFI_cse2, + DFI_life, + DFI_combine, + DFI_ce2, + DFI_regmove, + DFI_sms, + DFI_sched, + DFI_lreg, + DFI_greg, + DFI_postreload, + DFI_gcse2, + DFI_flow2, + DFI_peephole2, + DFI_ce3, + DFI_rnreg, + DFI_bbro, + DFI_branch_target_load, + DFI_sched2, + DFI_stack, + DFI_vartrack, + DFI_mach, + DFI_dbr, + TDI_end }; -/* Bit masks to control tree dumping. Not all values are applicable to - all tree dumps. Add new ones at the end. When you define new +/* Bit masks to control dumping. Not all values are applicable to + all dumps. Add new ones at the end. When you define new values, extend the DUMP_OPTIONS array in tree-dump.c */ #define TDF_ADDRESS (1 << 0) /* dump node addresses */ #define TDF_SLIM (1 << 1) /* don't go wild following links */ @@ -3733,11 +3773,15 @@ enum tree_dump_index #define TDF_LINENO (1 << 7) /* display statement line numbers */ #define TDF_UID (1 << 8) /* display decl UIDs */ +#define TDF_TREE (1 << 9) /* is a tree dump */ +#define TDF_RTL (1 << 10) /* is a RTL dump */ typedef struct dump_info *dump_info_p; +extern char *get_dump_file_name (enum tree_dump_index); extern int dump_flag (dump_info_p, int, tree); extern int dump_enabled_p (enum tree_dump_index); +extern int dump_initialized_p (enum tree_dump_index); extern FILE *dump_begin (enum tree_dump_index, int *); extern void dump_end (enum tree_dump_index, FILE *); extern void dump_node (tree, int, FILE *); -- 2.30.2