From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 4691 invoked by alias); 23 Jun 2005 12:40:42 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 3856 invoked by uid 22791); 23 Jun 2005 12:38:39 -0000 Received: from campus9.usilu.net (HELO campus9.usilu.net) (195.176.178.26) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Thu, 23 Jun 2005 12:38:39 +0000 Received: from [192.168.64.194] ([192.168.64.194] RDNS failed) by campus9.usilu.net with Microsoft SMTPSVC(5.0.2195.5329); Thu, 23 Jun 2005 14:35:44 +0200 Message-ID: <42BAAD4B.30704@lu.unisi.ch> Date: Thu, 23 Jun 2005 12:40:00 -0000 From: Paolo Bonzini User-Agent: Mozilla Thunderbird 0.9 (Macintosh/20041103) MIME-Version: 1.0 To: gcc-patches@gcc.gnu.org CC: Richard Henderson , Jan Hubicka Subject: Update RTL passes patch [was Re: Patch ping...] References: <20050620193733.GA29626@atrey.karlin.mff.cuni.cz> <20050620224212.GA23484@redhat.com> In-Reply-To: <20050620224212.GA23484@redhat.com> Content-Type: multipart/mixed; boundary="------------040206050304050704060205" X-SW-Source: 2005-06/txt/msg01793.txt.bz2 This is a multi-part message in MIME format. --------------040206050304050704060205 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 453 Richard Henderson wrote: > On Mon, Jun 20, 2005 at 09:37:33PM +0200, Jan Hubicka wrote: > >>fix to the -fdump-rtl-expand: >>http://gcc.gnu.org/ml/gcc-patches/2005-05/msg02126.html > > Ok. With this patch in, I can update the patch for using the pass manager in RTL passes, so that the code I move from tree-optimize.c to passes.c is exactly verbatim. Bootstrapped i686-pc-linux-gnu on top of Honza's patch, all languages, ok for mainline? Paolo --------------040206050304050704060205 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0"; name="rtl-passes-other-things.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="rtl-passes-other-things.patch" Content-length: 17895 2005-05-19 Paolo Bonzini * Makefile.in: Adjust dependencies for tree-pretty-print.c, cgraph.c, opts.c. * passes.c (finish_optimization_passes): Use dump_begin and dump_end, TDI_end. (gate_rest_of_compilation): New. (pass_rest_of_compilation): Use it. (gate_postreload, pass_postreload): New. * toplev.c (general_init): Rename init_tree_optimization_passes. * toplev.h (init_tree_optimization_passes): Rename to init_optimizations_passes. * tree-dump.c (dump_flag): Make static. (dump_files): Remove RTL dumps. * tree-optimize.c (pass_all_optimizations, pass_cleanup_cfg_post_optimizing, pass_free_datastructures, pass_init_datastructures, pass_fixup_cfg): Make non-static. * tree-pretty-print.c: Include tree-pass.h. * cgraph.c: Include tree-dump.h. cp: 2005-05-19 Paolo Bonzini * Makefile.in (class.o, decl2.o): Adjust dependencies. * class.c: Include tree-dump.h. * decl2.c: Include tree-dump.h. java: 2005-05-19 Paolo Bonzini * Makefile.in (parse.o): Adjust dependencies. * parse.y: Include tree-dump.h. Index: passes.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/passes.c,v retrieving revision 2.90 diff -p -u -r2.90 passes.c --- passes.c 27 Apr 2005 21:35:20 -0000 2.90 +++ passes.c 18 May 2005 10:29:55 -0000 @@ -209,20 +213,25 @@ timevar_push (TV_DUMP); if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) { - open_dump_file (DFI_bp, NULL); + dump_file = dump_begin (pass_branch_prob.static_pass_number, NULL); end_branch_prob (); - close_dump_file (DFI_bp, NULL, NULL_RTX); + if (dump_file) + dump_end (pass_branch_prob.static_pass_number, dump_file); } - if (optimize > 0 && open_dump_file (DFI_combine, NULL)) + if (optimize > 0) { - dump_combine_total_stats (dump_file); - close_dump_file (DFI_combine, NULL, NULL_RTX); + dump_file = dump_begin (pass_combine.static_pass_number, NULL); + if (dump_file) + { + dump_combine_total_stats (dump_file); + dump_end (pass_combine.static_pass_number, dump_file); + } } /* Do whatever is necessary to finish printing the graphs. */ if (graph_dump_format != no_graph) - for (i = DFI_MIN; (dfi = get_dump_file_info (i)) != NULL; ++i) + for (i = TDI_end; (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) @@ -234,23 +243,53 @@ timevar_pop (TV_DUMP); } +static bool +gate_rest_of_compilation (void) +{ + /* Early return if there were errors. We can run afoul of our + consistency checks, and there's not really much point in fixing them. */ + return !(rtl_dump_and_exit || flag_syntax_only || errorcount || sorrycount); +} + struct tree_opt_pass pass_rest_of_compilation = { - NULL, /* name */ - NULL, /* gate */ - rest_of_compilation, /* execute */ + NULL, /* name */ + gate_rest_of_compilation, /* gate */ + NULL, /* execute */ NULL, /* sub */ NULL, /* next */ 0, /* static_pass_number */ TV_REST_OF_COMPILATION, /* tv_id */ - PROP_rtl, /* properties_required */ + PROP_rtl, /* properties_required */ 0, /* properties_provided */ - PROP_rtl, /* properties_destroyed */ + 0, /* properties_destroyed */ 0, /* todo_flags_start */ - TODO_ggc_collect, /* todo_flags_finish */ - 0 /* letter */ + TODO_ggc_collect, /* todo_flags_finish */ + 0 /* letter */ }; +static bool +gate_postreload (void) +{ + return reload_completed; +} + +struct tree_opt_pass pass_postreload = +{ + NULL, /* name */ + gate_postreload, /* gate */ + NULL, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + PROP_rtl, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_ggc_collect, /* todo_flags_finish */ + 0 /* letter */ +}; /* The root of the compilation pass tree, once constructed. */ Index: toplev.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/toplev.c,v retrieving revision 1.954 diff -p -u -r1.954 toplev.c --- toplev.c 3 May 2005 17:55:38 -0000 1.954 +++ toplev.c 18 May 2005 10:30:36 -0000 @@ -1668,7 +1668,7 @@ general_init (const char *argv0) /* This must be done after add_params but before argument processing. */ init_ggc_heuristics(); - init_tree_optimization_passes (); + init_optimization_passes (); } /* Process the options that have been parsed. */ Index: toplev.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/toplev.h,v retrieving revision 1.134 diff -p -u -r1.134 toplev.h --- toplev.h 23 Apr 2005 21:27:56 -0000 1.134 +++ toplev.h 18 May 2005 10:30:36 -0000 @@ -77,7 +77,7 @@ extern void inform (const char *, ...) A extern void rest_of_decl_compilation (tree, int, int); extern void rest_of_type_compilation (tree, int); extern void tree_rest_of_compilation (tree); -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); Index: tree-dump.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-dump.c,v retrieving revision 1.42 diff -p -u -r1.42 tree-dump.c --- tree-dump.c 13 May 2005 13:56:53 -0000 1.42 +++ tree-dump.c 18 May 2005 10:30:38 -0000 @@ -681,43 +683,6 @@ static struct dump_file_info dump_files[ {NULL, "ipa-all", NULL, TDF_IPA, 0, 0, 0}, { ".cgraph", "ipa-cgraph", NULL, TDF_IPA, 0, 1, 0}, - - { ".sibling", "rtl-sibling", NULL, TDF_RTL, 0, 1, 'i'}, - { ".eh", "rtl-eh", NULL, TDF_RTL, 0, 2, 'h'}, - { ".jump", "rtl-jump", NULL, TDF_RTL, 0, 3, 'j'}, - { ".cse", "rtl-cse", NULL, TDF_RTL, 0, 4, 's'}, - { ".gcse", "rtl-gcse", NULL, TDF_RTL, 0, 5, 'G'}, - { ".loop", "rtl-loop", NULL, TDF_RTL, 0, 6, 'L'}, - { ".bypass", "rtl-bypass", NULL, TDF_RTL, 0, 7, 'G'}, - { ".cfg", "rtl-cfg", NULL, TDF_RTL, 0, 8, 'f'}, - { ".bp", "rtl-bp", NULL, TDF_RTL, 0, 9, 'b'}, - { ".vpt", "rtl-vpt", NULL, TDF_RTL, 0, 10, 'V'}, - { ".ce1", "rtl-ce1", NULL, TDF_RTL, 0, 11, 'C'}, - { ".tracer", "rtl-tracer", NULL, TDF_RTL, 0, 12, 'T'}, - { ".loop2", "rtl-loop2", NULL, TDF_RTL, 0, 13, 'L'}, - { ".web", "rtl-web", NULL, TDF_RTL, 0, 14, 'Z'}, - { ".cse2", "rtl-cse2", NULL, TDF_RTL, 0, 15, 't'}, - { ".life", "rtl-life", NULL, TDF_RTL, 0, 16, 'f'}, - { ".combine", "rtl-combine", NULL, TDF_RTL, 0, 17, 'c'}, - { ".ce2", "rtl-ce2", NULL, TDF_RTL, 0, 18, 'C'}, - { ".regmove", "rtl-regmove", NULL, TDF_RTL, 0, 19, 'N'}, - { ".sms", "rtl-sms", NULL, TDF_RTL, 0, 20, 'm'}, - { ".sched", "rtl-sched", NULL, TDF_RTL, 0, 21, 'S'}, - { ".lreg", "rtl-lreg", NULL, TDF_RTL, 0, 22, 'l'}, - { ".greg", "rtl-greg", NULL, TDF_RTL, 0, 23, 'g'}, - { ".postreload", "rtl-postreload", NULL, TDF_RTL, 0, 24, 'o'}, - { ".gcse2", "rtl-gcse2", NULL, TDF_RTL, 0, 25, 'J'}, - { ".flow2", "rtl-flow2", NULL, TDF_RTL, 0, 26, 'w'}, - { ".peephole2", "rtl-peephole2", NULL, TDF_RTL, 0, 27, 'z'}, - { ".ce3", "rtl-ce3", NULL, TDF_RTL, 0, 28, 'E'}, - { ".rnreg", "rtl-rnreg", NULL, TDF_RTL, 0, 29, 'n'}, - { ".bbro", "rtl-bbro", NULL, TDF_RTL, 0, 30, 'B'}, - { ".btl", "rtl-btl", NULL, TDF_RTL, 0, 31, 'd'}, - { ".sched2", "rtl-sched2", NULL, TDF_RTL, 0, 32, 'R'}, - { ".stack", "rtl-stack", NULL, TDF_RTL, 0, 33, 'k'}, - { ".vartrack", "rtl-vartrack", NULL, TDF_RTL, 0, 34, 'V'}, - { ".mach", "rtl-mach", NULL, TDF_RTL, 0, 35, 'M'}, - { ".dbr", "rtl-dbr", NULL, TDF_RTL, 0, 36, 'd'} }; /* Dynamically registered tree dump files and switches. */ Index: tree-optimize.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v retrieving revision 2.98 diff -p -u -r2.98 tree-optimize.c --- tree-optimize.c 17 May 2005 20:28:22 -0000 2.98 +++ tree-optimize.c 18 May 2005 10:30:39 -0000 @@ -68,7 +68,7 @@ gate_all_optimizations (void) && !(errorcount || sorrycount)); } -static struct tree_opt_pass pass_all_optimizations = +struct tree_opt_pass pass_all_optimizations = { NULL, /* name */ gate_all_optimizations, /* gate */ @@ -98,7 +98,7 @@ execute_cleanup_cfg_post_optimizing (voi group_case_labels (); } -static struct tree_opt_pass pass_cleanup_cfg_post_optimizing = +struct tree_opt_pass pass_cleanup_cfg_post_optimizing = { "final_cleanup", /* name */ NULL, /* gate */ @@ -142,7 +142,7 @@ execute_free_datastructures (void) delete_tree_cfg_annotations (); } -static struct tree_opt_pass pass_free_datastructures = +struct tree_opt_pass pass_free_datastructures = { NULL, /* name */ NULL, /* gate */ @@ -181,7 +181,7 @@ execute_fixup_cfg (void) cleanup_tree_cfg (); } -static struct tree_opt_pass pass_fixup_cfg = +struct tree_opt_pass pass_fixup_cfg = { NULL, /* name */ NULL, /* gate */ @@ -215,7 +215,7 @@ execute_init_datastructures (void) init_tree_ssa (); } -static struct tree_opt_pass pass_init_datastructures = +struct tree_opt_pass pass_init_datastructures = { NULL, /* name */ NULL, /* gate */ Index: cgraph.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cgraph.c,v retrieving revision 1.71 --- cgraph.c 27 Apr 2005 08:35:49 -0000 1.71 +++ cgraph.c 19 May 2005 18:46:47 -0000 @@ -97,6 +97,7 @@ #include "output.h" #include "intl.h" #include "tree-gimple.h" +#include "tree-dump.h" static void cgraph_node_remove_callers (struct cgraph_node *node); static inline void cgraph_edge_remove_caller (struct cgraph_edge *e); Index: tree-pretty-print.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-pretty-print.c,v retrieving revision 2.58 diff -p -u -r2.58 tree-pretty-print.c --- tree-pretty-print.c 04 May 2005 17:35:19 -0000 2.58 +++ tree-pretty-print.c 19 May 2005 18:29:11 -0000 @@ -32,6 +32,7 @@ #include "langhooks.h" #include "tree-iterator.h" #include "tree-chrec.h" +#include "tree-pass.h" /* Local functions, macros and variables. */ static int op_prio (tree); Index: opts.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/opts.c,v retrieving revision 1.113 diff -p -u -r1.113 opts.c --- opts.c 1 Jun 2005 07:02:17 -0000 1.113 +++ opts.c 7 Jun 2005 09:28:52 -0000 @@ -38,6 +38,7 @@ Software Foundation, 59 Temple Place - S #include "tm_p.h" /* For OPTIMIZATION_OPTIONS. */ #include "insn-attr.h" /* For INSN_SCHEDULING. */ #include "target.h" +#include "tree-pass.h" /* Value of the -G xx switch, and whether it was passed or not. */ unsigned HOST_WIDE_INT g_switch_value; Index: Makefile.in =================================================================== RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v retrieving revision 1.1486 diff -p -u -u -r1.1486 Makefile.in --- Makefile.in 17 May 2005 09:55:08 -0000 1.1486 +++ Makefile.in 18 May 2005 12:37:43 -0000 @@ -1908,7 +1908,7 @@ $(GGC_H) gt-tree-mudflap.h tree-pass.h toplev.h tree-pretty-print.o : tree-pretty-print.c $(CONFIG_H) $(SYSTEM_H) \ $(TREE_H) $(DIAGNOSTIC_H) real.h $(HASHTAB_H) $(TREE_FLOW_H) \ - $(TM_H) coretypes.h tree-iterator.h tree-chrec.h langhooks.h + $(TM_H) coretypes.h tree-iterator.h tree-chrec.h langhooks.h tree-pass.h fold-const.o : fold-const.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) $(FLAGS_H) real.h toplev.h $(HASHTAB_H) $(EXPR_H) $(RTL_H) \ $(GGC_H) $(TM_P_H) langhooks.h $(MD5_H) @@ -1923,7 +1923,7 @@ diagnostic.o : diagnostic.c $(CONFIG_H) opts.o : opts.c opts.h options.h toplev.h $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TREE_H) $(TM_H) langhooks.h $(GGC_H) $(RTL_H) \ output.h $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \ - $(FLAGS_H) $(PARAMS_H) + $(FLAGS_H) $(PARAMS_H) tree-pass.h targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ $(EXPR_H) $(TM_H) $(RTL_H) $(TM_P_H) function.h output.h toplev.h \ $(MACHMODE_H) $(TARGET_DEF_H) $(TARGET_H) @@ -1944,7 +1944,7 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM $(PARAMS_H) $(TM_P_H) reload.h dwarf2asm.h $(TARGET_H) \ langhooks.h insn-flags.h $(CFGLAYOUT_H) real.h $(CFGLOOP_H) \ hosthooks.h $(CGRAPH_H) $(COVERAGE_H) tree-pass.h $(TREE_DUMP_H) \ - $(GGC_H) $(INTEGRATE_H) $(CPPLIB_H) opts.h + $(GGC_H) $(INTEGRATE_H) $(CPPLIB_H) opts.h tree-flow.h tree-inline.h main.o : main.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h @@ -2067,7 +2068,7 @@ simplify-rtx.o : simplify-rtx.c $(CONFIG cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ langhooks.h toplev.h $(FLAGS_H) $(GGC_H) $(TARGET_H) $(CGRAPH_H) \ gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \ - tree-inline.h $(VARRAY_H) + tree-inline.h $(VARRAY_H) tree-dump.h cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TREE_H) langhooks.h tree-inline.h toplev.h $(FLAGS_H) $(GGC_H) \ $(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h function.h $(TREE_GIMPLE_H) \ Index: cp/Make-lang.in =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/Make-lang.in,v retrieving revision 1.204 diff -p -u -r1.204 Make-lang.in --- cp/Make-lang.in 2 Jun 2005 17:52:07 -0000 1.204 +++ cp/Make-lang.in 7 Jun 2005 10:06:25 -0000 @@ -243,7 +243,7 @@ cp/decl.o: cp/decl.c $(CXX_TREE_H) $(TM_ debug.h gt-cp-decl.h timevar.h $(TREE_FLOW_H) cp/decl2.o: cp/decl2.c $(CXX_TREE_H) $(TM_H) flags.h cp/decl.h $(EXPR_H) \ output.h except.h toplev.h $(RTL_H) c-common.h gt-cp-decl2.h cgraph.h \ - c-pragma.h + c-pragma.h $(TREE_DUMP_H) cp/cp-objcp-common.o : cp/cp-objcp-common.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) $(TREE_H) $(CXX_TREE_H) c-common.h toplev.h langhooks.h \ $(LANGHOOKS_DEF_H) $(DIAGNOSTIC_H) debug.h $(CXX_PRETTY_PRINT_H) \ @@ -253,7 +253,7 @@ cp/typeck2.o: cp/typeck2.c $(CXX_TREE_H) cp/typeck.o: cp/typeck.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) $(EXPR_H) \ toplev.h diagnostic.h convert.h c-common.h cp/class.o: cp/class.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) \ - $(TARGET_H) convert.h $(CGRAPH_H) + $(TARGET_H) convert.h $(CGRAPH_H) $(TREE_DUMP_H) cp/call.o: cp/call.c $(CXX_TREE_H) $(TM_H) flags.h toplev.h $(RTL_H) \ $(EXPR_H) diagnostic.h intl.h gt-cp-call.h convert.h target.h cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) flags.h $(RTL_H) toplev.h \ Index: cp/class.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v retrieving revision 1.719 diff -p -u -r1.719 class.c --- cp/class.c 6 Jun 2005 14:18:04 -0000 1.719 +++ cp/class.c 7 Jun 2005 10:06:25 -0000 @@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA. */ #include "target.h" #include "convert.h" #include "cgraph.h" +#include "tree-dump.h" /* The number of nested classes being processed. If we are not in the scope of any class, this is zero. */ Index: cp/decl2.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v retrieving revision 1.785 diff -p -u -r1.785 decl2.c --- cp/decl2.c 6 Jun 2005 14:18:06 -0000 1.785 +++ cp/decl2.c 7 Jun 2005 10:06:26 -0000 @@ -49,6 +49,7 @@ Boston, MA 02111-1307, USA. */ #include "cgraph.h" #include "tree-inline.h" #include "c-pragma.h" +#include "tree-dump.h" extern cpp_reader *parse_in; Index: java/Make-lang.in =================================================================== RCS file: /cvs/gcc/gcc/gcc/java/Make-lang.in,v retrieving revision 1.160 diff -p -u -r1.160 Make-lang.in --- java/Make-lang.in 1 Jun 2005 02:51:16 -0000 1.160 +++ java/Make-lang.in 7 Jun 2005 10:39:56 -0000 @@ -365,7 +365,8 @@ java/parse-scan.o: java/parse-scan.c $(C coretypes.h $(TM_H) toplev.h $(JAVA_LEX_C) java/parse.h java/lex.h input.h java/parse.o: java/parse.c java/jcf-reader.c $(CONFIG_H) $(SYSTEM_H) \ coretypes.h $(TM_H) function.h $(JAVA_TREE_H) $(JAVA_LEX_C) java/parse.h \ - java/lex.h input.h $(GGC_H) debug.h gt-java-parse.h gtype-java.h target.h + java/lex.h input.h $(GGC_H) debug.h gt-java-parse.h gtype-java.h target.h \ + $(TREE_DUMP_H) # jcf-io.o needs $(ZLIBINC) added to cflags. java/jcf-io.o: java/jcf-io.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ Index: java/parse.y =================================================================== RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v retrieving revision 1.537 diff -p -u -r1.537 parse.y --- java/parse.y 6 Jun 2005 19:31:35 -0000 1.537 +++ java/parse.y 7 Jun 2005 10:40:20 -0000 @@ -72,6 +72,7 @@ definitions and other extensions. */ #include "ggc.h" #include "debug.h" #include "tree-inline.h" +#include "tree-dump.h" #include "cgraph.h" #include "target.h" --------------040206050304050704060205 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0"; name="rtl-passes-move-stuff.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="rtl-passes-move-stuff.patch" Content-length: 42170 2005-05-19 Paolo Bonzini * cgraphunit.c (ipa_passes): Moved from tree-optimize.c. * passes.c (dump_flags, in_gimple_form, all_passes, all_ipa_passes, all_lowering_passes, register_one_dump_file, register_dump_files, next_pass_1, last_verified, execute_todo, execute_one_pass, execute_pass_list, execute_ipa_pass_list): Moved from tree-optimize.c. (init_optimization_passes): Moved from tree-optimize.c, adding the RTL optimizations. * tree-dump.h (dump_info_p, dump_flag): Moved from tree.h. * tree-optimize.c (dump_flags, in_gimple_form, all_passes, all_ipa_passes, all_lowering_passes, register_one_dump_file, register_dump_files, next_pass_1, last_verified, execute_todo, execute_one_pass, execute_pass_list, execute_ipa_pass_list, init_tree_optimization_passes, ipa_passes): Delete. * tree-pass.h (enum tree_dump_index): Moved from tree.h, removing the RTL dumps. (TDF_*, get_dump_file_name, dump_enabled_p, dump_initialized_p, dump_begin, dump_end, dump_node, dump_switch_p, dump_flag_name): Moved from tree.h. (ipa_passes): Remove. (all_passes, all_ipa_passes, all_lowering_passes): Now extern. * tree.h (enum tree_dump_index, TDF_*, get_dump_file_name, dump_enabled_p, dump_initialized_p, dump_begin, dump_end, dump_node, dump_switch_p, dump_flag_name): Moved to tree-pass.h. (dump_info_p, dump_flag): Moved to tree-dump.h. Index: cgraphunit.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v retrieving revision 1.107 diff -p -u -r1.107 cgraphunit.c --- cgraphunit.c 20 May 2005 08:05:07 -0000 1.107 +++ cgraphunit.c 25 May 2005 16:31:09 -0000 @@ -1089,6 +1089,16 @@ cgraph_preserve_function_body_p (tree de return false; } +static void +ipa_passes (void) +{ + cfun = NULL; + tree_register_cfg_hooks (); + bitmap_obstack_initialize (NULL); + execute_ipa_pass_list (all_ipa_passes); + bitmap_obstack_release (NULL); +} + /* Perform simple optimizations based on callgraph. */ void Index: passes.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/passes.c,v retrieving revision 2.90 diff -p -u -r2.90 passes.c --- passes.c 27 Apr 2005 21:35:20 -0000 2.90 +++ passes.c 18 May 2005 10:29:55 -0000 @@ -78,6 +78,8 @@ #include "opts.h" #include "coverage.h" #include "value-prof.h" +#include "tree-inline.h" +#include "tree-flow.h" #include "tree-pass.h" #include "tree-dump.h" @@ -98,6 +99,9 @@ declarations for e.g. AIX 4.x. */ #endif +/* Global variables used to communicate with passes. */ +int dump_flags; +bool in_gimple_form; /* This is called from various places for FUNCTION_DECL, VAR_DECL, @@ -254,3 +290,539 @@ 0 /* letter */ }; + + +/* The root of the compilation pass tree, once constructed. */ +struct tree_opt_pass *all_passes, *all_ipa_passes, *all_lowering_passes; + +/* Iterate over the pass tree allocating dump file numbers. We want + to do this depth first, and independent of whether the pass is + enabled or not. */ + +static void +register_one_dump_file (struct tree_opt_pass *pass, bool ipa, int n) +{ + char *dot_name, *flag_name, *glob_name; + char num[10]; + + /* See below in next_pass_1. */ + num[0] = '\0'; + if (pass->static_pass_number != -1) + sprintf (num, "%d", ((int) pass->static_pass_number < 0 + ? 1 : pass->static_pass_number)); + + dot_name = concat (".", pass->name, num, NULL); + if (ipa) + { + flag_name = concat ("ipa-", pass->name, num, NULL); + glob_name = concat ("ipa-", pass->name, NULL); + /* First IPA dump is cgraph that is dumped via separate channels. */ + pass->static_pass_number = dump_register (dot_name, flag_name, glob_name, + TDF_IPA, n + 1, 0); + } + else if (pass->properties_provided & PROP_trees) + { + flag_name = concat ("tree-", pass->name, num, NULL); + glob_name = concat ("tree-", pass->name, NULL); + pass->static_pass_number = dump_register (dot_name, flag_name, glob_name, + TDF_TREE, n + TDI_tree_all, 0); + } + else + { + flag_name = concat ("rtl-", pass->name, num, NULL); + glob_name = concat ("rtl-", pass->name, NULL); + pass->static_pass_number = dump_register (dot_name, flag_name, glob_name, + TDF_RTL, n, pass->letter); + } +} + +static int +register_dump_files (struct tree_opt_pass *pass, bool ipa, int properties) +{ + static int n = 0; + do + { + int new_properties; + int pass_number; + + pass->properties_required = properties; + new_properties = + (properties | pass->properties_provided) & ~pass->properties_destroyed; + + /* Reset the counter when we reach RTL-based passes. */ + if ((new_properties ^ pass->properties_required) & PROP_rtl) + n = 0; + + pass_number = n; + if (pass->name) + n++; + + if (pass->sub) + new_properties = register_dump_files (pass->sub, ipa, 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, ipa, pass_number); + + pass = pass->next; + } + while (pass); + + return properties; +} + +/* Add a pass to the pass list. Duplicate the pass if it's already + in the list. */ + +static struct tree_opt_pass ** +next_pass_1 (struct tree_opt_pass **list, struct tree_opt_pass *pass) +{ + + /* A nonzero static_pass_number indicates that the + pass is already in the list. */ + if (pass->static_pass_number) + { + struct tree_opt_pass *new; + + new = xmalloc (sizeof (*new)); + memcpy (new, pass, sizeof (*new)); + + /* Indicate to register_dump_files that this pass has duplicates, + and so it should rename the dump file. The first instance will + be -1, and be number of duplicates = -static_pass_number - 1. + Subsequent instances will be > 0 and just the duplicate number. */ + if (pass->name) + { + pass->static_pass_number -= 1; + new->static_pass_number = -pass->static_pass_number; + } + + *list = new; + } + else + { + pass->static_pass_number = -1; + *list = pass; + } + + return &(*list)->next; + +} + +/* Construct the pass tree. */ + +void +init_optimization_passes (void) +{ + struct tree_opt_pass **p; + +#define NEXT_PASS(PASS) (p = next_pass_1 (p, &PASS)) + /* Intraprocedural optimization passes. */ + p = &all_ipa_passes; + NEXT_PASS (pass_ipa_inline); + *p = NULL; + + /* All passes needed to lower the function into shape optimizers can operate + on. These passes are performed before interprocedural passes, unlike rest + of local passes (all_passes). */ + p = &all_lowering_passes; + NEXT_PASS (pass_remove_useless_stmts); + NEXT_PASS (pass_mudflap_1); + NEXT_PASS (pass_lower_cf); + NEXT_PASS (pass_lower_eh); + NEXT_PASS (pass_build_cfg); + NEXT_PASS (pass_lower_complex_O0); + NEXT_PASS (pass_lower_vector); + NEXT_PASS (pass_warn_function_return); + NEXT_PASS (pass_tree_profile); + *p = NULL; + + p = &all_passes; + NEXT_PASS (pass_fixup_cfg); + NEXT_PASS (pass_init_datastructures); + NEXT_PASS (pass_all_optimizations); + NEXT_PASS (pass_warn_function_noreturn); + NEXT_PASS (pass_mudflap_2); + NEXT_PASS (pass_free_datastructures); + NEXT_PASS (pass_expand); + NEXT_PASS (pass_rest_of_compilation); + NEXT_PASS (pass_clean_state); + *p = NULL; + + p = &pass_all_optimizations.sub; + NEXT_PASS (pass_referenced_vars); + NEXT_PASS (pass_create_structure_vars); + NEXT_PASS (pass_build_ssa); + NEXT_PASS (pass_build_pta); + NEXT_PASS (pass_may_alias); + NEXT_PASS (pass_del_pta); + NEXT_PASS (pass_rename_ssa_copies); + NEXT_PASS (pass_early_warn_uninitialized); + + /* Initial scalar cleanups. */ + NEXT_PASS (pass_ccp); + NEXT_PASS (pass_fre); + NEXT_PASS (pass_dce); + NEXT_PASS (pass_forwprop); + NEXT_PASS (pass_vrp); + NEXT_PASS (pass_copy_prop); + NEXT_PASS (pass_dce); + NEXT_PASS (pass_merge_phi); + NEXT_PASS (pass_dominator); + + NEXT_PASS (pass_phiopt); + NEXT_PASS (pass_build_pta); + NEXT_PASS (pass_may_alias); + NEXT_PASS (pass_del_pta); + NEXT_PASS (pass_tail_recursion); + NEXT_PASS (pass_profile); + NEXT_PASS (pass_ch); + NEXT_PASS (pass_stdarg); + NEXT_PASS (pass_lower_complex); + NEXT_PASS (pass_sra); + /* FIXME: SRA may generate arbitrary gimple code, exposing new + aliased and call-clobbered variables. As mentioned below, + pass_may_alias should be a TODO item. */ + NEXT_PASS (pass_may_alias); + NEXT_PASS (pass_rename_ssa_copies); + NEXT_PASS (pass_dominator); + NEXT_PASS (pass_copy_prop); + NEXT_PASS (pass_dce); + NEXT_PASS (pass_dse); + NEXT_PASS (pass_may_alias); + NEXT_PASS (pass_forwprop); + NEXT_PASS (pass_phiopt); + NEXT_PASS (pass_store_ccp); + NEXT_PASS (pass_store_copy_prop); + NEXT_PASS (pass_fold_builtins); + /* FIXME: May alias should a TODO but for 4.0.0, + we add may_alias right after fold builtins + which can create arbitrary GIMPLE. */ + NEXT_PASS (pass_may_alias); + NEXT_PASS (pass_cse_reciprocals); + NEXT_PASS (pass_split_crit_edges); + NEXT_PASS (pass_reassoc); + NEXT_PASS (pass_pre); + NEXT_PASS (pass_sink_code); + NEXT_PASS (pass_loop); + NEXT_PASS (pass_dominator); + NEXT_PASS (pass_copy_prop); + NEXT_PASS (pass_cd_dce); + + /* FIXME: If DCE is not run before checking for uninitialized uses, + we may get false warnings (e.g., testsuite/gcc.dg/uninit-5.c). + However, this also causes us to misdiagnose cases that should be + real warnings (e.g., testsuite/gcc.dg/pr18501.c). + + To fix the false positives in uninit-5.c, we would have to + account for the predicates protecting the set and the use of each + variable. Using a representation like Gated Single Assignment + may help. */ + NEXT_PASS (pass_late_warn_uninitialized); + NEXT_PASS (pass_dse); + NEXT_PASS (pass_forwprop); + NEXT_PASS (pass_phiopt); + NEXT_PASS (pass_tail_calls); + NEXT_PASS (pass_rename_ssa_copies); + NEXT_PASS (pass_uncprop); + NEXT_PASS (pass_del_ssa); + NEXT_PASS (pass_nrv); + NEXT_PASS (pass_remove_useless_vars); + NEXT_PASS (pass_mark_used_blocks); + NEXT_PASS (pass_cleanup_cfg_post_optimizing); + *p = NULL; + + p = &pass_loop.sub; + NEXT_PASS (pass_loop_init); + NEXT_PASS (pass_copy_prop); + NEXT_PASS (pass_lim); + NEXT_PASS (pass_unswitch); + NEXT_PASS (pass_scev_cprop); + NEXT_PASS (pass_record_bounds); + NEXT_PASS (pass_linear_transform); + NEXT_PASS (pass_iv_canon); + NEXT_PASS (pass_if_conversion); + NEXT_PASS (pass_vectorize); + /* NEXT_PASS (pass_may_alias) cannot be done again because the + vectorizer creates alias relations that are not supported by + pass_may_alias. */ + NEXT_PASS (pass_lower_vector_ssa); + NEXT_PASS (pass_complete_unroll); + NEXT_PASS (pass_iv_optimize); + NEXT_PASS (pass_loop_done); + *p = NULL; + + p = &pass_rest_of_compilation.sub; + NEXT_PASS (pass_remove_unnecessary_notes); + NEXT_PASS (pass_init_function); + NEXT_PASS (pass_jump); + NEXT_PASS (pass_insn_locators_initialize); + NEXT_PASS (pass_rtl_eh); + NEXT_PASS (pass_initial_value_sets); + NEXT_PASS (pass_unshare_all_rtl); + NEXT_PASS (pass_instantiate_virtual_regs); + NEXT_PASS (pass_jump2); + NEXT_PASS (pass_cse); + NEXT_PASS (pass_gcse); + NEXT_PASS (pass_loop_optimize); + NEXT_PASS (pass_jump_bypass); + NEXT_PASS (pass_cfg); + NEXT_PASS (pass_profiling); + NEXT_PASS (pass_rtl_ifcvt); + NEXT_PASS (pass_tracer); + NEXT_PASS (pass_loop2); + NEXT_PASS (pass_web); + NEXT_PASS (pass_cse2); + NEXT_PASS (pass_life); + NEXT_PASS (pass_combine); + NEXT_PASS (pass_if_after_combine); + NEXT_PASS (pass_partition_blocks); + NEXT_PASS (pass_regmove); + NEXT_PASS (pass_split_all_insns); + NEXT_PASS (pass_mode_switching); + NEXT_PASS (pass_recompute_reg_usage); + NEXT_PASS (pass_sms); + NEXT_PASS (pass_sched); + NEXT_PASS (pass_local_alloc); + NEXT_PASS (pass_global_alloc); + NEXT_PASS (pass_postreload); + *p = NULL; + + p = &pass_profiling.sub; + NEXT_PASS (pass_branch_prob); + NEXT_PASS (pass_value_profile_transformations); + NEXT_PASS (pass_remove_death_notes); + *p = NULL; + + p = &pass_postreload.sub; + NEXT_PASS (pass_postreload_cse); + NEXT_PASS (pass_gcse2); + NEXT_PASS (pass_flow2); + NEXT_PASS (pass_stack_adjustments); + NEXT_PASS (pass_peephole2); + NEXT_PASS (pass_if_after_reload); + NEXT_PASS (pass_regrename); + NEXT_PASS (pass_reorder_blocks); + NEXT_PASS (pass_branch_target_load_optimize); + NEXT_PASS (pass_leaf_regs); + NEXT_PASS (pass_sched2); + NEXT_PASS (pass_split_before_regstack); + NEXT_PASS (pass_stack_regs); + NEXT_PASS (pass_compute_alignments); + NEXT_PASS (pass_duplicate_computed_gotos); + NEXT_PASS (pass_variable_tracking); + NEXT_PASS (pass_free_cfg); + NEXT_PASS (pass_machine_reorg); + NEXT_PASS (pass_purge_lineno_notes); + NEXT_PASS (pass_cleanup_barriers); + NEXT_PASS (pass_delay_slots); + NEXT_PASS (pass_split_for_shorten_branches); + NEXT_PASS (pass_convert_to_eh_region_ranges); + NEXT_PASS (pass_shorten_branches); + NEXT_PASS (pass_set_nothrow_function_flags); + NEXT_PASS (pass_final); + *p = NULL; + +#undef NEXT_PASS + + /* Register the passes with the tree dump code. */ + register_dump_files (all_lowering_passes, false, PROP_gimple_any); + register_dump_files (all_passes, false, PROP_gimple_leh + | PROP_cfg); + register_dump_files (all_ipa_passes, true, PROP_gimple_leh + | PROP_cfg); +} + +static unsigned int last_verified; + +static void +execute_todo (struct tree_opt_pass *pass, unsigned int flags, bool use_required) +{ + int properties + = use_required ? pass->properties_required : pass->properties_provided; + +#if defined ENABLE_CHECKING + if (need_ssa_update_p ()) + gcc_assert (flags & TODO_update_ssa_any); +#endif + + if (flags & TODO_update_ssa_any) + { + unsigned update_flags = flags & TODO_update_ssa_any; + update_ssa (update_flags); + } + + if (flags & TODO_cleanup_cfg) + { + if (current_loops) + cleanup_tree_cfg_loop (); + else + cleanup_tree_cfg (); + } + + if ((flags & TODO_dump_func) + && dump_file && current_function_decl) + { + 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. */ + fflush (dump_file); + } + if ((flags & TODO_dump_cgraph) + && dump_file && !current_function_decl) + { + dump_cgraph (dump_file); + /* Flush the file. If verification fails, we won't be able to + close the file before aborting. */ + fflush (dump_file); + } + + if (flags & TODO_ggc_collect) + { + ggc_collect (); + } + +#if defined ENABLE_CHECKING + if ((pass->properties_required & PROP_ssa) + && !(pass->properties_destroyed & PROP_ssa)) + verify_ssa (true); + if (flags & TODO_verify_flow) + verify_flow_info (); + if (flags & TODO_verify_stmts) + verify_stmts (); + if (flags & TODO_verify_loops) + verify_loop_closed_ssa (); +#endif +} + +static bool +execute_one_pass (struct tree_opt_pass *pass) +{ + unsigned int todo; + + /* See if we're supposed to run this pass. */ + if (pass->gate && !pass->gate ()) + return false; + + /* Note that the folders should only create gimple expressions. + This is a hack until the new folder is ready. */ + in_gimple_form = (pass->properties_provided & PROP_trees) != 0; + + /* Run pre-pass verification. */ + todo = pass->todo_flags_start & ~last_verified; + if (todo) + execute_todo (pass, todo, true); + + /* 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 && current_function_decl) + { + const char *dname, *aname; + 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)%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. */ + if (pass->tv_id) + timevar_push (pass->tv_id); + + /* Do it! */ + if (pass->execute) + pass->execute (); + + /* Stop timevar. */ + if (pass->tv_id) + timevar_pop (pass->tv_id); + + /* Run post-pass cleanup and verification. */ + todo = pass->todo_flags_finish; + last_verified = todo & TODO_verify_all; + if (todo) + execute_todo (pass, todo, false); + + /* Flush and close dump file. */ + if (dump_file_name) + { + free ((char *) dump_file_name); + dump_file_name = NULL; + } + if (dump_file) + { + dump_end (pass->static_pass_number, dump_file); + dump_file = NULL; + } + + return true; +} + +void +execute_pass_list (struct tree_opt_pass *pass) +{ + do + { + if (execute_one_pass (pass) && pass->sub) + execute_pass_list (pass->sub); + pass = pass->next; + } + while (pass); +} + +/* Same as execute_pass_list but assume that subpasses of IPA passes + are local passes. */ +void +execute_ipa_pass_list (struct tree_opt_pass *pass) +{ + do + { + if (execute_one_pass (pass) && pass->sub) + { + struct cgraph_node *node; + for (node = cgraph_nodes; node; node = node->next) + if (node->analyzed) + { + push_cfun (DECL_STRUCT_FUNCTION (node->decl)); + current_function_decl = node->decl; + execute_pass_list (pass); + free_dominance_info (CDI_DOMINATORS); + free_dominance_info (CDI_POST_DOMINATORS); + current_function_decl = NULL; + pop_cfun (); + ggc_collect (); + } + } + pass = pass->next; + } + while (pass); +} Index: tree-dump.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-dump.h,v retrieving revision 1.10 diff -p -u -r1.10 tree-dump.h --- tree-dump.h 15 Feb 2005 15:53:47 -0000 1.10 +++ tree-dump.h 7 Jun 2005 10:17:12 -0000 @@ -23,6 +23,9 @@ Software Foundation, 59 Temple Place - S #define GCC_TREE_DUMP_H #include "splay-tree.h" +#include "tree-pass.h" + +typedef struct dump_info *dump_info_p; /* Flags used with queue functions. */ #define DUMP_NONE 0 @@ -87,6 +90,7 @@ extern void queue_and_dump_index (dump_i 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 int dump_flag (dump_info_p, int, tree); extern unsigned int dump_register (const char *, const char *, const char *, int, unsigned int, int); Index: tree-optimize.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-optimize.c,v retrieving revision 2.98 diff -p -u -r2.98 tree-optimize.c --- tree-optimize.c 17 May 2005 20:28:22 -0000 2.98 +++ tree-optimize.c 18 May 2005 10:30:39 -0000 @@ -51,13 +51,6 @@ #include "cfgloop.h" #include "except.h" -/* Global variables used to communicate with passes. */ -int dump_flags; -bool in_gimple_form; - -/* The root of the compilation pass tree, once constructed. */ -static struct tree_opt_pass *all_passes, *all_ipa_passes, * all_lowering_passes; - /* Gate: execute, or not, all of the non-trivial optimizations. */ static bool @@ -232,469 +244,7 @@ static struct tree_opt_pass pass_init_da 0 /* letter */ }; -/* Iterate over the pass tree allocating dump file numbers. We want - to do this depth first, and independent of whether the pass is - enabled or not. */ - -static void -register_one_dump_file (struct tree_opt_pass *pass, bool ipa, int n) -{ - char *dot_name, *flag_name, *glob_name; - char num[10]; - - /* See below in next_pass_1. */ - num[0] = '\0'; - if (pass->static_pass_number != -1) - sprintf (num, "%d", ((int) pass->static_pass_number < 0 - ? 1 : pass->static_pass_number)); - - dot_name = concat (".", pass->name, num, NULL); - if (ipa) - { - flag_name = concat ("ipa-", pass->name, num, NULL); - glob_name = concat ("ipa-", pass->name, NULL); - /* First IPA dump is cgraph that is dumped via separate channels. */ - pass->static_pass_number = dump_register (dot_name, flag_name, glob_name, - TDF_IPA, n + 1, 0); - } - else if (pass->properties_provided & PROP_trees) - { - flag_name = concat ("tree-", pass->name, num, NULL); - glob_name = concat ("tree-", pass->name, NULL); - pass->static_pass_number = dump_register (dot_name, flag_name, glob_name, - TDF_TREE, n + TDI_tree_all, 0); - } - else - { - flag_name = concat ("rtl-", pass->name, num, NULL); - glob_name = concat ("rtl-", pass->name, NULL); - pass->static_pass_number = dump_register (dot_name, flag_name, glob_name, - TDF_RTL, n, pass->letter); - } -} - -static int -register_dump_files (struct tree_opt_pass *pass, bool ipa, int properties) -{ - static int n = 0; - do - { - int new_properties; - int pass_number; - - pass->properties_required = properties; - new_properties = - (properties | pass->properties_provided) & ~pass->properties_destroyed; - - /* 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) - new_properties = register_dump_files (pass->sub, ipa, 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, ipa, pass_number); - - pass = pass->next; - } - while (pass); - - return properties; -} - -/* Add a pass to the pass list. Duplicate the pass if it's already - in the list. */ - -static struct tree_opt_pass ** -next_pass_1 (struct tree_opt_pass **list, struct tree_opt_pass *pass) -{ - - /* A nonzero static_pass_number indicates that the - pass is already in the list. */ - if (pass->static_pass_number) - { - struct tree_opt_pass *new; - - new = xmalloc (sizeof (*new)); - memcpy (new, pass, sizeof (*new)); - - /* Indicate to register_dump_files that this pass has duplicates, - and so it should rename the dump file. The first instance will - be -1, and be number of duplicates = -static_pass_number - 1. - Subsequent instances will be > 0 and just the duplicate number. */ - if (pass->name) - { - pass->static_pass_number -= 1; - new->static_pass_number = -pass->static_pass_number; - } - - *list = new; - } - else - { - pass->static_pass_number = -1; - *list = pass; - } - - return &(*list)->next; - -} - -/* Construct the pass tree. */ - -void -init_tree_optimization_passes (void) -{ - struct tree_opt_pass **p; - -#define NEXT_PASS(PASS) (p = next_pass_1 (p, &PASS)) - /* Intraprocedural optimization passes. */ - p = &all_ipa_passes; - NEXT_PASS (pass_ipa_inline); - *p = NULL; - - /* All passes needed to lower the function into shape optimizers can operate - on. These passes are performed before interprocedural passes, unlike rest - of local passes (all_passes). */ - p = &all_lowering_passes; - NEXT_PASS (pass_remove_useless_stmts); - NEXT_PASS (pass_mudflap_1); - NEXT_PASS (pass_lower_cf); - NEXT_PASS (pass_lower_eh); - NEXT_PASS (pass_build_cfg); - NEXT_PASS (pass_lower_complex_O0); - NEXT_PASS (pass_lower_vector); - NEXT_PASS (pass_warn_function_return); - NEXT_PASS (pass_tree_profile); - *p = NULL; - - p = &all_passes; - NEXT_PASS (pass_fixup_cfg); - NEXT_PASS (pass_init_datastructures); - NEXT_PASS (pass_all_optimizations); - NEXT_PASS (pass_warn_function_noreturn); - NEXT_PASS (pass_mudflap_2); - NEXT_PASS (pass_free_datastructures); - NEXT_PASS (pass_expand); - NEXT_PASS (pass_rest_of_compilation); - *p = NULL; - - p = &pass_all_optimizations.sub; - NEXT_PASS (pass_referenced_vars); - NEXT_PASS (pass_create_structure_vars); - NEXT_PASS (pass_build_ssa); - NEXT_PASS (pass_build_pta); - NEXT_PASS (pass_may_alias); - NEXT_PASS (pass_del_pta); - NEXT_PASS (pass_rename_ssa_copies); - NEXT_PASS (pass_early_warn_uninitialized); - - /* Initial scalar cleanups. */ - NEXT_PASS (pass_ccp); - NEXT_PASS (pass_fre); - NEXT_PASS (pass_dce); - NEXT_PASS (pass_forwprop); - NEXT_PASS (pass_vrp); - NEXT_PASS (pass_copy_prop); - NEXT_PASS (pass_dce); - NEXT_PASS (pass_merge_phi); - NEXT_PASS (pass_dominator); - - NEXT_PASS (pass_phiopt); - NEXT_PASS (pass_build_pta); - NEXT_PASS (pass_may_alias); - NEXT_PASS (pass_del_pta); - NEXT_PASS (pass_tail_recursion); - NEXT_PASS (pass_profile); - NEXT_PASS (pass_ch); - NEXT_PASS (pass_stdarg); - NEXT_PASS (pass_lower_complex); - NEXT_PASS (pass_sra); - /* FIXME: SRA may generate arbitrary gimple code, exposing new - aliased and call-clobbered variables. As mentioned below, - pass_may_alias should be a TODO item. */ - NEXT_PASS (pass_may_alias); - NEXT_PASS (pass_rename_ssa_copies); - NEXT_PASS (pass_dominator); - NEXT_PASS (pass_copy_prop); - NEXT_PASS (pass_dce); - NEXT_PASS (pass_dse); - NEXT_PASS (pass_may_alias); - NEXT_PASS (pass_forwprop); - NEXT_PASS (pass_phiopt); - NEXT_PASS (pass_store_ccp); - NEXT_PASS (pass_store_copy_prop); - NEXT_PASS (pass_fold_builtins); - /* FIXME: May alias should a TODO but for 4.0.0, - we add may_alias right after fold builtins - which can create arbitrary GIMPLE. */ - NEXT_PASS (pass_may_alias); - NEXT_PASS (pass_cse_reciprocals); - NEXT_PASS (pass_split_crit_edges); - NEXT_PASS (pass_reassoc); - NEXT_PASS (pass_pre); - NEXT_PASS (pass_sink_code); - NEXT_PASS (pass_loop); - NEXT_PASS (pass_dominator); - NEXT_PASS (pass_copy_prop); - NEXT_PASS (pass_cd_dce); - /* FIXME: If DCE is not run before checking for uninitialized uses, - we may get false warnings (e.g., testsuite/gcc.dg/uninit-5.c). - However, this also causes us to misdiagnose cases that should be - real warnings (e.g., testsuite/gcc.dg/pr18501.c). - - To fix the false positives in uninit-5.c, we would have to - account for the predicates protecting the set and the use of each - variable. Using a representation like Gated Single Assignment - may help. */ - NEXT_PASS (pass_late_warn_uninitialized); - NEXT_PASS (pass_dse); - NEXT_PASS (pass_forwprop); - NEXT_PASS (pass_phiopt); - NEXT_PASS (pass_tail_calls); - NEXT_PASS (pass_rename_ssa_copies); - NEXT_PASS (pass_uncprop); - NEXT_PASS (pass_del_ssa); - NEXT_PASS (pass_nrv); - NEXT_PASS (pass_remove_useless_vars); - NEXT_PASS (pass_mark_used_blocks); - NEXT_PASS (pass_cleanup_cfg_post_optimizing); - *p = NULL; - - p = &pass_loop.sub; - NEXT_PASS (pass_loop_init); - NEXT_PASS (pass_copy_prop); - NEXT_PASS (pass_lim); - NEXT_PASS (pass_unswitch); - NEXT_PASS (pass_scev_cprop); - NEXT_PASS (pass_record_bounds); - NEXT_PASS (pass_linear_transform); - NEXT_PASS (pass_iv_canon); - NEXT_PASS (pass_if_conversion); - NEXT_PASS (pass_vectorize); - /* NEXT_PASS (pass_may_alias) cannot be done again because the - vectorizer creates alias relations that are not supported by - pass_may_alias. */ - NEXT_PASS (pass_lower_vector_ssa); - NEXT_PASS (pass_complete_unroll); - NEXT_PASS (pass_iv_optimize); - NEXT_PASS (pass_loop_done); - *p = NULL; - -#undef NEXT_PASS - - register_dump_files (all_lowering_passes, false, PROP_gimple_any); - register_dump_files (all_passes, false, PROP_gimple_leh - | PROP_cfg); - register_dump_files (all_ipa_passes, true, PROP_gimple_leh - | PROP_cfg); -} - -static unsigned int last_verified; - -static void -execute_todo (struct tree_opt_pass *pass, unsigned int flags, bool use_required) -{ - int properties - = use_required ? pass->properties_required : pass->properties_provided; - -#if defined ENABLE_CHECKING - if (need_ssa_update_p ()) - gcc_assert (flags & TODO_update_ssa_any); -#endif - - if (flags & TODO_update_ssa_any) - { - unsigned update_flags = flags & TODO_update_ssa_any; - update_ssa (update_flags); - } - - if (flags & TODO_cleanup_cfg) - { - if (current_loops) - cleanup_tree_cfg_loop (); - else - cleanup_tree_cfg (); - } - - if ((flags & TODO_dump_func) - && dump_file && current_function_decl) - { - 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 dieing. */ - fflush (dump_file); - } - if ((flags & TODO_dump_cgraph) - && dump_file && !current_function_decl) - { - dump_cgraph (dump_file); - /* Flush the file. If verification fails, we won't be able to - close the file before aborting. */ - fflush (dump_file); - } - - if (flags & TODO_ggc_collect) - { - ggc_collect (); - } - -#if defined ENABLE_CHECKING - if ((pass->properties_required & PROP_ssa) - && !(pass->properties_destroyed & PROP_ssa)) - verify_ssa (true); - if (flags & TODO_verify_flow) - verify_flow_info (); - if (flags & TODO_verify_stmts) - verify_stmts (); - if (flags & TODO_verify_loops) - verify_loop_closed_ssa (); -#endif -} - -static bool -execute_one_pass (struct tree_opt_pass *pass) -{ - unsigned int todo; - - /* See if we're supposed to run this pass. */ - if (pass->gate && !pass->gate ()) - return false; - - /* Note that the folders should only create gimple expressions. - This is a hack until the new folder is ready. */ - in_gimple_form = (pass->properties_provided & PROP_trees) != 0; - - /* Run pre-pass verification. */ - todo = pass->todo_flags_start & ~last_verified; - if (todo) - execute_todo (pass, todo, true); - - /* 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 && current_function_decl) - { - const char *dname, *aname; - 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)%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. */ - if (pass->tv_id) - timevar_push (pass->tv_id); - - /* Do it! */ - if (pass->execute) - pass->execute (); - - /* Stop timevar. */ - if (pass->tv_id) - timevar_pop (pass->tv_id); - - if (dump_file - && (pass->properties_provided & (PROP_cfg | PROP_rtl)) - == (PROP_cfg | PROP_rtl)) - print_rtl_with_bb (dump_file, get_insns ()); - - /* Run post-pass cleanup and verification. */ - todo = pass->todo_flags_finish; - last_verified = todo & TODO_verify_all; - if (todo) - execute_todo (pass, todo, false); - - /* Flush and close dump file. */ - if (dump_file_name) - { - free ((char *) dump_file_name); - dump_file_name = NULL; - } - if (dump_file) - { - dump_end (pass->static_pass_number, dump_file); - dump_file = NULL; - } - - return true; -} - -static void -execute_pass_list (struct tree_opt_pass *pass) -{ - do - { - if (execute_one_pass (pass) && pass->sub) - execute_pass_list (pass->sub); - pass = pass->next; - } - while (pass); -} - -/* Same as execute_pass_list but assume that subpasses of IPA passes - are local passes. */ -static void -execute_ipa_pass_list (struct tree_opt_pass *pass) -{ - do - { - if (execute_one_pass (pass) && pass->sub) - { - struct cgraph_node *node; - for (node = cgraph_nodes; node; node = node->next) - if (node->analyzed) - { - push_cfun (DECL_STRUCT_FUNCTION (node->decl)); - current_function_decl = node->decl; - execute_pass_list (pass); - free_dominance_info (CDI_DOMINATORS); - free_dominance_info (CDI_POST_DOMINATORS); - current_function_decl = NULL; - pop_cfun (); - ggc_collect (); - } - } - pass = pass->next; - } - while (pass); -} - + void tree_lowering_passes (tree fn) { @@ -678,18 +262,6 @@ tree_lowering_passes (tree fn) pop_cfun (); } -/* Execute all IPA passes. */ -void -ipa_passes (void) -{ - cfun = NULL; - tree_register_cfg_hooks (); - bitmap_obstack_initialize (NULL); - execute_ipa_pass_list (all_ipa_passes); - bitmap_obstack_release (NULL); -} - - /* Update recursively all inlined_to pointers of functions inlined into NODE to INLINED_TO. */ static void Index: tree-pass.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-pass.h,v retrieving revision 2.35 diff -p -u -r2.35 tree-pass.h --- tree-pass.h 17 May 2005 09:55:24 -0000 2.35 +++ tree-pass.h 18 May 2005 10:30:40 -0000 @@ -23,6 +23,59 @@ Boston, MA 02111-1307, USA. */ #ifndef GCC_TREE_PASS_H #define GCC_TREE_PASS_H 1 +/* In tree-dump.c */ + +/* Different tree dump places. When you add new tree dump places, + extend the DUMP_FILES array in tree-dump.c. */ +enum tree_dump_index +{ + TDI_none, /* No dump */ + TDI_tu, /* dump the whole translation unit. */ + TDI_class, /* dump class hierarchy. */ + TDI_original, /* dump each function before optimizing it */ + TDI_generic, /* dump each function after genericizing it */ + TDI_nested, /* dump each function after unnesting it */ + TDI_inlined, /* dump each function after inlining + within it. */ + TDI_vcg, /* create a VCG graph file for each + function's flowgraph. */ + TDI_tree_all, /* enable all the GENERIC/GIMPLE dumps. */ + TDI_rtl_all, /* enable all the RTL dumps. */ + TDI_ipa_all, /* enable all the IPA dumps. */ + + TDI_cgraph, /* dump function call graph. */ + TDI_end +}; + +/* 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 */ +#define TDF_RAW (1 << 2) /* don't unparse the function */ +#define TDF_DETAILS (1 << 3) /* show more detailed info about + each pass */ +#define TDF_STATS (1 << 4) /* dump various statistics about + each pass */ +#define TDF_BLOCKS (1 << 5) /* display basic block boundaries */ +#define TDF_VOPS (1 << 6) /* display virtual operands */ +#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 */ +#define TDF_IPA (1 << 11) /* is an IPA dump */ +#define TDF_STMTADDR (1 << 12) /* Address of stmt. */ + +extern char *get_dump_file_name (enum tree_dump_index); +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 *); +extern int dump_switch_p (const char *); +extern const char *dump_flag_name (enum tree_dump_index); + /* Global variables used to communicate with passes. */ extern FILE *dump_file; extern int dump_flags; @@ -154,7 +207,6 @@ struct dump_file_info #define TODO_verify_all \ (TODO_verify_ssa | TODO_verify_flow | TODO_verify_stmts) -extern void ipa_passes (void); extern void tree_lowering_passes (tree decl); extern struct tree_opt_pass pass_mudflap_1; @@ -291,4 +342,11 @@ extern struct tree_opt_pass pass_uncprop extern struct tree_opt_pass pass_shorten_branches; extern struct tree_opt_pass pass_set_nothrow_function_flags; extern struct tree_opt_pass pass_final; + +/* The root of the compilation pass tree, once constructed. */ +extern struct tree_opt_pass *all_passes, *all_ipa_passes, *all_lowering_passes; + +extern void execute_pass_list (struct tree_opt_pass *); +extern void execute_ipa_pass_list (struct tree_opt_pass *); + #endif /* GCC_TREE_PASS_H */ Index: tree.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree.h,v retrieving revision 1.727 diff -p -u -r1.727 tree.h --- tree.h 11 May 2005 16:25:30 -0000 1.727 +++ tree.h 18 May 2005 10:30:50 -0000 @@ -3844,100 +3844,6 @@ typedef tree (*walk_tree_fn) (tree *, in extern tree walk_tree (tree*, walk_tree_fn, void*, struct pointer_set_t*); extern tree walk_tree_without_duplicates (tree*, walk_tree_fn, void*); -/* In tree-dump.c */ - -/* Different tree dump places. When you add new tree dump places, - extend the DUMP_FILES array in tree-dump.c. */ -enum tree_dump_index -{ - TDI_none, /* No dump */ - TDI_tu, /* dump the whole translation unit. */ - TDI_class, /* dump class hierarchy. */ - TDI_original, /* dump each function before optimizing it */ - TDI_generic, /* dump each function after genericizing it */ - TDI_nested, /* dump each function after unnesting it */ - TDI_inlined, /* dump each function after inlining - within it. */ - TDI_vcg, /* create a VCG graph file for each - function's flowgraph. */ - TDI_tree_all, /* enable all the GENERIC/GIMPLE dumps. */ - TDI_rtl_all, /* enable all the RTL dumps. */ - TDI_ipa_all, /* enable all the IPA dumps. */ - - TDI_cgraph, /* dump function call graph. */ - - 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 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 */ -#define TDF_RAW (1 << 2) /* don't unparse the function */ -#define TDF_DETAILS (1 << 3) /* show more detailed info about - each pass */ -#define TDF_STATS (1 << 4) /* dump various statistics about - each pass */ -#define TDF_BLOCKS (1 << 5) /* display basic block boundaries */ -#define TDF_VOPS (1 << 6) /* display virtual operands */ -#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 */ -#define TDF_IPA (1 << 11) /* is an IPA dump */ -#define TDF_STMTADDR (1 << 12) /* Address of stmt. */ - -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 *); -extern int dump_switch_p (const char *); -extern const char *dump_flag_name (enum tree_dump_index); /* Assign the RTX to declaration. */ extern void set_decl_rtl (tree, rtx); --------------040206050304050704060205 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0"; name="rtl-passes-delete-stuff.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="rtl-passes-delete-stuff.patch" Content-length: 45851 2005-05-19 Paolo Bonzini * passes.c (open_dump_file, close_dump_file, rest_of_handle_final, rest_of_handle_delay_slots, rest_of_handle_stack_regs, rest_of_handle_variable_tracking, rest_of_handle_machine_reorg, rest_of_handle_old_regalloc, rest_of_handle_regrename, rest_of_handle_reorder_blocks, rest_of_handle_partition_blocks, rest_of_handle_sms, rest_of_handle_sched, rest_of_handle_sched2, rest_of_handle_gcse2, rest_of_handle_regmove, rest_of_handle_tracer, rest_of_handle_if_conversion, rest_of_handle_if_after_combine, rest_of_handle_if_after_reload, rest_of_handle_web, rest_of_handle_branch_prob, rest_of_handle_value_profile_transformations, rest_of_handle_cfg, rest_of_handle_jump_bypass, rest_of_handle_combine, rest_of_handle_life, rest_of_handle_cse, rest_of_handle_cse2, rest_of_handle_gcse, rest_of_handle_loop_optimize, rest_of_handle_loop2, rest_of_handle_branch_target_load_optimize, rest_of_handle_mode_switching, rest_of_handle_jump, rest_of_handle_eh, rest_of_handle_stack_adjustments, rest_of_handle_flow2, rest_of_handle_jump2, rest_of_handle_peephole2, rest_of_handle_postreload, rest_of_handle_shorten_branches, rest_of_clean_state, rest_of_compilation): Remove. Index: passes.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/passes.c,v retrieving revision 2.90 diff -p -u -r2.90 passes.c --- passes.c 27 Apr 2005 21:35:20 -0000 2.90 +++ passes.c 18 May 2005 10:29:55 -0000 @@ -98,80 +99,7 @@ Software Foundation, 59 Temple Place - S declarations for e.g. AIX 4.x. */ #endif -#ifndef HAVE_conditional_execution -#define HAVE_conditional_execution 0 -#endif - -/* Format to use to print dumpfile index value */ -#ifndef DUMPFILE_FORMAT -#define DUMPFILE_FORMAT ".%02d." -#endif - -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 tree_dump_index index, tree decl) -{ - if (! dump_enabled_p (index)) - return 0; - - timevar_push (TV_DUMP); - - gcc_assert (!dump_file && !dump_file_name); - - dump_file_name = get_dump_file_name (index); - initializing_dump = !dump_initialized_p (index); - dump_file = dump_begin (index, NULL); - - if (dump_file == NULL) - fatal_error ("can't open %s: %m", dump_file_name); - - if (decl) - fprintf (dump_file, "\n;; Function %s%s\n\n", - lang_hooks.decl_printable_name (decl, 2), - cfun->function_frequency == FUNCTION_FREQUENCY_HOT - ? " (hot)" - : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED - ? " (unlikely executed)" - : ""); - - timevar_pop (TV_DUMP); - return 1; -} - -/* Routine to close a dump file. */ - -static void -close_dump_file (enum tree_dump_index index, - void (*func) (FILE *, rtx), - rtx insns) -{ - if (! dump_file) - return; - - timevar_push (TV_DUMP); - if (insns - && graph_dump_format != no_graph) - { - /* If we've not initialized the files, do so now. */ - if (initializing_dump) - clean_graph_dump_file (dump_file_name); - - print_rtl_graph_with_bb (dump_file_name, insns); - } - - if (func && insns) - func (dump_file, insns); - dump_end (index, dump_file); - free ((char *) dump_file_name); - - dump_file = NULL; - dump_file_name = NULL; - timevar_pop (TV_DUMP); -} /* This is called from various places for FUNCTION_DECL, VAR_DECL, and TYPE_DECL nodes. @@ -270,1487 +198,8 @@ rest_of_type_compilation (tree type, int timevar_pop (TV_SYMOUT); } -/* Turn the RTL into assembly. */ -static void -rest_of_handle_final (void) -{ - timevar_push (TV_FINAL); - { - rtx x; - const char *fnname; - - /* Get the function's name, as described by its RTL. This may be - different from the DECL_NAME name used in the source file. */ - - x = DECL_RTL (current_function_decl); - gcc_assert (MEM_P (x)); - x = XEXP (x, 0); - gcc_assert (GET_CODE (x) == SYMBOL_REF); - fnname = XSTR (x, 0); - - assemble_start_function (current_function_decl, fnname); - final_start_function (get_insns (), asm_out_file, optimize); - final (get_insns (), asm_out_file, optimize); - final_end_function (); - -#ifdef TARGET_UNWIND_INFO - /* ??? The IA-64 ".handlerdata" directive must be issued before - the ".endp" directive that closes the procedure descriptor. */ - output_function_exception_table (); -#endif - - assemble_end_function (current_function_decl, fnname); - -#ifndef TARGET_UNWIND_INFO - /* Otherwise, it feels unclean to switch sections in the middle. */ - output_function_exception_table (); -#endif - - user_defined_section_attribute = false; - - if (! quiet_flag) - fflush (asm_out_file); - - /* Release all memory allocated by flow. */ - free_basic_block_vars (); - } - - /* Write DBX symbols if requested. */ - - /* Note that for those inline functions where we don't initially - know for certain that we will be generating an out-of-line copy, - the first invocation of this routine (rest_of_compilation) will - skip over this code by doing a `goto exit_rest_of_compilation;'. - Later on, wrapup_global_declarations will (indirectly) call - rest_of_compilation again for those inline functions that need - to have out-of-line copies generated. During that call, we - *will* be routed past here. */ - - timevar_push (TV_SYMOUT); - (*debug_hooks->function_decl) (current_function_decl); - timevar_pop (TV_SYMOUT); - - ggc_collect (); - timevar_pop (TV_FINAL); -} - -#ifdef DELAY_SLOTS -/* Run delay slot optimization. */ -static void -rest_of_handle_delay_slots (void) -{ - timevar_push (TV_DBR_SCHED); - open_dump_file (DFI_dbr, current_function_decl); - - dbr_schedule (get_insns (), dump_file); - - close_dump_file (DFI_dbr, print_rtl, get_insns ()); - - ggc_collect (); - - timevar_pop (TV_DBR_SCHED); -} -#endif - -#ifdef STACK_REGS -/* Convert register usage from flat register file usage to a stack - register file. */ -static void -rest_of_handle_stack_regs (void) -{ -#if defined (HAVE_ATTR_length) - /* If flow2 creates new instructions which need splitting - and scheduling after reload is not done, they might not be - split until final which doesn't allow splitting - if HAVE_ATTR_length. */ -#ifdef INSN_SCHEDULING - if (optimize && !flag_schedule_insns_after_reload) -#else - if (optimize) -#endif - { - timevar_push (TV_SHORTEN_BRANCH); - split_all_insns (1); - timevar_pop (TV_SHORTEN_BRANCH); - } -#endif - - timevar_push (TV_REG_STACK); - open_dump_file (DFI_stack, current_function_decl); - - if (reg_to_stack (dump_file) && optimize) - { - if (cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK - | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0)) - && (flag_reorder_blocks || flag_reorder_blocks_and_partition)) - { - reorder_basic_blocks (0); - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK); - } - } - - close_dump_file (DFI_stack, print_rtl_with_bb, get_insns ()); - - ggc_collect (); - timevar_pop (TV_REG_STACK); -} -#endif - -/* Track the variables, i.e. compute where the variable is stored at each position in function. */ -static void -rest_of_handle_variable_tracking (void) -{ - timevar_push (TV_VAR_TRACKING); - open_dump_file (DFI_vartrack, current_function_decl); - - variable_tracking_main (); - - close_dump_file (DFI_vartrack, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_VAR_TRACKING); -} - -/* Machine dependent reorg pass. */ -static void -rest_of_handle_machine_reorg (void) -{ - timevar_push (TV_MACH_DEP); - open_dump_file (DFI_mach, current_function_decl); - - targetm.machine_dependent_reorg (); - - close_dump_file (DFI_mach, print_rtl, get_insns ()); - - ggc_collect (); - timevar_pop (TV_MACH_DEP); -} - - -/* Run old register allocator. Return TRUE if we must exit - rest_of_compilation upon return. */ -static bool -rest_of_handle_old_regalloc (void) -{ - int failure; - int rebuild_notes; - - timevar_push (TV_LOCAL_ALLOC); - open_dump_file (DFI_lreg, current_function_decl); - - /* Allocate the reg_renumber array. */ - allocate_reg_info (max_regno, FALSE, TRUE); - - /* And the reg_equiv_memory_loc array. */ - VARRAY_GROW (reg_equiv_memory_loc_varray, max_regno); - reg_equiv_memory_loc = &VARRAY_RTX (reg_equiv_memory_loc_varray, 0); - - allocate_initial_values (reg_equiv_memory_loc); - - regclass (get_insns (), max_reg_num (), dump_file); - rebuild_notes = local_alloc (); - - timevar_pop (TV_LOCAL_ALLOC); - - /* Local allocation may have turned an indirect jump into a direct - jump. If so, we must rebuild the JUMP_LABEL fields of jumping - instructions. */ - if (rebuild_notes) - { - timevar_push (TV_JUMP); - - rebuild_jump_labels (get_insns ()); - purge_all_dead_edges (); - delete_unreachable_blocks (); - - timevar_pop (TV_JUMP); - } - - if (dump_enabled_p (DFI_lreg)) - { - timevar_push (TV_DUMP); - dump_flow_info (dump_file); - dump_local_alloc (dump_file); - timevar_pop (TV_DUMP); - } - - close_dump_file (DFI_lreg, print_rtl_with_bb, get_insns ()); - - ggc_collect (); - - timevar_push (TV_GLOBAL_ALLOC); - open_dump_file (DFI_greg, current_function_decl); - - /* If optimizing, allocate remaining pseudo-regs. Do the reload - pass fixing up any insns that are invalid. */ - - if (optimize) - failure = global_alloc (dump_file); - else - { - build_insn_chain (get_insns ()); - failure = reload (get_insns (), 0); - } - - if (dump_enabled_p (DFI_greg)) - { - timevar_push (TV_DUMP); - dump_global_regs (dump_file); - timevar_pop (TV_DUMP); - - close_dump_file (DFI_greg, print_rtl_with_bb, get_insns ()); - } - - ggc_collect (); - - timevar_pop (TV_GLOBAL_ALLOC); - - return failure; -} - -/* Run the regrename and cprop passes. */ -static void -rest_of_handle_regrename (void) -{ - timevar_push (TV_RENAME_REGISTERS); - open_dump_file (DFI_rnreg, current_function_decl); - - if (flag_rename_registers) - regrename_optimize (); - if (flag_cprop_registers) - copyprop_hardreg_forward (); - - close_dump_file (DFI_rnreg, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_RENAME_REGISTERS); -} - -/* Reorder basic blocks. */ -static void -rest_of_handle_reorder_blocks (void) -{ - bool changed; - unsigned int liveness_flags; - - open_dump_file (DFI_bbro, current_function_decl); - - /* Last attempt to optimize CFG, as scheduling, peepholing and insn - splitting possibly introduced more crossjumping opportunities. */ - liveness_flags = (!HAVE_conditional_execution ? CLEANUP_UPDATE_LIFE : 0); - changed = cleanup_cfg (CLEANUP_EXPENSIVE | liveness_flags); - - if (flag_sched2_use_traces && flag_schedule_insns_after_reload) - tracer (liveness_flags); - if (flag_reorder_blocks || flag_reorder_blocks_and_partition) - reorder_basic_blocks (liveness_flags); - if (flag_reorder_blocks || flag_reorder_blocks_and_partition - || (flag_sched2_use_traces && flag_schedule_insns_after_reload)) - changed |= cleanup_cfg (CLEANUP_EXPENSIVE | liveness_flags); - - /* On conditional execution targets we can not update the life cheaply, so - we deffer the updating to after both cleanups. This may lose some cases - but should not be terribly bad. */ - if (changed && HAVE_conditional_execution) - update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES, - PROP_DEATH_NOTES); - close_dump_file (DFI_bbro, print_rtl_with_bb, get_insns ()); -} - -/* Partition hot and cold basic blocks. */ -static void -rest_of_handle_partition_blocks (void) -{ - no_new_pseudos = 0; - partition_hot_cold_basic_blocks (); - allocate_reg_life_data (); - update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES, - PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES); - no_new_pseudos = 1; -} - -#ifdef INSN_SCHEDULING -/* Run instruction scheduler. */ -/* Perform SMS module scheduling. */ -static void -rest_of_handle_sms (void) -{ - basic_block bb; - sbitmap blocks; - - timevar_push (TV_SMS); - open_dump_file (DFI_sms, current_function_decl); - - /* We want to be able to create new pseudos. */ - no_new_pseudos = 0; - /* Collect loop information to be used in SMS. */ - cfg_layout_initialize (CLEANUP_UPDATE_LIFE); - sms_schedule (dump_file); - close_dump_file (DFI_sms, print_rtl, get_insns ()); - - /* Update the life information, because we add pseudos. */ - max_regno = max_reg_num (); - allocate_reg_info (max_regno, FALSE, FALSE); - blocks = sbitmap_alloc (last_basic_block); - sbitmap_ones (blocks); - update_life_info (blocks, UPDATE_LIFE_GLOBAL_RM_NOTES, - (PROP_DEATH_NOTES - | PROP_REG_INFO - | PROP_KILL_DEAD_CODE - | PROP_SCAN_DEAD_CODE)); - - no_new_pseudos = 1; - - /* Finalize layout changes. */ - FOR_EACH_BB (bb) - if (bb->next_bb != EXIT_BLOCK_PTR) - bb->rbi->next = bb->next_bb; - cfg_layout_finalize (); - free_dominance_info (CDI_DOMINATORS); - ggc_collect (); - timevar_pop (TV_SMS); -} - -/* Run instruction scheduler. */ -static void -rest_of_handle_sched (void) -{ - timevar_push (TV_SCHED); - - /* Print function header into sched dump now - because doing the sched analysis makes some of the dump. */ - open_dump_file (DFI_sched, current_function_decl); - - /* Do control and data sched analysis, - and write some of the results to dump file. */ - - schedule_insns (dump_file); - - close_dump_file (DFI_sched, print_rtl_with_bb, get_insns ()); - - ggc_collect (); - timevar_pop (TV_SCHED); -} - -/* Run second scheduling pass after reload. */ -static void -rest_of_handle_sched2 (void) -{ - timevar_push (TV_SCHED2); - open_dump_file (DFI_sched2, current_function_decl); - - /* Do control and data sched analysis again, - and write some more of the results to dump file. */ - - split_all_insns (1); - - if (flag_sched2_use_superblocks || flag_sched2_use_traces) - { - schedule_ebbs (dump_file); - /* No liveness updating code yet, but it should be easy to do. - reg-stack recomputes the liveness when needed for now. */ - count_or_remove_death_notes (NULL, 1); - cleanup_cfg (CLEANUP_EXPENSIVE); - } - else - schedule_insns (dump_file); - - close_dump_file (DFI_sched2, print_rtl_with_bb, get_insns ()); - - ggc_collect (); - - timevar_pop (TV_SCHED2); -} -#endif - -static void -rest_of_handle_gcse2 (void) -{ - timevar_push (TV_GCSE_AFTER_RELOAD); - open_dump_file (DFI_gcse2, current_function_decl); - - gcse_after_reload_main (get_insns ()); - rebuild_jump_labels (get_insns ()); - delete_trivially_dead_insns (get_insns (), max_reg_num ()); - close_dump_file (DFI_gcse2, print_rtl_with_bb, get_insns ()); - - ggc_collect (); - -#ifdef ENABLE_CHECKING - verify_flow_info (); -#endif - - timevar_pop (TV_GCSE_AFTER_RELOAD); -} - -/* Register allocation pre-pass, to reduce number of moves necessary - for two-address machines. */ -static void -rest_of_handle_regmove (void) -{ - timevar_push (TV_REGMOVE); - open_dump_file (DFI_regmove, current_function_decl); - - regmove_optimize (get_insns (), max_reg_num (), dump_file); - - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE); - close_dump_file (DFI_regmove, print_rtl_with_bb, get_insns ()); - - ggc_collect (); - timevar_pop (TV_REGMOVE); -} - -/* Run tracer. */ -static void -rest_of_handle_tracer (void) -{ - open_dump_file (DFI_tracer, current_function_decl); - if (dump_file) - dump_flow_info (dump_file); - tracer (0); - cleanup_cfg (CLEANUP_EXPENSIVE); - reg_scan (get_insns (), max_reg_num ()); - close_dump_file (DFI_tracer, print_rtl_with_bb, get_insns ()); -} - -/* If-conversion and CFG cleanup. */ -static void -rest_of_handle_if_conversion (void) -{ - timevar_push (TV_IFCVT); - open_dump_file (DFI_ce1, current_function_decl); - - if (flag_if_conversion) - { - if (dump_file) - dump_flow_info (dump_file); - cleanup_cfg (CLEANUP_EXPENSIVE); - reg_scan (get_insns (), max_reg_num ()); - if_convert (0); - } - - timevar_push (TV_JUMP); - cleanup_cfg (CLEANUP_EXPENSIVE); - reg_scan (get_insns (), max_reg_num ()); - timevar_pop (TV_JUMP); - - close_dump_file (DFI_ce1, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_IFCVT); -} - -/* Rerun if-conversion, as combine may have simplified things enough - to now meet sequence length restrictions. */ -static void -rest_of_handle_if_after_combine (void) -{ - timevar_push (TV_IFCVT); - open_dump_file (DFI_ce2, current_function_decl); - - no_new_pseudos = 0; - if_convert (1); - no_new_pseudos = 1; - - close_dump_file (DFI_ce2, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_IFCVT); -} - -static void -rest_of_handle_if_after_reload (void) -{ - timevar_push (TV_IFCVT2); - open_dump_file (DFI_ce3, current_function_decl); - - /* Last attempt to optimize CFG, as scheduling, peepholing and insn - splitting possibly introduced more crossjumping opportunities. */ - cleanup_cfg (CLEANUP_EXPENSIVE - | CLEANUP_UPDATE_LIFE - | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0)); - if (flag_if_conversion2) - if_convert (1); - close_dump_file (DFI_ce3, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_IFCVT2); -} - -static void -rest_of_handle_web (void) -{ - open_dump_file (DFI_web, current_function_decl); - timevar_push (TV_WEB); - web_main (); - delete_trivially_dead_insns (get_insns (), max_reg_num ()); - cleanup_cfg (CLEANUP_EXPENSIVE); - - timevar_pop (TV_WEB); - close_dump_file (DFI_web, print_rtl_with_bb, get_insns ()); - reg_scan (get_insns (), max_reg_num ()); -} - -/* Do branch profiling and static profile estimation passes. */ -static void -rest_of_handle_branch_prob (void) -{ - struct loops loops; - - timevar_push (TV_BRANCH_PROB); - open_dump_file (DFI_bp, current_function_decl); - - if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) - branch_prob (); - - /* Discover and record the loop depth at the head of each basic - block. The loop infrastructure does the real job for us. */ - flow_loops_find (&loops); - - if (dump_file) - flow_loops_dump (&loops, dump_file, NULL, 0); - - /* Estimate using heuristics if no profiling info is available. */ - if (flag_guess_branch_prob) - estimate_probability (&loops); - - flow_loops_free (&loops); - free_dominance_info (CDI_DOMINATORS); - close_dump_file (DFI_bp, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_BRANCH_PROB); -} - -/* Do optimizations based on expression value profiles. */ -static void -rest_of_handle_value_profile_transformations (void) -{ - open_dump_file (DFI_vpt, current_function_decl); - timevar_push (TV_VPT); - - if (value_profile_transformations ()) - cleanup_cfg (CLEANUP_EXPENSIVE); - - timevar_pop (TV_VPT); - close_dump_file (DFI_vpt, print_rtl_with_bb, get_insns ()); -} - -/* Do control and data flow analysis; write some of the results to the - dump file. */ -static void -rest_of_handle_cfg (void) -{ - open_dump_file (DFI_cfg, current_function_decl); - if (dump_file) - dump_flow_info (dump_file); - if (optimize) - cleanup_cfg (CLEANUP_EXPENSIVE - | (flag_thread_jumps ? CLEANUP_THREADING : 0)); - - /* It may make more sense to mark constant functions after dead code is - eliminated by life_analysis, but we need to do it early, as -fprofile-arcs - may insert code making function non-constant, but we still must consider - it as constant, otherwise -fbranch-probabilities will not read data back. - - life_analysis rarely eliminates modification of external memory. - - FIXME: now with tree based profiling we are in the trap described above - again. It seems to be easiest to disable the optimization for time - being before the problem is either solved by moving the transformation - to the IPA level (we need the CFG for this) or the very early optimization - passes are made to ignore the const/pure flags so code does not change. */ - if (optimize - && (!flag_tree_based_profiling - || (!profile_arc_flag && !flag_branch_probabilities))) - { - /* Alias analysis depends on this information and mark_constant_function - depends on alias analysis. */ - reg_scan (get_insns (), max_reg_num ()); - mark_constant_function (); - } - - close_dump_file (DFI_cfg, print_rtl_with_bb, get_insns ()); -} - -/* Perform jump bypassing and control flow optimizations. */ -static void -rest_of_handle_jump_bypass (void) -{ - timevar_push (TV_BYPASS); - open_dump_file (DFI_bypass, current_function_decl); - - cleanup_cfg (CLEANUP_EXPENSIVE); - reg_scan (get_insns (), max_reg_num ()); - - if (bypass_jumps (dump_file)) - { - rebuild_jump_labels (get_insns ()); - cleanup_cfg (CLEANUP_EXPENSIVE); - delete_trivially_dead_insns (get_insns (), max_reg_num ()); - } - - close_dump_file (DFI_bypass, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_BYPASS); - - ggc_collect (); - -#ifdef ENABLE_CHECKING - verify_flow_info (); -#endif -} - -/* Try combining insns through substitution. */ -static void -rest_of_handle_combine (void) -{ - int rebuild_jump_labels_after_combine = 0; - - timevar_push (TV_COMBINE); - open_dump_file (DFI_combine, current_function_decl); - - rebuild_jump_labels_after_combine - = combine_instructions (get_insns (), max_reg_num ()); - - /* Combining insns may have turned an indirect jump into a - direct jump. Rebuild the JUMP_LABEL fields of jumping - instructions. */ - if (rebuild_jump_labels_after_combine) - { - timevar_push (TV_JUMP); - rebuild_jump_labels (get_insns ()); - timevar_pop (TV_JUMP); - - delete_dead_jumptables (); - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE); - } - - close_dump_file (DFI_combine, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_COMBINE); - - ggc_collect (); -} - -/* Perform life analysis. */ -static void -rest_of_handle_life (void) -{ - open_dump_file (DFI_life, current_function_decl); - regclass_init (); - -#ifdef ENABLE_CHECKING - verify_flow_info (); -#endif - life_analysis (dump_file, PROP_FINAL); - if (optimize) - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE | CLEANUP_LOG_LINKS - | (flag_thread_jumps ? CLEANUP_THREADING : 0)); - - if (extra_warnings) - { - setjmp_vars_warning (DECL_INITIAL (current_function_decl)); - setjmp_args_warning (); - } - - if (optimize) - { - if (initialize_uninitialized_subregs ()) - { - /* Insns were inserted, and possibly pseudos created, so - things might look a bit different. */ - allocate_reg_life_data (); - update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES, - PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES); - } - } - - no_new_pseudos = 1; - - close_dump_file (DFI_life, print_rtl_with_bb, get_insns ()); - - ggc_collect (); -} - -/* Perform common subexpression elimination. Nonzero value from - `cse_main' means that jumps were simplified and some code may now - be unreachable, so do jump optimization again. */ -static void -rest_of_handle_cse (void) -{ - int tem; - - open_dump_file (DFI_cse, current_function_decl); - if (dump_file) - dump_flow_info (dump_file); - timevar_push (TV_CSE); - - reg_scan (get_insns (), max_reg_num ()); - - tem = cse_main (get_insns (), max_reg_num (), dump_file); - if (tem) - rebuild_jump_labels (get_insns ()); - if (purge_all_dead_edges ()) - delete_unreachable_blocks (); - - delete_trivially_dead_insns (get_insns (), max_reg_num ()); - - /* If we are not running more CSE passes, then we are no longer - expecting CSE to be run. But always rerun it in a cheap mode. */ - cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse; - - if (tem) - delete_dead_jumptables (); - - if (tem || optimize > 1) - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); - - timevar_pop (TV_CSE); - close_dump_file (DFI_cse, print_rtl_with_bb, get_insns ()); - - ggc_collect (); -} - -/* Run second CSE pass after loop optimizations. */ -static void -rest_of_handle_cse2 (void) -{ - int tem; - - timevar_push (TV_CSE2); - open_dump_file (DFI_cse2, current_function_decl); - if (dump_file) - dump_flow_info (dump_file); - /* CFG is no longer maintained up-to-date. */ - tem = cse_main (get_insns (), max_reg_num (), dump_file); - - /* Run a pass to eliminate duplicated assignments to condition code - registers. We have to run this after bypass_jumps, because it - makes it harder for that pass to determine whether a jump can be - bypassed safely. */ - cse_condition_code_reg (); - - purge_all_dead_edges (); - delete_trivially_dead_insns (get_insns (), max_reg_num ()); - - if (tem) - { - timevar_push (TV_JUMP); - rebuild_jump_labels (get_insns ()); - delete_dead_jumptables (); - cleanup_cfg (CLEANUP_EXPENSIVE); - timevar_pop (TV_JUMP); - } - reg_scan (get_insns (), max_reg_num ()); - close_dump_file (DFI_cse2, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_CSE2); - - ggc_collect (); -} - -/* Perform global cse. */ -static void -rest_of_handle_gcse (void) -{ - int save_csb, save_cfj; - int tem2 = 0, tem; - - timevar_push (TV_GCSE); - open_dump_file (DFI_gcse, current_function_decl); - - tem = gcse_main (get_insns (), dump_file); - rebuild_jump_labels (get_insns ()); - delete_trivially_dead_insns (get_insns (), max_reg_num ()); - - save_csb = flag_cse_skip_blocks; - save_cfj = flag_cse_follow_jumps; - flag_cse_skip_blocks = flag_cse_follow_jumps = 0; - - /* If -fexpensive-optimizations, re-run CSE to clean up things done - by gcse. */ - if (flag_expensive_optimizations) - { - timevar_push (TV_CSE); - reg_scan (get_insns (), max_reg_num ()); - tem2 = cse_main (get_insns (), max_reg_num (), dump_file); - purge_all_dead_edges (); - delete_trivially_dead_insns (get_insns (), max_reg_num ()); - timevar_pop (TV_CSE); - cse_not_expected = !flag_rerun_cse_after_loop; - } - - /* If gcse or cse altered any jumps, rerun jump optimizations to clean - things up. */ - if (tem || tem2) - { - timevar_push (TV_JUMP); - rebuild_jump_labels (get_insns ()); - delete_dead_jumptables (); - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); - timevar_pop (TV_JUMP); - } - - close_dump_file (DFI_gcse, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_GCSE); - - ggc_collect (); - flag_cse_skip_blocks = save_csb; - flag_cse_follow_jumps = save_cfj; -#ifdef ENABLE_CHECKING - verify_flow_info (); -#endif -} - -/* Move constant computations out of loops. */ -static void -rest_of_handle_loop_optimize (void) -{ - int do_prefetch; - - timevar_push (TV_LOOP); - open_dump_file (DFI_loop, current_function_decl); - - /* CFG is no longer maintained up-to-date. */ - free_bb_for_insn (); - profile_status = PROFILE_ABSENT; - - do_prefetch = flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0; - - if (flag_rerun_loop_opt) - { - cleanup_barriers (); - - /* We only want to perform unrolling once. */ - loop_optimize (get_insns (), dump_file, 0); - - /* The first call to loop_optimize makes some instructions - trivially dead. We delete those instructions now in the - hope that doing so will make the heuristics in loop work - better and possibly speed up compilation. */ - delete_trivially_dead_insns (get_insns (), max_reg_num ()); - - /* The regscan pass is currently necessary as the alias - analysis code depends on this information. */ - reg_scan (get_insns (), max_reg_num ()); - } - cleanup_barriers (); - loop_optimize (get_insns (), dump_file, do_prefetch); - - /* Loop can create trivially dead instructions. */ - delete_trivially_dead_insns (get_insns (), max_reg_num ()); - find_basic_blocks (get_insns ()); - close_dump_file (DFI_loop, print_rtl, get_insns ()); - timevar_pop (TV_LOOP); - - ggc_collect (); -} - -/* Perform loop optimizations. It might be better to do them a bit - sooner, but we want the profile feedback to work more - efficiently. */ -static void -rest_of_handle_loop2 (void) -{ - struct loops *loops; - basic_block bb; - - if (!flag_move_loop_invariants - && !flag_unswitch_loops - && !flag_peel_loops - && !flag_unroll_loops - && !flag_branch_on_count_reg) - return; - - timevar_push (TV_LOOP); - open_dump_file (DFI_loop2, current_function_decl); - if (dump_file) - dump_flow_info (dump_file); - - /* Initialize structures for layout changes. */ - cfg_layout_initialize (0); - - loops = loop_optimizer_init (dump_file); - - if (loops) - { - /* The optimizations: */ - if (flag_move_loop_invariants) - move_loop_invariants (loops); - - if (flag_unswitch_loops) - unswitch_loops (loops); - - if (flag_peel_loops || flag_unroll_loops) - unroll_and_peel_loops (loops, - (flag_peel_loops ? UAP_PEEL : 0) | - (flag_unroll_loops ? UAP_UNROLL : 0) | - (flag_unroll_all_loops ? UAP_UNROLL_ALL : 0)); - -#ifdef HAVE_doloop_end - if (flag_branch_on_count_reg && HAVE_doloop_end) - doloop_optimize_loops (loops); -#endif /* HAVE_doloop_end */ - - loop_optimizer_finalize (loops, dump_file); - } - - free_dominance_info (CDI_DOMINATORS); - - /* Finalize layout changes. */ - FOR_EACH_BB (bb) - if (bb->next_bb != EXIT_BLOCK_PTR) - bb->rbi->next = bb->next_bb; - cfg_layout_finalize (); - - cleanup_cfg (CLEANUP_EXPENSIVE); - delete_trivially_dead_insns (get_insns (), max_reg_num ()); - reg_scan (get_insns (), max_reg_num ()); - if (dump_file) - dump_flow_info (dump_file); - close_dump_file (DFI_loop2, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_LOOP); - ggc_collect (); -} - -static void -rest_of_handle_branch_target_load_optimize (void) -{ - static int warned = 0; - - /* Leave this a warning for now so that it is possible to experiment - with running this pass twice. In 3.6, we should either make this - an error, or use separate dump files. */ - if (flag_branch_target_load_optimize - && flag_branch_target_load_optimize2 - && !warned) - { - warning (0, "branch target register load optimization is not intended " - "to be run twice"); - - warned = 1; - } - - open_dump_file (DFI_branch_target_load, current_function_decl); - branch_target_load_optimize (epilogue_completed); - close_dump_file (DFI_branch_target_load, print_rtl_with_bb, get_insns ()); - ggc_collect (); -} - -#ifdef OPTIMIZE_MODE_SWITCHING -static void -rest_of_handle_mode_switching (void) -{ - timevar_push (TV_MODE_SWITCH); - - no_new_pseudos = 0; - optimize_mode_switching (NULL); - no_new_pseudos = 1; - - timevar_pop (TV_MODE_SWITCH); -} -#endif - -static void -rest_of_handle_jump (void) -{ - ggc_collect (); - - timevar_push (TV_JUMP); - open_dump_file (DFI_sibling, current_function_decl); - - delete_unreachable_blocks (); -#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); -} - -static void -rest_of_handle_eh (void) -{ - insn_locators_initialize (); - /* Complete generation of exception handling code. */ - if (doing_eh (0)) - { - timevar_push (TV_JUMP); - open_dump_file (DFI_eh, current_function_decl); - - cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL); - - finish_eh_generation (); - - cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL); - - close_dump_file (DFI_eh, print_rtl, get_insns ()); - timevar_pop (TV_JUMP); - } -} - -static void -rest_of_handle_stack_adjustments (void) -{ - life_analysis (dump_file, PROP_POSTRELOAD); - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE - | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0)); - - /* This is kind of a heuristic. We need to run combine_stack_adjustments - even for machines with possibly nonzero RETURN_POPS_ARGS - and ACCUMULATE_OUTGOING_ARGS. We expect that only ports having - push instructions will have popping returns. */ -#ifndef PUSH_ROUNDING - if (!ACCUMULATE_OUTGOING_ARGS) -#endif - combine_stack_adjustments (); -} - -static void -rest_of_handle_flow2 (void) -{ - timevar_push (TV_FLOW2); - open_dump_file (DFI_flow2, current_function_decl); - - /* Re-create the death notes which were deleted during reload. */ -#ifdef ENABLE_CHECKING - verify_flow_info (); -#endif - - /* If optimizing, then go ahead and split insns now. */ -#ifndef STACK_REGS - if (optimize > 0) -#endif - split_all_insns (0); - - if (flag_branch_target_load_optimize) - { - close_dump_file (DFI_flow2, print_rtl_with_bb, get_insns ()); - rest_of_handle_branch_target_load_optimize (); - open_dump_file (DFI_flow2, current_function_decl); - } - - if (optimize) - cleanup_cfg (CLEANUP_EXPENSIVE); - - /* On some machines, the prologue and epilogue code, or parts thereof, - can be represented as RTL. Doing so lets us schedule insns between - it and the rest of the code and also allows delayed branch - scheduling to operate in the epilogue. */ - thread_prologue_and_epilogue_insns (get_insns ()); - epilogue_completed = 1; - - if (optimize) - rest_of_handle_stack_adjustments (); - - flow2_completed = 1; - - close_dump_file (DFI_flow2, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_FLOW2); - - ggc_collect (); -} - - -static void -rest_of_handle_jump2 (void) -{ - open_dump_file (DFI_jump, current_function_decl); - - /* Always do one jump optimization pass to ensure that JUMP_LABEL fields - are initialized and to compute whether control can drop off the end - of the function. */ - - timevar_push (TV_JUMP); - /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB. Do this - before jump optimization switches branch directions. */ - if (flag_guess_branch_prob) - expected_value_to_br_prob (); - - delete_trivially_dead_insns (get_insns (), max_reg_num ()); - reg_scan (get_insns (), max_reg_num ()); - if (dump_file) - dump_flow_info (dump_file); - cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP - | (flag_thread_jumps ? CLEANUP_THREADING : 0)); - - create_loop_notes (); - - purge_line_number_notes (get_insns ()); - - if (optimize) - cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); - - /* Jump optimization, and the removal of NULL pointer checks, may - have reduced the number of instructions substantially. CSE, and - future passes, allocate arrays whose dimensions involve the - maximum instruction UID, so if we can reduce the maximum UID - we'll save big on memory. */ - renumber_insns (dump_file); - - close_dump_file (DFI_jump, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_JUMP); - - ggc_collect (); -} - -#ifdef HAVE_peephole2 -static void -rest_of_handle_peephole2 (void) -{ - timevar_push (TV_PEEPHOLE2); - open_dump_file (DFI_peephole2, current_function_decl); - - peephole2_optimize (dump_file); - - close_dump_file (DFI_peephole2, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_PEEPHOLE2); -} -#endif - -static void -rest_of_handle_postreload (void) -{ - timevar_push (TV_RELOAD_CSE_REGS); - open_dump_file (DFI_postreload, current_function_decl); - - /* Do a very simple CSE pass over just the hard registers. */ - reload_cse_regs (get_insns ()); - /* reload_cse_regs can eliminate potentially-trapping MEMs. - Remove any EH edges associated with them. */ - if (flag_non_call_exceptions) - purge_all_dead_edges (); - - close_dump_file (DFI_postreload, print_rtl_with_bb, get_insns ()); - timevar_pop (TV_RELOAD_CSE_REGS); -} - -static void -rest_of_handle_shorten_branches (void) -{ - /* Shorten branches. */ - timevar_push (TV_SHORTEN_BRANCH); - shorten_branches (get_insns ()); - timevar_pop (TV_SHORTEN_BRANCH); -} - -static void -rest_of_clean_state (void) -{ - rtx insn, next; - - /* It is very important to decompose the RTL instruction chain here: - debug information keeps pointing into CODE_LABEL insns inside the function - body. If these remain pointing to the other insns, we end up preserving - whole RTL chain and attached detailed debug info in memory. */ - for (insn = get_insns (); insn; insn = next) - { - next = NEXT_INSN (insn); - NEXT_INSN (insn) = NULL; - PREV_INSN (insn) = NULL; - } - - /* In case the function was not output, - don't leave any temporary anonymous types - queued up for sdb output. */ -#ifdef SDB_DEBUGGING_INFO - if (write_symbols == SDB_DEBUG) - sdbout_types (NULL_TREE); -#endif - - reload_completed = 0; - epilogue_completed = 0; - flow2_completed = 0; - no_new_pseudos = 0; - - timevar_push (TV_FINAL); - - /* Clear out the insn_length contents now that they are no - longer valid. */ - init_insn_lengths (); - - /* Show no temporary slots allocated. */ - init_temp_slots (); - - free_basic_block_vars (); - free_bb_for_insn (); - - timevar_pop (TV_FINAL); - - if (targetm.binds_local_p (current_function_decl)) - { - int pref = cfun->preferred_stack_boundary; - if (cfun->stack_alignment_needed > cfun->preferred_stack_boundary) - pref = cfun->stack_alignment_needed; - cgraph_rtl_info (current_function_decl)->preferred_incoming_stack_boundary - = pref; - } - - /* Make sure volatile mem refs aren't considered valid operands for - arithmetic insns. We must call this here if this is a nested inline - function, since the above code leaves us in the init_recog state - (from final.c), and the function context push/pop code does not - save/restore volatile_ok. - - ??? Maybe it isn't necessary for expand_start_function to call this - anymore if we do it here? */ - - init_recog_no_volatile (); - - /* We're done with this function. Free up memory if we can. */ - free_after_parsing (cfun); - free_after_compilation (cfun); -} -/* This function is called from the pass manager in tree-optimize.c - after all tree passes have finished for a single function, and we - have expanded the function body from trees to RTL. - Once we are here, we have decided that we're supposed to output - that function, i.e. that we should write assembler code for it. - - We run a series of low-level passes here on the function's RTL - representation. Each pass is called via a rest_of_* function. */ - -static void -rest_of_compilation (void) -{ - /* If we're emitting a nested function, make sure its parent gets - emitted as well. Doing otherwise confuses debug info. */ - { - tree parent; - for (parent = DECL_CONTEXT (current_function_decl); - parent != NULL_TREE; - parent = get_containing_scope (parent)) - if (TREE_CODE (parent) == FUNCTION_DECL) - TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (parent)) = 1; - } - - /* We are now committed to emitting code for this function. Do any - preparation, such as emitting abstract debug info for the inline - before it gets mangled by optimization. */ - if (cgraph_function_possibly_inlined_p (current_function_decl)) - (*debug_hooks->outlining_inline_function) (current_function_decl); - - /* Remove any notes we don't need. That will make iterating - over the instruction sequence faster, and allow the garbage - collector to reclaim the memory used by the notes. */ - remove_unnecessary_notes (); - - /* Initialize some variables used by the optimizers. */ - init_function_for_compilation (); - - TREE_ASM_WRITTEN (current_function_decl) = 1; - - /* Early return if there were errors. We can run afoul of our - consistency checks, and there's not really much point in fixing them. */ - if (rtl_dump_and_exit || flag_syntax_only || errorcount || sorrycount) - goto exit_rest_of_compilation; - - rest_of_handle_jump (); - - rest_of_handle_eh (); - - /* Delay emitting hard_reg_initial_value sets until after EH landing pad - generation, which might create new sets. */ - emit_initial_value_sets (); - -#ifdef FINALIZE_PIC - /* If we are doing position-independent code generation, now - is the time to output special prologues and epilogues. - We do not want to do this earlier, because it just clutters - up inline functions with meaningless insns. */ - if (flag_pic) - FINALIZE_PIC; -#endif - - /* Copy any shared structure that should not be shared. */ - unshare_all_rtl (); - - /* Instantiate all virtual registers. */ - instantiate_virtual_regs (); - - rest_of_handle_jump2 (); - - if (optimize > 0) - rest_of_handle_cse (); - - if (optimize > 0) - { - if (flag_gcse) - rest_of_handle_gcse (); - - if (flag_loop_optimize) - rest_of_handle_loop_optimize (); - - if (flag_gcse) - rest_of_handle_jump_bypass (); - } - - timevar_push (TV_FLOW); - rest_of_handle_cfg (); - - if (!flag_tree_based_profiling - && (optimize > 0 || profile_arc_flag - || flag_test_coverage || flag_branch_probabilities)) - { - rtl_register_profile_hooks (); - rtl_register_value_prof_hooks (); - rest_of_handle_branch_prob (); - - if (flag_branch_probabilities - && flag_profile_values - && (flag_value_profile_transformations - || flag_speculative_prefetching)) - rest_of_handle_value_profile_transformations (); - - /* Remove the death notes created for vpt. */ - if (flag_profile_values) - count_or_remove_death_notes (NULL, 1); - } - - if (optimize > 0) - rest_of_handle_if_conversion (); - - if (optimize > 0 && flag_tracer) - rest_of_handle_tracer (); - - if (optimize > 0 - && flag_loop_optimize2) - rest_of_handle_loop2 (); - - if (optimize > 0 && flag_web) - rest_of_handle_web (); - - if (optimize > 0 && flag_rerun_cse_after_loop) - rest_of_handle_cse2 (); - - cse_not_expected = 1; - - rest_of_handle_life (); - timevar_pop (TV_FLOW); - - if (optimize > 0) - rest_of_handle_combine (); - - if (optimize > 0 && flag_if_conversion) - rest_of_handle_if_after_combine (); - - /* The optimization to partition hot/cold basic blocks into separate - sections of the .o file does not work well with linkonce or with - user defined section attributes. Don't call it if either case - arises. */ - - if (flag_reorder_blocks_and_partition - && !DECL_ONE_ONLY (current_function_decl) - && !user_defined_section_attribute) - rest_of_handle_partition_blocks (); - - if (optimize > 0 && flag_regmove) - rest_of_handle_regmove (); - - /* Do unconditional splitting before register allocation to allow machine - description to add extra information not needed previously. */ - split_all_insns (1); - -#ifdef OPTIMIZE_MODE_SWITCHING - rest_of_handle_mode_switching (); -#endif - - /* Any of the several passes since flow1 will have munged register - lifetime data a bit. We need it to be up to date for scheduling - (see handling of reg_known_equiv in init_alias_analysis). */ - recompute_reg_usage (); - -#ifdef INSN_SCHEDULING - if (optimize > 0 && flag_modulo_sched) - rest_of_handle_sms (); - - if (flag_schedule_insns) - rest_of_handle_sched (); -#endif - - /* Determine if the current function is a leaf before running reload - since this can impact optimizations done by the prologue and - epilogue thus changing register elimination offsets. */ - current_function_is_leaf = leaf_function_p (); - - if (rest_of_handle_old_regalloc ()) - goto exit_rest_of_compilation; - - if (optimize > 0) - rest_of_handle_postreload (); - - if (optimize > 0 && flag_gcse_after_reload) - rest_of_handle_gcse2 (); - - rest_of_handle_flow2 (); - -#ifdef HAVE_peephole2 - if (optimize > 0 && flag_peephole2) - rest_of_handle_peephole2 (); -#endif - - if (optimize > 0) - rest_of_handle_if_after_reload (); - - if (optimize > 0) - { - if (flag_rename_registers || flag_cprop_registers) - rest_of_handle_regrename (); - - rest_of_handle_reorder_blocks (); - } - - if (flag_branch_target_load_optimize2) - rest_of_handle_branch_target_load_optimize (); - -#ifdef LEAF_REGISTERS - current_function_uses_only_leaf_regs - = optimize > 0 && only_leaf_regs_used () && leaf_function_p (); -#endif - -#ifdef INSN_SCHEDULING - if (optimize > 0 && flag_schedule_insns_after_reload) - rest_of_handle_sched2 (); -#endif - -#ifdef STACK_REGS - rest_of_handle_stack_regs (); -#endif - - compute_alignments (); - - /* Aggressively duplicate basic blocks ending in computed gotos to the - tails of their predecessors, unless we are optimizing for size. */ - if (flag_expensive_optimizations && !optimize_size) - duplicate_computed_gotos (); - - if (flag_var_tracking) - rest_of_handle_variable_tracking (); - - /* CFG is no longer maintained up-to-date. */ - free_bb_for_insn (); - - if (targetm.machine_dependent_reorg != 0) - rest_of_handle_machine_reorg (); - - purge_line_number_notes (get_insns ()); - cleanup_barriers (); - -#ifdef DELAY_SLOTS - if (flag_delayed_branch) - rest_of_handle_delay_slots (); -#endif - -#if defined (HAVE_ATTR_length) && !defined (STACK_REGS) - timevar_push (TV_SHORTEN_BRANCH); - split_all_insns_noflow (); - timevar_pop (TV_SHORTEN_BRANCH); -#endif - - convert_to_eh_region_ranges (); - - rest_of_handle_shorten_branches (); - - set_nothrow_function_flags (); - - rest_of_handle_final (); - - exit_rest_of_compilation: - - rest_of_clean_state (); -} - void finish_optimization_passes (void) { --------------040206050304050704060205 Content-Type: text/plain; x-mac-type="0"; x-mac-creator="0"; name="rtl-add-passes.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="rtl-add-passes.patch" Content-length: 140222 2005-05-19 Paolo Bonzini * Makefile.in: Adjust dependencies. * tree-pass.h: Add new passes and passes formerly in tree-optimize.c. * basic-block.h (duplicate_computed_gotos): Remove, it is now static. * alias.c (rest_of_handle_cfg, pass_cfg): New. * bb-reorder.c (duplicate_computed_gotos): Make it static. * cfgexpand.c (tree_expand_cfg): Add code formerly at the beginning of rest_of_compilation. * bb-reorder.c (gate_duplicate_computed_gotos, pass_duplicate_computed_gotos, gate_handle_reorder_blocks, rest_of_handle_reorder_blocks, pass_reorder_blocks, gate_handle_partition_blocks, rest_of_handle_partition_blocks, pass_partition_blocks): New. * bt-load.c (gate_handle_branch_target_load_optimize, rest_of_handle_branch_target_load_optimize, pass_branch_target_load_optimize): New. * cfgcleanup.c (rest_of_handle_jump, pass_jump, rest_of_handle_jump2, pass_jump2): New. * cfglayout.c (pass_insn_locators_initialize): New. * cfgrtl.c (pass_free_cfg): New. * combine.c (gate_handle_combine, rest_of_handle_combine, pass_combine): New. * cse.c (gate_handle_cse, rest_of_handle_cse, pass_cse, gate_handle_cse2, rest_of_handle_cse2, pass_cse2): New. * emit-rtl.c (pass_unshare_all_rtl, pass_remove_unnecessary_notes): New. * except.c (pass_set_nothrow_function_flags, pass_convert_to_eh_region_ranges, gate_handle_eh, rest_of_handle_eh, pass_rtl_eh): New. * final.c (pass_compute_alignments, rest_of_handle_final, pass_final, rest_of_handle_shorten_branches, pass_shorten_branches, rest_of_clean_state, pass_clean_state): New. * flow.c (pass_recompute_reg_usage, gate_remove_death_notes, rest_of_handle_remove_death_notes, pass_remove_death_notes, rest_of_handle_life, pass_life, rest_of_handle_flow2, pass_flow2): New. * function.c (pass_instantiate_virtual_regs, pass_init_function, rest_of_handle_check_leaf_regs, pass_leaf_regs): New. * gcse.c (gate_handle_jump_bypass, rest_of_handle_jump_bypass, pass_jump_bypass, gate_handle_gcse, rest_of_handle_gcse, pass_gcse): New. * global.c (rest_of_handle_global_alloc, pass_global_alloc): New. * ifcvt.c (gate_handle_if_conversion, rest_of_handle_if_conversion, pass_rtl_ifcvt, gate_handle_if_after_combine, rest_of_handle_if_after_combine, pass_if_after_combine, gate_handle_if_after_reload, rest_of_handle_if_after_reload, pass_if_after_reload): New. * integrate.c (pass_initial_value_sets): New. * jump.c (pass_cleanup_barriers, purge_line_number_notes, pass_purge_lineno_notes): New. * mode-switching.c (rest_of_handle_mode_switching, pass_mode_switching): New. * local-alloc.c (rest_of_handle_local_alloc, pass_local_alloc): New. * loop-init.c (gate_handle_loop2, rest_of_handle_loop2, pass_loop2): New. * loop.c (gate_handle_loop_optimize, rest_of_handle_loop_optimize, pass_loop_optimize): New. * modulo-sched.c (gate_handle_sms, rest_of_handle_sms, pass_sms): New. * postreload-gcse.c (gate_handle_gcse2, rest_of_handle_gcse2, pass_gcse2): New. * postreload.c (gate_handle_postreload, rest_of_handle_postreload, pass_postreload_cse): New. * profile.c (gate_handle_profiling, pass_profiling, rest_of_handle_branch_prob, pass_branch_prob): New. * recog.c (pass pass_split_for_shorten_branches, gate_do_final_split, pass_split_before_regstack, gate_handle_split_before_regstack, gate_handle_peephole2, rest_of_handle_peephole2, pass_peephole2, rest_of_handle_split_all_insns, pass_split_all_insns): New. * reg-stack.c (gate_handle_stack_regs, rest_of_handle_stack_regs, pass_stack_regs): New. * regmove.c (gate_handle_regmove, rest_of_handle_regmove, pass_regmove, gate_handle_stack_adjustments, rest_of_handle_stack_adjustments, pass_stack_adjustments): New. * regrename.c (gate_handle_regrename, rest_of_handle_regrename, pass_regrename): New. * reorg.c (gate_handle_delay_slots, rest_of_handle_delay_slots, pass_delay_slots, gate_handle_machine_reorg, rest_of_handle_machine_reorg, pass_machine_reorg): New. * rtl.h (extern void purge_line_number_notes): New. * sched-rgn.c (gate_handle_sched, rest_of_handle_sched, gate_handle_sched2, rest_of_handle_sched2, pass_sched, pass_sched2): New. * tracer.c (gate_handle_tracer, rest_of_handle_tracer, pass_tracer): New. * value-prof.c (gate_handle_value_profile_transformations, rest_of_handle_value_profile_transformations, pass_value_profile_transformations): New. * var-tracking.c (gate_handle_var_tracking, pass_variable_tracking): New. * web.c (gate_handle_web, rest_of_handle_web, pass_web): New. Index: Makefile.in =================================================================== RCS file: /cvs/gcc/gcc/gcc/Makefile.in,v retrieving revision 1.1496 diff -p -u -r1.1496 Makefile.in --- Makefile.in 4 Jun 2005 17:07:50 -0000 1.1496 +++ Makefile.in 6 Jun 2005 07:41:49 -0000 @@ -1974,7 +1974,7 @@ function.o : function.c $(CONFIG_H) $(SY $(TREE_H) $(CFGLAYOUT_H) $(TREE_GIMPLE_H) $(FLAGS_H) function.h $(EXPR_H) \ $(OPTABS_H) libfuncs.h $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \ output.h toplev.h except.h $(HASHTAB_H) $(GGC_H) $(TM_P_H) langhooks.h \ - gt-function.h $(TARGET_H) $(BASIC_BLOCK_H) $(INTEGRATE_H) + gt-function.h $(TARGET_H) $(BASIC_BLOCK_H) $(INTEGRATE_H) tree-pass.h stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) function.h insn-config.h hard-reg-set.h $(EXPR_H) \ libfuncs.h except.h $(RECOG_H) toplev.h output.h $(GGC_H) $(TM_P_H) \ @@ -1985,7 +1985,7 @@ except.o : except.c $(CONFIG_H) $(SYSTEM langhooks.h insn-config.h hard-reg-set.h $(BASIC_BLOCK_H) output.h \ dwarf2asm.h dwarf2out.h toplev.h $(HASHTAB_H) intl.h $(GGC_H) \ gt-except.h $(CGRAPH_H) $(INTEGRATE_H) $(DIAGNOSTIC_H) dwarf2.h \ - $(TARGET_H) $(TM_P_H) + $(TARGET_H) $(TM_P_H) tree-pass.h timevar.h expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) function.h $(REGS_H) $(EXPR_H) $(OPTABS_H) \ libfuncs.h $(INSN_ATTR_H) insn-config.h $(RECOG_H) output.h \ @@ -2042,16 +2042,17 @@ xcoffout.o : xcoffout.c $(CONFIG_H) $(SY emit-rtl.o : emit-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) function.h $(REGS_H) insn-config.h $(RECOG_H) real.h \ $(GGC_H) $(EXPR_H) hard-reg-set.h bitmap.h toplev.h $(BASIC_BLOCK_H) \ - $(HASHTAB_H) $(TM_P_H) debug.h langhooks.h gt-emit-rtl.h + $(HASHTAB_H) $(TM_P_H) debug.h langhooks.h tree-pass.h gt-emit-rtl.h real.o : real.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \ toplev.h $(TM_P_H) real.h integrate.o : integrate.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(TREE_H) $(FLAGS_H) debug.h $(INTEGRATE_H) insn-config.h \ $(EXPR_H) real.h $(REGS_H) intl.h function.h output.h $(RECOG_H) \ except.h toplev.h $(PARAMS_H) $(TM_P_H) $(TARGET_H) langhooks.h \ - gt-integrate.h $(GGC_H) + gt-integrate.h $(GGC_H) tree-pass.h jump.o : jump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \ - hard-reg-set.h $(REGS_H) insn-config.h $(RECOG_H) $(EXPR_H) real.h except.h function.h \ + hard-reg-set.h $(REGS_H) insn-config.h $(RECOG_H) $(EXPR_H) real.h except.h \ + function.h tree-pass.h \ toplev.h $(INSN_ATTR_H) $(TM_P_H) reload.h $(PREDICT_H) $(TIMEVAR_H) \ $(DIAGNOSTIC_H) @@ -2084,24 +2085,25 @@ cselib.o : cselib.c $(CONFIG_H) $(SYSTEM cse.o : cse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \ hard-reg-set.h $(FLAGS_H) real.h insn-config.h $(RECOG_H) $(EXPR_H) toplev.h \ output.h function.h $(BASIC_BLOCK_H) $(GGC_H) $(TM_P_H) $(TIMEVAR_H) \ - except.h $(TARGET_H) $(PARAMS_H) rtlhooks-def.h + except.h $(TARGET_H) $(PARAMS_H) rtlhooks-def.h tree-pass.h web.o : web.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) function.h output.h toplev.h \ - $(DF_H) $(OBSTACK_H) + $(DF_H) $(OBSTACK_H) timevar.h tree-pass.h gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(REGS_H) hard-reg-set.h $(FLAGS_H) real.h insn-config.h $(GGC_H) \ $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) function.h output.h toplev.h \ $(TM_P_H) $(PARAMS_H) except.h gt-gcse.h $(TREE_H) cselib.h $(TIMEVAR_H) \ - intl.h $(OBSTACK_H) + intl.h $(OBSTACK_H) tree-pass.h resource.o : resource.c $(CONFIG_H) $(RTL_H) hard-reg-set.h $(SYSTEM_H) \ coretypes.h $(TM_H) $(REGS_H) $(FLAGS_H) output.h $(RESOURCE_H) \ function.h toplev.h $(INSN_ATTR_H) except.h $(PARAMS_H) $(TM_P_H) lcm.o : lcm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \ hard-reg-set.h $(FLAGS_H) real.h insn-config.h $(INSN_ATTR_H) $(RECOG_H) \ $(BASIC_BLOCK_H) $(TM_P_H) function.h output.h -mode-switching.o : mode-switching.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ - $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) real.h insn-config.h \ - $(INSN_ATTR_H) $(RECOG_H) $(BASIC_BLOCK_H) $(TM_P_H) function.h output.h +mode-switching.o : mode-switching.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ + $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) real.h insn-config.h \ + $(INSN_ATTR_H) $(RECOG_H) $(BASIC_BLOCK_H) $(TM_P_H) function.h output.h \ + tree-pass.h timevar.h tree-ssa-dce.o : tree-ssa-dce.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) \ $(RTL_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) \ coretypes.h $(TREE_DUMP_H) tree-pass.h $(FLAGS_H) $(BASIC_BLOCK_H) \ @@ -2131,12 +2133,13 @@ df.o : df.c $(CONFIG_H) $(SYSTEM_H) core var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(TREE_H) hard-reg-set.h insn-config.h reload.h $(FLAGS_H) \ $(BASIC_BLOCK_H) output.h sbitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \ - $(REGS_H) $(EXPR_H) + $(REGS_H) $(EXPR_H) timevar.h tree-pass.h conflict.o : conflict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(OBSTACK_H) \ $(HASHTAB_H) $(RTL_H) hard-reg-set.h $(BASIC_BLOCK_H) profile.o : profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) function.h \ - toplev.h $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h + toplev.h $(COVERAGE_H) $(TREE_FLOW_H) value-prof.h cfghooks.h \ + cfgloop.h timevar.h tree-pass.h tree-profile.o : tree-profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) output.h $(REGS_H) $(EXPR_H) \ function.h toplev.h $(COVERAGE_H) $(TREE_H) value-prof.h $(TREE_DUMP_H) \ @@ -2148,11 +2152,12 @@ value-prof.o : value-prof.c $(CONFIG_H) $(BASIC_BLOCK_H) hard-reg-set.h value-prof.h $(EXPR_H) output.h $(FLAGS_H) \ $(RECOG_H) insn-config.h $(OPTABS_H) $(REGS_H) $(GGC_H) $(DIAGNOSTIC_H) \ $(TREE_H) $(COVERAGE_H) $(RTL_H) $(GCOV_IO_H) $(TREE_FLOW_H) \ - tree-flow-inline.h + tree-flow-inline.h timevar.h tree-pass.h loop.o : loop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(FLAGS_H) insn-config.h $(REGS_H) hard-reg-set.h $(RECOG_H) $(EXPR_H) \ real.h $(PREDICT_H) $(BASIC_BLOCK_H) function.h $(CFGLOOP_H) \ - toplev.h except.h cselib.h $(OPTABS_H) $(TM_P_H) $(GGC_H) insn-flags.h + toplev.h except.h cselib.h $(OPTABS_H) $(TM_P_H) $(GGC_H) insn-flags.h \ + timevar.h tree-pass.h loop-doloop.o : loop-doloop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(FLAGS_H) $(EXPR_H) hard-reg-set.h $(BASIC_BLOCK_H) $(TM_P_H) \ toplev.h $(CFGLOOP_H) output.h $(PARAMS_H) @@ -2160,7 +2165,7 @@ alloc-pool.o : alloc-pool.c $(CONFIG_H) flow.o : flow.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) \ hard-reg-set.h output.h toplev.h $(RECOG_H) function.h except.h \ - $(EXPR_H) $(TM_P_H) $(OBSTACK_H) $(SPLAY_TREE_H) $(TIMEVAR_H) + $(EXPR_H) $(TM_P_H) $(OBSTACK_H) $(SPLAY_TREE_H) $(TIMEVAR_H) tree-pass.h cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \ $(REGS_H) hard-reg-set.h output.h toplev.h function.h except.h $(GGC_H) \ $(TM_P_H) $(TIMEVAR_H) $(OBSTACK_H) $(TREE_H) @@ -2169,11 +2174,12 @@ cfghooks.o: cfghooks.c $(CONFIG_H) $(SYS cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ $(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) function.h $(TIMEVAR_H) $(TM_H) \ coretypes.h $(TREE_DUMP_H) except.h langhooks.h tree-pass.h $(RTL_H) \ - $(DIAGNOSTIC_H) toplev.h $(BASIC_BLOCK_H) $(FLAGS_H) + $(DIAGNOSTIC_H) toplev.h $(BASIC_BLOCK_H) $(FLAGS_H) debug.h cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \ output.h toplev.h function.h except.h $(TM_P_H) insn-config.h $(EXPR_H) \ - $(CFGLAYOUT_H) $(CFGLOOP_H) $(OBSTACK_H) $(TARGET_H) $(TREE_H) + $(CFGLAYOUT_H) $(CFGLOOP_H) $(OBSTACK_H) $(TARGET_H) $(TREE_H) \ + tree-pass.h cfganal.o : cfganal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(BASIC_BLOCK_H) hard-reg-set.h insn-config.h $(RECOG_H) $(TM_P_H) \ $(TIMEVAR_H) $(OBSTACK_H) toplev.h @@ -2183,7 +2189,7 @@ cfgbuild.o : cfgbuild.c $(CONFIG_H) $(SY cfgcleanup.o : cfgcleanup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(TIMEVAR_H) hard-reg-set.h output.h $(FLAGS_H) $(RECOG_H) \ toplev.h insn-config.h cselib.h $(TARGET_H) $(TM_P_H) $(PARAMS_H) \ - $(REGS_H) $(EMIT_RTL_H) $(CFGLAYOUT_H) + $(REGS_H) $(EMIT_RTL_H) $(CFGLAYOUT_H) tree-pass.h cfgloop.h expr.h cfgloop.o : cfgloop.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) coretypes.h $(TM_H) \ $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(FLAGS_H) function.h \ $(OBSTACK_H) toplev.h $(TREE_FLOW_H) $(TREE_H) @@ -2201,7 +2207,7 @@ cfgloopmanip.o : cfgloopmanip.c $(CONFIG coretypes.h $(TM_H) cfghooks.h $(OBSTACK_H) loop-init.o : loop-init.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) \ $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) \ - coretypes.h $(TM_H) $(OBSTACK_H) + coretypes.h $(TM_H) $(OBSTACK_H) tree-pass.h timevar.h $(FLAGS_H) loop-unswitch.o : loop-unswitch.c $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TM_H) \ $(BASIC_BLOCK_H) hard-reg-set.h $(CFGLOOP_H) $(CFGLAYOUT_H) $(PARAMS_H) \ output.h $(EXPR_H) coretypes.h $(TM_H) $(OBSTACK_H) @@ -2217,7 +2223,7 @@ combine.o : combine.c $(CONFIG_H) $(SYST $(FLAGS_H) function.h insn-config.h $(INSN_ATTR_H) $(REGS_H) $(EXPR_H) \ rtlhooks-def.h $(BASIC_BLOCK_H) $(RECOG_H) real.h hard-reg-set.h \ toplev.h $(TM_P_H) $(TREE_H) $(TARGET_H) output.h $(PARAMS_H) $(OPTABS_H) \ - insn-codes.h + insn-codes.h timevar.h tree-pass.h regclass.o : regclass.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ hard-reg-set.h $(FLAGS_H) $(BASIC_BLOCK_H) $(REGS_H) insn-config.h \ $(RECOG_H) reload.h real.h toplev.h function.h output.h $(GGC_H) \ @@ -2225,12 +2231,13 @@ regclass.o : regclass.c $(CONFIG_H) $(SY local-alloc.o : local-alloc.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(RECOG_H) \ output.h function.h $(INSN_ATTR_H) toplev.h except.h reload.h $(TM_P_H) \ - $(GGC_H) $(INTEGRATE_H) + $(GGC_H) $(INTEGRATE_H) timevar.h tree-pass.h bitmap.o : bitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(FLAGS_H) $(GGC_H) gt-bitmap.h bitmap.h $(OBSTACK_H) global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(FLAGS_H) reload.h function.h $(RECOG_H) $(REGS_H) hard-reg-set.h \ - insn-config.h output.h toplev.h $(TM_P_H) $(MACHMODE_H) + insn-config.h output.h toplev.h $(TM_P_H) $(MACHMODE_H) tree-pass.h \ + timevar.h varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GGC_H) \ $(HASHTAB_H) $(BCONFIG_H) $(VARRAY_H) toplev.h vec.o : vec.c $(CONFIG_H) $(SYSTEM_H) $(TREE_H) coretypes.h vec.h $(GGC_H) \ @@ -2249,28 +2256,30 @@ postreload.o : postreload.c $(CONFIG_H) $(RTL_H) real.h $(FLAGS_H) $(EXPR_H) $(OPTABS_H) reload.h $(REGS_H) \ hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) $(RECOG_H) output.h \ function.h toplev.h cselib.h $(TM_P_H) except.h $(TREE_H) $(MACHMODE_H) \ - $(OBSTACK_H) + $(OBSTACK_H) timevar.h tree-pass.h postreload-gcse.o : postreload-gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) real.h insn-config.h \ $(RECOG_H) $(EXPR_H) $(BASIC_BLOCK_H) function.h output.h toplev.h \ $(TM_P_H) except.h $(TREE_H) $(TARGET_H) $(HASHTAB_H) intl.h $(OBSTACK_H) \ - $(PARAMS_H) + $(PARAMS_H) timevar.h tree-pass.h caller-save.o : caller-save.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(FLAGS_H) $(REGS_H) hard-reg-set.h insn-config.h $(BASIC_BLOCK_H) function.h \ $(RECOG_H) reload.h $(EXPR_H) toplev.h $(TM_P_H) bt-load.o : bt-load.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) except.h \ - $(RTL_H) hard-reg-set.h $(REGS_H) $(TM_P_H) $(FIBHEAP_H) output.h \ - $(TARGET_H) $(EXPR_H) $(FLAGS_H) $(INSN_ATTR_H) function.h + $(RTL_H) hard-reg-set.h $(REGS_H) $(TM_P_H) $(FIBHEAP_H) output.h $(EXPR_H) \ + $(TARGET_H) $(FLAGS_H) $(INSN_ATTR_H) function.h tree-pass.h toplev.h reorg.o : reorg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ conditions.h hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) insn-config.h \ $(INSN_ATTR_H) except.h $(RECOG_H) function.h $(FLAGS_H) output.h \ - $(EXPR_H) toplev.h $(PARAMS_H) $(TM_P_H) $(OBSTACK_H) $(RESOURCE_H) + $(EXPR_H) toplev.h $(PARAMS_H) $(TM_P_H) $(OBSTACK_H) $(RESOURCE_H) \ + timevar.h target.h tree-pass.h alias.o : alias.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(FLAGS_H) hard-reg-set.h $(BASIC_BLOCK_H) $(REGS_H) toplev.h output.h \ $(ALIAS_H) $(EMIT_RTL_H) $(GGC_H) function.h cselib.h $(TREE_H) $(TM_P_H) \ langhooks.h $(TARGET_H) gt-alias.h $(TIMEVAR_H) $(CGRAPH_H) \ - $(SPLAY_TREE_H) $(VARRAY_H) -regmove.o : regmove.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) insn-config.h \ + $(SPLAY_TREE_H) $(VARRAY_H) tree-pass.h +regmove.o : regmove.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ + insn-config.h timevar.h tree-pass.h \ $(RECOG_H) output.h $(REGS_H) hard-reg-set.h $(FLAGS_H) function.h \ $(EXPR_H) $(BASIC_BLOCK_H) toplev.h $(TM_P_H) except.h reload.h ddg.o : ddg.c $(DDG_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TARGET_H) \ @@ -2282,7 +2291,7 @@ modulo-sched.o : modulo-sched.c $(DDG_H) coretypes.h $(TARGET_H) toplev.h $(RTL_H) $(TM_P_H) $(REGS_H) function.h \ $(FLAGS_H) insn-config.h $(INSN_ATTR_H) except.h $(RECOG_H) \ $(SCHED_INT_H) $(CFGLAYOUT_H) $(CFGLOOP_H) $(EXPR_H) $(PARAMS_H) \ - cfghooks.h $(DF_H) $(GCOV_IO_H) hard-reg-set.h $(TM_H) + cfghooks.h $(DF_H) $(GCOV_IO_H) hard-reg-set.h $(TM_H) timevar.h tree-pass.h haifa-sched.o : haifa-sched.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h function.h \ $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) $(TARGET_H) @@ -2293,7 +2302,7 @@ sched-deps.o : sched-deps.c $(CONFIG_H) sched-rgn.o : sched-rgn.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ function.h $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(PARAMS_H) \ - $(TM_P_H) $(TARGET_H) $(CFGLAYOUT_H) + $(TM_P_H) $(TARGET_H) $(CFGLAYOUT_H) timevar.h tree-pass.h sched-ebb.o : sched-ebb.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(SCHED_INT_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) insn-config.h \ function.h $(INSN_ATTR_H) toplev.h $(RECOG_H) except.h $(TM_P_H) \ @@ -2304,16 +2313,17 @@ sched-vis.o : sched-vis.c $(CONFIG_H) $( final.o : final.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) intl.h $(REGS_H) $(RECOG_H) conditions.h \ insn-config.h $(INSN_ATTR_H) function.h real.h output.h hard-reg-set.h \ - except.h debug.h xcoffout.h toplev.h reload.h dwarf2out.h \ - $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H) $(EXPR_H) $(CFGLAYOUT_H) dbxout.h + except.h debug.h xcoffout.h toplev.h reload.h dwarf2out.h tree-pass.h \ + $(BASIC_BLOCK_H) $(TM_P_H) $(TARGET_H) $(EXPR_H) $(CFGLAYOUT_H) dbxout.h \ + timevar.h cgraph.h coverage.h recog.o : recog.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ function.h $(BASIC_BLOCK_H) $(REGS_H) $(RECOG_H) $(EXPR_H) hard-reg-set.h \ $(FLAGS_H) insn-config.h $(INSN_ATTR_H) real.h toplev.h output.h reload.h \ - $(TM_P_H) + $(TM_P_H) timevar.h tree-pass.h reg-stack.o : reg-stack.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(TREE_H) $(RECOG_H) $(REGS_H) hard-reg-set.h $(FLAGS_H) \ insn-config.h toplev.h reload.h function.h $(TM_P_H) $(GGC_H) \ - gt-reg-stack.h $(BASIC_BLOCK_H) output.h $(VARRAY_H) + gt-reg-stack.h $(BASIC_BLOCK_H) output.h $(VARRAY_H) timevar.h tree-pass.h sreal.o: sreal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) sreal.h predict.o: predict.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(FLAGS_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) \ @@ -2326,24 +2336,25 @@ lists.o: lists.c $(CONFIG_H) $(SYSTEM_H) bb-reorder.o : bb-reorder.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(FLAGS_H) $(TIMEVAR_H) output.h $(CFGLAYOUT_H) $(FIBHEAP_H) \ $(TARGET_H) function.h $(TM_P_H) $(OBSTACK_H) $(EXPR_H) $(REGS_H) \ - $(PARAMS_H) toplev.h + $(PARAMS_H) toplev.h tree-pass.h tracer.o : tracer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(BASIC_BLOCK_H) hard-reg-set.h output.h $(CFGLAYOUT_H) \ - $(FLAGS_H) $(TIMEVAR_H) $(PARAMS_H) $(COVERAGE_H) $(FIBHEAP_H) + $(FLAGS_H) $(TIMEVAR_H) $(PARAMS_H) $(COVERAGE_H) $(FIBHEAP_H) \ + tree-pass.h cfglayout.o : cfglayout.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) $(TREE_H) insn-config.h $(BASIC_BLOCK_H) hard-reg-set.h output.h \ function.h $(CFGLAYOUT_H) $(CFGLOOP_H) $(TARGET_H) gt-cfglayout.h \ - $(GGC_H) alloc-pool.h $(FLAGS_H) $(OBSTACK_H) + $(GGC_H) alloc-pool.h $(FLAGS_H) $(OBSTACK_H) tree-pass.h timevar.o : timevar.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(TIMEVAR_H) $(FLAGS_H) intl.h toplev.h $(RTL_H) timevar.def regrename.o : regrename.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \ $(RTL_H) insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h \ output.h $(RECOG_H) function.h $(OBSTACK_H) $(FLAGS_H) $(TM_P_H) \ - reload.h toplev.h + reload.h toplev.h timevar.h tree-pass.h ifcvt.o : ifcvt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(REGS_H) toplev.h $(FLAGS_H) insn-config.h function.h $(RECOG_H) \ $(TARGET_H) $(BASIC_BLOCK_H) $(EXPR_H) output.h except.h $(TM_P_H) \ - real.h $(OPTABS_H) $(CFGLOOP_H) hard-reg-set.h + real.h $(OPTABS_H) $(CFGLOOP_H) hard-reg-set.h timevar.h tree-pass.h lambda-mat.o : lambda-mat.c $(LAMBDA_H) $(GGC_H) $(SYSTEM_H) $(CONFIG_H) \ $(TM_H) coretypes.h $(TREE_H) $(VARRAY_H) lambda-trans.o: lambda-trans.c $(LAMBDA_H) $(GGC_H) $(SYSTEM_H) $(CONFIG_H) \ Index: alias.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/alias.c,v retrieving revision 1.250 diff -p -u -r1.250 alias.c --- alias.c 21 Apr 2005 15:47:04 -0000 1.250 +++ alias.c 18 May 2005 10:27:08 -0000 @@ -44,6 +44,7 @@ Software Foundation, 59 Temple Place - S #include "target.h" #include "cgraph.h" #include "varray.h" +#include "tree-pass.h" /* The alias sets assigned to MEMs assist the back-end in determining which MEMs can alias which other MEMs. In general, two MEMs in @@ -2967,5 +2968,57 @@ end_alias_analysis (void) alias_invariant_size = 0; } } + +/* Do control and data flow analysis; write some of the results to the + dump file. */ +static void +rest_of_handle_cfg (void) +{ + if (dump_file) + dump_flow_info (dump_file); + if (optimize) + cleanup_cfg (CLEANUP_EXPENSIVE + | (flag_thread_jumps ? CLEANUP_THREADING : 0)); + + /* It may make more sense to mark constant functions after dead code is + eliminated by life_analysis, but we need to do it early, as -fprofile-arcs + may insert code making function non-constant, but we still must consider + it as constant, otherwise -fbranch-probabilities will not read data back. + + life_analysis rarely eliminates modification of external memory. + + FIXME: now with tree based profiling we are in the trap described above + again. It seems to be easiest to disable the optimization for time + being before the problem is either solved by moving the transformation + to the IPA level (we need the CFG for this) or the very early optimization + passes are made to ignore the const/pure flags so code does not change. */ + if (optimize + && (!flag_tree_based_profiling + || (!profile_arc_flag && !flag_branch_probabilities))) + { + /* Alias analysis depends on this information and mark_constant_function + depends on alias analysis. */ + reg_scan (get_insns (), max_reg_num ()); + mark_constant_function (); + } +} + +struct tree_opt_pass pass_cfg = +{ + "cfg", /* name */ + NULL, /* gate */ + rest_of_handle_cfg, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_FLOW, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'f' /* letter */ +}; + #include "gt-alias.h" Index: basic-block.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/basic-block.h,v retrieving revision 1.256 diff -p -u -r1.256 basic-block.h --- basic-block.h 13 May 2005 13:34:17 -0000 1.256 +++ basic-block.h 18 May 2005 10:27:10 -0000 @@ -934,7 +934,6 @@ extern bool control_flow_insn_p (rtx); /* In bb-reorder.c */ extern void reorder_basic_blocks (unsigned int); -extern void duplicate_computed_gotos (void); extern void partition_hot_cold_basic_blocks (void); /* In cfg.c */ Index: bb-reorder.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/bb-reorder.c,v retrieving revision 1.104 diff -p -u -u -p -r1.104 bb-reorder.c --- bb-reorder.c 1 Jun 2005 02:50:51 -0000 1.104 +++ bb-reorder.c 6 Jun 2005 08:43:28 -0000 @@ -83,6 +83,11 @@ #include "expr.h" #include "params.h" #include "toplev.h" +#include "tree-pass.h" + +#ifndef HAVE_conditional_execution +#define HAVE_conditional_execution 0 +#endif /* The number of rounds. In most cases there will only be 4 rounds, but when partitioning hot and cold basic blocks into separate sections of @@ -1893,8 +1898,6 @@ reorder_basic_blocks (unsigned int flags if (targetm.cannot_modify_jumps_p ()) return; - timevar_push (TV_REORDER_BLOCKS); - cfg_layout_initialize (flags); set_edge_can_fallthru_flag (); @@ -1930,8 +1933,6 @@ reorder_basic_blocks (unsigned int flags cfg_layout_finalize (); if (flag_reorder_blocks_and_partition) verify_hot_cold_block_grouping (); - - timevar_pop (TV_REORDER_BLOCKS); } /* Determine which partition the first basic block in the function @@ -1969,7 +1970,14 @@ insert_section_boundary_note (void) which can seriously pessimize code with many computed jumps in the source code, such as interpreters. See e.g. PR15242. */ -void +static bool +gate_duplicate_computed_gotos (void) +{ + return (optimize > 0 && flag_expensive_optimizations && !optimize_size); +} + + +static void duplicate_computed_gotos (void) { basic_block bb, new_bb; @@ -1982,8 +1990,6 @@ duplicate_computed_gotos (void) if (targetm.cannot_modify_jumps_p ()) return; - timevar_push (TV_REORDER_BLOCKS); - cfg_layout_initialize (0); /* We are estimating the length of uncond jump insn only once @@ -2075,10 +2081,26 @@ done: cfg_layout_finalize (); BITMAP_FREE (candidates); - - timevar_pop (TV_REORDER_BLOCKS); } +struct tree_opt_pass pass_duplicate_computed_gotos = +{ + NULL, /* name */ + gate_duplicate_computed_gotos, /* gate */ + duplicate_computed_gotos, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_REORDER_BLOCKS, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + + /* This function is the main 'entrance' for the optimization that partitions hot and cold basic blocks into separate sections of the .o file (to improve performance and cache locality). Ideally it @@ -2168,3 +2190,104 @@ partition_hot_cold_basic_blocks (void) cfg_layout_finalize(); } + +static bool +gate_handle_reorder_blocks (void) +{ + return (optimize > 0); +} + + +/* Reorder basic blocks. */ +static void +rest_of_handle_reorder_blocks (void) +{ + bool changed; + unsigned int liveness_flags; + + /* Last attempt to optimize CFG, as scheduling, peepholing and insn + splitting possibly introduced more crossjumping opportunities. */ + liveness_flags = (!HAVE_conditional_execution ? CLEANUP_UPDATE_LIFE : 0); + changed = cleanup_cfg (CLEANUP_EXPENSIVE | liveness_flags); + + if (flag_sched2_use_traces && flag_schedule_insns_after_reload) + { + timevar_push (TV_TRACER); + tracer (liveness_flags); + timevar_pop (TV_TRACER); + } + + if (flag_reorder_blocks || flag_reorder_blocks_and_partition) + reorder_basic_blocks (liveness_flags); + if (flag_reorder_blocks || flag_reorder_blocks_and_partition + || (flag_sched2_use_traces && flag_schedule_insns_after_reload)) + changed |= cleanup_cfg (CLEANUP_EXPENSIVE | liveness_flags); + + /* On conditional execution targets we can not update the life cheaply, so + we deffer the updating to after both cleanups. This may lose some cases + but should not be terribly bad. */ + if (changed && HAVE_conditional_execution) + update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES, + PROP_DEATH_NOTES); +} + +struct tree_opt_pass pass_reorder_blocks = +{ + "bbro", /* name */ + gate_handle_reorder_blocks, /* gate */ + rest_of_handle_reorder_blocks, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_REORDER_BLOCKS, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'B' /* letter */ +}; + +static bool +gate_handle_partition_blocks (void) +{ + /* The optimization to partition hot/cold basic blocks into separate + sections of the .o file does not work well with linkonce or with + user defined section attributes. Don't call it if either case + arises. */ + + return (flag_reorder_blocks_and_partition + && !DECL_ONE_ONLY (current_function_decl) + && !user_defined_section_attribute); +} + +/* Partition hot and cold basic blocks. */ +static void +rest_of_handle_partition_blocks (void) +{ + no_new_pseudos = 0; + partition_hot_cold_basic_blocks (); + allocate_reg_life_data (); + update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES, + PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES); + no_new_pseudos = 1; +} + +struct tree_opt_pass pass_partition_blocks = +{ + NULL, /* name */ + gate_handle_partition_blocks, /* gate */ + rest_of_handle_partition_blocks, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_REORDER_BLOCKS, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + + Index: bt-load.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/bt-load.c,v retrieving revision 2.34 diff -p -u -r2.34 bt-load.c --- bt-load.c 13 May 2005 16:56:11 -0000 2.34 +++ bt-load.c 18 May 2005 10:27:17 -0000 @@ -34,6 +34,8 @@ Software Foundation, 59 Temple Place - S #include "function.h" #include "except.h" #include "tm_p.h" +#include "toplev.h" +#include "tree-pass.h" /* Target register optimizations - these are performed after reload. */ @@ -1478,3 +1480,50 @@ branch_target_load_optimize (bool after_ PROP_DEATH_NOTES | PROP_REG_INFO); } } + +static bool +gate_handle_branch_target_load_optimize (void) +{ + return (optimize > 0 && flag_branch_target_load_optimize2); +} + + +static void +rest_of_handle_branch_target_load_optimize (void) +{ + static int warned = 0; + + /* Leave this a warning for now so that it is possible to experiment + with running this pass twice. In 3.6, we should either make this + an error, or use separate dump files. */ + if (flag_branch_target_load_optimize + && flag_branch_target_load_optimize2 + && !warned) + { + warning (0, "branch target register load optimization is not intended " + "to be run twice"); + + warned = 1; + } + + branch_target_load_optimize (epilogue_completed); +} + +struct tree_opt_pass pass_branch_target_load_optimize = +{ + "btl", /* name */ + gate_handle_branch_target_load_optimize, /* gate */ + rest_of_handle_branch_target_load_optimize, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'd' /* letter */ +}; + Index: cfgcleanup.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cfgcleanup.c,v retrieving revision 1.145 diff -p -u -r1.145 cfgcleanup.c --- cfgcleanup.c 17 May 2005 06:48:17 -0000 1.145 +++ cfgcleanup.c 18 May 2005 10:27:21 -0000 @@ -50,6 +50,9 @@ Software Foundation, 59 Temple Place - S #include "target.h" #include "cfglayout.h" #include "emit-rtl.h" +#include "tree-pass.h" +#include "cfgloop.h" +#include "expr.h" /* cleanup_cfg maintains following flags for each basic block. */ @@ -2138,3 +2141,81 @@ cleanup_cfg (int mode) return changed; } + +static void +rest_of_handle_jump (void) +{ + delete_unreachable_blocks (); + + if (cfun->tail_call_emit) + fixup_tail_calls (); +} + +struct tree_opt_pass pass_jump = +{ + "sibling", /* name */ + NULL, /* gate */ + rest_of_handle_jump, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_JUMP, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + TODO_ggc_collect, /* todo_flags_start */ + TODO_dump_func | + TODO_verify_flow, /* todo_flags_finish */ + 'i' /* letter */ +}; + + +static void +rest_of_handle_jump2 (void) +{ + /* Turn NOTE_INSN_EXPECTED_VALUE into REG_BR_PROB. Do this + before jump optimization switches branch directions. */ + if (flag_guess_branch_prob) + expected_value_to_br_prob (); + + delete_trivially_dead_insns (get_insns (), max_reg_num ()); + reg_scan (get_insns (), max_reg_num ()); + if (dump_file) + dump_flow_info (dump_file); + cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP + | (flag_thread_jumps ? CLEANUP_THREADING : 0)); + + create_loop_notes (); + + purge_line_number_notes (); + + if (optimize) + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); + + /* Jump optimization, and the removal of NULL pointer checks, may + have reduced the number of instructions substantially. CSE, and + future passes, allocate arrays whose dimensions involve the + maximum instruction UID, so if we can reduce the maximum UID + we'll save big on memory. */ + renumber_insns (dump_file); +} + + +struct tree_opt_pass pass_jump2 = +{ + "jump", /* name */ + NULL, /* gate */ + rest_of_handle_jump2, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_JUMP, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + TODO_ggc_collect, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'j' /* letter */ +}; + + Index: cfgexpand.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cfgexpand.c,v retrieving revision 2.38 diff -p -u -r2.38 cfgexpand.c --- cfgexpand.c 28 Apr 2005 05:02:59 -0000 2.38 +++ cfgexpand.c 18 May 2005 10:27:23 -0000 @@ -37,6 +37,7 @@ Boston, MA 02111-1307, USA. */ #include "flags.h" #include "diagnostic.h" #include "toplev.h" +#include "debug.h" /* Verify that there is exactly single jump instruction since last and attach REG_BR_PROB note specifying probability. @@ -1342,6 +1343,30 @@ tree_expand_cfg (void) "\n\n;;\n;; Full RTL generated for this function:\n;;\n"); /* And the pass manager will dump RTL for us. */ } + + /* If we're emitting a nested function, make sure its parent gets + emitted as well. Doing otherwise confuses debug info. */ + { + tree parent; + for (parent = DECL_CONTEXT (current_function_decl); + parent != NULL_TREE; + parent = get_containing_scope (parent)) + if (TREE_CODE (parent) == FUNCTION_DECL) + TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (parent)) = 1; + } + + /* We are now committed to emitting code for this function. Do any + preparation, such as emitting abstract debug info for the inline + before it gets mangled by optimization. */ + if (cgraph_function_possibly_inlined_p (current_function_decl)) + (*debug_hooks->outlining_inline_function) (current_function_decl); + + TREE_ASM_WRITTEN (current_function_decl) = 1; + +#ifdef FINALIZE_PIC + if (flag_pic) + FINALIZE_PIC; +#endif } struct tree_opt_pass pass_expand = @@ -1358,6 +1383,6 @@ struct tree_opt_pass pass_expand = PROP_rtl, /* properties_provided */ PROP_gimple_leh, /* properties_destroyed */ 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ + TODO_dump_func, /* todo_flags_finish */ 'r' /* letter */ }; Index: cfglayout.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cfglayout.c,v retrieving revision 1.87 diff -p -u -r1.87 cfglayout.c --- cfglayout.c 3 May 2005 16:35:17 -0000 1.87 +++ cfglayout.c 18 May 2005 10:27:25 -0000 @@ -36,6 +36,7 @@ Software Foundation, 59 Temple Place - S #include "ggc.h" #include "alloc-pool.h" #include "flags.h" +#include "tree-pass.h" /* Holds the interesting trailing notes for the function. */ rtx cfg_layout_function_footer, cfg_layout_function_header; @@ -327,6 +328,24 @@ insn_locators_initialize (void) free_block_changes (); } +struct tree_opt_pass pass_insn_locators_initialize = +{ + NULL, /* name */ + NULL, /* gate */ + insn_locators_initialize, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + + /* For each lexical block, set BLOCK_NUMBER to the depth at which it is found in the block tree. */ Index: cfgrtl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cfgrtl.c,v retrieving revision 1.174 diff -p -u -u -p -r1.174 cfgrtl.c --- cfgrtl.c 4 Jun 2005 17:07:55 -0000 1.174 +++ cfgrtl.c 6 Jun 2005 08:43:40 -0000 @@ -58,6 +58,7 @@ Software Foundation, 59 Temple Place - S #include "target.h" #include "cfgloop.h" #include "ggc.h" +#include "tree-pass.h" static int can_delete_note_p (rtx); static int can_delete_label_p (rtx); @@ -417,6 +418,23 @@ free_bb_for_insn (void) BLOCK_FOR_INSN (insn) = NULL; } +struct tree_opt_pass pass_free_cfg = +{ + NULL, /* name */ + NULL, /* gate */ + free_bb_for_insn, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + PROP_cfg, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + /* Return RTX to emit after when we want to emit code on the entry of function. */ rtx entry_of_function (void) Index: combine.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/combine.c,v retrieving revision 1.489 diff -p -u -r1.489 combine.c --- combine.c 3 May 2005 22:15:39 -0000 1.489 +++ combine.c 18 May 2005 10:27:59 -0000 @@ -96,6 +96,8 @@ Software Foundation, 59 Temple Place - S /* Include output.h for dump_file. */ #include "output.h" #include "params.h" +#include "timevar.h" +#include "tree-pass.h" /* Number of attempts to combine instructions in this function. */ @@ -12510,3 +12512,50 @@ dump_combine_total_stats (FILE *file) "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n", total_attempts, total_merges, total_extras, total_successes); } + + +static bool +gate_handle_combine (void) +{ + return (optimize > 0); +} + +/* Try combining insns through substitution. */ +static void +rest_of_handle_combine (void) +{ + int rebuild_jump_labels_after_combine + = combine_instructions (get_insns (), max_reg_num ()); + + /* Combining insns may have turned an indirect jump into a + direct jump. Rebuild the JUMP_LABEL fields of jumping + instructions. */ + if (rebuild_jump_labels_after_combine) + { + timevar_push (TV_JUMP); + rebuild_jump_labels (get_insns ()); + timevar_pop (TV_JUMP); + + delete_dead_jumptables (); + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE); + } +} + +struct tree_opt_pass pass_combine = +{ + "combine", /* name */ + gate_handle_combine, /* gate */ + rest_of_handle_combine, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_COMBINE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'c' /* letter */ +}; + Index: cse.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cse.c,v retrieving revision 1.354 diff -p -u -r1.354 cse.c --- cse.c 22 Apr 2005 16:14:52 -0000 1.354 +++ cse.c 18 May 2005 10:28:13 -0000 @@ -43,6 +43,7 @@ Software Foundation, 59 Temple Place - S #include "target.h" #include "params.h" #include "rtlhooks-def.h" +#include "tree-pass.h" /* The basic idea of common subexpression elimination is to go through the code, keeping a record of expressions that would @@ -7741,3 +7742,119 @@ cse_condition_code_reg (void) } } } + + +/* Perform common subexpression elimination. Nonzero value from + `cse_main' means that jumps were simplified and some code may now + be unreachable, so do jump optimization again. */ +static bool +gate_handle_cse (void) +{ + return optimize > 0; +} + +static void +rest_of_handle_cse (void) +{ + int tem; + + if (dump_file) + dump_flow_info (dump_file); + + reg_scan (get_insns (), max_reg_num ()); + + tem = cse_main (get_insns (), max_reg_num (), dump_file); + if (tem) + rebuild_jump_labels (get_insns ()); + if (purge_all_dead_edges ()) + delete_unreachable_blocks (); + + delete_trivially_dead_insns (get_insns (), max_reg_num ()); + + /* If we are not running more CSE passes, then we are no longer + expecting CSE to be run. But always rerun it in a cheap mode. */ + cse_not_expected = !flag_rerun_cse_after_loop && !flag_gcse; + + if (tem) + delete_dead_jumptables (); + + if (tem || optimize > 1) + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); +} + +struct tree_opt_pass pass_cse = +{ + "cse1", /* name */ + gate_handle_cse, /* gate */ + rest_of_handle_cse, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_CSE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 's' /* letter */ +}; + + +static bool +gate_handle_cse2 (void) +{ + return optimize > 0 && flag_rerun_cse_after_loop; +} + +/* Run second CSE pass after loop optimizations. */ +static void +rest_of_handle_cse2 (void) +{ + int tem; + + if (dump_file) + dump_flow_info (dump_file); + /* CFG is no longer maintained up-to-date. */ + tem = cse_main (get_insns (), max_reg_num (), dump_file); + + /* Run a pass to eliminate duplicated assignments to condition code + registers. We have to run this after bypass_jumps, because it + makes it harder for that pass to determine whether a jump can be + bypassed safely. */ + cse_condition_code_reg (); + + purge_all_dead_edges (); + delete_trivially_dead_insns (get_insns (), max_reg_num ()); + + if (tem) + { + timevar_push (TV_JUMP); + rebuild_jump_labels (get_insns ()); + delete_dead_jumptables (); + cleanup_cfg (CLEANUP_EXPENSIVE); + timevar_pop (TV_JUMP); + } + reg_scan (get_insns (), max_reg_num ()); + cse_not_expected = 1; +} + + +struct tree_opt_pass pass_cse2 = +{ + "cse2", /* name */ + gate_handle_cse2, /* gate */ + rest_of_handle_cse2, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_CSE2, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 't' /* letter */ +}; + Index: emit-rtl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/emit-rtl.c,v retrieving revision 1.440 diff -p -u -r1.440 emit-rtl.c --- emit-rtl.c 28 Apr 2005 05:03:02 -0000 1.440 +++ emit-rtl.c 18 May 2005 10:28:21 -0000 @@ -55,6 +55,7 @@ Software Foundation, 59 Temple Place - S #include "ggc.h" #include "debug.h" #include "langhooks.h" +#include "tree-pass.h" /* Commonly used modes. */ @@ -2135,6 +2136,24 @@ unshare_all_rtl (void) unshare_all_rtl_1 (current_function_decl, get_insns ()); } +struct tree_opt_pass pass_unshare_all_rtl = +{ + NULL, /* name */ + NULL, /* gate */ + unshare_all_rtl, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + + /* Check that ORIG is not marked when it should not be and mark ORIG as in use, Recursively does the same for subexpressions. */ @@ -3705,6 +3724,23 @@ remove_unnecessary_notes (void) gcc_assert (!eh_stack); } +struct tree_opt_pass pass_remove_unnecessary_notes = +{ + NULL, /* name */ + NULL, /* gate */ + remove_unnecessary_notes, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + /* Emit insn(s) of given code and pattern at a specified place within the doubly-linked list. Index: except.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/except.c,v retrieving revision 1.306 diff -p -u -r1.306 except.c --- except.c 12 May 2005 19:29:16 -0000 1.306 +++ except.c 18 May 2005 10:28:27 -0000 @@ -75,6 +75,8 @@ Software Foundation, 59 Temple Place - S #include "langhooks.h" #include "cgraph.h" #include "diagnostic.h" +#include "tree-pass.h" +#include "timevar.h" /* Provide defaults for stuff that may not be defined when using sjlj exceptions. */ @@ -2696,6 +2698,23 @@ set_nothrow_function_flags (void) } } +struct tree_opt_pass pass_set_nothrow_function_flags = +{ + NULL, /* name */ + NULL, /* gate */ + set_nothrow_function_flags, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + /* Various hooks for unwind library. */ @@ -3205,6 +3224,23 @@ convert_to_eh_region_ranges (void) htab_delete (ar_hash); } +struct tree_opt_pass pass_convert_to_eh_region_ranges = +{ + NULL, /* name */ + NULL, /* gate */ + convert_to_eh_region_ranges, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + static void push_uleb128 (varray_type *data_area, unsigned int value) @@ -3729,4 +3765,38 @@ verify_eh_tree (struct function *fun) } } } + + +static bool +gate_handle_eh (void) +{ + return doing_eh (0); +} + +/* Complete generation of exception handling code. */ +static void +rest_of_handle_eh (void) +{ + cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL); + finish_eh_generation (); + cleanup_cfg (CLEANUP_PRE_LOOP | CLEANUP_NO_INSN_DEL); +} + +struct tree_opt_pass pass_rtl_eh = +{ + "eh", /* name */ + gate_handle_eh, /* gate */ + rest_of_handle_eh, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_JUMP, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'h' /* letter */ +}; + #include "gt-except.h" Index: final.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/final.c,v retrieving revision 1.355 diff -p -u -r1.355 final.c --- final.c 26 Apr 2005 01:01:19 -0000 1.355 +++ final.c 18 May 2005 10:28:35 -0000 @@ -72,6 +72,10 @@ Software Foundation, 59 Temple Place - S #include "debug.h" #include "expr.h" #include "cfglayout.h" +#include "tree-pass.h" +#include "timevar.h" +#include "cgraph.h" +#include "coverage.h" #ifdef XCOFF_DEBUGGING_INFO #include "xcoffout.h" /* Needed for external data @@ -735,6 +739,24 @@ compute_alignments (void) LABEL_TO_MAX_SKIP (label) = max_skip; } } + +struct tree_opt_pass pass_compute_alignments = +{ + NULL, /* name */ + NULL, /* gate */ + compute_alignments, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + /* Make a pass over all insns and compute their actual lengths by shortening any branches of variable length if possible. */ @@ -3862,3 +3884,186 @@ debug_free_queue (void) symbol_queue_size = 0; } } + +/* Turn the RTL into assembly. */ +static void +rest_of_handle_final (void) +{ + rtx x; + const char *fnname; + + /* Get the function's name, as described by its RTL. This may be + different from the DECL_NAME name used in the source file. */ + + x = DECL_RTL (current_function_decl); + gcc_assert (MEM_P (x)); + x = XEXP (x, 0); + gcc_assert (GET_CODE (x) == SYMBOL_REF); + fnname = XSTR (x, 0); + + assemble_start_function (current_function_decl, fnname); + final_start_function (get_insns (), asm_out_file, optimize); + final (get_insns (), asm_out_file, optimize); + final_end_function (); + +#ifdef TARGET_UNWIND_INFO + /* ??? The IA-64 ".handlerdata" directive must be issued before + the ".endp" directive that closes the procedure descriptor. */ + output_function_exception_table (); +#endif + + assemble_end_function (current_function_decl, fnname); + +#ifndef TARGET_UNWIND_INFO + /* Otherwise, it feels unclean to switch sections in the middle. */ + output_function_exception_table (); +#endif + + user_defined_section_attribute = false; + + if (! quiet_flag) + fflush (asm_out_file); + + /* Release all memory allocated by flow. */ + free_basic_block_vars (); + + /* Write DBX symbols if requested. */ + + /* Note that for those inline functions where we don't initially + know for certain that we will be generating an out-of-line copy, + the first invocation of this routine (rest_of_compilation) will + skip over this code by doing a `goto exit_rest_of_compilation;'. + Later on, wrapup_global_declarations will (indirectly) call + rest_of_compilation again for those inline functions that need + to have out-of-line copies generated. During that call, we + *will* be routed past here. */ + + timevar_push (TV_SYMOUT); + (*debug_hooks->function_decl) (current_function_decl); + timevar_pop (TV_SYMOUT); +} + +struct tree_opt_pass pass_final = +{ + NULL, /* name */ + NULL, /* gate */ + rest_of_handle_final, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_FINAL, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_ggc_collect, /* todo_flags_finish */ + 0 /* letter */ +}; + + +static void +rest_of_handle_shorten_branches (void) +{ + /* Shorten branches. */ + shorten_branches (get_insns ()); +} + +struct tree_opt_pass pass_shorten_branches = +{ + NULL, /* name */ + NULL, /* gate */ + rest_of_handle_shorten_branches, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_FINAL, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + + +static void +rest_of_clean_state (void) +{ + rtx insn, next; + + /* It is very important to decompose the RTL instruction chain here: + debug information keeps pointing into CODE_LABEL insns inside the function + body. If these remain pointing to the other insns, we end up preserving + whole RTL chain and attached detailed debug info in memory. */ + for (insn = get_insns (); insn; insn = next) + { + next = NEXT_INSN (insn); + NEXT_INSN (insn) = NULL; + PREV_INSN (insn) = NULL; + } + + /* In case the function was not output, + don't leave any temporary anonymous types + queued up for sdb output. */ +#ifdef SDB_DEBUGGING_INFO + if (write_symbols == SDB_DEBUG) + sdbout_types (NULL_TREE); +#endif + + reload_completed = 0; + epilogue_completed = 0; + flow2_completed = 0; + no_new_pseudos = 0; + + /* Clear out the insn_length contents now that they are no + longer valid. */ + init_insn_lengths (); + + /* Show no temporary slots allocated. */ + init_temp_slots (); + + free_basic_block_vars (); + free_bb_for_insn (); + + + if (targetm.binds_local_p (current_function_decl)) + { + int pref = cfun->preferred_stack_boundary; + if (cfun->stack_alignment_needed > cfun->preferred_stack_boundary) + pref = cfun->stack_alignment_needed; + cgraph_rtl_info (current_function_decl)->preferred_incoming_stack_boundary + = pref; + } + + /* Make sure volatile mem refs aren't considered valid operands for + arithmetic insns. We must call this here if this is a nested inline + function, since the above code leaves us in the init_recog state, + and the function context push/pop code does not save/restore volatile_ok. + + ??? Maybe it isn't necessary for expand_start_function to call this + anymore if we do it here? */ + + init_recog_no_volatile (); + + /* We're done with this function. Free up memory if we can. */ + free_after_parsing (cfun); + free_after_compilation (cfun); +} + +struct tree_opt_pass pass_clean_state = +{ + NULL, /* name */ + NULL, /* gate */ + rest_of_clean_state, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_FINAL, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + PROP_rtl, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + Index: flow.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/flow.c,v retrieving revision 1.628 diff -p -u -r1.628 flow.c --- flow.c 13 May 2005 12:25:28 -0000 1.628 +++ flow.c 18 May 2005 10:28:44 -0000 @@ -140,6 +140,7 @@ Software Foundation, 59 Temple Place - S #include "obstack.h" #include "splay-tree.h" +#include "tree-pass.h" #ifndef HAVE_epilogue #define HAVE_epilogue 0 @@ -4347,6 +4348,23 @@ recompute_reg_usage (void) update_life_info (NULL, UPDATE_LIFE_LOCAL, PROP_REG_INFO | PROP_DEATH_NOTES); } +struct tree_opt_pass pass_recompute_reg_usage = +{ + NULL, /* name */ + NULL, /* gate */ + recompute_reg_usage, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + /* Optionally removes all the REG_DEAD and REG_UNUSED notes from a set of blocks. If BLOCKS is NULL, assume the universal set. Returns a count of the number of registers that died. */ @@ -4488,3 +4506,131 @@ reg_set_to_hard_reg_set (HARD_REG_SET *t SET_HARD_REG_BIT (*to, i); } } + + +static bool +gate_remove_death_notes (void) +{ + return flag_profile_values; +} + +static void +rest_of_handle_remove_death_notes (void) +{ + count_or_remove_death_notes (NULL, 1); +} + +struct tree_opt_pass pass_remove_death_notes = +{ + NULL, /* name */ + gate_remove_death_notes, /* gate */ + rest_of_handle_remove_death_notes, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + +/* Perform life analysis. */ +static void +rest_of_handle_life (void) +{ + regclass_init (); + + life_analysis (dump_file, PROP_FINAL); + if (optimize) + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE | CLEANUP_LOG_LINKS + | (flag_thread_jumps ? CLEANUP_THREADING : 0)); + + if (extra_warnings) + { + setjmp_vars_warning (DECL_INITIAL (current_function_decl)); + setjmp_args_warning (); + } + + if (optimize) + { + if (initialize_uninitialized_subregs ()) + { + /* Insns were inserted, and possibly pseudos created, so + things might look a bit different. */ + allocate_reg_life_data (); + update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES, + PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES); + } + } + + no_new_pseudos = 1; +} + +struct tree_opt_pass pass_life = +{ + "life", /* name */ + NULL, /* gate */ + rest_of_handle_life, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_FLOW, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + TODO_verify_flow, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'f' /* letter */ +}; + +static void +rest_of_handle_flow2 (void) +{ + /* Re-create the death notes which were deleted during reload. */ +#ifdef ENABLE_CHECKING + verify_flow_info (); +#endif + + /* If optimizing, then go ahead and split insns now. */ +#ifndef STACK_REGS + if (optimize > 0) +#endif + split_all_insns (0); + + if (flag_branch_target_load_optimize) + branch_target_load_optimize (epilogue_completed); + + if (optimize) + cleanup_cfg (CLEANUP_EXPENSIVE); + + /* On some machines, the prologue and epilogue code, or parts thereof, + can be represented as RTL. Doing so lets us schedule insns between + it and the rest of the code and also allows delayed branch + scheduling to operate in the epilogue. */ + thread_prologue_and_epilogue_insns (get_insns ()); + epilogue_completed = 1; + flow2_completed = 1; +} + +struct tree_opt_pass pass_flow2 = +{ + "flow2", /* name */ + NULL, /* gate */ + rest_of_handle_flow2, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_FLOW2, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + TODO_verify_flow, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'w' /* letter */ +}; + Index: function.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/function.c,v retrieving revision 1.624 diff -p -u -u -p -r1.624 function.c --- function.c 4 Jun 2005 17:22:18 -0000 1.624 +++ function.c 6 Jun 2005 08:43:12 -0000 @@ -61,6 +61,7 @@ Software Foundation, 59 Temple Place - S #include "target.h" #include "cfglayout.h" #include "tree-gimple.h" +#include "tree-pass.h" #ifndef LOCAL_ALIGNMENT #define LOCAL_ALIGNMENT(TYPE, ALIGNMENT) ALIGNMENT @@ -1662,6 +1663,24 @@ instantiate_virtual_regs (void) frame_pointer_rtx. */ virtuals_instantiated = 1; } + +struct tree_opt_pass pass_instantiate_virtual_regs = +{ + NULL, /* name */ + NULL, /* gate */ + instantiate_virtual_regs, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + /* Return 1 if EXP is an aggregate type (or a value with aggregate type). This means a type for which function calls must pass an address to the @@ -3876,6 +3895,24 @@ init_function_for_compilation (void) gcc_assert (VEC_length (int, sibcall_epilogue) == 0); } +struct tree_opt_pass pass_init_function = +{ + NULL, /* name */ + NULL, /* gate */ + init_function_for_compilation, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + + void expand_main_function (void) { @@ -5397,5 +5434,33 @@ current_function_name (void) { return lang_hooks.decl_printable_name (cfun->decl, 2); } + + +static void +rest_of_handle_check_leaf_regs (void) +{ +#ifdef LEAF_REGISTERS + current_function_uses_only_leaf_regs + = optimize > 0 && only_leaf_regs_used () && leaf_function_p (); +#endif +} + +struct tree_opt_pass pass_leaf_regs = +{ + NULL, /* name */ + NULL, /* gate */ + rest_of_handle_check_leaf_regs, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + #include "gt-function.h" Index: gcse.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/gcse.c,v retrieving revision 1.341 diff -p -u -r1.341 gcse.c --- gcse.c 9 May 2005 17:52:16 -0000 1.341 +++ gcse.c 18 May 2005 10:29:04 -0000 @@ -169,6 +169,7 @@ Software Foundation, 59 Temple Place - S #include "intl.h" #include "obstack.h" #include "timevar.h" +#include "tree-pass.h" /* Propagate flow information through back edges and thus enable PRE's moving loop invariant calculations out of loops. @@ -6551,5 +6552,113 @@ is_too_expensive (const char *pass) return false; } + +static bool +gate_handle_jump_bypass (void) +{ + return optimize > 0 && flag_gcse; +} + +/* Perform jump bypassing and control flow optimizations. */ +static void +rest_of_handle_jump_bypass (void) +{ + cleanup_cfg (CLEANUP_EXPENSIVE); + reg_scan (get_insns (), max_reg_num ()); + + if (bypass_jumps (dump_file)) + { + rebuild_jump_labels (get_insns ()); + cleanup_cfg (CLEANUP_EXPENSIVE); + delete_trivially_dead_insns (get_insns (), max_reg_num ()); + } +} + +struct tree_opt_pass pass_jump_bypass = +{ + "bypass", /* name */ + gate_handle_jump_bypass, /* gate */ + rest_of_handle_jump_bypass, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_BYPASS, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect | TODO_verify_flow, /* todo_flags_finish */ + 'G' /* letter */ +}; + + +static bool +gate_handle_gcse (void) +{ + return optimize > 0 && flag_gcse; +} + + +static void +rest_of_handle_gcse (void) +{ + int save_csb, save_cfj; + int tem2 = 0, tem; + + tem = gcse_main (get_insns (), dump_file); + rebuild_jump_labels (get_insns ()); + delete_trivially_dead_insns (get_insns (), max_reg_num ()); + + save_csb = flag_cse_skip_blocks; + save_cfj = flag_cse_follow_jumps; + flag_cse_skip_blocks = flag_cse_follow_jumps = 0; + + /* If -fexpensive-optimizations, re-run CSE to clean up things done + by gcse. */ + if (flag_expensive_optimizations) + { + timevar_push (TV_CSE); + reg_scan (get_insns (), max_reg_num ()); + tem2 = cse_main (get_insns (), max_reg_num (), dump_file); + purge_all_dead_edges (); + delete_trivially_dead_insns (get_insns (), max_reg_num ()); + timevar_pop (TV_CSE); + cse_not_expected = !flag_rerun_cse_after_loop; + } + + /* If gcse or cse altered any jumps, rerun jump optimizations to clean + things up. */ + if (tem || tem2) + { + timevar_push (TV_JUMP); + rebuild_jump_labels (get_insns ()); + delete_dead_jumptables (); + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_PRE_LOOP); + timevar_pop (TV_JUMP); + } + + flag_cse_skip_blocks = save_csb; + flag_cse_follow_jumps = save_cfj; +} + +struct tree_opt_pass pass_gcse = +{ + "gcse1", /* name */ + gate_handle_gcse, /* gate */ + rest_of_handle_gcse, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_GCSE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_verify_flow | TODO_ggc_collect, /* todo_flags_finish */ + 'G' /* letter */ +}; + #include "gt-gcse.h" Index: global.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/global.c,v retrieving revision 1.126 diff -p -u -r1.126 global.c --- global.c 1 May 2005 23:34:24 -0000 1.126 +++ global.c 18 May 2005 10:29:09 -0000 @@ -36,6 +36,8 @@ Software Foundation, 59 Temple Place - S #include "reload.h" #include "output.h" #include "toplev.h" +#include "tree-pass.h" +#include "timevar.h" /* This pass of the compiler performs global register allocation. It assigns hard register numbers to all the pseudo registers @@ -2474,3 +2476,50 @@ make_accurate_live_analysis (void) } free_bb_info (); } +/* Run old register allocator. Return TRUE if we must exit + rest_of_compilation upon return. */ +static void +rest_of_handle_global_alloc (void) +{ + bool failure; + + /* If optimizing, allocate remaining pseudo-regs. Do the reload + pass fixing up any insns that are invalid. */ + + if (optimize) + failure = global_alloc (dump_file); + else + { + build_insn_chain (get_insns ()); + failure = reload (get_insns (), 0); + } + + if (dump_enabled_p (pass_global_alloc.static_pass_number)) + { + timevar_push (TV_DUMP); + dump_global_regs (dump_file); + timevar_pop (TV_DUMP); + } + + gcc_assert (reload_completed || failure); + reload_completed = !failure; +} + +struct tree_opt_pass pass_global_alloc = +{ + "greg", /* name */ + NULL, /* gate */ + rest_of_handle_global_alloc, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_GLOBAL_ALLOC, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'g' /* letter */ +}; + Index: ifcvt.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v retrieving revision 1.186 diff -p -u -r1.186 ifcvt.c --- ifcvt.c 21 Apr 2005 15:47:23 -0000 1.186 +++ ifcvt.c 18 May 2005 10:29:15 -0000 @@ -41,6 +41,8 @@ #include "tm_p.h" #include "cfgloop.h" #include "target.h" +#include "timevar.h" +#include "tree-pass.h" #ifndef HAVE_conditional_execution @@ -3396,3 +3398,120 @@ if_convert (int x_life_data_ok) verify_flow_info (); #endif } + +static bool +gate_handle_if_conversion (void) +{ + return (optimize > 0); +} + +/* If-conversion and CFG cleanup. */ +static void +rest_of_handle_if_conversion (void) +{ + if (flag_if_conversion) + { + if (dump_file) + dump_flow_info (dump_file); + cleanup_cfg (CLEANUP_EXPENSIVE); + reg_scan (get_insns (), max_reg_num ()); + if_convert (0); + } + + timevar_push (TV_JUMP); + cleanup_cfg (CLEANUP_EXPENSIVE); + reg_scan (get_insns (), max_reg_num ()); + timevar_pop (TV_JUMP); +} + +struct tree_opt_pass pass_rtl_ifcvt = +{ + "ce1", /* name */ + gate_handle_if_conversion, /* gate */ + rest_of_handle_if_conversion, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_IFCVT, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'C' /* letter */ +}; + +static bool +gate_handle_if_after_combine (void) +{ + return (optimize > 0 && flag_if_conversion); +} + + +/* Rerun if-conversion, as combine may have simplified things enough + to now meet sequence length restrictions. */ +static void +rest_of_handle_if_after_combine (void) +{ + no_new_pseudos = 0; + if_convert (1); + no_new_pseudos = 1; +} + +struct tree_opt_pass pass_if_after_combine = +{ + "ce2", /* name */ + gate_handle_if_after_combine, /* gate */ + rest_of_handle_if_after_combine, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_IFCVT, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'C' /* letter */ +}; + + +static bool +gate_handle_if_after_reload (void) +{ + return (optimize > 0); +} + +static void +rest_of_handle_if_after_reload (void) +{ + /* Last attempt to optimize CFG, as scheduling, peepholing and insn + splitting possibly introduced more crossjumping opportunities. */ + cleanup_cfg (CLEANUP_EXPENSIVE + | CLEANUP_UPDATE_LIFE + | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0)); + if (flag_if_conversion2) + if_convert (1); +} + + +struct tree_opt_pass pass_if_after_reload = +{ + "ce3", /* name */ + gate_handle_if_after_reload, /* gate */ + rest_of_handle_if_after_reload, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_IFCVT2, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'E' /* letter */ +}; + + Index: integrate.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/integrate.c,v retrieving revision 1.278 diff -p -u -r1.278 integrate.c --- integrate.c 13 May 2005 16:56:11 -0000 1.278 +++ integrate.c 18 May 2005 10:29:16 -0000 @@ -45,6 +45,7 @@ Software Foundation, 59 Temple Place - S #include "ggc.h" #include "target.h" #include "langhooks.h" +#include "tree-pass.h" /* Round to the next highest integer that meets the alignment. */ #define CEIL_ROUND(VALUE,ALIGN) (((VALUE) + (ALIGN) - 1) & ~((ALIGN)- 1)) @@ -369,6 +370,23 @@ emit_initial_value_sets (void) emit_insn_after (seq, entry_of_function ()); } +struct tree_opt_pass pass_initial_value_sets = +{ + NULL, /* name */ + NULL, /* gate */ + emit_initial_value_sets, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + /* If the backend knows where to allocate pseudos for hard register initial values, register these allocations now. */ void Index: jump.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/jump.c,v retrieving revision 1.260 diff -p -u -r1.260 jump.c --- jump.c 25 Apr 2005 12:46:09 -0000 1.260 +++ jump.c 18 May 2005 10:29:19 -0000 @@ -56,6 +56,7 @@ Software Foundation, 59 Temple Place - S #include "reload.h" #include "predict.h" #include "timevar.h" +#include "tree-pass.h" /* Optimize jump y; x: ... y: jumpif... x? Don't know if it is worth bothering with. */ @@ -120,8 +121,25 @@ cleanup_barriers (void) } } +struct tree_opt_pass pass_cleanup_barriers = +{ + NULL, /* name */ + NULL, /* gate */ + cleanup_barriers, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + void -purge_line_number_notes (rtx f) +purge_line_number_notes (void) { rtx last_note = 0; rtx insn; @@ -130,7 +148,7 @@ purge_line_number_notes (rtx f) extraneous. There should be some indication where that line belonged, even if it became empty. */ - for (insn = f; insn; insn = NEXT_INSN (insn)) + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) if (NOTE_P (insn)) { if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_FUNCTION_BEG) @@ -157,6 +175,24 @@ purge_line_number_notes (rtx f) } } } + +struct tree_opt_pass pass_purge_lineno_notes = +{ + NULL, /* name */ + NULL, /* gate */ + purge_line_number_notes, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + /* Initialize LABEL_NUSES and JUMP_LABEL fields. Delete any REG_LABEL notes whose labels don't occur in the insn any more. Returns the Index: mode-switching.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/mode-switching.c,v retrieving revision 2.1 diff -p -u -u -p -r2.1 mode-switching.c --- mode-switching.c 4 Jun 2005 17:07:56 -0000 2.1 +++ mode-switching.c 6 Jun 2005 07:42:36 -0000 @@ -34,6 +34,8 @@ Software Foundation, 59 Temple Place - S #include "output.h" #include "tm_p.h" #include "function.h" +#include "tree-pass.h" +#include "timevar.h" /* We want target macros for the mode switching code to be able to refer to instruction attribute values. */ @@ -708,4 +710,43 @@ optimize_mode_switching (FILE *file) return 1; } + #endif /* OPTIMIZE_MODE_SWITCHING */ + +static bool +gate_mode_switching (void) +{ +#ifdef OPTIMIZE_MODE_SWITCHING + return true; +#else + return false; +#endif +} + +static void +rest_of_handle_mode_switching (void) +{ +#ifdef OPTIMIZE_MODE_SWITCHING + no_new_pseudos = 0; + optimize_mode_switching (NULL); + no_new_pseudos = 1; +#endif /* OPTIMIZE_MODE_SWITCHING */ +} + + +struct tree_opt_pass pass_mode_switching = +{ + NULL, /* name */ + gate_mode_switching, /* gate */ + rest_of_handle_mode_switching, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_MODE_SWITCH, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; Index: local-alloc.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/local-alloc.c,v retrieving revision 1.147 diff -p -u -r1.147 local-alloc.c --- local-alloc.c 28 Apr 2005 05:38:32 -0000 1.147 +++ local-alloc.c 18 May 2005 10:29:26 -0000 @@ -76,6 +76,8 @@ Software Foundation, 59 Temple Place - S #include "integrate.h" #include "reload.h" #include "ggc.h" +#include "timevar.h" +#include "tree-pass.h" /* Next quantity number available for allocation. */ @@ -2416,3 +2419,69 @@ dump_local_alloc (FILE *file) if (reg_renumber[i] != -1) fprintf (file, ";; Register %d in %d.\n", i, reg_renumber[i]); } + +/* Run old register allocator. Return TRUE if we must exit + rest_of_compilation upon return. */ +static void +rest_of_handle_local_alloc (void) +{ + int rebuild_notes; + + /* Determine if the current function is a leaf before running reload + since this can impact optimizations done by the prologue and + epilogue thus changing register elimination offsets. */ + current_function_is_leaf = leaf_function_p (); + + /* Allocate the reg_renumber array. */ + allocate_reg_info (max_regno, FALSE, TRUE); + + /* And the reg_equiv_memory_loc array. */ + VARRAY_GROW (reg_equiv_memory_loc_varray, max_regno); + reg_equiv_memory_loc = &VARRAY_RTX (reg_equiv_memory_loc_varray, 0); + + allocate_initial_values (reg_equiv_memory_loc); + + regclass (get_insns (), max_reg_num (), dump_file); + rebuild_notes = local_alloc (); + + /* Local allocation may have turned an indirect jump into a direct + jump. If so, we must rebuild the JUMP_LABEL fields of jumping + instructions. */ + if (rebuild_notes) + { + timevar_push (TV_JUMP); + + rebuild_jump_labels (get_insns ()); + purge_all_dead_edges (); + delete_unreachable_blocks (); + + timevar_pop (TV_JUMP); + } + + if (dump_enabled_p (pass_local_alloc.static_pass_number)) + { + timevar_push (TV_DUMP); + dump_flow_info (dump_file); + dump_local_alloc (dump_file); + timevar_pop (TV_DUMP); + } +} + +struct tree_opt_pass pass_local_alloc = +{ + "lreg", /* name */ + NULL, /* gate */ + rest_of_handle_local_alloc, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_LOCAL_ALLOC, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'l' /* letter */ +}; + Index: loop-init.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/loop-init.c,v retrieving revision 1.16 diff -p -u -r1.16 loop-init.c --- loop-init.c 11 Mar 2005 09:05:03 -0000 1.16 +++ loop-init.c 18 May 2005 10:29:26 -0000 @@ -28,6 +29,9 @@ Software Foundation, 59 Temple Place - S #include "basic-block.h" #include "cfgloop.h" #include "cfglayout.h" +#include "tree-pass.h" +#include "timevar.h" +#include "flags.h" /* Initialize loop optimizer. */ @@ -116,3 +119,88 @@ loop_optimizer_finalize (struct loops *l verify_flow_info (); #endif } + +static bool +gate_handle_loop2 (void) +{ + return (optimize > 0 && flag_loop_optimize2 + && (flag_move_loop_invariants + || flag_unswitch_loops + || flag_peel_loops + || flag_unroll_loops + || flag_branch_on_count_reg)); +} + +/* Perform loop optimizations. It might be better to do them a bit + sooner, but we want the profile feedback to work more + efficiently. */ +static void +rest_of_handle_loop2 (void) +{ + struct loops *loops; + basic_block bb; + + if (dump_file) + dump_flow_info (dump_file); + + /* Initialize structures for layout changes. */ + cfg_layout_initialize (0); + + loops = loop_optimizer_init (dump_file); + + if (loops) + { + /* The optimizations: */ + if (flag_move_loop_invariants) + move_loop_invariants (loops); + + if (flag_unswitch_loops) + unswitch_loops (loops); + + if (flag_peel_loops || flag_unroll_loops) + unroll_and_peel_loops (loops, + (flag_peel_loops ? UAP_PEEL : 0) | + (flag_unroll_loops ? UAP_UNROLL : 0) | + (flag_unroll_all_loops ? UAP_UNROLL_ALL : 0)); + +#ifdef HAVE_doloop_end + if (flag_branch_on_count_reg && HAVE_doloop_end) + doloop_optimize_loops (loops); +#endif /* HAVE_doloop_end */ + + loop_optimizer_finalize (loops, dump_file); + } + + free_dominance_info (CDI_DOMINATORS); + + /* Finalize layout changes. */ + FOR_EACH_BB (bb) + if (bb->next_bb != EXIT_BLOCK_PTR) + bb->rbi->next = bb->next_bb; + cfg_layout_finalize (); + + cleanup_cfg (CLEANUP_EXPENSIVE); + delete_trivially_dead_insns (get_insns (), max_reg_num ()); + reg_scan (get_insns (), max_reg_num ()); + if (dump_file) + dump_flow_info (dump_file); +} + +struct tree_opt_pass pass_loop2 = +{ + "loop2", /* name */ + gate_handle_loop2, /* gate */ + rest_of_handle_loop2, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_LOOP, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'L' /* letter */ +}; + Index: loop.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/loop.c,v retrieving revision 1.529 diff -p -u -r1.529 loop.c --- loop.c 25 Apr 2005 12:46:10 -0000 1.529 +++ loop.c 18 May 2005 10:29:48 -0000 @@ -66,6 +66,8 @@ Software Foundation, 59 Temple Place - S #include "optabs.h" #include "cfgloop.h" #include "ggc.h" +#include "timevar.h" +#include "tree-pass.h" /* Get the loop info pointer of a loop. */ #define LOOP_INFO(LOOP) ((struct loop_info *) (LOOP)->aux) @@ -11806,3 +11808,66 @@ debug_loops (const struct loops *loops) { flow_loops_dump (loops, stderr, loop_dump_aux, 1); } + +static bool +gate_handle_loop_optimize (void) +{ + return (optimize > 0 && flag_loop_optimize); +} + +/* Move constant computations out of loops. */ +static void +rest_of_handle_loop_optimize (void) +{ + int do_prefetch; + + /* CFG is no longer maintained up-to-date. */ + free_bb_for_insn (); + profile_status = PROFILE_ABSENT; + + do_prefetch = flag_prefetch_loop_arrays ? LOOP_PREFETCH : 0; + + if (flag_rerun_loop_opt) + { + cleanup_barriers (); + + /* We only want to perform unrolling once. */ + loop_optimize (get_insns (), dump_file, 0); + + /* The first call to loop_optimize makes some instructions + trivially dead. We delete those instructions now in the + hope that doing so will make the heuristics in loop work + better and possibly speed up compilation. */ + delete_trivially_dead_insns (get_insns (), max_reg_num ()); + + /* The regscan pass is currently necessary as the alias + analysis code depends on this information. */ + reg_scan (get_insns (), max_reg_num ()); + } + cleanup_barriers (); + loop_optimize (get_insns (), dump_file, do_prefetch); + + /* Loop can create trivially dead instructions. */ + delete_trivially_dead_insns (get_insns (), max_reg_num ()); + find_basic_blocks (get_insns ()); +} + +struct tree_opt_pass pass_loop_optimize = +{ + "old-loop", /* name */ + gate_handle_loop_optimize, /* gate */ + rest_of_handle_loop_optimize, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_LOOP, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'L' /* letter */ +}; + + Index: modulo-sched.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/modulo-sched.c,v retrieving revision 1.29 diff -p -u -r1.29 modulo-sched.c --- modulo-sched.c 28 Apr 2005 02:25:22 -0000 1.29 +++ modulo-sched.c 18 May 2005 10:29:53 -0000 @@ -47,6 +47,8 @@ Software Foundation, 59 Temple Place - S #include "gcov-io.h" #include "df.h" #include "ddg.h" +#include "timevar.h" +#include "tree-pass.h" #ifdef INSN_SCHEDULING @@ -2551,5 +2553,67 @@ ps_unschedule_node (partial_schedule_ptr return remove_node_from_ps (ps, ps_i); } -#endif /* INSN_SCHEDULING*/ +#endif /* INSN_SCHEDULING */ + +static bool +gate_handle_sms (void) +{ + return (optimize > 0 && flag_modulo_sched); +} + + +/* Run instruction scheduler. */ +/* Perform SMS module scheduling. */ +static void +rest_of_handle_sms (void) +{ +#ifdef INSN_SCHEDULING + basic_block bb; + sbitmap blocks; + + /* We want to be able to create new pseudos. */ + no_new_pseudos = 0; + /* Collect loop information to be used in SMS. */ + cfg_layout_initialize (CLEANUP_UPDATE_LIFE); + sms_schedule (dump_file); + + /* Update the life information, because we add pseudos. */ + max_regno = max_reg_num (); + allocate_reg_info (max_regno, FALSE, FALSE); + blocks = sbitmap_alloc (last_basic_block); + sbitmap_ones (blocks); + update_life_info (blocks, UPDATE_LIFE_GLOBAL_RM_NOTES, + (PROP_DEATH_NOTES + | PROP_REG_INFO + | PROP_KILL_DEAD_CODE + | PROP_SCAN_DEAD_CODE)); + + no_new_pseudos = 1; + + /* Finalize layout changes. */ + FOR_EACH_BB (bb) + if (bb->next_bb != EXIT_BLOCK_PTR) + bb->rbi->next = bb->next_bb; + cfg_layout_finalize (); + free_dominance_info (CDI_DOMINATORS); +#endif /* INSN_SCHEDULING */ +} + +struct tree_opt_pass pass_sms = +{ + "sms", /* name */ + gate_handle_sms, /* gate */ + rest_of_handle_sms, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_SMS, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'm' /* letter */ +}; Index: postreload-gcse.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/postreload-gcse.c,v retrieving revision 2.14 diff -p -u -r2.14 postreload-gcse.c --- postreload-gcse.c 27 Apr 2005 18:39:05 -0000 2.14 +++ postreload-gcse.c 18 May 2005 10:29:57 -0000 @@ -44,6 +44,8 @@ Software Foundation, 59 Temple Place - S #include "hashtab.h" #include "params.h" #include "target.h" +#include "timevar.h" +#include "tree-pass.h" /* The following code implements gcse after reload, the purpose of this pass is to cleanup redundant loads generated by reload and other @@ -1337,3 +1339,37 @@ gcse_after_reload_main (rtx f ATTRIBUTE_ free_mem (); } + +static bool +gate_handle_gcse2 (void) +{ + return (optimize > 0 && flag_gcse_after_reload); +} + + +static void +rest_of_handle_gcse2 (void) +{ + gcse_after_reload_main (get_insns ()); + rebuild_jump_labels (get_insns ()); + delete_trivially_dead_insns (get_insns (), max_reg_num ()); +} + +struct tree_opt_pass pass_gcse2 = +{ + "gcse2", /* name */ + gate_handle_gcse2, /* gate */ + rest_of_handle_gcse2, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_GCSE_AFTER_RELOAD, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_verify_flow | TODO_ggc_collect, /* todo_flags_finish */ + 'J' /* letter */ +}; + Index: postreload.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/postreload.c,v retrieving revision 2.30 diff -p -u -r2.30 postreload.c --- postreload.c 29 Apr 2005 18:39:22 -0000 2.30 +++ postreload.c 18 May 2005 10:30:00 -0000 @@ -44,6 +44,8 @@ Software Foundation, 59 Temple Place - S #include "toplev.h" #include "except.h" #include "tree.h" +#include "timevar.h" +#include "tree-pass.h" static int reload_cse_noop_set_p (rtx); static void reload_cse_simplify (rtx, rtx); @@ -1561,3 +1563,39 @@ move2add_note_store (rtx dst, rtx set, v reg_set_luid[i] = 0; } } + +static bool +gate_handle_postreload (void) +{ + return (optimize > 0); +} + + +static void +rest_of_handle_postreload (void) +{ + /* Do a very simple CSE pass over just the hard registers. */ + reload_cse_regs (get_insns ()); + /* reload_cse_regs can eliminate potentially-trapping MEMs. + Remove any EH edges associated with them. */ + if (flag_non_call_exceptions) + purge_all_dead_edges (); +} + +struct tree_opt_pass pass_postreload_cse = +{ + "postreload", /* name */ + gate_handle_postreload, /* gate */ + rest_of_handle_postreload, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_RELOAD_CSE_REGS, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'o' /* letter */ +}; + Index: profile.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/profile.c,v retrieving revision 1.157 diff -p -u -r1.157 profile.c --- profile.c 21 Apr 2005 09:17:19 -0000 1.157 +++ profile.c 18 May 2005 10:30:03 -0000 @@ -65,6 +65,9 @@ Software Foundation, 59 Temple Place - S #include "tree.h" #include "cfghooks.h" #include "tree-flow.h" +#include "timevar.h" +#include "cfgloop.h" +#include "tree-pass.h" /* Hooks for profiling. */ static struct profile_hooks* profile_hooks; @@ -1328,3 +1331,76 @@ rtl_register_profile_hooks (void) gcc_assert (!ir_type ()); profile_hooks = &rtl_profile_hooks; } + +static bool +gate_handle_profiling (void) +{ + return (!flag_tree_based_profiling + && (optimize > 0 || profile_arc_flag + || flag_test_coverage || flag_branch_probabilities)); +} + +struct tree_opt_pass pass_profiling = +{ + NULL, /* name */ + gate_handle_profiling, /* gate */ + NULL, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + + +/* Do branch profiling and static profile estimation passes. */ +static void +rest_of_handle_branch_prob (void) +{ + struct loops loops; + + rtl_register_profile_hooks (); + rtl_register_value_prof_hooks (); + + if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities) + branch_prob (); + + /* Discover and record the loop depth at the head of each basic + block. The loop infrastructure does the real job for us. */ + flow_loops_find (&loops); + + if (dump_file) + flow_loops_dump (&loops, dump_file, NULL, 0); + + /* Estimate using heuristics if no profiling info is available. */ + if (flag_guess_branch_prob) + estimate_probability (&loops); + + flow_loops_free (&loops); + free_dominance_info (CDI_DOMINATORS); +} + +struct tree_opt_pass pass_branch_prob = +{ + "bp", /* name */ + NULL, /* gate */ + rest_of_handle_branch_prob, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_BRANCH_PROB, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'b' /* letter */ +}; + + + Index: recog.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/recog.c,v retrieving revision 1.222 diff -p -u -r1.222 recog.c --- recog.c 10 Apr 2005 04:00:46 -0000 1.222 +++ recog.c 7 Jun 2005 11:18:19 -0000 @@ -39,6 +39,8 @@ Software Foundation, 59 Temple Place - S #include "basic-block.h" #include "output.h" #include "reload.h" +#include "timevar.h" +#include "tree-pass.h" #ifndef STACK_PUSH_CODE #ifdef STACK_GROWS_DOWNWARD @@ -3418,3 +3421,122 @@ if_test_bypass_p (rtx out_insn, rtx in_i return true; } + +static bool +gate_handle_peephole2 (void) +{ + return (optimize > 0 && flag_peephole2); +} + +static void +rest_of_handle_peephole2 (void) +{ +#ifdef HAVE_peephole2 + peephole2_optimize (dump_file); +#endif +} + +struct tree_opt_pass pass_peephole2 = +{ + "peephole2", /* name */ + gate_handle_peephole2, /* gate */ + rest_of_handle_peephole2, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_PEEPHOLE2, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'z' /* letter */ +}; + +static void +rest_of_handle_split_all_insns (void) +{ + split_all_insns (1); +} + +struct tree_opt_pass pass_split_all_insns = +{ + NULL, /* name */ + NULL, /* gate */ + rest_of_handle_split_all_insns, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + +/* The placement of the splitting that we do for shorten_branches + depends on whether regstack is used by the target or not. */ +static bool +gate_do_final_split (void) +{ +#if defined (HAVE_ATTR_length) && !defined (STACK_REGS) + return 1; +#else + return 0; +#endif +} + +struct tree_opt_pass pass_split_for_shorten_branches = +{ + NULL, /* name */ + gate_do_final_split, /* gate */ + split_all_insns_noflow, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_SHORTEN_BRANCH, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; + + +static bool +gate_handle_split_before_regstack (void) +{ +#if defined (HAVE_ATTR_length) && defined (STACK_REGS) + /* If flow2 creates new instructions which need splitting + and scheduling after reload is not done, they might not be + split until final which doesn't allow splitting + if HAVE_ATTR_length. */ +# ifdef INSN_SCHEDULING + return (optimize && !flag_schedule_insns_after_reload); +# else + return (optimize); +# endif +#else + return 0; +#endif +} + +struct tree_opt_pass pass_split_before_regstack = +{ + NULL, /* name */ + gate_handle_split_before_regstack, /* gate */ + rest_of_handle_split_all_insns, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_SHORTEN_BRANCH, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ + 0 /* letter */ +}; Index: reg-stack.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/reg-stack.c,v retrieving revision 1.183 diff -p -u -r1.183 reg-stack.c --- reg-stack.c 4 Jun 2005 22:05:35 -0000 1.183 +++ reg-stack.c 7 Jun 2005 11:25:07 -0000 @@ -170,6 +170,8 @@ #include "varray.h" #include "reload.h" #include "ggc.h" +#include "timevar.h" +#include "tree-pass.h" /* We use this array to cache info about insns, because otherwise we spend too much time in stack_regs_mentioned_p. @@ -3125,5 +3127,52 @@ reg_to_stack (FILE *file) return true; } #endif /* STACK_REGS */ + +static bool +gate_handle_stack_regs (void) +{ +#ifdef STACK_REGS + return 1; +#else + return 0; +#endif +} + +/* Convert register usage from flat register file usage to a stack + register file. */ +static void +rest_of_handle_stack_regs (void) +{ +#ifdef STACK_REGS + if (reg_to_stack (dump_file) && optimize) + { + if (cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK + | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0)) + && (flag_reorder_blocks || flag_reorder_blocks_and_partition)) + { + reorder_basic_blocks (0); + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_POST_REGSTACK); + } + } +#endif +} + +struct tree_opt_pass pass_stack_regs = +{ + "stack", /* name */ + gate_handle_stack_regs, /* gate */ + rest_of_handle_stack_regs, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_REG_STACK, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'k' /* letter */ +}; #include "gt-reg-stack.h" Index: regmove.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/regmove.c,v retrieving revision 1.168 diff -p -u -r1.168 regmove.c --- regmove.c 28 Apr 2005 05:38:34 -0000 1.168 +++ regmove.c 18 May 2005 10:30:17 -0000 @@ -43,6 +43,8 @@ Software Foundation, 59 Temple Place - S #include "except.h" #include "toplev.h" #include "reload.h" +#include "timevar.h" +#include "tree-pass.h" /* Turn STACK_GROWS_DOWNWARD into a boolean. */ @@ -2461,3 +2463,80 @@ combine_stack_adjustments_for_block (bas if (memlist) free_csa_memlist (memlist); } + +static bool +gate_handle_regmove (void) +{ + return (optimize > 0 && flag_regmove); +} + + +/* Register allocation pre-pass, to reduce number of moves necessary + for two-address machines. */ +static void +rest_of_handle_regmove (void) +{ + regmove_optimize (get_insns (), max_reg_num (), dump_file); + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE); +} + +struct tree_opt_pass pass_regmove = +{ + "regmove", /* name */ + gate_handle_regmove, /* gate */ + rest_of_handle_regmove, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_REGMOVE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'N' /* letter */ +}; + + +static bool +gate_handle_stack_adjustments (void) +{ + return (optimize > 0); +} + +static void +rest_of_handle_stack_adjustments (void) +{ + life_analysis (dump_file, PROP_POSTRELOAD); + cleanup_cfg (CLEANUP_EXPENSIVE | CLEANUP_UPDATE_LIFE + | (flag_crossjumping ? CLEANUP_CROSSJUMP : 0)); + + /* This is kind of a heuristic. We need to run combine_stack_adjustments + even for machines with possibly nonzero RETURN_POPS_ARGS + and ACCUMULATE_OUTGOING_ARGS. We expect that only ports having + push instructions will have popping returns. */ +#ifndef PUSH_ROUNDING + if (!ACCUMULATE_OUTGOING_ARGS) +#endif + combine_stack_adjustments (); +} + +struct tree_opt_pass pass_stack_adjustments = +{ + NULL, /* name */ + gate_handle_stack_adjustments, /* gate */ + rest_of_handle_stack_adjustments, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + 0, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 0 /* letter */ +}; + Index: regrename.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/regrename.c,v retrieving revision 1.97 diff -p -u -r1.97 regrename.c --- regrename.c 11 Mar 2005 09:05:06 -0000 1.97 +++ regrename.c 18 May 2005 10:30:20 -0000 @@ -36,6 +36,8 @@ #include "flags.h" #include "toplev.h" #include "obstack.h" +#include "timevar.h" +#include "tree-pass.h" struct du_chain { @@ -1901,3 +1903,38 @@ validate_value_data (struct value_data * vd->e[i].next_regno); } #endif + +static bool +gate_handle_regrename (void) +{ + return (optimize > 0 && (flag_rename_registers || flag_cprop_registers)); +} + + +/* Run the regrename and cprop passes. */ +static void +rest_of_handle_regrename (void) +{ + if (flag_rename_registers) + regrename_optimize (); + if (flag_cprop_registers) + copyprop_hardreg_forward (); +} + +struct tree_opt_pass pass_regrename = +{ + "rnreg", /* name */ + gate_handle_regrename, /* gate */ + rest_of_handle_regrename, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_RENAME_REGISTERS, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'n' /* letter */ +}; + Index: reorg.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/reorg.c,v retrieving revision 1.107 diff -p -u -r1.107 reorg.c --- reorg.c 28 Apr 2005 05:03:08 -0000 1.107 +++ reorg.c 18 May 2005 10:30:27 -0000 @@ -133,6 +133,9 @@ Software Foundation, 59 Temple Place - S #include "resource.h" #include "except.h" #include "params.h" +#include "timevar.h" +#include "target.h" +#include "tree-pass.h" #ifdef DELAY_SLOTS @@ -3809,3 +3812,73 @@ dbr_schedule (rtx first, FILE *file) #endif } #endif /* DELAY_SLOTS */ + +static bool +gate_handle_delay_slots (void) +{ +#ifdef DELAY_SLOTS + return flag_delayed_branch; +#else + return 0; +#endif +} + +/* Run delay slot optimization. */ +static void +rest_of_handle_delay_slots (void) +{ +#ifdef DELAY_SLOTS + dbr_schedule (get_insns (), dump_file); +#endif +} + +struct tree_opt_pass pass_delay_slots = +{ + "dbr", /* name */ + gate_handle_delay_slots, /* gate */ + rest_of_handle_delay_slots, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_DBR_SCHED, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'd' /* letter */ +}; + +/* Machine dependent reorg pass. */ +static bool +gate_handle_machine_reorg (void) +{ + return targetm.machine_dependent_reorg != 0; +} + + +static void +rest_of_handle_machine_reorg (void) +{ + targetm.machine_dependent_reorg (); +} + +struct tree_opt_pass pass_machine_reorg = +{ + "mach", /* name */ + gate_handle_machine_reorg, /* gate */ + rest_of_handle_machine_reorg, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_MACH_DEP, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'M' /* letter */ +}; + Index: rtl.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/rtl.h,v retrieving revision 1.549 diff -p -u -r1.549 rtl.h --- rtl.h 27 Apr 2005 17:38:17 -0000 1.549 +++ rtl.h 18 May 2005 10:30:31 -0000 @@ -1899,7 +1899,7 @@ extern enum rtx_code reversed_comparison rtx, rtx, rtx); extern void delete_for_peephole (rtx, rtx); extern int condjump_in_parallel_p (rtx); -extern void purge_line_number_notes (rtx); +extern void purge_line_number_notes (void); /* In emit-rtl.c. */ extern int max_reg_num (void); Index: sched-rgn.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/sched-rgn.c,v retrieving revision 1.93 diff -p -u -r1.93 sched-rgn.c --- sched-rgn.c 11 Mar 2005 09:05:06 -0000 1.93 +++ sched-rgn.c 18 May 2005 10:30:34 -0000 @@ -65,6 +65,8 @@ Software Foundation, 59 Temple Place - S #include "params.h" #include "sched-int.h" #include "target.h" +#include "timevar.h" +#include "tree-pass.h" /* Define when we want to do count REG_DEAD notes before and after scheduling for sanity checking. We can't do that when conditional execution is used, @@ -2585,3 +2587,95 @@ schedule_insns (FILE *dump_file) sbitmap_free (large_region_blocks); } #endif + +static bool +gate_handle_sched (void) +{ +#ifdef INSN_SCHEDULING + return flag_schedule_insns; +#else + return 0; +#endif +} + +/* Run instruction scheduler. */ +static void +rest_of_handle_sched (void) +{ +#ifdef INSN_SCHEDULING + /* Do control and data sched analysis, + and write some of the results to dump file. */ + + schedule_insns (dump_file); +#endif +} + +static bool +gate_handle_sched2 (void) +{ +#ifdef INSN_SCHEDULING + return optimize > 0 && flag_schedule_insns_after_reload; +#else + return 0; +#endif +} + +/* Run second scheduling pass after reload. */ +static void +rest_of_handle_sched2 (void) +{ +#ifdef INSN_SCHEDULING + /* Do control and data sched analysis again, + and write some more of the results to dump file. */ + + split_all_insns (1); + + if (flag_sched2_use_superblocks || flag_sched2_use_traces) + { + schedule_ebbs (dump_file); + /* No liveness updating code yet, but it should be easy to do. + reg-stack recomputes the liveness when needed for now. */ + count_or_remove_death_notes (NULL, 1); + cleanup_cfg (CLEANUP_EXPENSIVE); + } + else + schedule_insns (dump_file); +#endif +} + +struct tree_opt_pass pass_sched = +{ + "sched1", /* name */ + gate_handle_sched, /* gate */ + rest_of_handle_sched, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_SCHED, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'S' /* letter */ +}; + +struct tree_opt_pass pass_sched2 = +{ + "sched2", /* name */ + gate_handle_sched2, /* gate */ + rest_of_handle_sched2, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_SCHED2, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func | + TODO_ggc_collect, /* todo_flags_finish */ + 'R' /* letter */ +}; + Index: tracer.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tracer.c,v retrieving revision 1.25 diff -p -u -r1.25 tracer.c --- tracer.c 12 Mar 2005 00:34:04 -0000 1.25 +++ tracer.c 18 May 2005 10:30:37 -0000 @@ -48,6 +48,7 @@ #include "timevar.h" #include "params.h" #include "coverage.h" +#include "tree-pass.h" static int count_insns (basic_block); static bool ignore_bb_p (basic_block); @@ -365,8 +366,6 @@ tracer (unsigned int flags) if (n_basic_blocks <= 1) return; - timevar_push (TV_TRACER); - cfg_layout_initialize (flags); mark_dfs_back_edges (); if (dump_file) @@ -379,6 +378,39 @@ tracer (unsigned int flags) /* Merge basic blocks in duplicated traces. */ cleanup_cfg (CLEANUP_EXPENSIVE); +} + +static bool +gate_handle_tracer (void) +{ + return (optimize > 0 && flag_tracer); +} - timevar_pop (TV_TRACER); +/* Run tracer. */ +static void +rest_of_handle_tracer (void) +{ + if (dump_file) + dump_flow_info (dump_file); + tracer (0); + cleanup_cfg (CLEANUP_EXPENSIVE); + reg_scan (get_insns (), max_reg_num ()); } + +struct tree_opt_pass pass_tracer = +{ + "tracer", /* name */ + gate_handle_tracer, /* gate */ + rest_of_handle_tracer, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_TRACER, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'T' /* letter */ +}; + Index: tree-pass.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-pass.h,v retrieving revision 2.35 diff -p -u -r2.35 tree-pass.h --- tree-pass.h 17 May 2005 09:55:24 -0000 2.35 +++ tree-pass.h 18 May 2005 10:30:40 -0000 @@ -221,4 +272,74 @@ extern struct tree_opt_pass pass_uncprop extern struct tree_opt_pass pass_ipa_inline; +extern struct tree_opt_pass pass_all_optimizations; +extern struct tree_opt_pass pass_cleanup_cfg_post_optimizing; +extern struct tree_opt_pass pass_free_datastructures; +extern struct tree_opt_pass pass_init_datastructures; +extern struct tree_opt_pass pass_fixup_cfg; + +extern struct tree_opt_pass pass_remove_unnecessary_notes; +extern struct tree_opt_pass pass_init_function; +extern struct tree_opt_pass pass_jump; +extern struct tree_opt_pass pass_insn_locators_initialize; +extern struct tree_opt_pass pass_rtl_eh; +extern struct tree_opt_pass pass_initial_value_sets; +extern struct tree_opt_pass pass_unshare_all_rtl; +extern struct tree_opt_pass pass_instantiate_virtual_regs; +extern struct tree_opt_pass pass_jump2; +extern struct tree_opt_pass pass_cse; +extern struct tree_opt_pass pass_gcse; +extern struct tree_opt_pass pass_loop_optimize; +extern struct tree_opt_pass pass_jump_bypass; +extern struct tree_opt_pass pass_cfg; +extern struct tree_opt_pass pass_profiling; +extern struct tree_opt_pass pass_rtl_ifcvt; +extern struct tree_opt_pass pass_tracer; +extern struct tree_opt_pass pass_loop2; +extern struct tree_opt_pass pass_web; +extern struct tree_opt_pass pass_cse2; +extern struct tree_opt_pass pass_life; +extern struct tree_opt_pass pass_combine; +extern struct tree_opt_pass pass_if_after_combine; +extern struct tree_opt_pass pass_partition_blocks; +extern struct tree_opt_pass pass_partition_blocks; +extern struct tree_opt_pass pass_regmove; +extern struct tree_opt_pass pass_split_all_insns; +extern struct tree_opt_pass pass_mode_switching; +extern struct tree_opt_pass pass_recompute_reg_usage; +extern struct tree_opt_pass pass_sms; +extern struct tree_opt_pass pass_sched; +extern struct tree_opt_pass pass_local_alloc; +extern struct tree_opt_pass pass_global_alloc; +extern struct tree_opt_pass pass_postreload; +extern struct tree_opt_pass pass_clean_state; +extern struct tree_opt_pass pass_branch_prob; +extern struct tree_opt_pass pass_value_profile_transformations; +extern struct tree_opt_pass pass_remove_death_notes; +extern struct tree_opt_pass pass_postreload_cse; +extern struct tree_opt_pass pass_gcse2; +extern struct tree_opt_pass pass_flow2; +extern struct tree_opt_pass pass_stack_adjustments; +extern struct tree_opt_pass pass_peephole2; +extern struct tree_opt_pass pass_if_after_reload; +extern struct tree_opt_pass pass_regrename; +extern struct tree_opt_pass pass_reorder_blocks; +extern struct tree_opt_pass pass_branch_target_load_optimize; +extern struct tree_opt_pass pass_leaf_regs; +extern struct tree_opt_pass pass_sched2; +extern struct tree_opt_pass pass_stack_regs; +extern struct tree_opt_pass pass_compute_alignments; +extern struct tree_opt_pass pass_duplicate_computed_gotos; +extern struct tree_opt_pass pass_variable_tracking; +extern struct tree_opt_pass pass_free_cfg; +extern struct tree_opt_pass pass_machine_reorg; +extern struct tree_opt_pass pass_purge_lineno_notes; +extern struct tree_opt_pass pass_cleanup_barriers; +extern struct tree_opt_pass pass_delay_slots; +extern struct tree_opt_pass pass_split_for_shorten_branches; +extern struct tree_opt_pass pass_split_before_regstack; +extern struct tree_opt_pass pass_convert_to_eh_region_ranges; +extern struct tree_opt_pass pass_shorten_branches; +extern struct tree_opt_pass pass_set_nothrow_function_flags; +extern struct tree_opt_pass pass_final; #endif /* GCC_TREE_PASS_H */ Index: value-prof.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/value-prof.c,v retrieving revision 1.28 diff -p -u -r1.28 value-prof.c --- value-prof.c 28 Apr 2005 05:03:09 -0000 1.28 +++ value-prof.c 18 May 2005 10:30:54 -0000 @@ -40,6 +40,8 @@ Software Foundation, 59 Temple Place - S #include "coverage.h" #include "tree.h" #include "gcov-io.h" +#include "timevar.h" +#include "tree-pass.h" static struct value_prof_hooks *value_prof_hooks; @@ -1797,3 +1799,39 @@ value_profile_transformations (void) VEC_free (histogram_value, heap, static_values); return retval; } + +static bool +gate_handle_value_profile_transformations (void) +{ + return flag_branch_probabilities + && flag_profile_values + && (flag_value_profile_transformations + || flag_speculative_prefetching); +} + + +/* Do optimizations based on expression value profiles. */ +static void +rest_of_handle_value_profile_transformations (void) +{ + if (value_profile_transformations ()) + cleanup_cfg (CLEANUP_EXPENSIVE); +} + +struct tree_opt_pass pass_value_profile_transformations = +{ + "vpt", /* name */ + gate_handle_value_profile_transformations, /* gate */ + rest_of_handle_value_profile_transformations, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_VPT, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'V' /* letter */ +}; + Index: var-tracking.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/var-tracking.c,v retrieving revision 2.27 diff -p -u -r2.27 var-tracking.c --- var-tracking.c 10 Mar 2005 15:36:39 -0000 2.27 +++ var-tracking.c 18 May 2005 10:30:58 -0000 @@ -102,6 +102,8 @@ #include "hashtab.h" #include "regs.h" #include "expr.h" +#include "timevar.h" +#include "tree-pass.h" /* Type of micro operation. */ enum micro_operation_type @@ -2734,3 +2736,29 @@ variable_tracking_main (void) vt_finalize (); } + +static bool +gate_handle_var_tracking (void) +{ + return (flag_var_tracking); +} + + + +struct tree_opt_pass pass_variable_tracking = +{ + "vartrack", /* name */ + gate_handle_var_tracking, /* gate */ + variable_tracking_main, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_VAR_TRACKING, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'V' /* letter */ +}; + Index: web.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/web.c,v retrieving revision 2.14 diff -p -u -r2.14 web.c --- web.c 22 Nov 2004 12:23:59 -0000 2.14 +++ web.c 18 May 2005 10:30:59 -0000 @@ -56,6 +56,8 @@ Software Foundation, 59 Temple Place - S #include "output.h" #include "df.h" #include "function.h" +#include "timevar.h" +#include "tree-pass.h" /* This entry is allocated for each reference in the insn stream. */ @@ -271,3 +273,36 @@ web_main (void) free (used); df_finish (df); } + +static bool +gate_handle_web (void) +{ + return (optimize > 0 && flag_web); +} + +static void +rest_of_handle_web (void) +{ + web_main (); + delete_trivially_dead_insns (get_insns (), max_reg_num ()); + cleanup_cfg (CLEANUP_EXPENSIVE); + reg_scan (get_insns (), max_reg_num ()); +} + +struct tree_opt_pass pass_web = +{ + "web", /* name */ + gate_handle_web, /* gate */ + rest_of_handle_web, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_WEB, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_dump_func, /* todo_flags_finish */ + 'Z' /* letter */ +}; + --------------040206050304050704060205--