From 65b0537f9e9741318f7c8e738b6dd3b8f82f58b5 Mon Sep 17 00:00:00 2001 From: tbsaunde Date: Thu, 17 Apr 2014 12:37:34 +0000 Subject: [PATCH] pass cfun to pass::execute gcc/ * passes.c (opt_pass::execute): Adjust. (pass_manager::execute_pass_mode_switching): Likewise. (early_local_passes::execute): Likewise. (execute_one_pass): Pass cfun to the pass's execute method. * tree-pass.h (opt_pass::execute): Add function * argument. * asan.c, auto-inc-dec.c, bb-reorder.c, bt-load.c, cfgcleanup.c, cfgexpand.c, cfgrtl.c, cgraphbuild.c, combine-stack-adj.c, combine.c, compare-elim.c, config/arc/arc.c, config/epiphany/mode-switch-use.c, config/epiphany/resolve-sw-modes.c, config/i386/i386.c, config/mips/mips.c, config/rl78/rl78.c, config/s390/s390.c, config/sparc/sparc.c, cprop.c, dce.c, df-core.c, dse.c, dwarf2cfi.c, except.c, final.c, function.c, fwprop.c, gcse.c, gimple-low.c, gimple-ssa-isolate-paths.c, gimple-ssa-strength-reduction.c, graphite.c, ifcvt.c, init-regs.c, ipa-cp.c, ipa-devirt.c, ipa-inline-analysis.c, ipa-inline.c, ipa-profile.c, ipa-pure-const.c, ipa-reference.c, ipa-split.c, ipa.c, ira.c, jump.c, loop-init.c, lower-subreg.c, mode-switching.c, omp-low.c, postreload-gcse.c, postreload.c, predict.c, recog.c, ree.c, reg-stack.c, regcprop.c, reginfo.c, regrename.c, reorg.c, sched-rgn.c, stack-ptr-mod.c, store-motion.c, tracer.c, trans-mem.c, tree-call-cdce.c, tree-cfg.c, tree-cfgcleanup.c, tree-complex.c, tree-eh.c, tree-emutls.c, tree-if-conv.c, tree-into-ssa.c, tree-loop-distribution.c, tree-nrv.c, tree-object-size.c, tree-parloops.c, tree-predcom.c, tree-ssa-ccp.c, tree-ssa-copy.c, tree-ssa-copyrename.c, tree-ssa-dce.c, tree-ssa-dom.c, tree-ssa-dse.c, tree-ssa-forwprop.c, tree-ssa-ifcombine.c, tree-ssa-loop-ch.c, tree-ssa-loop-im.c, tree-ssa-loop-ivcanon.c, tree-ssa-loop-prefetch.c, tree-ssa-loop-unswitch.c, tree-ssa-loop.c, tree-ssa-math-opts.c, tree-ssa-phiopt.c, tree-ssa-phiprop.c, tree-ssa-pre.c, tree-ssa-reassoc.c, tree-ssa-sink.c, tree-ssa-strlen.c, tree-ssa-structalias.c, tree-ssa-uncprop.c, tree-ssa-uninit.c, tree-ssa.c, tree-ssanames.c, tree-stdarg.c, tree-switch-conversion.c, tree-tailcall.c, tree-vect-generic.c, tree-vectorizer.c, tree-vrp.c, tree.c, tsan.c, ubsan.c, var-tracking.c, vtable-verify.c, web.c: Adjust. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@209482 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 38 +++ gcc/asan.c | 70 ++-- gcc/auto-inc-dec.c | 63 ++-- gcc/bb-reorder.c | 231 +++++++------ gcc/bt-load.c | 64 ++-- gcc/cfgcleanup.c | 37 +- gcc/cfgexpand.c | 136 ++++---- gcc/cfgrtl.c | 85 +++-- gcc/cgraphbuild.c | 88 ++--- gcc/combine-stack-adj.c | 5 +- gcc/combine.c | 5 +- gcc/compare-elim.c | 5 +- gcc/config/arc/arc.c | 7 +- gcc/config/epiphany/mode-switch-use.c | 2 +- gcc/config/epiphany/resolve-sw-modes.c | 68 ++-- gcc/config/i386/i386.c | 5 +- gcc/config/mips/mips.c | 2 +- gcc/config/rl78/rl78.c | 17 +- gcc/config/s390/s390.c | 56 ++-- gcc/config/sparc/sparc.c | 5 +- gcc/cprop.c | 2 +- gcc/cse.c | 11 +- gcc/dce.c | 10 +- gcc/df-core.c | 15 +- gcc/dse.c | 4 +- gcc/dwarf2cfi.c | 2 +- gcc/except.c | 10 +- gcc/final.c | 14 +- gcc/function.c | 79 +++-- gcc/fwprop.c | 4 +- gcc/gcse.c | 4 +- gcc/gimple-low.c | 2 +- gcc/gimple-ssa-isolate-paths.c | 5 +- gcc/gimple-ssa-strength-reduction.c | 64 ++-- gcc/graphite.c | 2 +- gcc/ifcvt.c | 31 +- gcc/init-regs.c | 13 +- gcc/ipa-cp.c | 2 +- gcc/ipa-devirt.c | 2 +- gcc/ipa-inline-analysis.c | 7 +- gcc/ipa-inline.c | 65 ++-- gcc/ipa-profile.c | 2 +- gcc/ipa-pure-const.c | 93 +++--- gcc/ipa-reference.c | 2 +- gcc/ipa-split.c | 10 +- gcc/ipa.c | 35 +- gcc/ira.c | 25 +- gcc/jump.c | 2 +- gcc/loop-init.c | 135 ++++---- gcc/lower-subreg.c | 30 +- gcc/mode-switching.c | 18 +- gcc/modulo-sched.c | 47 +-- gcc/omp-low.c | 13 +- gcc/passes.c | 11 +- gcc/postreload-gcse.c | 2 +- gcc/postreload.c | 36 +- gcc/predict.c | 170 +++++----- gcc/recog.c | 48 +-- gcc/ree.c | 2 +- gcc/reg-stack.c | 5 +- gcc/regcprop.c | 174 +++++----- gcc/reginfo.c | 2 +- gcc/regrename.c | 2 +- gcc/reorg.c | 18 +- gcc/sched-rgn.c | 12 +- gcc/stack-ptr-mod.c | 73 ++-- gcc/store-motion.c | 5 +- gcc/testsuite/g++.dg/plugin/dumb_plugin.c | 18 +- gcc/testsuite/g++.dg/plugin/selfassign.c | 34 +- gcc/testsuite/gcc.dg/plugin/one_time_plugin.c | 5 +- gcc/testsuite/gcc.dg/plugin/selfassign.c | 34 +- gcc/tracer.c | 59 ++-- gcc/trans-mem.c | 62 ++-- gcc/tree-call-cdce.c | 82 +++-- gcc/tree-cfg.c | 136 ++++---- gcc/tree-cfgcleanup.c | 73 ++-- gcc/tree-complex.c | 4 +- gcc/tree-eh.c | 236 +++++++------ gcc/tree-emutls.c | 2 +- gcc/tree-if-conv.c | 56 ++-- gcc/tree-into-ssa.c | 86 ++--- gcc/tree-loop-distribution.c | 82 ++--- gcc/tree-nrv.c | 128 +++---- gcc/tree-object-size.c | 65 ++-- gcc/tree-parloops.c | 24 +- gcc/tree-pass.h | 2 +- gcc/tree-predcom.c | 5 +- gcc/tree-profile.c | 2 +- gcc/tree-sra.c | 6 +- gcc/tree-ssa-ccp.c | 69 ++-- gcc/tree-ssa-copy.c | 2 +- gcc/tree-ssa-copyrename.c | 70 ++-- gcc/tree-ssa-dce.c | 6 +- gcc/tree-ssa-dom.c | 152 ++++----- gcc/tree-ssa-dse.c | 68 ++-- gcc/tree-ssa-forwprop.c | 68 ++-- gcc/tree-ssa-ifcombine.c | 62 ++-- gcc/tree-ssa-loop-ch.c | 72 ++-- gcc/tree-ssa-loop-im.c | 20 +- gcc/tree-ssa-loop-ivcanon.c | 84 ++--- gcc/tree-ssa-loop-prefetch.c | 20 +- gcc/tree-ssa-loop-unswitch.c | 20 +- gcc/tree-ssa-loop.c | 128 +++---- gcc/tree-ssa-math-opts.c | 316 +++++++++--------- gcc/tree-ssa-phiopt.c | 315 +++++++++-------- gcc/tree-ssa-phiprop.c | 64 ++-- gcc/tree-ssa-pre.c | 129 ++++--- gcc/tree-ssa-reassoc.c | 2 +- gcc/tree-ssa-sink.c | 47 ++- gcc/tree-ssa-strlen.c | 58 ++-- gcc/tree-ssa-structalias.c | 2 +- gcc/tree-ssa-uncprop.c | 81 +++-- gcc/tree-ssa-uninit.c | 130 +++---- gcc/tree-ssa.c | 5 +- gcc/tree-ssanames.c | 69 ++-- gcc/tree-stdarg.c | 96 +++--- gcc/tree-switch-conversion.c | 68 ++-- gcc/tree-tailcall.c | 13 +- gcc/tree-vect-generic.c | 10 +- gcc/tree-vectorizer.c | 58 ++-- gcc/tree-vrp.c | 2 +- gcc/tree.c | 2 +- gcc/tsan.c | 4 +- gcc/ubsan.c | 74 ++-- gcc/var-tracking.c | 5 +- gcc/vtable-verify.c | 35 +- gcc/web.c | 68 ++-- 127 files changed, 3013 insertions(+), 2991 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e2ca3289f6f3..ea9bb14a40b8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,41 @@ +2014-04-17 Trevor Saunders + + * passes.c (opt_pass::execute): Adjust. + (pass_manager::execute_pass_mode_switching): Likewise. + (early_local_passes::execute): Likewise. + (execute_one_pass): Pass cfun to the pass's execute method. + * tree-pass.h (opt_pass::execute): Add function * argument. + * asan.c, auto-inc-dec.c, bb-reorder.c, bt-load.c, cfgcleanup.c, + cfgexpand.c, cfgrtl.c, cgraphbuild.c, combine-stack-adj.c, combine.c, + compare-elim.c, config/arc/arc.c, config/epiphany/mode-switch-use.c, + config/epiphany/resolve-sw-modes.c, config/i386/i386.c, + config/mips/mips.c, config/rl78/rl78.c, config/s390/s390.c, + config/sparc/sparc.c, cprop.c, dce.c, df-core.c, dse.c, dwarf2cfi.c, + except.c, final.c, function.c, fwprop.c, gcse.c, gimple-low.c, + gimple-ssa-isolate-paths.c, gimple-ssa-strength-reduction.c, + graphite.c, ifcvt.c, init-regs.c, ipa-cp.c, ipa-devirt.c, + ipa-inline-analysis.c, ipa-inline.c, ipa-profile.c, ipa-pure-const.c, + ipa-reference.c, ipa-split.c, ipa.c, ira.c, jump.c, loop-init.c, + lower-subreg.c, mode-switching.c, omp-low.c, postreload-gcse.c, + postreload.c, predict.c, recog.c, ree.c, reg-stack.c, regcprop.c, + reginfo.c, regrename.c, reorg.c, sched-rgn.c, stack-ptr-mod.c, + store-motion.c, tracer.c, trans-mem.c, tree-call-cdce.c, tree-cfg.c, + tree-cfgcleanup.c, tree-complex.c, tree-eh.c, tree-emutls.c, + tree-if-conv.c, tree-into-ssa.c, tree-loop-distribution.c, tree-nrv.c, + tree-object-size.c, tree-parloops.c, tree-predcom.c, tree-ssa-ccp.c, + tree-ssa-copy.c, tree-ssa-copyrename.c, tree-ssa-dce.c, + tree-ssa-dom.c, tree-ssa-dse.c, tree-ssa-forwprop.c, + tree-ssa-ifcombine.c, tree-ssa-loop-ch.c, tree-ssa-loop-im.c, + tree-ssa-loop-ivcanon.c, tree-ssa-loop-prefetch.c, + tree-ssa-loop-unswitch.c, tree-ssa-loop.c, tree-ssa-math-opts.c, + tree-ssa-phiopt.c, tree-ssa-phiprop.c, tree-ssa-pre.c, + tree-ssa-reassoc.c, tree-ssa-sink.c, tree-ssa-strlen.c, + tree-ssa-structalias.c, tree-ssa-uncprop.c, tree-ssa-uninit.c, + tree-ssa.c, tree-ssanames.c, tree-stdarg.c, tree-switch-conversion.c, + tree-tailcall.c, tree-vect-generic.c, tree-vectorizer.c, tree-vrp.c, + tree.c, tsan.c, ubsan.c, var-tracking.c, vtable-verify.c, web.c: + Adjust. + 2014-04-17 Trevor Saunders * passes.c (opt_pass::gate): Take function * argument. diff --git a/gcc/asan.c b/gcc/asan.c index 3fe50ef2a093..9f298079d6b8 100644 --- a/gcc/asan.c +++ b/gcc/asan.c @@ -2505,7 +2505,7 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_asan (m_ctxt); } virtual bool gate (function *) { return gate_asan (); } - unsigned int execute () { return asan_instrument (); } + virtual unsigned int execute (function *) { return asan_instrument (); } }; // class pass_asan @@ -2543,7 +2543,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return !optimize && gate_asan (); } - unsigned int execute () { return asan_instrument (); } + virtual unsigned int execute (function *) { return asan_instrument (); } }; // class pass_asan_O0 @@ -2557,12 +2557,42 @@ make_pass_asan_O0 (gcc::context *ctxt) /* Perform optimization of sanitize functions. */ -static unsigned int -execute_sanopt (void) +namespace { + +const pass_data pass_data_sanopt = +{ + GIMPLE_PASS, /* type */ + "sanopt", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_NONE, /* tv_id */ + ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_verify_flow | TODO_verify_stmts + | TODO_update_ssa ), /* todo_flags_finish */ +}; + +class pass_sanopt : public gimple_opt_pass +{ +public: + pass_sanopt (gcc::context *ctxt) + : gimple_opt_pass (pass_data_sanopt, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) { return flag_sanitize; } + virtual unsigned int execute (function *); + +}; // class pass_sanopt + +unsigned int +pass_sanopt::execute (function *fun) { basic_block bb; - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { gimple_stmt_iterator gsi; for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) @@ -2593,36 +2623,6 @@ execute_sanopt (void) return 0; } -namespace { - -const pass_data pass_data_sanopt = -{ - GIMPLE_PASS, /* type */ - "sanopt", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_NONE, /* tv_id */ - ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_verify_flow | TODO_verify_stmts - | TODO_update_ssa ), /* todo_flags_finish */ -}; - -class pass_sanopt : public gimple_opt_pass -{ -public: - pass_sanopt (gcc::context *ctxt) - : gimple_opt_pass (pass_data_sanopt, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) { return flag_sanitize; } - unsigned int execute () { return execute_sanopt (); } - -}; // class pass_sanopt - } // anon namespace gimple_opt_pass * diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c index e1485a3cb2a9..0314d183a834 100644 --- a/gcc/auto-inc-dec.c +++ b/gcc/auto-inc-dec.c @@ -1462,37 +1462,6 @@ merge_in_block (int max_reg, basic_block bb) #endif -static unsigned int -rest_of_handle_auto_inc_dec (void) -{ -#ifdef AUTO_INC_DEC - basic_block bb; - int max_reg = max_reg_num (); - - if (!initialized) - init_decision_table (); - - mem_tmp = gen_rtx_MEM (Pmode, NULL_RTX); - - df_note_add_problem (); - df_analyze (); - - reg_next_use = XCNEWVEC (rtx, max_reg); - reg_next_inc_use = XCNEWVEC (rtx, max_reg); - reg_next_def = XCNEWVEC (rtx, max_reg); - FOR_EACH_BB_FN (bb, cfun) - merge_in_block (max_reg, bb); - - free (reg_next_use); - free (reg_next_inc_use); - free (reg_next_def); - - mem_tmp = NULL; -#endif - return 0; -} - - /* Discover auto-inc auto-dec instructions. */ namespace { @@ -1529,10 +1498,40 @@ public: } - unsigned int execute () { return rest_of_handle_auto_inc_dec (); } + unsigned int execute (function *); }; // class pass_inc_dec +unsigned int +pass_inc_dec::execute (function *fun ATTRIBUTE_UNUSED) +{ +#ifdef AUTO_INC_DEC + basic_block bb; + int max_reg = max_reg_num (); + + if (!initialized) + init_decision_table (); + + mem_tmp = gen_rtx_MEM (Pmode, NULL_RTX); + + df_note_add_problem (); + df_analyze (); + + reg_next_use = XCNEWVEC (rtx, max_reg); + reg_next_inc_use = XCNEWVEC (rtx, max_reg); + reg_next_def = XCNEWVEC (rtx, max_reg); + FOR_EACH_BB_FN (bb, fun) + merge_in_block (max_reg, bb); + + free (reg_next_use); + free (reg_next_inc_use); + free (reg_next_def); + + mem_tmp = NULL; +#endif + return 0; +} + } // anon namespace rtl_opt_pass * diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c index 57103bd323a3..db490f1f8760 100644 --- a/gcc/bb-reorder.c +++ b/gcc/bb-reorder.c @@ -2302,26 +2302,6 @@ insert_section_boundary_note (void) } } -static unsigned int -rest_of_handle_reorder_blocks (void) -{ - basic_block bb; - - /* Last attempt to optimize CFG, as scheduling, peepholing and insn - splitting possibly introduced more crossjumping opportunities. */ - cfg_layout_initialize (CLEANUP_EXPENSIVE); - - reorder_basic_blocks (); - cleanup_cfg (CLEANUP_EXPENSIVE); - - FOR_EACH_BB_FN (bb, cfun) - if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) - bb->aux = bb->next_bb; - cfg_layout_finalize (); - - return 0; -} - namespace { const pass_data pass_data_reorder_blocks = @@ -2354,10 +2334,30 @@ public: && (flag_reorder_blocks || flag_reorder_blocks_and_partition)); } - unsigned int execute () { return rest_of_handle_reorder_blocks (); } + virtual unsigned int execute (function *); }; // class pass_reorder_blocks +unsigned int +pass_reorder_blocks::execute (function *fun) +{ + basic_block bb; + + /* Last attempt to optimize CFG, as scheduling, peepholing and insn + splitting possibly introduced more crossjumping opportunities. */ + cfg_layout_initialize (CLEANUP_EXPENSIVE); + + reorder_basic_blocks (); + cleanup_cfg (CLEANUP_EXPENSIVE); + + FOR_EACH_BB_FN (bb, fun) + if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (fun)) + bb->aux = bb->next_bb; + cfg_layout_finalize (); + + return 0; +} + } // anon namespace rtl_opt_pass * @@ -2372,16 +2372,54 @@ make_pass_reorder_blocks (gcc::context *ctxt) which can seriously pessimize code with many computed jumps in the source code, such as interpreters. See e.g. PR15242. */ +namespace { -static unsigned int -duplicate_computed_gotos (void) +const pass_data pass_data_duplicate_computed_gotos = +{ + RTL_PASS, /* type */ + "compgotos", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_REORDER_BLOCKS, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_verify_rtl_sharing, /* todo_flags_finish */ +}; + +class pass_duplicate_computed_gotos : public rtl_opt_pass +{ +public: + pass_duplicate_computed_gotos (gcc::context *ctxt) + : rtl_opt_pass (pass_data_duplicate_computed_gotos, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *); + virtual unsigned int execute (function *); + +}; // class pass_duplicate_computed_gotos + +bool +pass_duplicate_computed_gotos::gate (function *fun) +{ + if (targetm.cannot_modify_jumps_p ()) + return false; + return (optimize > 0 + && flag_expensive_optimizations + && ! optimize_function_for_size_p (fun)); +} + +unsigned int +pass_duplicate_computed_gotos::execute (function *fun) { basic_block bb, new_bb; bitmap candidates; int max_size; bool changed = false; - if (n_basic_blocks_for_fn (cfun) <= NUM_FIXED_BLOCKS + 1) + if (n_basic_blocks_for_fn (fun) <= NUM_FIXED_BLOCKS + 1) return 0; clear_bb_flags (); @@ -2400,7 +2438,7 @@ duplicate_computed_gotos (void) /* Look for blocks that end in a computed jump, and see if such blocks are suitable for unfactoring. If a block is a candidate for unfactoring, mark it in the candidates. */ - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { rtx insn; edge e; @@ -2408,7 +2446,7 @@ duplicate_computed_gotos (void) int size, all_flags; /* Build the reorder chain for the original order of blocks. */ - if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) + if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (fun)) bb->aux = bb->next_bb; /* Obviously the block has to end in a computed jump. */ @@ -2447,7 +2485,7 @@ duplicate_computed_gotos (void) goto done; /* Duplicate computed gotos. */ - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { if (bb->flags & BB_VISITED) continue; @@ -2458,7 +2496,7 @@ duplicate_computed_gotos (void) the exit block or the next block. The destination must have more than one predecessor. */ if (!single_succ_p (bb) - || single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (cfun) + || single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (fun) || single_succ (bb) == bb->next_bb || single_pred_p (single_succ (bb))) continue; @@ -2491,45 +2529,6 @@ done: return 0; } -namespace { - -const pass_data pass_data_duplicate_computed_gotos = -{ - RTL_PASS, /* type */ - "compgotos", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_REORDER_BLOCKS, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_verify_rtl_sharing, /* todo_flags_finish */ -}; - -class pass_duplicate_computed_gotos : public rtl_opt_pass -{ -public: - pass_duplicate_computed_gotos (gcc::context *ctxt) - : rtl_opt_pass (pass_data_duplicate_computed_gotos, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *); - unsigned int execute () { return duplicate_computed_gotos (); } - -}; // class pass_duplicate_computed_gotos - -bool -pass_duplicate_computed_gotos::gate (function *fun) -{ - if (targetm.cannot_modify_jumps_p ()) - return false; - return (optimize > 0 - && flag_expensive_optimizations - && ! optimize_function_for_size_p (fun)); -} - } // anon namespace rtl_opt_pass * @@ -2627,12 +2626,57 @@ make_pass_duplicate_computed_gotos (gcc::context *ctxt) Unconditional branches are dealt with by converting them into indirect jumps. */ -static unsigned -partition_hot_cold_basic_blocks (void) +namespace { + +const pass_data pass_data_partition_blocks = +{ + RTL_PASS, /* type */ + "bbpart", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_REORDER_BLOCKS, /* tv_id */ + PROP_cfglayout, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_partition_blocks : public rtl_opt_pass +{ +public: + pass_partition_blocks (gcc::context *ctxt) + : rtl_opt_pass (pass_data_partition_blocks, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *); + virtual unsigned int execute (function *); + +}; // class pass_partition_blocks + +bool +pass_partition_blocks::gate (function *fun) +{ + /* 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 + && optimize + /* See gate_handle_reorder_blocks. We should not partition if + we are going to omit the reordering. */ + && optimize_function_for_speed_p (fun) + && !DECL_ONE_ONLY (current_function_decl) + && !user_defined_section_attribute); +} + +unsigned +pass_partition_blocks::execute (function *fun) { vec crossing_edges; - if (n_basic_blocks_for_fn (cfun) <= NUM_FIXED_BLOCKS + 1) + if (n_basic_blocks_for_fn (fun) <= NUM_FIXED_BLOCKS + 1) return 0; df_set_flags (DF_DEFER_INSN_RESCAN); @@ -2693,7 +2737,7 @@ partition_hot_cold_basic_blocks (void) In the meantime, we have no other option but to throw away all of the DF data and recompute it all. */ - if (cfun->eh->lp_array) + if (fun->eh->lp_array) { df_finish_pass (true); df_scan_alloc (NULL); @@ -2708,51 +2752,6 @@ partition_hot_cold_basic_blocks (void) return TODO_verify_flow | TODO_verify_rtl_sharing; } -namespace { - -const pass_data pass_data_partition_blocks = -{ - RTL_PASS, /* type */ - "bbpart", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_REORDER_BLOCKS, /* tv_id */ - PROP_cfglayout, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_partition_blocks : public rtl_opt_pass -{ -public: - pass_partition_blocks (gcc::context *ctxt) - : rtl_opt_pass (pass_data_partition_blocks, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *); - unsigned int execute () { return partition_hot_cold_basic_blocks (); } - -}; // class pass_partition_blocks - -bool -pass_partition_blocks::gate (function *fun) -{ - /* 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 - && optimize - /* See gate_handle_reorder_blocks. We should not partition if - we are going to omit the reordering. */ - && optimize_function_for_speed_p (fun) - && !DECL_ONE_ONLY (current_function_decl) - && !user_defined_section_attribute); -} - } // anon namespace rtl_opt_pass * diff --git a/gcc/bt-load.c b/gcc/bt-load.c index fc2aea7fd727..53c5f5804617 100644 --- a/gcc/bt-load.c +++ b/gcc/bt-load.c @@ -1494,14 +1494,6 @@ branch_target_load_optimize (bool after_prologue_epilogue_gen) } } - -static unsigned int -rest_of_handle_branch_target_load_optimize1 (void) -{ - branch_target_load_optimize (epilogue_completed); - return 0; -} - namespace { const pass_data pass_data_branch_target_load_optimize1 = @@ -1527,9 +1519,11 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_branch_target_load_optimize; } - unsigned int execute () { - return rest_of_handle_branch_target_load_optimize1 (); - } + virtual unsigned int execute (function *) + { + branch_target_load_optimize (epilogue_completed); + return 0; + } }; // class pass_branch_target_load_optimize1 @@ -1542,28 +1536,6 @@ make_pass_branch_target_load_optimize1 (gcc::context *ctxt) } -static unsigned int -rest_of_handle_branch_target_load_optimize2 (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); - return 0; -} - namespace { const pass_data pass_data_branch_target_load_optimize2 = @@ -1593,12 +1565,32 @@ public: return (optimize > 0 && flag_branch_target_load_optimize2); } - unsigned int execute () { - return rest_of_handle_branch_target_load_optimize2 (); - } + virtual unsigned int execute (function *); }; // class pass_branch_target_load_optimize2 +unsigned int +pass_branch_target_load_optimize2::execute (function *) +{ + 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); + return 0; +} + } // anon namespace rtl_opt_pass * diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index d5d68bf27898..d793a70b4dbc 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -3078,17 +3078,6 @@ cleanup_cfg (int mode) return changed; } -static unsigned int -execute_jump (void) -{ - delete_trivially_dead_insns (get_insns (), max_reg_num ()); - if (dump_file) - dump_flow_info (dump_file, dump_flags); - cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) - | (flag_thread_jumps ? CLEANUP_THREADING : 0)); - return 0; -} - namespace { const pass_data pass_data_jump = @@ -3113,10 +3102,21 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return execute_jump (); } + virtual unsigned int execute (function *); }; // class pass_jump +unsigned int +pass_jump::execute (function *) +{ + delete_trivially_dead_insns (get_insns (), max_reg_num ()); + if (dump_file) + dump_flow_info (dump_file, dump_flags); + cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) + | (flag_thread_jumps ? CLEANUP_THREADING : 0)); + return 0; +} + } // anon namespace rtl_opt_pass * @@ -3125,13 +3125,6 @@ make_pass_jump (gcc::context *ctxt) return new pass_jump (ctxt); } -static unsigned int -execute_jump2 (void) -{ - cleanup_cfg (flag_crossjumping ? CLEANUP_CROSSJUMP : 0); - return 0; -} - namespace { const pass_data pass_data_jump2 = @@ -3156,7 +3149,11 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return execute_jump2 (); } + virtual unsigned int execute (function *) + { + cleanup_cfg (flag_crossjumping ? CLEANUP_CROSSJUMP : 0); + return 0; + } }; // class pass_jump2 diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index c60703f2bb48..f2fd5fc92a9b 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -5530,8 +5530,39 @@ stack_protect_prologue (void) confuse the CFG hooks, so be careful to not manipulate CFG during the expansion. */ -static unsigned int -gimple_expand_cfg (void) +namespace { + +const pass_data pass_data_expand = +{ + RTL_PASS, /* type */ + "expand", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_EXPAND, /* tv_id */ + ( PROP_ssa | PROP_gimple_leh | PROP_cfg + | PROP_gimple_lcx + | PROP_gimple_lvec ), /* properties_required */ + PROP_rtl, /* properties_provided */ + ( PROP_ssa | PROP_trees ), /* properties_destroyed */ + ( TODO_verify_ssa | TODO_verify_flow + | TODO_verify_stmts ), /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_expand : public rtl_opt_pass +{ +public: + pass_expand (gcc::context *ctxt) + : rtl_opt_pass (pass_data_expand, ctxt) + {} + + /* opt_pass methods: */ + virtual unsigned int execute (function *); + +}; // class pass_expand + +unsigned int +pass_expand::execute (function *fun) { basic_block bb, init_block; sbitmap blocks; @@ -5554,17 +5585,17 @@ gimple_expand_cfg (void) /* Dominators are not kept up-to-date as we may create new basic-blocks. */ free_dominance_info (CDI_DOMINATORS); - rtl_profile_for_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun)); + rtl_profile_for_bb (ENTRY_BLOCK_PTR_FOR_FN (fun)); insn_locations_init (); if (!DECL_IS_BUILTIN (current_function_decl)) { /* Eventually, all FEs should explicitly set function_start_locus. */ - if (LOCATION_LOCUS (cfun->function_start_locus) == UNKNOWN_LOCATION) - set_curr_insn_location - (DECL_SOURCE_LOCATION (current_function_decl)); + if (LOCATION_LOCUS (fun->function_start_locus) == UNKNOWN_LOCATION) + set_curr_insn_location + (DECL_SOURCE_LOCATION (current_function_decl)); else - set_curr_insn_location (cfun->function_start_locus); + set_curr_insn_location (fun->function_start_locus); } else set_curr_insn_location (UNKNOWN_LOCATION); @@ -5587,7 +5618,7 @@ gimple_expand_cfg (void) crtl->max_used_stack_slot_alignment = STACK_BOUNDARY; crtl->stack_alignment_estimated = 0; crtl->preferred_stack_boundary = STACK_BOUNDARY; - cfun->cfg->max_jumptable_ents = 0; + fun->cfg->max_jumptable_ents = 0; /* Resovle the function section. Some targets, like ARM EABI rely on knowledge of the function section at exapnsion time to predict distance of calls. */ @@ -5606,14 +5637,14 @@ gimple_expand_cfg (void) /* Honor stack protection warnings. */ if (warn_stack_protect) { - if (cfun->calls_alloca) + if (fun->calls_alloca) warning (OPT_Wstack_protector, "stack protector not protecting local variables: " - "variable length buffer"); + "variable length buffer"); if (has_short_buffer && !crtl->stack_protect_guard) warning (OPT_Wstack_protector, "stack protector not protecting function: " - "all local arrays are less than %d bytes long", + "all local arrays are less than %d bytes long", (int) PARAM_VALUE (PARAM_SSP_BUFFER_SIZE)); } @@ -5644,12 +5675,12 @@ gimple_expand_cfg (void) gcc_assert (SA.partition_to_pseudo[i]); /* If this decl was marked as living in multiple places, reset - this now to NULL. */ + this now to NULL. */ if (DECL_RTL_IF_SET (var) == pc_rtx) SET_DECL_RTL (var, NULL); /* Some RTL parts really want to look at DECL_RTL(x) when x - was a decl marked in REG_ATTR or MEM_ATTR. We could use + was a decl marked in REG_ATTR or MEM_ATTR. We could use SET_DECL_RTL here making this available, but that would mean to select one of the potentially many RTLs for one DECL. Instead of doing that we simply reset the MEM_EXPR of the RTL in question, @@ -5718,11 +5749,11 @@ gimple_expand_cfg (void) /* Clear EDGE_EXECUTABLE on the entry edge(s). It is cleaned from the remaining edges later. */ - FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs) + FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (fun)->succs) e->flags &= ~EDGE_EXECUTABLE; lab_rtx_for_bb = pointer_map_create (); - FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), + FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR_FOR_FN (fun), next_bb) bb = expand_gimple_basic_block (bb, var_ret_seq != NULL_RTX); @@ -5740,7 +5771,7 @@ gimple_expand_cfg (void) timevar_push (TV_POST_EXPAND); /* We are no longer in SSA form. */ - cfun->gimple_df->in_ssa_p = false; + fun->gimple_df->in_ssa_p = false; if (current_loops) loops_state_clear (LOOP_CLOSED_SSA); @@ -5762,14 +5793,14 @@ gimple_expand_cfg (void) } /* Zap the tree EH table. */ - set_eh_throw_stmt_table (cfun, NULL); + set_eh_throw_stmt_table (fun, NULL); /* We need JUMP_LABEL be set in order to redirect jumps, and hence split edges which edge insertions might do. */ rebuild_jump_labels (get_insns ()); - FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), - EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb) + FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (fun), + EXIT_BLOCK_PTR_FOR_FN (fun), next_bb) { edge e; edge_iterator ei; @@ -5780,8 +5811,8 @@ gimple_expand_cfg (void) rebuild_jump_labels_chain (e->insns.r); /* Put insns after parm birth, but before NOTE_INSNS_FUNCTION_BEG. */ - if (e->src == ENTRY_BLOCK_PTR_FOR_FN (cfun) - && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun))) + if (e->src == ENTRY_BLOCK_PTR_FOR_FN (fun) + && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (fun))) { rtx insns = e->insns.r; e->insns.r = NULL_RTX; @@ -5802,8 +5833,8 @@ gimple_expand_cfg (void) /* We're done expanding trees to RTL. */ currently_expanding_to_rtl = 0; - FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb, - EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb) + FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (fun)->next_bb, + EXIT_BLOCK_PTR_FOR_FN (fun), next_bb) { edge e; edge_iterator ei; @@ -5824,7 +5855,7 @@ gimple_expand_cfg (void) } } - blocks = sbitmap_alloc (last_basic_block_for_fn (cfun)); + blocks = sbitmap_alloc (last_basic_block_for_fn (fun)); bitmap_ones (blocks); find_many_sub_basic_blocks (blocks); sbitmap_free (blocks); @@ -5840,7 +5871,7 @@ gimple_expand_cfg (void) /* After initial rtl generation, call back to finish generating exception support code. We need to do this before cleaning up the CFG as the code does not expect dead landing pads. */ - if (cfun->eh->region_tree != NULL) + if (fun->eh->region_tree != NULL) finish_eh_generation (); /* Remove unreachable blocks, otherwise we cannot compute dominators @@ -5878,14 +5909,14 @@ gimple_expand_cfg (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; - } + { + 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 @@ -5900,15 +5931,15 @@ gimple_expand_cfg (void) naked_return_label = NULL; /* After expanding, the tm_restart map is no longer needed. */ - if (cfun->gimple_df->tm_restart) + if (fun->gimple_df->tm_restart) { - htab_delete (cfun->gimple_df->tm_restart); - cfun->gimple_df->tm_restart = NULL; + htab_delete (fun->gimple_df->tm_restart); + fun->gimple_df->tm_restart = NULL; } /* Tag the blocks with a depth number so that change_scope can find the common parent easily. */ - set_block_levels (DECL_INITIAL (cfun->decl), 0); + set_block_levels (DECL_INITIAL (fun->decl), 0); default_rtl_profile (); timevar_pop (TV_POST_EXPAND); @@ -5916,37 +5947,6 @@ gimple_expand_cfg (void) return 0; } -namespace { - -const pass_data pass_data_expand = -{ - RTL_PASS, /* type */ - "expand", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_EXPAND, /* tv_id */ - ( PROP_ssa | PROP_gimple_leh | PROP_cfg - | PROP_gimple_lcx - | PROP_gimple_lvec ), /* properties_required */ - PROP_rtl, /* properties_provided */ - ( PROP_ssa | PROP_trees ), /* properties_destroyed */ - ( TODO_verify_ssa | TODO_verify_flow - | TODO_verify_stmts ), /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_expand : public rtl_opt_pass -{ -public: - pass_expand (gcc::context *ctxt) - : rtl_opt_pass (pass_data_expand, ctxt) - {} - - /* opt_pass methods: */ - unsigned int execute () { return gimple_expand_cfg (); } - -}; // class pass_expand - } // anon namespace rtl_opt_pass * diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 0404d087bbca..5dd27d2795b5 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -442,26 +442,6 @@ free_bb_for_insn (void) return 0; } -static unsigned int -rest_of_pass_free_cfg (void) -{ -#ifdef DELAY_SLOTS - /* The resource.c machinery uses DF but the CFG isn't guaranteed to be - valid at that point so it would be too late to call df_analyze. */ - if (optimize > 0 && flag_delayed_branch) - { - df_note_add_problem (); - df_analyze (); - } -#endif - - if (crtl->has_bb_partition) - insert_section_boundary_note (); - - free_bb_for_insn (); - return 0; -} - namespace { const pass_data pass_data_free_cfg = @@ -486,10 +466,30 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rest_of_pass_free_cfg (); } + virtual unsigned int execute (function *); }; // class pass_free_cfg +unsigned int +pass_free_cfg::execute (function *) +{ +#ifdef DELAY_SLOTS + /* The resource.c machinery uses DF but the CFG isn't guaranteed to be + valid at that point so it would be too late to call df_analyze. */ + if (optimize > 0 && flag_delayed_branch) + { + df_note_add_problem (); + df_analyze (); + } +#endif + + if (crtl->has_bb_partition) + insert_section_boundary_note (); + + free_bb_for_insn (); + return 0; +} + } // anon namespace rtl_opt_pass * @@ -3466,27 +3466,6 @@ record_effective_endpoints (void) cfg_layout_function_footer = unlink_insn_chain (cfg_layout_function_footer, get_last_insn ()); } -static unsigned int -into_cfg_layout_mode (void) -{ - cfg_layout_initialize (0); - return 0; -} - -static unsigned int -outof_cfg_layout_mode (void) -{ - basic_block bb; - - FOR_EACH_BB_FN (bb, cfun) - if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) - bb->aux = bb->next_bb; - - cfg_layout_finalize (); - - return 0; -} - namespace { const pass_data pass_data_into_cfg_layout_mode = @@ -3511,7 +3490,11 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return into_cfg_layout_mode (); } + virtual unsigned int execute (function *) + { + cfg_layout_initialize (0); + return 0; + } }; // class pass_into_cfg_layout_mode @@ -3547,10 +3530,24 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return outof_cfg_layout_mode (); } + virtual unsigned int execute (function *); }; // class pass_outof_cfg_layout_mode +unsigned int +pass_outof_cfg_layout_mode::execute (function *fun) +{ + basic_block bb; + + FOR_EACH_BB_FN (bb, fun) + if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (fun)) + bb->aux = bb->next_bb; + + cfg_layout_finalize (); + + return 0; +} + } // anon namespace rtl_opt_pass * diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c index 9c6d46deeb35..6bdc8ca0eda9 100644 --- a/gcc/cgraphbuild.c +++ b/gcc/cgraphbuild.c @@ -305,8 +305,36 @@ ipa_record_stmt_references (struct cgraph_node *node, gimple stmt) /* Create cgraph edges for function calls. Also look for functions and variables having addresses taken. */ -static unsigned int -build_cgraph_edges (void) +namespace { + +const pass_data pass_data_build_cgraph_edges = +{ + GIMPLE_PASS, /* type */ + "*build_cgraph_edges", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_NONE, /* tv_id */ + PROP_cfg, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_build_cgraph_edges : public gimple_opt_pass +{ +public: + pass_build_cgraph_edges (gcc::context *ctxt) + : gimple_opt_pass (pass_data_build_cgraph_edges, ctxt) + {} + + /* opt_pass methods: */ + virtual unsigned int execute (function *); + +}; // class pass_build_cgraph_edges + +unsigned int +pass_build_cgraph_edges::execute (function *fun) { basic_block bb; struct cgraph_node *node = cgraph_get_node (current_function_decl); @@ -317,7 +345,7 @@ build_cgraph_edges (void) /* Create the callgraph edges and record the nodes referenced by the function. body. */ - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { @@ -370,45 +398,17 @@ build_cgraph_edges (void) } /* Look for initializers of constant variables and private statics. */ - FOR_EACH_LOCAL_DECL (cfun, ix, decl) + FOR_EACH_LOCAL_DECL (fun, ix, decl) if (TREE_CODE (decl) == VAR_DECL && (TREE_STATIC (decl) && !DECL_EXTERNAL (decl)) && !DECL_HAS_VALUE_EXPR_P (decl)) varpool_finalize_decl (decl); - record_eh_tables (node, cfun); + record_eh_tables (node, fun); pointer_set_destroy (visited_nodes); return 0; } -namespace { - -const pass_data pass_data_build_cgraph_edges = -{ - GIMPLE_PASS, /* type */ - "*build_cgraph_edges", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_NONE, /* tv_id */ - PROP_cfg, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_build_cgraph_edges : public gimple_opt_pass -{ -public: - pass_build_cgraph_edges (gcc::context *ctxt) - : gimple_opt_pass (pass_data_build_cgraph_edges, ctxt) - {} - - /* opt_pass methods: */ - unsigned int execute () { return build_cgraph_edges (); } - -}; // class pass_build_cgraph_edges - } // anon namespace gimple_opt_pass * @@ -539,7 +539,7 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_rebuild_cgraph_edges (m_ctxt); } - unsigned int execute () { return rebuild_cgraph_edges (); } + virtual unsigned int execute (function *) { return rebuild_cgraph_edges (); } }; // class pass_rebuild_cgraph_edges @@ -552,15 +552,6 @@ make_pass_rebuild_cgraph_edges (gcc::context *ctxt) } -static unsigned int -remove_cgraph_callee_edges (void) -{ - struct cgraph_node *node = cgraph_get_node (current_function_decl); - cgraph_node_remove_callees (node); - ipa_remove_all_references (&node->ref_list); - return 0; -} - namespace { const pass_data pass_data_remove_cgraph_callee_edges = @@ -588,10 +579,19 @@ public: opt_pass * clone () { return new pass_remove_cgraph_callee_edges (m_ctxt); } - unsigned int execute () { return remove_cgraph_callee_edges (); } + virtual unsigned int execute (function *); }; // class pass_remove_cgraph_callee_edges +unsigned int +pass_remove_cgraph_callee_edges::execute (function *) +{ + struct cgraph_node *node = cgraph_get_node (current_function_decl); + cgraph_node_remove_callees (node); + ipa_remove_all_references (&node->ref_list); + return 0; +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c index 37fc7a5d271d..399beb4c1bfd 100644 --- a/gcc/combine-stack-adj.c +++ b/gcc/combine-stack-adj.c @@ -653,7 +653,10 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return rest_of_handle_stack_adjustments (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_stack_adjustments (); + } }; // class pass_stack_adjustments diff --git a/gcc/combine.c b/gcc/combine.c index 1b1e33c9d082..9a78c064945c 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -13909,7 +13909,10 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return (optimize > 0); } - unsigned int execute () { return rest_of_handle_combine (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_combine (); + } }; // class pass_combine diff --git a/gcc/compare-elim.c b/gcc/compare-elim.c index 9cddb7a2d357..7555d48c6132 100644 --- a/gcc/compare-elim.c +++ b/gcc/compare-elim.c @@ -676,7 +676,10 @@ public: return flag_compare_elim_after_reload; } - unsigned int execute () { return execute_compare_elim_after_reload (); } + virtual unsigned int execute (function *) + { + return execute_compare_elim_after_reload (); + } }; // class pass_compare_elim_after_reload diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c index eddc55ed8045..64d1312bf654 100644 --- a/gcc/config/arc/arc.c +++ b/gcc/config/arc/arc.c @@ -623,7 +623,7 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_arc_ifcvt (m_ctxt); } - unsigned int execute () { return arc_ifcvt (); } + virtual unsigned int execute (function *) { return arc_ifcvt (); } }; } // anon namespace @@ -660,7 +660,10 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return arc_predicate_delay_insns (); } + virtual unsigned int execute (function *) + { + return arc_predicate_delay_insns (); + } }; } // anon namespace diff --git a/gcc/config/epiphany/mode-switch-use.c b/gcc/config/epiphany/mode-switch-use.c index d89393438950..9617041a3106 100644 --- a/gcc/config/epiphany/mode-switch-use.c +++ b/gcc/config/epiphany/mode-switch-use.c @@ -95,7 +95,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return insert_uses (); } + virtual unsigned int execute (function *) { return insert_uses (); } }; // class pass_mode_switch_use diff --git a/gcc/config/epiphany/resolve-sw-modes.c b/gcc/config/epiphany/resolve-sw-modes.c index 31928fdb0ff8..fa8fea509772 100644 --- a/gcc/config/epiphany/resolve-sw-modes.c +++ b/gcc/config/epiphany/resolve-sw-modes.c @@ -38,6 +38,35 @@ along with GCC; see the file COPYING3. If not see #include "insn-attr-common.h" #include "tree-pass.h" +namespace { + +const pass_data pass_data_resolve_sw_modes = +{ + RTL_PASS, /* type */ + "resolve_sw_modes", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_MODE_SWITCH, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_df_finish | TODO_verify_rtl_sharing | 0 ), /* todo_flags_finish */ +}; + +class pass_resolve_sw_modes : public rtl_opt_pass +{ +public: + pass_resolve_sw_modes(gcc::context *ctxt) + : rtl_opt_pass(pass_data_resolve_sw_modes, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) { return optimize; } + virtual unsigned int execute (function *); + +}; // class pass_resolve_sw_modes + /* Clean-up after mode switching: Check for mode setting insns that have FP_MODE_ROUND_UNKNOWN. If only one rounding mode is required, select that one. @@ -45,8 +74,8 @@ along with GCC; see the file COPYING3. If not see insert new mode setting insns on the edges where the other mode becomes unambigous. */ -static unsigned -resolve_sw_modes (void) +unsigned +pass_resolve_sw_modes::execute (function *fun) { basic_block bb; rtx insn, src; @@ -55,15 +84,15 @@ resolve_sw_modes (void) bool need_commit = false; bool finalize_fp_sets = (MACHINE_FUNCTION (cfun)->unknown_mode_sets == 0); - todo.create (last_basic_block_for_fn (cfun)); - pushed = sbitmap_alloc (last_basic_block_for_fn (cfun)); + todo.create (last_basic_block_for_fn (fun)); + pushed = sbitmap_alloc (last_basic_block_for_fn (fun)); bitmap_clear (pushed); if (!finalize_fp_sets) { df_note_add_problem (); df_analyze (); } - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) FOR_BB_INSNS (bb, insn) { enum attr_fp_mode selected_mode; @@ -155,35 +184,6 @@ resolve_sw_modes (void) return 0; } -namespace { - -const pass_data pass_data_resolve_sw_modes = -{ - RTL_PASS, /* type */ - "resolve_sw_modes", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_MODE_SWITCH, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_df_finish | TODO_verify_rtl_sharing | 0 ), /* todo_flags_finish */ -}; - -class pass_resolve_sw_modes : public rtl_opt_pass -{ -public: - pass_resolve_sw_modes(gcc::context *ctxt) - : rtl_opt_pass(pass_data_resolve_sw_modes, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) { return optimize; } - unsigned int execute () { return resolve_sw_modes (); } - -}; // class pass_resolve_sw_modes - } // anon namespace rtl_opt_pass * diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 10d2fcbea296..c2dcbce1dc01 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -2542,7 +2542,10 @@ public: return TARGET_AVX && !TARGET_AVX512F && TARGET_VZEROUPPER; } - unsigned int execute () { return rest_of_handle_insert_vzeroupper (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_insert_vzeroupper (); + } }; // class pass_insert_vzeroupper diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index 6c0b3c21e4fb..45256e99250f 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -16550,7 +16550,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return mips_machine_reorg2 (); } + virtual unsigned int execute (function *) { return mips_machine_reorg2 (); } }; // class pass_mips_machine_reorg2 diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c index 988e1cd0ac00..0731491a23f3 100644 --- a/gcc/config/rl78/rl78.c +++ b/gcc/config/rl78/rl78.c @@ -117,14 +117,6 @@ rl78_init_machine_status (void) return m; } -/* Runs the devirtualization pass. */ -static unsigned int -devirt_pass (void) -{ - rl78_reorg (); - return 0; -} - /* This pass converts virtual instructions using virtual registers, to real instructions using real registers. Rather than run it as reorg, we reschedule it before vartrack to help with debugging. */ @@ -153,7 +145,12 @@ public: } /* opt_pass methods: */ - unsigned int execute () { return devirt_pass (); } + virtual unsigned int execute (function *) + { + rl78_reorg (); + return 0; + } + }; } // anon namespace @@ -235,7 +232,7 @@ public: } /* opt_pass methods: */ - unsigned int execute () { return move_elim_pass (); } + virtual unsigned int execute (function *) { return move_elim_pass (); } }; } // anon namespace diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 77e163fac797..cc8f32e169c7 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -8631,33 +8631,6 @@ s390_restore_gprs_from_fprs (void) /* A pass run immediately before shrink-wrapping and prologue and epilogue generation. */ -static unsigned int -s390_early_mach (void) -{ - rtx insn; - - /* Try to get rid of the FPR clobbers. */ - s390_optimize_nonescaping_tx (); - - /* Re-compute register info. */ - s390_register_info (); - - /* If we're using a base register, ensure that it is always valid for - the first non-prologue instruction. */ - if (cfun->machine->base_reg) - emit_insn_at_entry (gen_main_pool (cfun->machine->base_reg)); - - /* Annotate all constant pool references to let the scheduler know - they implicitly use the base register. */ - for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) - if (INSN_P (insn)) - { - annotate_constant_pool_refs (&PATTERN (insn)); - df_insn_rescan (insn); - } - return 0; -} - namespace { const pass_data pass_data_s390_early_mach = @@ -8683,10 +8656,37 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return s390_early_mach (); } + virtual unsigned int execute (function *); }; // class pass_s390_early_mach +unsigned int +pass_s390_early_mach::execute (function *fun) +{ + rtx insn; + + /* Try to get rid of the FPR clobbers. */ + s390_optimize_nonescaping_tx (); + + /* Re-compute register info. */ + s390_register_info (); + + /* If we're using a base register, ensure that it is always valid for + the first non-prologue instruction. */ + if (fun->machine->base_reg) + emit_insn_at_entry (gen_main_pool (fun->machine->base_reg)); + + /* Annotate all constant pool references to let the scheduler know + they implicitly use the base register. */ + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + if (INSN_P (insn)) + { + annotate_constant_pool_refs (&PATTERN (insn)); + df_insn_rescan (insn); + } + return 0; +} + } // anon namespace /* Expand the prologue into a bunch of separate insns. */ diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 5578cb8afcb3..62354eed028f 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -1145,7 +1145,10 @@ public: return sparc_fix_at697f != 0 || sparc_fix_ut699 != 0; } - unsigned int execute () { return sparc_do_work_around_errata (); } + virtual unsigned int execute (function *) + { + return sparc_do_work_around_errata (); + } }; // class pass_work_around_errata diff --git a/gcc/cprop.c b/gcc/cprop.c index 9802b8a42b58..d29b6f68f271 100644 --- a/gcc/cprop.c +++ b/gcc/cprop.c @@ -1943,7 +1943,7 @@ public: && dbg_cnt (cprop); } - unsigned int execute () { return execute_rtl_cprop (); } + virtual unsigned int execute (function *) { return execute_rtl_cprop (); } }; // class pass_rtl_cprop diff --git a/gcc/cse.c b/gcc/cse.c index 60ec9a99d752..40bc2be6a018 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -7510,7 +7510,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return optimize > 0; } - unsigned int execute () { return rest_of_handle_cse (); } + virtual unsigned int execute (function *) { return rest_of_handle_cse (); } }; // class pass_cse @@ -7587,7 +7587,7 @@ public: return optimize > 0 && flag_rerun_cse_after_loop; } - unsigned int execute () { return rest_of_handle_cse2 (); } + virtual unsigned int execute (function *) { return rest_of_handle_cse2 (); } }; // class pass_cse2 @@ -7662,9 +7662,10 @@ public: return optimize > 0 && flag_rerun_cse_after_global_opts; } - unsigned int execute () { - return rest_of_handle_cse_after_global_opts (); - } + virtual unsigned int execute (function *) + { + return rest_of_handle_cse_after_global_opts (); + } }; // class pass_cse_after_global_opts diff --git a/gcc/dce.c b/gcc/dce.c index 1d290e37ee44..344e31af0746 100644 --- a/gcc/dce.c +++ b/gcc/dce.c @@ -808,7 +808,10 @@ public: return optimize > 1 && flag_dce && dbg_cnt (dce_ud); } - unsigned int execute () { return rest_of_handle_ud_dce (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_ud_dce (); + } }; // class pass_ud_rtl_dce @@ -1237,7 +1240,10 @@ public: return optimize > 0 && flag_dce && dbg_cnt (dce_fast); } - unsigned int execute () { return rest_of_handle_fast_dce (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_fast_dce (); + } }; // class pass_fast_rtl_dce diff --git a/gcc/df-core.c b/gcc/df-core.c index bd3cb31ebd92..9fdf601071c2 100644 --- a/gcc/df-core.c +++ b/gcc/df-core.c @@ -765,7 +765,10 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return optimize > 0; } - unsigned int execute () { return rest_of_handle_df_initialize (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_df_initialize (); + } }; // class pass_df_initialize_opt @@ -803,7 +806,10 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return optimize == 0; } - unsigned int execute () { return rest_of_handle_df_initialize (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_df_initialize (); + } }; // class pass_df_initialize_no_opt @@ -867,7 +873,10 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rest_of_handle_df_finish (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_df_finish (); + } }; // class pass_df_finish diff --git a/gcc/dse.c b/gcc/dse.c index a80c0259b38a..88b8c373bbf5 100644 --- a/gcc/dse.c +++ b/gcc/dse.c @@ -3736,7 +3736,7 @@ public: return optimize > 0 && flag_dse && dbg_cnt (dse1); } - unsigned int execute () { return rest_of_handle_dse (); } + virtual unsigned int execute (function *) { return rest_of_handle_dse (); } }; // class pass_rtl_dse1 @@ -3777,7 +3777,7 @@ public: return optimize > 0 && flag_dse && dbg_cnt (dse2); } - unsigned int execute () { return rest_of_handle_dse (); } + virtual unsigned int execute (function *) { return rest_of_handle_dse (); } }; // class pass_rtl_dse2 diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c index 37492776ca06..41808905bc18 100644 --- a/gcc/dwarf2cfi.c +++ b/gcc/dwarf2cfi.c @@ -3402,7 +3402,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return execute_dwarf2_frame (); } + virtual unsigned int execute (function *) { return execute_dwarf2_frame (); } }; // class pass_dwarf2_frame diff --git a/gcc/except.c b/gcc/except.c index 2015809f4db7..5b33c9cc301f 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -2025,7 +2025,10 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return set_nothrow_function_flags (); } + virtual unsigned int execute (function *) + { + return set_nothrow_function_flags (); + } }; // class pass_set_nothrow_function_flags @@ -2645,7 +2648,10 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return convert_to_eh_region_ranges (); } + virtual unsigned int execute (function *) + { + return convert_to_eh_region_ranges (); + } }; // class pass_convert_to_eh_region_ranges diff --git a/gcc/final.c b/gcc/final.c index 8a908bfca79e..8c6f6ee682b5 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -871,7 +871,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return compute_alignments (); } + virtual unsigned int execute (function *) { return compute_alignments (); } }; // class pass_compute_alignments @@ -4499,7 +4499,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rest_of_handle_final (); } + virtual unsigned int execute (function *) { return rest_of_handle_final (); } }; // class pass_final @@ -4544,7 +4544,10 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rest_of_handle_shorten_branches (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_shorten_branches (); + } }; // class pass_shorten_branches @@ -4707,7 +4710,10 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rest_of_clean_state (); } + virtual unsigned int execute (function *) + { + return rest_of_clean_state (); + } }; // class pass_clean_state diff --git a/gcc/function.c b/gcc/function.c index cf07255c3949..383a52a8fc0b 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -1967,7 +1967,10 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return instantiate_virtual_regs (); } + virtual unsigned int execute (function *) + { + return instantiate_virtual_regs (); + } }; // class pass_instantiate_virtual_regs @@ -6965,7 +6968,10 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rest_of_handle_check_leaf_regs (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_check_leaf_regs (); + } }; // class pass_leaf_regs @@ -7025,9 +7031,10 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { - return rest_of_handle_thread_prologue_and_epilogue (); - } + virtual unsigned int execute (function *) + { + return rest_of_handle_thread_prologue_and_epilogue (); + } }; // class pass_thread_prologue_and_epilogue @@ -7184,8 +7191,36 @@ match_asm_constraints_1 (rtx insn, rtx *p_sets, int noutputs) df_insn_rescan (insn); } -static unsigned -rest_of_match_asm_constraints (void) +namespace { + +const pass_data pass_data_match_asm_constraints = +{ + RTL_PASS, /* type */ + "asmcons", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_NONE, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_match_asm_constraints : public rtl_opt_pass +{ +public: + pass_match_asm_constraints (gcc::context *ctxt) + : rtl_opt_pass (pass_data_match_asm_constraints, ctxt) + {} + + /* opt_pass methods: */ + virtual unsigned int execute (function *); + +}; // class pass_match_asm_constraints + +unsigned +pass_match_asm_constraints::execute (function *fun) { basic_block bb; rtx insn, pat, *p_sets; @@ -7195,7 +7230,7 @@ rest_of_match_asm_constraints (void) return 0; df_set_flags (DF_DEFER_INSN_RESCAN); - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { FOR_BB_INSNS (bb, insn) { @@ -7219,34 +7254,6 @@ rest_of_match_asm_constraints (void) return TODO_df_finish; } -namespace { - -const pass_data pass_data_match_asm_constraints = -{ - RTL_PASS, /* type */ - "asmcons", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_NONE, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_match_asm_constraints : public rtl_opt_pass -{ -public: - pass_match_asm_constraints (gcc::context *ctxt) - : rtl_opt_pass (pass_data_match_asm_constraints, ctxt) - {} - - /* opt_pass methods: */ - unsigned int execute () { return rest_of_match_asm_constraints (); } - -}; // class pass_match_asm_constraints - } // anon namespace rtl_opt_pass * diff --git a/gcc/fwprop.c b/gcc/fwprop.c index c6fa4ee22d0c..6960d62e250c 100644 --- a/gcc/fwprop.c +++ b/gcc/fwprop.c @@ -1509,7 +1509,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return gate_fwprop (); } - unsigned int execute () { return fwprop (); } + virtual unsigned int execute (function *) { return fwprop (); } }; // class pass_rtl_fwprop @@ -1574,7 +1574,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return gate_fwprop (); } - unsigned int execute () { return fwprop_addr (); } + virtual unsigned int execute (function *) { return fwprop_addr (); } }; // class pass_rtl_fwprop_addr diff --git a/gcc/gcse.c b/gcc/gcse.c index 942ea64325f8..d88b2750d52b 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -4209,7 +4209,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return execute_rtl_pre (); } + virtual unsigned int execute (function *) { return execute_rtl_pre (); } }; // class pass_rtl_pre @@ -4261,7 +4261,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return execute_rtl_hoist (); } + virtual unsigned int execute (function *) { return execute_rtl_hoist (); } }; // class pass_rtl_hoist diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c index 66ea322502e9..eff4b4f84ba9 100644 --- a/gcc/gimple-low.c +++ b/gcc/gimple-low.c @@ -180,7 +180,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return lower_function_body (); } + virtual unsigned int execute (function *) { return lower_function_body (); } }; // class pass_lower_cf diff --git a/gcc/gimple-ssa-isolate-paths.c b/gcc/gimple-ssa-isolate-paths.c index ab6185c27676..b01417d09e59 100644 --- a/gcc/gimple-ssa-isolate-paths.c +++ b/gcc/gimple-ssa-isolate-paths.c @@ -446,7 +446,10 @@ public: || flag_isolate_erroneous_paths_attribute != 0); } - unsigned int execute () { return gimple_ssa_isolate_erroneous_paths (); } + virtual unsigned int execute (function *) + { + return gimple_ssa_isolate_erroneous_paths (); + } }; // class pass_isolate_erroneous_paths } diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c index a8596e0529ba..ff55d0eff67f 100644 --- a/gcc/gimple-ssa-strength-reduction.c +++ b/gcc/gimple-ssa-strength-reduction.c @@ -3594,8 +3594,37 @@ analyze_candidates_and_replace (void) } } -static unsigned -execute_strength_reduction (void) +namespace { + +const pass_data pass_data_strength_reduction = +{ + GIMPLE_PASS, /* type */ + "slsr", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_GIMPLE_SLSR, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_verify_ssa, /* todo_flags_finish */ +}; + +class pass_strength_reduction : public gimple_opt_pass +{ +public: + pass_strength_reduction (gcc::context *ctxt) + : gimple_opt_pass (pass_data_strength_reduction, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) { return flag_tree_slsr; } + virtual unsigned int execute (function *); + +}; // class pass_strength_reduction + +unsigned +pass_strength_reduction::execute (function *fun) { /* Create the obstack where candidates will reside. */ gcc_obstack_init (&cand_obstack); @@ -3622,7 +3651,7 @@ execute_strength_reduction (void) /* Walk the CFG in predominator order looking for strength reduction candidates. */ find_candidates_dom_walker (CDI_DOMINATORS) - .walk (cfun->cfg->x_entry_block_ptr); + .walk (fun->cfg->x_entry_block_ptr); if (dump_file && (dump_flags & TDF_DETAILS)) { @@ -3646,35 +3675,6 @@ execute_strength_reduction (void) return 0; } -namespace { - -const pass_data pass_data_strength_reduction = -{ - GIMPLE_PASS, /* type */ - "slsr", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_GIMPLE_SLSR, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_verify_ssa, /* todo_flags_finish */ -}; - -class pass_strength_reduction : public gimple_opt_pass -{ -public: - pass_strength_reduction (gcc::context *ctxt) - : gimple_opt_pass (pass_data_strength_reduction, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) { return flag_tree_slsr; } - unsigned int execute () { return execute_strength_reduction (); } - -}; // class pass_strength_reduction - } // anon namespace gimple_opt_pass * diff --git a/gcc/graphite.c b/gcc/graphite.c index 68c93904fd90..2e1f439ef9e1 100644 --- a/gcc/graphite.c +++ b/gcc/graphite.c @@ -411,7 +411,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return gate_graphite_transforms (); } - unsigned int execute () { return graphite_transforms (); } + virtual unsigned int execute (function *) { return graphite_transforms (); } }; // class pass_graphite_transforms diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c index 657b585a07ac..e8a9fec9d66c 100644 --- a/gcc/ifcvt.c +++ b/gcc/ifcvt.c @@ -4560,7 +4560,10 @@ public: return (optimize > 0) && dbg_cnt (if_conversion); } - unsigned int execute () { return rest_of_handle_if_conversion (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_if_conversion (); + } }; // class pass_rtl_ifcvt @@ -4575,12 +4578,6 @@ make_pass_rtl_ifcvt (gcc::context *ctxt) /* Rerun if-conversion, as combine may have simplified things enough to now meet sequence length restrictions. */ -static unsigned int -rest_of_handle_if_after_combine (void) -{ - if_convert (true); - return 0; -} namespace { @@ -4612,7 +4609,11 @@ public: && dbg_cnt (if_after_combine); } - unsigned int execute () { return rest_of_handle_if_after_combine (); } + virtual unsigned int execute (function *) + { + if_convert (true); + return 0; + } }; // class pass_if_after_combine @@ -4625,14 +4626,6 @@ make_pass_if_after_combine (gcc::context *ctxt) } -static unsigned int -rest_of_handle_if_after_reload (void) -{ - if_convert (true); - return 0; -} - - namespace { const pass_data pass_data_if_after_reload = @@ -4663,7 +4656,11 @@ public: && dbg_cnt (if_after_reload); } - unsigned int execute () { return rest_of_handle_if_after_reload (); } + virtual unsigned int execute (function *) + { + if_convert (true); + return 0; + } }; // class pass_if_after_reload diff --git a/gcc/init-regs.c b/gcc/init-regs.c index 2025b777897b..59c5bc91004a 100644 --- a/gcc/init-regs.c +++ b/gcc/init-regs.c @@ -125,13 +125,6 @@ initialize_uninitialized_regs (void) BITMAP_FREE (already_genned); } -static unsigned int -rest_of_handle_initialize_regs (void) -{ - initialize_uninitialized_regs (); - return 0; -} - namespace { const pass_data pass_data_initialize_regs = @@ -157,7 +150,11 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return optimize > 0; } - unsigned int execute () { return rest_of_handle_initialize_regs (); } + virtual unsigned int execute (function *) + { + initialize_uninitialized_regs (); + return 0; + } }; // class pass_initialize_regs diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index ee48fc095ad5..479963cdb6ba 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -3804,7 +3804,7 @@ public: return flag_ipa_cp && optimize; } - unsigned int execute () { return ipcp_driver (); } + virtual unsigned int execute (function *) { return ipcp_driver (); } }; // class pass_ipa_cp diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index ee8091c21464..d484b20e48ac 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -2136,7 +2136,7 @@ public: && optimize); } - unsigned int execute () { return ipa_devirt (); } + virtual unsigned int execute (function *) { return ipa_devirt (); } }; // class pass_ipa_devirt diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c index 8783caa24a1e..c471e0cd899d 100644 --- a/gcc/ipa-inline-analysis.c +++ b/gcc/ipa-inline-analysis.c @@ -2938,9 +2938,10 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_inline_parameters (m_ctxt); } - unsigned int execute () { - return compute_inline_parameters_for_current (); - } + virtual unsigned int execute (function *) + { + return compute_inline_parameters_for_current (); + } }; // class pass_inline_parameters diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index da02afccabb5..83a836a12116 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -2231,8 +2231,37 @@ early_inline_small_functions (struct cgraph_node *node) /* Do inlining of small functions. Doing so early helps profiling and other passes to be somewhat more effective and avoids some code duplication in later real inlining pass for testcases with very many function calls. */ -static unsigned int -early_inliner (void) + +namespace { + +const pass_data pass_data_early_inline = +{ + GIMPLE_PASS, /* type */ + "einline", /* name */ + OPTGROUP_INLINE, /* optinfo_flags */ + true, /* has_execute */ + TV_EARLY_INLINING, /* tv_id */ + PROP_ssa, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_early_inline : public gimple_opt_pass +{ +public: + pass_early_inline (gcc::context *ctxt) + : gimple_opt_pass (pass_data_early_inline, ctxt) + {} + + /* opt_pass methods: */ + virtual unsigned int execute (function *); + +}; // class pass_early_inline + +unsigned int +pass_early_inline::execute (function *fun) { struct cgraph_node *node = cgraph_get_node (current_function_decl); struct cgraph_edge *edge; @@ -2328,39 +2357,11 @@ early_inliner (void) timevar_pop (TV_INTEGRATION); } - cfun->always_inline_functions_inlined = true; + fun->always_inline_functions_inlined = true; return todo; } -namespace { - -const pass_data pass_data_early_inline = -{ - GIMPLE_PASS, /* type */ - "einline", /* name */ - OPTGROUP_INLINE, /* optinfo_flags */ - true, /* has_execute */ - TV_EARLY_INLINING, /* tv_id */ - PROP_ssa, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_early_inline : public gimple_opt_pass -{ -public: - pass_early_inline (gcc::context *ctxt) - : gimple_opt_pass (pass_data_early_inline, ctxt) - {} - - /* opt_pass methods: */ - unsigned int execute () { return early_inliner (); } - -}; // class pass_early_inline - } // anon namespace gimple_opt_pass * @@ -2402,7 +2403,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return ipa_inline (); } + virtual unsigned int execute (function *) { return ipa_inline (); } }; // class pass_ipa_inline diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c index 7b58716c45b0..71bd61b12120 100644 --- a/gcc/ipa-profile.c +++ b/gcc/ipa-profile.c @@ -745,7 +745,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_ipa_profile; } - unsigned int execute () { return ipa_profile (); } + virtual unsigned int execute (function *) { return ipa_profile (); } }; // class pass_ipa_profile diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c index eab7633b1de7..0ebfe5d5994a 100644 --- a/gcc/ipa-pure-const.c +++ b/gcc/ipa-pure-const.c @@ -1542,7 +1542,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return gate_pure_const (); } - unsigned int execute () { return propagate (); } + virtual unsigned int execute (function *) { return propagate (); } }; // class pass_ipa_pure_const @@ -1581,8 +1581,38 @@ skip_function_for_local_pure_const (struct cgraph_node *node) ipa_pure_const. This pass is effective when executed together with other optimization passes in early optimization pass queue. */ -static unsigned int -local_pure_const (void) +namespace { + +const pass_data pass_data_local_pure_const = +{ + GIMPLE_PASS, /* type */ + "local-pure-const", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_IPA_PURE_CONST, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_local_pure_const : public gimple_opt_pass +{ +public: + pass_local_pure_const (gcc::context *ctxt) + : gimple_opt_pass (pass_data_local_pure_const, ctxt) + {} + + /* opt_pass methods: */ + opt_pass * clone () { return new pass_local_pure_const (m_ctxt); } + virtual bool gate (function *) { return gate_pure_const (); } + virtual unsigned int execute (function *); + +}; // class pass_local_pure_const + +unsigned int +pass_local_pure_const::execute (function *fun) { bool changed = false; funct_state l; @@ -1600,17 +1630,17 @@ local_pure_const (void) /* Do NORETURN discovery. */ if (!skip && !TREE_THIS_VOLATILE (current_function_decl) - && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) == 0) + && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) == 0) { - warn_function_noreturn (cfun->decl); + warn_function_noreturn (fun->decl); if (dump_file) - fprintf (dump_file, "Function found to be noreturn: %s\n", - current_function_name ()); + fprintf (dump_file, "Function found to be noreturn: %s\n", + current_function_name ()); /* Update declaration and reduce profile to executed once. */ TREE_THIS_VOLATILE (current_function_decl) = 1; if (node->frequency > NODE_FREQUENCY_EXECUTED_ONCE) - node->frequency = NODE_FREQUENCY_EXECUTED_ONCE; + node->frequency = NODE_FREQUENCY_EXECUTED_ONCE; changed = true; } @@ -1691,36 +1721,6 @@ local_pure_const (void) return 0; } -namespace { - -const pass_data pass_data_local_pure_const = -{ - GIMPLE_PASS, /* type */ - "local-pure-const", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_IPA_PURE_CONST, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_local_pure_const : public gimple_opt_pass -{ -public: - pass_local_pure_const (gcc::context *ctxt) - : gimple_opt_pass (pass_data_local_pure_const, ctxt) - {} - - /* opt_pass methods: */ - opt_pass * clone () { return new pass_local_pure_const (m_ctxt); } - virtual bool gate (function *) { return gate_pure_const (); } - unsigned int execute () { return local_pure_const (); } - -}; // class pass_local_pure_const - } // anon namespace gimple_opt_pass * @@ -1731,15 +1731,6 @@ make_pass_local_pure_const (gcc::context *ctxt) /* Emit noreturn warnings. */ -static unsigned int -execute_warn_function_noreturn (void) -{ - if (!TREE_THIS_VOLATILE (current_function_decl) - && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) == 0) - warn_function_noreturn (current_function_decl); - return 0; -} - namespace { const pass_data pass_data_warn_function_noreturn = @@ -1765,7 +1756,13 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return warn_suggest_attribute_noreturn; } - unsigned int execute () { return execute_warn_function_noreturn (); } + virtual unsigned int execute (function *fun) + { + if (!TREE_THIS_VOLATILE (current_function_decl) + && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) == 0) + warn_function_noreturn (current_function_decl); + return 0; + } }; // class pass_warn_function_noreturn diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c index 51a57ac8d759..dc1169da66db 100644 --- a/gcc/ipa-reference.c +++ b/gcc/ipa-reference.c @@ -1190,7 +1190,7 @@ public: && !seen_error ()); } - unsigned int execute () { return propagate (); } + virtual unsigned int execute (function *) { return propagate (); } }; // class pass_ipa_reference diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 187dc988489b..eefa1954e302 100644 --- a/gcc/ipa-split.c +++ b/gcc/ipa-split.c @@ -1671,7 +1671,10 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return execute_split_functions (); } + virtual unsigned int execute (function *) + { + return execute_split_functions (); + } }; // class pass_split_functions @@ -1728,7 +1731,10 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return execute_feedback_split_functions (); } + virtual unsigned int execute (function *) + { + return execute_feedback_split_functions (); + } }; // class pass_feedback_split_functions diff --git a/gcc/ipa.c b/gcc/ipa.c index e14f0c42eb2f..8b65abdb3496 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -1193,12 +1193,6 @@ function_and_variable_visibility (bool whole_program) /* Local function pass handling visibilities. This happens before LTO streaming so in particular -fwhole-program should be ignored at this level. */ -static unsigned int -local_function_and_variable_visibility (void) -{ - return function_and_variable_visibility (flag_whole_program && !flag_lto); -} - namespace { const pass_data pass_data_ipa_function_and_variable_visibility = @@ -1224,9 +1218,10 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { - return local_function_and_variable_visibility (); - } + virtual unsigned int execute (function *) + { + return function_and_variable_visibility (flag_whole_program && !flag_lto); + } }; // class pass_ipa_function_and_variable_visibility @@ -1240,13 +1235,6 @@ make_pass_ipa_function_and_variable_visibility (gcc::context *ctxt) /* Free inline summary. */ -static unsigned -free_inline_summary (void) -{ - inline_free_summary (); - return 0; -} - namespace { const pass_data pass_data_ipa_free_inline_summary = @@ -1271,7 +1259,11 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return free_inline_summary (); } + virtual unsigned int execute (function *) + { + inline_free_summary (); + return 0; + } }; // class pass_ipa_free_inline_summary @@ -1333,9 +1325,10 @@ public: /* Do not re-run on ltrans stage. */ return !flag_ltrans; } - unsigned int execute () { - return whole_program_function_and_variable_visibility (); - } + virtual unsigned int execute (function *) + { + return whole_program_function_and_variable_visibility (); + } }; // class pass_ipa_whole_program_visibility @@ -1653,7 +1646,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return ipa_cdtor_merge (); } + virtual unsigned int execute (function *) { return ipa_cdtor_merge (); } }; // class pass_ipa_cdtor_merge diff --git a/gcc/ira.c b/gcc/ira.c index da0f453e8f4e..d9730011c036 100644 --- a/gcc/ira.c +++ b/gcc/ira.c @@ -5548,12 +5548,6 @@ do_reload (void) } /* Run the integrated register allocator. */ -static unsigned int -rest_of_handle_ira (void) -{ - ira (dump_file); - return 0; -} namespace { @@ -5579,7 +5573,11 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rest_of_handle_ira (); } + virtual unsigned int execute (function *) + { + ira (dump_file); + return 0; + } }; // class pass_ira @@ -5591,13 +5589,6 @@ make_pass_ira (gcc::context *ctxt) return new pass_ira (ctxt); } -static unsigned int -rest_of_handle_reload (void) -{ - do_reload (); - return 0; -} - namespace { const pass_data pass_data_reload = @@ -5622,7 +5613,11 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rest_of_handle_reload (); } + virtual unsigned int execute (function *) + { + do_reload (); + return 0; + } }; // class pass_reload diff --git a/gcc/jump.c b/gcc/jump.c index 73611015dcca..cdea8d5b885f 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -163,7 +163,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return cleanup_barriers (); } + virtual unsigned int execute (function *) { return cleanup_barriers (); } }; // class pass_cleanup_barriers diff --git a/gcc/loop-init.c b/gcc/loop-init.c index 6da29d3c0f15..90453f67ecaf 100644 --- a/gcc/loop-init.c +++ b/gcc/loop-init.c @@ -390,7 +390,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rtl_loop_init (); } + virtual unsigned int execute (function *) { return rtl_loop_init (); } }; // class pass_rtl_loop_init @@ -405,24 +405,6 @@ make_pass_rtl_loop_init (gcc::context *ctxt) /* Finalization of the RTL loop passes. */ -static unsigned int -rtl_loop_done (void) -{ - /* No longer preserve loops, remove them now. */ - cfun->curr_properties &= ~PROP_loops; - loop_optimizer_finalize (); - free_dominance_info (CDI_DOMINATORS); - - cleanup_cfg (0); - if (dump_file) - { - dump_reg_info (dump_file); - dump_flow_info (dump_file, dump_flags); - } - - return 0; -} - namespace { const pass_data pass_data_rtl_loop_done = @@ -447,10 +429,28 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rtl_loop_done (); } + virtual unsigned int execute (function *); }; // class pass_rtl_loop_done +unsigned int +pass_rtl_loop_done::execute (function *fun) +{ + /* No longer preserve loops, remove them now. */ + fun->curr_properties &= ~PROP_loops; + loop_optimizer_finalize (); + free_dominance_info (CDI_DOMINATORS); + + cleanup_cfg (0); + if (dump_file) + { + dump_reg_info (dump_file); + dump_flow_info (dump_file, dump_flags); + } + + return 0; +} + } // anon namespace rtl_opt_pass * @@ -461,13 +461,6 @@ make_pass_rtl_loop_done (gcc::context *ctxt) /* Loop invariant code motion. */ -static unsigned int -rtl_move_loop_invariants (void) -{ - if (number_of_loops (cfun) > 1) - move_loop_invariants (); - return 0; -} namespace { @@ -495,7 +488,12 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_move_loop_invariants; } - unsigned int execute () { return rtl_move_loop_invariants (); } + virtual unsigned int execute (function *fun) + { + if (number_of_loops (fun) > 1) + move_loop_invariants (); + return 0; + } }; // class pass_rtl_move_loop_invariants @@ -508,14 +506,6 @@ make_pass_rtl_move_loop_invariants (gcc::context *ctxt) } -static unsigned int -rtl_unswitch (void) -{ - if (number_of_loops (cfun) > 1) - unswitch_loops (); - return 0; -} - namespace { const pass_data pass_data_rtl_unswitch = @@ -541,7 +531,12 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_unswitch_loops; } - unsigned int execute () { return rtl_unswitch (); } + virtual unsigned int execute (function *fun) + { + if (number_of_loops (fun) > 1) + unswitch_loops (); + return 0; + } }; // class pass_rtl_unswitch @@ -554,27 +549,6 @@ make_pass_rtl_unswitch (gcc::context *ctxt) } -static unsigned int -rtl_unroll_and_peel_loops (void) -{ - if (number_of_loops (cfun) > 1) - { - int flags = 0; - if (dump_file) - df_dump (dump_file); - - if (flag_peel_loops) - flags |= UAP_PEEL; - if (flag_unroll_loops) - flags |= UAP_UNROLL; - if (flag_unroll_all_loops) - flags |= UAP_UNROLL_ALL; - - unroll_and_peel_loops (flags); - } - return 0; -} - namespace { const pass_data pass_data_rtl_unroll_and_peel_loops = @@ -604,10 +578,31 @@ public: return (flag_peel_loops || flag_unroll_loops || flag_unroll_all_loops); } - unsigned int execute () { return rtl_unroll_and_peel_loops (); } + virtual unsigned int execute (function *); }; // class pass_rtl_unroll_and_peel_loops +unsigned int +pass_rtl_unroll_and_peel_loops::execute (function *fun) +{ + if (number_of_loops (fun) > 1) + { + int flags = 0; + if (dump_file) + df_dump (dump_file); + + if (flag_peel_loops) + flags |= UAP_PEEL; + if (flag_unroll_loops) + flags |= UAP_UNROLL; + if (flag_unroll_all_loops) + flags |= UAP_UNROLL_ALL; + + unroll_and_peel_loops (flags); + } + return 0; +} + } // anon namespace rtl_opt_pass * @@ -617,16 +612,6 @@ make_pass_rtl_unroll_and_peel_loops (gcc::context *ctxt) } -static unsigned int -rtl_doloop (void) -{ -#ifdef HAVE_doloop_end - if (number_of_loops (cfun) > 1) - doloop_optimize_loops (); -#endif - return 0; -} - namespace { const pass_data pass_data_rtl_doloop = @@ -652,7 +637,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return rtl_doloop (); } + virtual unsigned int execute (function *); }; // class pass_rtl_doloop @@ -666,6 +651,16 @@ pass_rtl_doloop::gate (function *) #endif } +unsigned int +pass_rtl_doloop::execute (function *fun ATTRIBUTE_UNUSED) +{ +#ifdef HAVE_doloop_end + if (number_of_loops (fun) > 1) + doloop_optimize_loops (); +#endif + return 0; +} + } // anon namespace rtl_opt_pass * diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c index 89d976390a56..bdad2a6aa9cb 100644 --- a/gcc/lower-subreg.c +++ b/gcc/lower-subreg.c @@ -1689,22 +1689,6 @@ decompose_multiword_subregs (bool decompose_copies) /* Implement first lower subreg pass. */ -static unsigned int -rest_of_handle_lower_subreg (void) -{ - decompose_multiword_subregs (false); - return 0; -} - -/* Implement second lower subreg pass. */ - -static unsigned int -rest_of_handle_lower_subreg2 (void) -{ - decompose_multiword_subregs (true); - return 0; -} - namespace { const pass_data pass_data_lower_subreg = @@ -1730,7 +1714,11 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_split_wide_types != 0; } - unsigned int execute () { return rest_of_handle_lower_subreg (); } + virtual unsigned int execute (function *) + { + decompose_multiword_subregs (false); + return 0; + } }; // class pass_lower_subreg @@ -1742,6 +1730,8 @@ make_pass_lower_subreg (gcc::context *ctxt) return new pass_lower_subreg (ctxt); } +/* Implement second lower subreg pass. */ + namespace { const pass_data pass_data_lower_subreg2 = @@ -1768,7 +1758,11 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_split_wide_types != 0; } - unsigned int execute () { return rest_of_handle_lower_subreg2 (); } + virtual unsigned int execute (function *) + { + decompose_multiword_subregs (true); + return 0; + } }; // class pass_lower_subreg2 diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c index e73d6ee3a937..b132cba4f2a6 100644 --- a/gcc/mode-switching.c +++ b/gcc/mode-switching.c @@ -789,16 +789,6 @@ optimize_mode_switching (void) #endif /* OPTIMIZE_MODE_SWITCHING */ -static unsigned int -rest_of_handle_mode_switching (void) -{ -#ifdef OPTIMIZE_MODE_SWITCHING - optimize_mode_switching (); -#endif /* OPTIMIZE_MODE_SWITCHING */ - return 0; -} - - namespace { const pass_data pass_data_mode_switching = @@ -835,7 +825,13 @@ public: #endif } - unsigned int execute () { return rest_of_handle_mode_switching (); } + virtual unsigned int execute (function *) + { +#ifdef OPTIMIZE_MODE_SWITCHING + optimize_mode_switching (); +#endif /* OPTIMIZE_MODE_SWITCHING */ + return 0; + } }; // class pass_mode_switching diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c index 20e2e623e684..2e454f553e7a 100644 --- a/gcc/modulo-sched.c +++ b/gcc/modulo-sched.c @@ -3325,28 +3325,6 @@ rotate_partial_schedule (partial_schedule_ptr ps, int start_cycle) /* Run instruction scheduler. */ /* Perform SMS module scheduling. */ -static unsigned int -rest_of_handle_sms (void) -{ -#ifdef INSN_SCHEDULING - basic_block bb; - - /* Collect loop information to be used in SMS. */ - cfg_layout_initialize (0); - sms_schedule (); - - /* Update the life information, because we add pseudos. */ - max_regno = max_reg_num (); - - /* Finalize layout changes. */ - FOR_EACH_BB_FN (bb, cfun) - if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (cfun)) - bb->aux = bb->next_bb; - free_dominance_info (CDI_DOMINATORS); - cfg_layout_finalize (); -#endif /* INSN_SCHEDULING */ - return 0; -} namespace { @@ -3378,10 +3356,33 @@ public: return (optimize > 0 && flag_modulo_sched); } - unsigned int execute () { return rest_of_handle_sms (); } + virtual unsigned int execute (function *); }; // class pass_sms +unsigned int +pass_sms::execute (function *fun ATTRIBUTE_UNUSED) +{ +#ifdef INSN_SCHEDULING + basic_block bb; + + /* Collect loop information to be used in SMS. */ + cfg_layout_initialize (0); + sms_schedule (); + + /* Update the life information, because we add pseudos. */ + max_regno = max_reg_num (); + + /* Finalize layout changes. */ + FOR_EACH_BB_FN (bb, fun) + if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (fun)) + bb->aux = bb->next_bb; + free_dominance_info (CDI_DOMINATORS); + cfg_layout_finalize (); +#endif /* INSN_SCHEDULING */ + return 0; +} + } // anon namespace rtl_opt_pass * diff --git a/gcc/omp-low.c b/gcc/omp-low.c index 0e96b881d77a..0a46fb7fcfa5 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -8356,7 +8356,7 @@ public: || flag_cilkplus != 0) && !seen_error ()); } - unsigned int execute () { return execute_expand_omp (); } + virtual unsigned int execute (function *) { return execute_expand_omp (); } }; // class pass_expand_omp @@ -10215,7 +10215,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return execute_lower_omp (); } + virtual unsigned int execute (function *) { return execute_lower_omp (); } }; // class pass_lower_omp @@ -10640,9 +10640,10 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_openmp || flag_cilkplus; } - unsigned int execute () { - return diagnose_omp_structured_block_errors (); - } + virtual unsigned int execute (function *) + { + return diagnose_omp_structured_block_errors (); + } }; // class pass_diagnose_omp_blocks @@ -11804,7 +11805,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return ipa_omp_simd_clone (); } + virtual unsigned int execute (function *) { return ipa_omp_simd_clone (); } }; bool diff --git a/gcc/passes.c b/gcc/passes.c index b71c11e3e316..2be7856f29b8 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -114,7 +114,7 @@ opt_pass::gate (function *) } unsigned int -opt_pass::execute () +opt_pass::execute (function *) { return 0; } @@ -138,7 +138,7 @@ pass_manager::execute_early_local_passes () unsigned int pass_manager::execute_pass_mode_switching () { - return pass_mode_switching_1->execute (); + return pass_mode_switching_1->execute (cfun); } @@ -367,7 +367,10 @@ public: return (!seen_error () && !in_lto_p); } - unsigned int execute () { return execute_all_early_local_passes (); } + virtual unsigned int execute (function *) + { + return execute_all_early_local_passes (); + } }; // class pass_early_local_passes @@ -2153,7 +2156,7 @@ execute_one_pass (opt_pass *pass) /* Do it! */ if (pass->has_execute) { - todo_after = pass->execute (); + todo_after = pass->execute (cfun); do_per_function (clear_last_verified, NULL); } diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c index 8a804fb98eab..f5d536335391 100644 --- a/gcc/postreload-gcse.c +++ b/gcc/postreload-gcse.c @@ -1347,7 +1347,7 @@ public: && optimize_function_for_speed_p (fun)); } - unsigned int execute () { return rest_of_handle_gcse2 (); } + virtual unsigned int execute (function *) { return rest_of_handle_gcse2 (); } }; // class pass_gcse2 diff --git a/gcc/postreload.c b/gcc/postreload.c index 0568c53f78ac..b093287d5a98 100644 --- a/gcc/postreload.c +++ b/gcc/postreload.c @@ -2315,23 +2315,6 @@ move2add_note_store (rtx dst, const_rtx set, void *data) } } -static unsigned int -rest_of_handle_postreload (void) -{ - if (!dbg_cnt (postreload_cse)) - return 0; - - /* 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 (cfun->can_throw_non_call_exceptions - && purge_all_dead_edges ()) - cleanup_cfg (0); - - return 0; -} - namespace { const pass_data pass_data_postreload_cse = @@ -2358,10 +2341,27 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return (optimize > 0 && reload_completed); } - unsigned int execute () { return rest_of_handle_postreload (); } + virtual unsigned int execute (function *); }; // class pass_postreload_cse +unsigned int +pass_postreload_cse::execute (function *fun) +{ + if (!dbg_cnt (postreload_cse)) + return 0; + + /* 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 (fun->can_throw_non_call_exceptions + && purge_all_dead_edges ()) + cleanup_cfg (0); + + return 0; +} + } // anon namespace rtl_opt_pass * diff --git a/gcc/predict.c b/gcc/predict.c index 068c1877a305..a847ec6f9d93 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -1986,59 +1986,6 @@ expr_expected_value (tree expr, bitmap visited, return expr_expected_value_1 (TREE_TYPE (expr), op0, code, op1, visited, predictor); } - - -/* Get rid of all builtin_expect calls and GIMPLE_PREDICT statements - we no longer need. */ -static unsigned int -strip_predict_hints (void) -{ - basic_block bb; - gimple ass_stmt; - tree var; - - FOR_EACH_BB_FN (bb, cfun) - { - gimple_stmt_iterator bi; - for (bi = gsi_start_bb (bb); !gsi_end_p (bi);) - { - gimple stmt = gsi_stmt (bi); - - if (gimple_code (stmt) == GIMPLE_PREDICT) - { - gsi_remove (&bi, true); - continue; - } - else if (is_gimple_call (stmt)) - { - tree fndecl = gimple_call_fndecl (stmt); - - if ((fndecl - && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL - && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT - && gimple_call_num_args (stmt) == 2) - || (gimple_call_internal_p (stmt) - && gimple_call_internal_fn (stmt) == IFN_BUILTIN_EXPECT)) - { - var = gimple_call_lhs (stmt); - if (var) - { - ass_stmt - = gimple_build_assign (var, gimple_call_arg (stmt, 0)); - gsi_replace (&bi, ass_stmt, true); - } - else - { - gsi_remove (&bi, true); - continue; - } - } - } - gsi_next (&bi); - } - } - return 0; -} /* Predict using opcode of the last statement in basic block. */ static void @@ -2468,37 +2415,6 @@ tree_estimate_probability (void) free_dominance_info (CDI_POST_DOMINATORS); remove_fake_exit_edges (); } - -/* Predict branch probabilities and estimate profile of the tree CFG. - This is the driver function for PASS_PROFILE. */ - -static unsigned int -tree_estimate_probability_driver (void) -{ - unsigned nb_loops; - - loop_optimizer_init (LOOPS_NORMAL); - if (dump_file && (dump_flags & TDF_DETAILS)) - flow_loops_dump (dump_file, NULL, 0); - - mark_irreducible_loops (); - - nb_loops = number_of_loops (cfun); - if (nb_loops > 1) - scev_initialize (); - - tree_estimate_probability (); - - if (nb_loops > 1) - scev_finalize (); - - loop_optimizer_finalize (); - if (dump_file && (dump_flags & TDF_DETAILS)) - gimple_dump_cfg (dump_file, dump_flags); - if (profile_status_for_fn (cfun) == PROFILE_ABSENT) - profile_status_for_fn (cfun) = PROFILE_GUESSED; - return 0; -} /* Predict edges to successors of CUR whose sources are not postdominated by BB by PRED and recurse to all postdominators. */ @@ -3147,6 +3063,8 @@ predictor_name (enum br_predictor predictor) return predictor_info[predictor].name; } +/* Predict branch probabilities and estimate profile of the tree CFG. */ + namespace { const pass_data pass_data_profile = @@ -3172,10 +3090,38 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_guess_branch_prob; } - unsigned int execute () { return tree_estimate_probability_driver (); } + virtual unsigned int execute (function *); }; // class pass_profile +unsigned int +pass_profile::execute (function *fun) +{ + unsigned nb_loops; + + loop_optimizer_init (LOOPS_NORMAL); + if (dump_file && (dump_flags & TDF_DETAILS)) + flow_loops_dump (dump_file, NULL, 0); + + mark_irreducible_loops (); + + nb_loops = number_of_loops (fun); + if (nb_loops > 1) + scev_initialize (); + + tree_estimate_probability (); + + if (nb_loops > 1) + scev_finalize (); + + loop_optimizer_finalize (); + if (dump_file && (dump_flags & TDF_DETAILS)) + gimple_dump_cfg (dump_file, dump_flags); + if (profile_status_for_fn (fun) == PROFILE_ABSENT) + profile_status_for_fn (fun) = PROFILE_GUESSED; + return 0; +} + } // anon namespace gimple_opt_pass * @@ -3209,10 +3155,62 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_strip_predict_hints (m_ctxt); } - unsigned int execute () { return strip_predict_hints (); } + virtual unsigned int execute (function *); }; // class pass_strip_predict_hints +/* Get rid of all builtin_expect calls and GIMPLE_PREDICT statements + we no longer need. */ +unsigned int +pass_strip_predict_hints::execute (function *fun) +{ + basic_block bb; + gimple ass_stmt; + tree var; + + FOR_EACH_BB_FN (bb, fun) + { + gimple_stmt_iterator bi; + for (bi = gsi_start_bb (bb); !gsi_end_p (bi);) + { + gimple stmt = gsi_stmt (bi); + + if (gimple_code (stmt) == GIMPLE_PREDICT) + { + gsi_remove (&bi, true); + continue; + } + else if (is_gimple_call (stmt)) + { + tree fndecl = gimple_call_fndecl (stmt); + + if ((fndecl + && DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL + && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_EXPECT + && gimple_call_num_args (stmt) == 2) + || (gimple_call_internal_p (stmt) + && gimple_call_internal_fn (stmt) == IFN_BUILTIN_EXPECT)) + { + var = gimple_call_lhs (stmt); + if (var) + { + ass_stmt + = gimple_build_assign (var, gimple_call_arg (stmt, 0)); + gsi_replace (&bi, ass_stmt, true); + } + else + { + gsi_remove (&bi, true); + continue; + } + } + } + gsi_next (&bi); + } + } + return 0; +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/recog.c b/gcc/recog.c index 8afea7eca617..057f41128a57 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -3847,7 +3847,10 @@ public: a clone method. */ opt_pass * clone () { return new pass_peephole2 (m_ctxt); } virtual bool gate (function *) { return (optimize > 0 && flag_peephole2); } - unsigned int execute () { return rest_of_handle_peephole2 (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_peephole2 (); + } }; // class pass_peephole2 @@ -3859,13 +3862,6 @@ make_pass_peephole2 (gcc::context *ctxt) return new pass_peephole2 (ctxt); } -static unsigned int -rest_of_handle_split_all_insns (void) -{ - split_all_insns (); - return 0; -} - namespace { const pass_data pass_data_split_all_insns = @@ -3893,7 +3889,11 @@ public: /* The epiphany backend creates a second instance of this pass, so we need a clone method. */ opt_pass * clone () { return new pass_split_all_insns (m_ctxt); } - unsigned int execute () { return rest_of_handle_split_all_insns (); } + virtual unsigned int execute (function *) + { + split_all_insns (); + return 0; + } }; // class pass_split_all_insns @@ -3940,7 +3940,10 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rest_of_handle_split_after_reload (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_split_after_reload (); + } }; // class pass_split_after_reload @@ -3952,13 +3955,6 @@ make_pass_split_after_reload (gcc::context *ctxt) return new pass_split_after_reload (ctxt); } -static unsigned int -rest_of_handle_split_before_regstack (void) -{ - split_all_insns (); - return 0; -} - namespace { const pass_data pass_data_split_before_regstack = @@ -3984,9 +3980,11 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { - return rest_of_handle_split_before_regstack (); - } + virtual unsigned int execute (function *) + { + split_all_insns (); + return 0; + } }; // class pass_split_before_regstack @@ -4058,7 +4056,10 @@ public: #endif } - unsigned int execute () { return rest_of_handle_split_before_sched2 (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_split_before_sched2 (); + } }; // class pass_split_before_sched2 @@ -4105,7 +4106,10 @@ public: #endif } - unsigned int execute () { return split_all_insns_noflow (); } + virtual unsigned int execute (function *) + { + return split_all_insns_noflow (); + } }; // class pass_split_for_shorten_branches diff --git a/gcc/ree.c b/gcc/ree.c index 435bb88747c5..b4710333ba79 100644 --- a/gcc/ree.c +++ b/gcc/ree.c @@ -1118,7 +1118,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return (optimize > 0 && flag_ree); } - unsigned int execute () { return rest_of_handle_ree (); } + virtual unsigned int execute (function *) { return rest_of_handle_ree (); } }; // class pass_ree diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index f8f865887c7d..7aa8a6b800e9 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -3364,7 +3364,10 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rest_of_handle_stack_regs (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_stack_regs (); + } }; // class pass_stack_regs_run diff --git a/gcc/regcprop.c b/gcc/regcprop.c index 24992e4e2c5e..c1fbb65ca4f4 100644 --- a/gcc/regcprop.c +++ b/gcc/regcprop.c @@ -1056,93 +1056,6 @@ copyprop_hardreg_forward_1 (basic_block bb, struct value_data *vd) return anything_changed; } -/* Main entry point for the forward copy propagation optimization. */ - -static unsigned int -copyprop_hardreg_forward (void) -{ - struct value_data *all_vd; - basic_block bb; - sbitmap visited; - bool analyze_called = false; - - all_vd = XNEWVEC (struct value_data, last_basic_block_for_fn (cfun)); - - visited = sbitmap_alloc (last_basic_block_for_fn (cfun)); - bitmap_clear (visited); - - if (MAY_HAVE_DEBUG_INSNS) - debug_insn_changes_pool - = create_alloc_pool ("debug insn changes pool", - sizeof (struct queued_debug_insn_change), 256); - - FOR_EACH_BB_FN (bb, cfun) - { - bitmap_set_bit (visited, bb->index); - - /* If a block has a single predecessor, that we've already - processed, begin with the value data that was live at - the end of the predecessor block. */ - /* ??? Ought to use more intelligent queuing of blocks. */ - if (single_pred_p (bb) - && bitmap_bit_p (visited, single_pred (bb)->index) - && ! (single_pred_edge (bb)->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))) - { - all_vd[bb->index] = all_vd[single_pred (bb)->index]; - if (all_vd[bb->index].n_debug_insn_changes) - { - unsigned int regno; - - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - { - if (all_vd[bb->index].e[regno].debug_insn_changes) - { - all_vd[bb->index].e[regno].debug_insn_changes = NULL; - if (--all_vd[bb->index].n_debug_insn_changes == 0) - break; - } - } - } - } - else - init_value_data (all_vd + bb->index); - - copyprop_hardreg_forward_1 (bb, all_vd + bb->index); - } - - if (MAY_HAVE_DEBUG_INSNS) - { - FOR_EACH_BB_FN (bb, cfun) - if (bitmap_bit_p (visited, bb->index) - && all_vd[bb->index].n_debug_insn_changes) - { - unsigned int regno; - bitmap live; - - if (!analyze_called) - { - df_analyze (); - analyze_called = true; - } - live = df_get_live_out (bb); - for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) - if (all_vd[bb->index].e[regno].debug_insn_changes) - { - if (REGNO_REG_SET_P (live, regno)) - apply_debug_insn_changes (all_vd + bb->index, regno); - if (all_vd[bb->index].n_debug_insn_changes == 0) - break; - } - } - - free_alloc_pool (debug_insn_changes_pool); - } - - sbitmap_free (visited); - free (all_vd); - return 0; -} - /* Dump the value chain data to stderr. */ DEBUG_FUNCTION void @@ -1276,10 +1189,95 @@ public: return (optimize > 0 && (flag_cprop_registers)); } - unsigned int execute () { return copyprop_hardreg_forward (); } + virtual unsigned int execute (function *); }; // class pass_cprop_hardreg +unsigned int +pass_cprop_hardreg::execute (function *fun) +{ + struct value_data *all_vd; + basic_block bb; + sbitmap visited; + bool analyze_called = false; + + all_vd = XNEWVEC (struct value_data, last_basic_block_for_fn (fun)); + + visited = sbitmap_alloc (last_basic_block_for_fn (fun)); + bitmap_clear (visited); + + if (MAY_HAVE_DEBUG_INSNS) + debug_insn_changes_pool + = create_alloc_pool ("debug insn changes pool", + sizeof (struct queued_debug_insn_change), 256); + + FOR_EACH_BB_FN (bb, fun) + { + bitmap_set_bit (visited, bb->index); + + /* If a block has a single predecessor, that we've already + processed, begin with the value data that was live at + the end of the predecessor block. */ + /* ??? Ought to use more intelligent queuing of blocks. */ + if (single_pred_p (bb) + && bitmap_bit_p (visited, single_pred (bb)->index) + && ! (single_pred_edge (bb)->flags & (EDGE_ABNORMAL_CALL | EDGE_EH))) + { + all_vd[bb->index] = all_vd[single_pred (bb)->index]; + if (all_vd[bb->index].n_debug_insn_changes) + { + unsigned int regno; + + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + { + if (all_vd[bb->index].e[regno].debug_insn_changes) + { + all_vd[bb->index].e[regno].debug_insn_changes = NULL; + if (--all_vd[bb->index].n_debug_insn_changes == 0) + break; + } + } + } + } + else + init_value_data (all_vd + bb->index); + + copyprop_hardreg_forward_1 (bb, all_vd + bb->index); + } + + if (MAY_HAVE_DEBUG_INSNS) + { + FOR_EACH_BB_FN (bb, fun) + if (bitmap_bit_p (visited, bb->index) + && all_vd[bb->index].n_debug_insn_changes) + { + unsigned int regno; + bitmap live; + + if (!analyze_called) + { + df_analyze (); + analyze_called = true; + } + live = df_get_live_out (bb); + for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) + if (all_vd[bb->index].e[regno].debug_insn_changes) + { + if (REGNO_REG_SET_P (live, regno)) + apply_debug_insn_changes (all_vd + bb->index, regno); + if (all_vd[bb->index].n_debug_insn_changes == 0) + break; + } + } + + free_alloc_pool (debug_insn_changes_pool); + } + + sbitmap_free (visited); + free (all_vd); + return 0; +} + } // anon namespace rtl_opt_pass * diff --git a/gcc/reginfo.c b/gcc/reginfo.c index 82b6081850a3..42668a158eb7 100644 --- a/gcc/reginfo.c +++ b/gcc/reginfo.c @@ -985,7 +985,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return reginfo_init (); } + virtual unsigned int execute (function *) { return reginfo_init (); } }; // class pass_reginfo_init diff --git a/gcc/regrename.c b/gcc/regrename.c index 321d5bfbe5be..68e8ad730152 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -1865,7 +1865,7 @@ public: return (optimize > 0 && (flag_rename_registers)); } - unsigned int execute () { return regrename_optimize (); } + virtual unsigned int execute (function *) { return regrename_optimize (); } }; // class pass_regrename diff --git a/gcc/reorg.c b/gcc/reorg.c index 22f0b5a8287b..95e942f3eaf1 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -3898,7 +3898,10 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return rest_of_handle_delay_slots (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_delay_slots (); + } }; // class pass_delay_slots @@ -3923,13 +3926,6 @@ make_pass_delay_slots (gcc::context *ctxt) /* Machine dependent reorg pass. */ -static unsigned int -rest_of_handle_machine_reorg (void) -{ - targetm.machine_dependent_reorg (); - return 0; -} - namespace { const pass_data pass_data_machine_reorg = @@ -3959,7 +3955,11 @@ public: return targetm.machine_dependent_reorg != 0; } - unsigned int execute () { return rest_of_handle_machine_reorg (); } + virtual unsigned int execute (function *) + { + targetm.machine_dependent_reorg (); + return 0; + } }; // class pass_machine_reorg diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c index e0a80c229e94..ce3fe5df0163 100644 --- a/gcc/sched-rgn.c +++ b/gcc/sched-rgn.c @@ -3677,7 +3677,10 @@ public: #endif } - unsigned int execute () { return rest_of_handle_live_range_shrinkage (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_live_range_shrinkage (); + } }; // class pass_live_range_shrinkage @@ -3715,7 +3718,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return rest_of_handle_sched (); } + virtual unsigned int execute (function *) { return rest_of_handle_sched (); } }; // class pass_sched @@ -3763,7 +3766,10 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return rest_of_handle_sched2 (); } + virtual unsigned int execute (function *) + { + return rest_of_handle_sched2 (); + } }; // class pass_sched2 diff --git a/gcc/stack-ptr-mod.c b/gcc/stack-ptr-mod.c index d1375a4222b7..75bec2fbdcdc 100644 --- a/gcc/stack-ptr-mod.c +++ b/gcc/stack-ptr-mod.c @@ -48,48 +48,10 @@ notice_stack_pointer_modification_1 (rtx x, const_rtx pat ATTRIBUTE_UNUSED, crtl->sp_is_unchanging = 0; } -static void -notice_stack_pointer_modification (void) -{ - basic_block bb; - rtx insn; - - /* Assume that the stack pointer is unchanging if alloca hasn't - been used. */ - crtl->sp_is_unchanging = !cfun->calls_alloca; - if (crtl->sp_is_unchanging) - FOR_EACH_BB_FN (bb, cfun) - FOR_BB_INSNS (bb, insn) - { - if (INSN_P (insn)) - { - /* Check if insn modifies the stack pointer. */ - note_stores (PATTERN (insn), - notice_stack_pointer_modification_1, - NULL); - if (! crtl->sp_is_unchanging) - return; - } - } - - /* The value coming into this pass was 0, and the exit block uses - are based on this. If the value is now 1, we need to redo the - exit block uses. */ - if (df && crtl->sp_is_unchanging) - df_update_exit_block_uses (); -} - /* Some targets can emit simpler epilogues if they know that sp was not ever modified during the function. After reload, of course, we've already emitted the epilogue so there's no sense searching. */ -static unsigned int -rest_of_handle_stack_ptr_mod (void) -{ - notice_stack_pointer_modification (); - return 0; -} - namespace { const pass_data pass_data_stack_ptr_mod = @@ -114,10 +76,43 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return rest_of_handle_stack_ptr_mod (); } + virtual unsigned int execute (function *); }; // class pass_stack_ptr_mod +unsigned int +pass_stack_ptr_mod::execute (function *fun) +{ + basic_block bb; + rtx insn; + + /* Assume that the stack pointer is unchanging if alloca hasn't + been used. */ + crtl->sp_is_unchanging = !fun->calls_alloca; + if (crtl->sp_is_unchanging) + FOR_EACH_BB_FN (bb, fun) + FOR_BB_INSNS (bb, insn) + { + if (INSN_P (insn)) + { + /* Check if insn modifies the stack pointer. */ + note_stores (PATTERN (insn), + notice_stack_pointer_modification_1, + NULL); + if (! crtl->sp_is_unchanging) + return 0; + } + } + + /* The value coming into this pass was 0, and the exit block uses + are based on this. If the value is now 1, we need to redo the + exit block uses. */ + if (df && crtl->sp_is_unchanging) + df_update_exit_block_uses (); + + return 0; +} + } // anon namespace rtl_opt_pass * diff --git a/gcc/store-motion.c b/gcc/store-motion.c index 7c57754d1c4b..920da5312134 100644 --- a/gcc/store-motion.c +++ b/gcc/store-motion.c @@ -1258,7 +1258,10 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return execute_rtl_store_motion (); } + virtual unsigned int execute (function *) + { + return execute_rtl_store_motion (); + } }; // class pass_rtl_store_motion diff --git a/gcc/testsuite/g++.dg/plugin/dumb_plugin.c b/gcc/testsuite/g++.dg/plugin/dumb_plugin.c index a3b04a24928a..35eae15ffe58 100644 --- a/gcc/testsuite/g++.dg/plugin/dumb_plugin.c +++ b/gcc/testsuite/g++.dg/plugin/dumb_plugin.c @@ -44,14 +44,6 @@ handle_end_of_compilation_unit (void *event_data, void *data) } -static unsigned int -execute_dumb_plugin_example (void) -{ - warning (0, G_("Analyze function %s"), - IDENTIFIER_POINTER (DECL_NAME (current_function_decl))); - return 0; -} - namespace { const pass_data pass_data_dumb_plugin_example = @@ -76,10 +68,18 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return execute_dumb_plugin_example (); } + virtual unsigned int execute (function *); }; // class pass_dumb_plugin_example +unsigned int +pass_dumb_plugin_example::execute (function *) +{ + warning (0, G_("Analyze function %s"), + IDENTIFIER_POINTER (DECL_NAME (current_function_decl))); + return 0; +} + } // anon namespace static gimple_opt_pass * diff --git a/gcc/testsuite/g++.dg/plugin/selfassign.c b/gcc/testsuite/g++.dg/plugin/selfassign.c index 033047b9894e..59bb03ac2a79 100644 --- a/gcc/testsuite/g++.dg/plugin/selfassign.c +++ b/gcc/testsuite/g++.dg/plugin/selfassign.c @@ -253,23 +253,6 @@ warn_self_assign (gimple stmt) } } -/* Entry point for the self-assignment detection pass. */ - -static unsigned int -execute_warn_self_assign (void) -{ - gimple_stmt_iterator gsi; - basic_block bb; - - FOR_EACH_BB_FN (bb, cfun) - { - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - warn_self_assign (gsi_stmt (gsi)); - } - - return 0; -} - namespace { const pass_data pass_data_warn_self_assign = @@ -295,10 +278,25 @@ public: /* opt_pass methods: */ bool gate (function *) { return true; } - unsigned int execute () { return execute_warn_self_assign (); } + virtual unsigned int execute (function *); }; // class pass_warn_self_assign +unsigned int +pass_warn_self_assign::execute (function *fun) +{ + gimple_stmt_iterator gsi; + basic_block bb; + + FOR_EACH_BB_FN (bb, fun) + { + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + warn_self_assign (gsi_stmt (gsi)); + } + + return 0; +} + } // anon namespace static gimple_opt_pass * diff --git a/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c b/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c index 18e8b07a77f3..d70f5584dc28 100644 --- a/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c +++ b/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c @@ -50,7 +50,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute (); + virtual unsigned int execute (function *); private: int counter; @@ -63,7 +63,8 @@ bool one_pass::gate (function *) return true; } -unsigned int one_pass::execute () +unsigned int +one_pass::execute (function *) { if (counter > 0) { printf ("Executed more than once \n"); diff --git a/gcc/testsuite/gcc.dg/plugin/selfassign.c b/gcc/testsuite/gcc.dg/plugin/selfassign.c index 098df060c821..4dad0c28817a 100644 --- a/gcc/testsuite/gcc.dg/plugin/selfassign.c +++ b/gcc/testsuite/gcc.dg/plugin/selfassign.c @@ -253,23 +253,6 @@ warn_self_assign (gimple stmt) } } -/* Entry point for the self-assignment detection pass. */ - -static unsigned int -execute_warn_self_assign (void) -{ - gimple_stmt_iterator gsi; - basic_block bb; - - FOR_EACH_BB_FN (bb, cfun) - { - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - warn_self_assign (gsi_stmt (gsi)); - } - - return 0; -} - namespace { const pass_data pass_data_warn_self_assign = @@ -294,10 +277,25 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return execute_warn_self_assign (); } + virtual unsigned int execute (function *); }; // class pass_warn_self_assign +unsigned int +pass_warn_self_assign::execute (function *fun) +{ + gimple_stmt_iterator gsi; + basic_block bb; + + FOR_EACH_BB_FN (bb, fun) + { + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + warn_self_assign (gsi_stmt (gsi)); + } + + return 0; +} + } // anon namespace static gimple_opt_pass * diff --git a/gcc/tracer.c b/gcc/tracer.c index 794d385988f1..09a8f40c7f53 100644 --- a/gcc/tracer.c +++ b/gcc/tracer.c @@ -367,36 +367,6 @@ tail_duplicate (void) return changed; } - -/* Main entry point to this file. */ - -static unsigned int -tracer (void) -{ - bool changed; - - if (n_basic_blocks_for_fn (cfun) <= NUM_FIXED_BLOCKS + 1) - return 0; - - mark_dfs_back_edges (); - if (dump_file) - brief_dump_cfg (dump_file, dump_flags); - - /* Trace formation is done on the fly inside tail_duplicate */ - changed = tail_duplicate (); - if (changed) - { - free_dominance_info (CDI_DOMINATORS); - /* If we changed the CFG schedule loops for fixup by cleanup_cfg. */ - if (current_loops) - loops_state_set (LOOPS_NEED_FIXUP); - } - - if (dump_file) - brief_dump_cfg (dump_file, dump_flags); - - return changed ? TODO_cleanup_cfg : 0; -} namespace { @@ -427,10 +397,37 @@ public: return (optimize > 0 && flag_tracer && flag_reorder_blocks); } - unsigned int execute () { return tracer (); } + virtual unsigned int execute (function *); }; // class pass_tracer +unsigned int +pass_tracer::execute (function *fun) +{ + bool changed; + + if (n_basic_blocks_for_fn (fun) <= NUM_FIXED_BLOCKS + 1) + return 0; + + mark_dfs_back_edges (); + if (dump_file) + brief_dump_cfg (dump_file, dump_flags); + + /* Trace formation is done on the fly inside tail_duplicate */ + changed = tail_duplicate (); + if (changed) + { + free_dominance_info (CDI_DOMINATORS); + /* If we changed the CFG schedule loops for fixup by cleanup_cfg. */ + if (current_loops) + loops_state_set (LOOPS_NEED_FIXUP); + } + + if (dump_file) + brief_dump_cfg (dump_file, dump_flags); + + return changed ? TODO_cleanup_cfg : 0; +} } // anon namespace gimple_opt_pass * diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index eb172a6079b9..417ca8a8fa27 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -856,7 +856,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_tm; } - unsigned int execute () { return diagnose_tm_blocks (); } + virtual unsigned int execute (function *) { return diagnose_tm_blocks (); } }; // class pass_diagnose_tm_blocks @@ -1778,7 +1778,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_tm; } - unsigned int execute () { return execute_lower_tm (); } + virtual unsigned int execute (function *) { return execute_lower_tm (); } }; // class pass_lower_tm @@ -3029,7 +3029,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return execute_tm_mark (); } + virtual unsigned int execute (function *) { return execute_tm_mark (); } }; // class pass_tm_mark @@ -3162,31 +3162,6 @@ expand_block_edges (struct tm_region *const region, basic_block bb) /* Entry point to the final expansion of transactional nodes. */ -static unsigned int -execute_tm_edges (void) -{ - vec bb_regions - = get_bb_regions_instrumented (/*traverse_clones=*/false, - /*include_uninstrumented_p=*/true); - struct tm_region *r; - unsigned i; - - FOR_EACH_VEC_ELT (bb_regions, i, r) - if (r != NULL) - expand_block_edges (r, BASIC_BLOCK_FOR_FN (cfun, i)); - - bb_regions.release (); - - /* We've got to release the dominance info now, to indicate that it - must be rebuilt completely. Otherwise we'll crash trying to update - the SSA web in the TODO section following this pass. */ - free_dominance_info (CDI_DOMINATORS); - bitmap_obstack_release (&tm_obstack); - all_tm_regions = NULL; - - return 0; -} - namespace { const pass_data pass_data_tm_edges = @@ -3211,10 +3186,35 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return execute_tm_edges (); } + virtual unsigned int execute (function *); }; // class pass_tm_edges +unsigned int +pass_tm_edges::execute (function *fun) +{ + vec bb_regions + = get_bb_regions_instrumented (/*traverse_clones=*/false, + /*include_uninstrumented_p=*/true); + struct tm_region *r; + unsigned i; + + FOR_EACH_VEC_ELT (bb_regions, i, r) + if (r != NULL) + expand_block_edges (r, BASIC_BLOCK_FOR_FN (fun, i)); + + bb_regions.release (); + + /* We've got to release the dominance info now, to indicate that it + must be rebuilt completely. Otherwise we'll crash trying to update + the SSA web in the TODO section following this pass. */ + free_dominance_info (CDI_DOMINATORS); + bitmap_obstack_release (&tm_obstack); + all_tm_regions = NULL; + + return 0; +} + } // anon namespace gimple_opt_pass * @@ -3946,7 +3946,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_tm && optimize > 0; } - unsigned int execute () { return execute_tm_memopt (); } + virtual unsigned int execute (function *) { return execute_tm_memopt (); } }; // class pass_tm_memopt @@ -5582,7 +5582,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_tm; } - unsigned int execute () { return ipa_tm_execute (); } + virtual unsigned int execute (function *) { return ipa_tm_execute (); } }; // class pass_ipa_tm diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c index c27149321621..ea1df8b2210d 100644 --- a/gcc/tree-call-cdce.c +++ b/gcc/tree-call-cdce.c @@ -867,16 +867,51 @@ shrink_wrap_conditional_dead_built_in_calls (vec calls) return changed; } -/* Pass entry points. */ +namespace { + +const pass_data pass_data_call_cdce = +{ + GIMPLE_PASS, /* type */ + "cdce", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_CALL_CDCE, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_verify_ssa, /* todo_flags_finish */ +}; + +class pass_call_cdce : public gimple_opt_pass +{ +public: + pass_call_cdce (gcc::context *ctxt) + : gimple_opt_pass (pass_data_call_cdce, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *fun) + { + /* The limit constants used in the implementation + assume IEEE floating point format. Other formats + can be supported in the future if needed. */ + return flag_tree_builtin_call_dce != 0 + && optimize_function_for_speed_p (fun); + } -static unsigned int -tree_call_cdce (void) + virtual unsigned int execute (function *); + +}; // class pass_call_cdce + +unsigned int +pass_call_cdce::execute (function *fun) { basic_block bb; gimple_stmt_iterator i; bool something_changed = false; auto_vec cond_dead_built_in_calls; - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { /* Collect dead call candidates. */ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i)) @@ -910,50 +945,13 @@ tree_call_cdce (void) free_dominance_info (CDI_POST_DOMINATORS); /* As we introduced new control-flow we need to insert PHI-nodes for the call-clobbers of the remaining call. */ - mark_virtual_operands_for_renaming (cfun); + mark_virtual_operands_for_renaming (fun); return TODO_update_ssa; } return 0; } -namespace { - -const pass_data pass_data_call_cdce = -{ - GIMPLE_PASS, /* type */ - "cdce", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_CALL_CDCE, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_verify_ssa, /* todo_flags_finish */ -}; - -class pass_call_cdce : public gimple_opt_pass -{ -public: - pass_call_cdce (gcc::context *ctxt) - : gimple_opt_pass (pass_data_call_cdce, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *fun) - { - /* The limit constants used in the implementation - assume IEEE floating point format. Other formats - can be supported in the future if needed. */ - return flag_tree_builtin_call_dce != 0 - && optimize_function_for_speed_p (fun); - } - - unsigned int execute () { return tree_call_cdce (); } - -}; // class pass_call_cdce - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 8fcaae8c7802..0fb2681c7236 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -368,7 +368,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return execute_build_cfg (); } + virtual unsigned int execute (function *) { return execute_build_cfg (); } }; // class pass_build_cfg @@ -8100,7 +8100,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return split_critical_edges (); } + virtual unsigned int execute (function *) { return split_critical_edges (); } opt_pass * clone () { return new pass_split_crit_edges (m_ctxt); } }; // class pass_split_crit_edges @@ -8165,64 +8165,6 @@ gimplify_build1 (gimple_stmt_iterator *gsi, enum tree_code code, tree type, -/* Emit return warnings. */ - -static unsigned int -execute_warn_function_return (void) -{ - source_location location; - gimple last; - edge e; - edge_iterator ei; - - if (!targetm.warn_func_return (cfun->decl)) - return 0; - - /* If we have a path to EXIT, then we do return. */ - if (TREE_THIS_VOLATILE (cfun->decl) - && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) > 0) - { - location = UNKNOWN_LOCATION; - FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) - { - last = last_stmt (e->src); - if ((gimple_code (last) == GIMPLE_RETURN - || gimple_call_builtin_p (last, BUILT_IN_RETURN)) - && (location = gimple_location (last)) != UNKNOWN_LOCATION) - break; - } - if (location == UNKNOWN_LOCATION) - location = cfun->function_end_locus; - warning_at (location, 0, "% function does return"); - } - - /* If we see "return;" in some basic block, then we do reach the end - without returning a value. */ - else if (warn_return_type - && !TREE_NO_WARNING (cfun->decl) - && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) > 0 - && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (cfun->decl)))) - { - FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) - { - gimple last = last_stmt (e->src); - if (gimple_code (last) == GIMPLE_RETURN - && gimple_return_retval (last) == NULL - && !gimple_no_warning_p (last)) - { - location = gimple_location (last); - if (location == UNKNOWN_LOCATION) - location = cfun->function_end_locus; - warning_at (location, OPT_Wreturn_type, "control reaches end of non-void function"); - TREE_NO_WARNING (cfun->decl) = 1; - break; - } - } - } - return 0; -} - - /* Given a basic block B which ends with a conditional and has precisely two successors, determine which of the edges is taken if the conditional is true and which is taken if the conditional is @@ -8247,6 +8189,8 @@ extract_true_false_edges_from_block (basic_block b, } } +/* Emit return warnings. */ + namespace { const pass_data pass_data_warn_function_return = @@ -8271,10 +8215,65 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return execute_warn_function_return (); } + virtual unsigned int execute (function *); }; // class pass_warn_function_return +unsigned int +pass_warn_function_return::execute (function *fun) +{ + source_location location; + gimple last; + edge e; + edge_iterator ei; + + if (!targetm.warn_func_return (fun->decl)) + return 0; + + /* If we have a path to EXIT, then we do return. */ + if (TREE_THIS_VOLATILE (fun->decl) + && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) > 0) + { + location = UNKNOWN_LOCATION; + FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds) + { + last = last_stmt (e->src); + if ((gimple_code (last) == GIMPLE_RETURN + || gimple_call_builtin_p (last, BUILT_IN_RETURN)) + && (location = gimple_location (last)) != UNKNOWN_LOCATION) + break; + } + if (location == UNKNOWN_LOCATION) + location = cfun->function_end_locus; + warning_at (location, 0, "% function does return"); + } + + /* If we see "return;" in some basic block, then we do reach the end + without returning a value. */ + else if (warn_return_type + && !TREE_NO_WARNING (fun->decl) + && EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (fun)->preds) > 0 + && !VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fun->decl)))) + { + FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (fun)->preds) + { + gimple last = last_stmt (e->src); + if (gimple_code (last) == GIMPLE_RETURN + && gimple_return_retval (last) == NULL + && !gimple_no_warning_p (last)) + { + location = gimple_location (last); + if (location == UNKNOWN_LOCATION) + location = fun->function_end_locus; + warning_at (location, OPT_Wreturn_type, "control reaches end of non-void function"); + TREE_NO_WARNING (fun->decl) = 1; + break; + } + } + } + return 0; +} + } // anon namespace gimple_opt_pass * @@ -8348,13 +8347,6 @@ do_warn_unused_result (gimple_seq seq) } } -static unsigned int -run_warn_unused_result (void) -{ - do_warn_unused_result (gimple_body (current_function_decl)); - return 0; -} - namespace { const pass_data pass_data_warn_unused_result = @@ -8380,7 +8372,11 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_warn_unused_result; } - unsigned int execute () { return run_warn_unused_result (); } + virtual unsigned int execute (function *) + { + do_warn_unused_result (gimple_body (current_function_decl)); + return 0; + } }; // class pass_warn_unused_result @@ -8522,7 +8518,7 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_fixup_cfg (m_ctxt); } - unsigned int execute () { return execute_fixup_cfg (); } + virtual unsigned int execute (function *) { return execute_fixup_cfg (); } }; // class pass_fixup_cfg diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c index 19433f961566..104620716ec0 100644 --- a/gcc/tree-cfgcleanup.c +++ b/gcc/tree-cfgcleanup.c @@ -944,17 +944,46 @@ remove_forwarder_block_with_phi (basic_block bb) :; */ -static unsigned int -merge_phi_nodes (void) +namespace { + +const pass_data pass_data_merge_phi = +{ + GIMPLE_PASS, /* type */ + "mergephi", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_MERGE_PHI, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_verify_ssa, /* todo_flags_finish */ +}; + +class pass_merge_phi : public gimple_opt_pass { - basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun)); +public: + pass_merge_phi (gcc::context *ctxt) + : gimple_opt_pass (pass_data_merge_phi, ctxt) + {} + + /* opt_pass methods: */ + opt_pass * clone () { return new pass_merge_phi (m_ctxt); } + virtual unsigned int execute (function *); + +}; // class pass_merge_phi + +unsigned int +pass_merge_phi::execute (function *fun) +{ + basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun)); basic_block *current = worklist; basic_block bb; calculate_dominance_info (CDI_DOMINATORS); /* Find all PHI nodes that we may be able to merge. */ - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { basic_block dest; @@ -1035,35 +1064,6 @@ merge_phi_nodes (void) return 0; } -namespace { - -const pass_data pass_data_merge_phi = -{ - GIMPLE_PASS, /* type */ - "mergephi", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_MERGE_PHI, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_verify_ssa, /* todo_flags_finish */ -}; - -class pass_merge_phi : public gimple_opt_pass -{ -public: - pass_merge_phi (gcc::context *ctxt) - : gimple_opt_pass (pass_data_merge_phi, ctxt) - {} - - /* opt_pass methods: */ - opt_pass * clone () { return new pass_merge_phi (m_ctxt); } - unsigned int execute () { return merge_phi_nodes (); } - -}; // class pass_merge_phi - } // anon namespace gimple_opt_pass * @@ -1142,9 +1142,10 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { - return execute_cleanup_cfg_post_optimizing (); - } + virtual unsigned int execute (function *) + { + return execute_cleanup_cfg_post_optimizing (); + } }; // class pass_cleanup_cfg_post_optimizing diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c index 9ec83d9830f2..a97aaf974ce7 100644 --- a/gcc/tree-complex.c +++ b/gcc/tree-complex.c @@ -1680,7 +1680,7 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_lower_complex (m_ctxt); } - unsigned int execute () { return tree_lower_complex (); } + virtual unsigned int execute (function *) { return tree_lower_complex (); } }; // class pass_lower_complex @@ -1724,7 +1724,7 @@ public: return !(fun->curr_properties & PROP_gimple_lcx); } - unsigned int execute () { return tree_lower_complex (); } + virtual unsigned int execute (function *) { return tree_lower_complex (); } }; // class pass_lower_complex_O0 diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c index 41f96c461bde..960c04a14d0f 100644 --- a/gcc/tree-eh.c +++ b/gcc/tree-eh.c @@ -2121,8 +2121,36 @@ lower_eh_constructs_1 (struct leh_state *state, gimple_seq *pseq) lower_eh_constructs_2 (state, &gsi); } -static unsigned int -lower_eh_constructs (void) +namespace { + +const pass_data pass_data_lower_eh = +{ + GIMPLE_PASS, /* type */ + "eh", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_EH, /* tv_id */ + PROP_gimple_lcf, /* properties_required */ + PROP_gimple_leh, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_lower_eh : public gimple_opt_pass +{ +public: + pass_lower_eh (gcc::context *ctxt) + : gimple_opt_pass (pass_data_lower_eh, ctxt) + {} + + /* opt_pass methods: */ + virtual unsigned int execute (function *); + +}; // class pass_lower_eh + +unsigned int +pass_lower_eh::execute (function *fun) { struct leh_state null_state; gimple_seq bodyp; @@ -2155,7 +2183,7 @@ lower_eh_constructs (void) /* If this function needs a language specific EH personality routine and the frontend didn't already set one do so now. */ - if (function_needs_eh_personality (cfun) == eh_personality_lang + if (function_needs_eh_personality (fun) == eh_personality_lang && !DECL_FUNCTION_PERSONALITY (current_function_decl)) DECL_FUNCTION_PERSONALITY (current_function_decl) = lang_hooks.eh_personality (); @@ -2163,34 +2191,6 @@ lower_eh_constructs (void) return 0; } -namespace { - -const pass_data pass_data_lower_eh = -{ - GIMPLE_PASS, /* type */ - "eh", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_EH, /* tv_id */ - PROP_gimple_lcf, /* properties_required */ - PROP_gimple_leh, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_lower_eh : public gimple_opt_pass -{ -public: - pass_lower_eh (gcc::context *ctxt) - : gimple_opt_pass (pass_data_lower_eh, ctxt) - {} - - /* opt_pass methods: */ - unsigned int execute () { return lower_eh_constructs (); } - -}; // class pass_lower_eh - } // anon namespace gimple_opt_pass * @@ -3108,13 +3108,6 @@ refactor_eh_r (gimple_seq seq) } } -static unsigned -refactor_eh (void) -{ - refactor_eh_r (gimple_body (current_function_decl)); - return 0; -} - namespace { const pass_data pass_data_refactor_eh = @@ -3140,7 +3133,11 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_exceptions != 0; } - unsigned int execute () { return refactor_eh (); } + virtual unsigned int execute (function *) + { + refactor_eh_r (gimple_body (current_function_decl)); + return 0; + } }; // class pass_refactor_eh @@ -3304,37 +3301,6 @@ lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map) return ret; } -static unsigned -execute_lower_resx (void) -{ - basic_block bb; - struct pointer_map_t *mnt_map; - bool dominance_invalidated = false; - bool any_rewritten = false; - - mnt_map = pointer_map_create (); - - FOR_EACH_BB_FN (bb, cfun) - { - gimple last = last_stmt (bb); - if (last && is_gimple_resx (last)) - { - dominance_invalidated |= lower_resx (bb, last, mnt_map); - any_rewritten = true; - } - } - - pointer_map_destroy (mnt_map); - - if (dominance_invalidated) - { - free_dominance_info (CDI_DOMINATORS); - free_dominance_info (CDI_POST_DOMINATORS); - } - - return any_rewritten ? TODO_update_ssa_only_virtuals : 0; -} - namespace { const pass_data pass_data_lower_resx = @@ -3360,10 +3326,41 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_exceptions != 0; } - unsigned int execute () { return execute_lower_resx (); } + virtual unsigned int execute (function *); }; // class pass_lower_resx +unsigned +pass_lower_resx::execute (function *fun) +{ + basic_block bb; + struct pointer_map_t *mnt_map; + bool dominance_invalidated = false; + bool any_rewritten = false; + + mnt_map = pointer_map_create (); + + FOR_EACH_BB_FN (bb, fun) + { + gimple last = last_stmt (bb); + if (last && is_gimple_resx (last)) + { + dominance_invalidated |= lower_resx (bb, last, mnt_map); + any_rewritten = true; + } + } + + pointer_map_destroy (mnt_map); + + if (dominance_invalidated) + { + free_dominance_info (CDI_DOMINATORS); + free_dominance_info (CDI_POST_DOMINATORS); + } + + return any_rewritten ? TODO_update_ssa_only_virtuals : 0; +} + } // anon namespace gimple_opt_pass * @@ -3704,8 +3701,37 @@ lower_eh_dispatch (basic_block src, gimple stmt) return redirected; } -static unsigned -execute_lower_eh_dispatch (void) +namespace { + +const pass_data pass_data_lower_eh_dispatch = +{ + GIMPLE_PASS, /* type */ + "ehdisp", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_EH, /* tv_id */ + PROP_gimple_lcf, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_verify_flow, /* todo_flags_finish */ +}; + +class pass_lower_eh_dispatch : public gimple_opt_pass +{ +public: + pass_lower_eh_dispatch (gcc::context *ctxt) + : gimple_opt_pass (pass_data_lower_eh_dispatch, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *fun) { return fun->eh->region_tree != NULL; } + virtual unsigned int execute (function *); + +}; // class pass_lower_eh_dispatch + +unsigned +pass_lower_eh_dispatch::execute (function *fun) { basic_block bb; int flags = 0; @@ -3713,7 +3739,7 @@ execute_lower_eh_dispatch (void) assign_filter_values (); - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { gimple last = last_stmt (bb); if (last == NULL) @@ -3737,36 +3763,6 @@ execute_lower_eh_dispatch (void) return flags; } -namespace { - -const pass_data pass_data_lower_eh_dispatch = -{ - GIMPLE_PASS, /* type */ - "ehdisp", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_EH, /* tv_id */ - PROP_gimple_lcf, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_verify_flow, /* todo_flags_finish */ -}; - -class pass_lower_eh_dispatch : public gimple_opt_pass -{ -public: - pass_lower_eh_dispatch (gcc::context *ctxt) - : gimple_opt_pass (pass_data_lower_eh_dispatch, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *fun) { return fun->eh->region_tree != NULL; } - - unsigned int execute () { return execute_lower_eh_dispatch (); } - -}; // class pass_lower_eh_dispatch - } // anon namespace gimple_opt_pass * @@ -4564,21 +4560,6 @@ execute_cleanup_eh_1 (void) return 0; } -static unsigned int -execute_cleanup_eh (void) -{ - int ret = execute_cleanup_eh_1 (); - - /* If the function no longer needs an EH personality routine - clear it. This exposes cross-language inlining opportunities - and avoids references to a never defined personality routine. */ - if (DECL_FUNCTION_PERSONALITY (current_function_decl) - && function_needs_eh_personality (cfun) != eh_personality_lang) - DECL_FUNCTION_PERSONALITY (current_function_decl) = NULL_TREE; - - return ret; -} - namespace { const pass_data pass_data_cleanup_eh = @@ -4609,10 +4590,25 @@ public: return fun->eh != NULL && fun->eh->region_tree != NULL; } - unsigned int execute () { return execute_cleanup_eh (); } + virtual unsigned int execute (function *); }; // class pass_cleanup_eh +unsigned int +pass_cleanup_eh::execute (function *fun) +{ + int ret = execute_cleanup_eh_1 (); + + /* If the function no longer needs an EH personality routine + clear it. This exposes cross-language inlining opportunities + and avoids references to a never defined personality routine. */ + if (DECL_FUNCTION_PERSONALITY (current_function_decl) + && function_needs_eh_personality (fun) != eh_personality_lang) + DECL_FUNCTION_PERSONALITY (current_function_decl) = NULL_TREE; + + return ret; +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c index 280a606221d8..0ed503aec3fa 100644 --- a/gcc/tree-emutls.c +++ b/gcc/tree-emutls.c @@ -846,7 +846,7 @@ public: return !targetm.have_tls; } - unsigned int execute () { return ipa_lower_emutls (); } + virtual unsigned int execute (function *) { return ipa_lower_emutls (); } }; // class pass_ipa_lower_emutls diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c index 90b62a83a125..21a9f05c78bf 100644 --- a/gcc/tree-if-conv.c +++ b/gcc/tree-if-conv.c @@ -1986,33 +1986,6 @@ tree_if_conversion (struct loop *loop) /* Tree if-conversion pass management. */ -static unsigned int -main_tree_if_conversion (void) -{ - struct loop *loop; - unsigned todo = 0; - - if (number_of_loops (cfun) <= 1) - return 0; - - FOR_EACH_LOOP (loop, 0) - if (flag_tree_loop_if_convert == 1 - || flag_tree_loop_if_convert_stores == 1 - || ((flag_tree_loop_vectorize || loop->force_vectorize) - && !loop->dont_vectorize)) - todo |= tree_if_conversion (loop); - -#ifdef ENABLE_CHECKING - { - basic_block bb; - FOR_EACH_BB_FN (bb, cfun) - gcc_assert (!bb->aux); - } -#endif - - return todo; -} - namespace { const pass_data pass_data_if_conversion = @@ -2039,7 +2012,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return main_tree_if_conversion (); } + virtual unsigned int execute (function *); }; // class pass_if_conversion @@ -2052,6 +2025,33 @@ pass_if_conversion::gate (function *fun) || flag_tree_loop_if_convert_stores == 1); } +unsigned int +pass_if_conversion::execute (function *fun) +{ + struct loop *loop; + unsigned todo = 0; + + if (number_of_loops (fun) <= 1) + return 0; + + FOR_EACH_LOOP (loop, 0) + if (flag_tree_loop_if_convert == 1 + || flag_tree_loop_if_convert_stores == 1 + || ((flag_tree_loop_vectorize || loop->force_vectorize) + && !loop->dont_vectorize)) + todo |= tree_if_conversion (loop); + +#ifdef ENABLE_CHECKING + { + basic_block bb; + FOR_EACH_BB_FN (bb, fun) + gcc_assert (!bb->aux); + } +#endif + + return todo; +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c index 332901d3f415..8fc419344c77 100644 --- a/gcc/tree-into-ssa.c +++ b/gcc/tree-into-ssa.c @@ -2299,15 +2299,49 @@ fini_ssa_renamer (void) Steps 3 and 4 are done using the dominator tree walker (walk_dominator_tree). */ -static unsigned int -rewrite_into_ssa (void) +namespace { + +const pass_data pass_data_build_ssa = +{ + GIMPLE_PASS, /* type */ + "ssa", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_SSA_OTHER, /* tv_id */ + PROP_cfg, /* properties_required */ + PROP_ssa, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_verify_ssa | TODO_remove_unused_locals ), /* todo_flags_finish */ +}; + +class pass_build_ssa : public gimple_opt_pass +{ +public: + pass_build_ssa (gcc::context *ctxt) + : gimple_opt_pass (pass_data_build_ssa, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *fun) + { + /* Do nothing for funcions that was produced already in SSA form. */ + return !(fun->curr_properties & PROP_ssa); + } + + virtual unsigned int execute (function *); + +}; // class pass_build_ssa + +unsigned int +pass_build_ssa::execute (function *fun) { bitmap_head *dfs; basic_block bb; unsigned i; /* Initialize operand data structures. */ - init_ssa_operands (cfun); + init_ssa_operands (fun); /* Initialize internal data needed by the renamer. */ init_ssa_renamer (); @@ -2315,12 +2349,12 @@ rewrite_into_ssa (void) /* Initialize the set of interesting blocks. The callback mark_def_sites will add to this set those blocks that the renamer should process. */ - interesting_blocks = sbitmap_alloc (last_basic_block_for_fn (cfun)); + interesting_blocks = sbitmap_alloc (last_basic_block_for_fn (fun)); bitmap_clear (interesting_blocks); /* Initialize dominance frontier. */ - dfs = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun)); - FOR_EACH_BB_FN (bb, cfun) + dfs = XNEWVEC (bitmap_head, last_basic_block_for_fn (fun)); + FOR_EACH_BB_FN (bb, fun) bitmap_initialize (&dfs[bb->index], &bitmap_default_obstack); /* 1- Compute dominance frontiers. */ @@ -2328,16 +2362,16 @@ rewrite_into_ssa (void) compute_dominance_frontiers (dfs); /* 2- Find and mark definition sites. */ - mark_def_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr); + mark_def_dom_walker (CDI_DOMINATORS).walk (fun->cfg->x_entry_block_ptr); /* 3- Insert PHI nodes at dominance frontiers of definition blocks. */ insert_phi_nodes (dfs); /* 4- Rename all the blocks. */ - rewrite_blocks (ENTRY_BLOCK_PTR_FOR_FN (cfun), REWRITE_ALL); + rewrite_blocks (ENTRY_BLOCK_PTR_FOR_FN (fun), REWRITE_ALL); /* Free allocated memory. */ - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) bitmap_clear (&dfs[bb->index]); free (dfs); @@ -2365,40 +2399,6 @@ rewrite_into_ssa (void) return 0; } -namespace { - -const pass_data pass_data_build_ssa = -{ - GIMPLE_PASS, /* type */ - "ssa", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_SSA_OTHER, /* tv_id */ - PROP_cfg, /* properties_required */ - PROP_ssa, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_verify_ssa | TODO_remove_unused_locals ), /* todo_flags_finish */ -}; - -class pass_build_ssa : public gimple_opt_pass -{ -public: - pass_build_ssa (gcc::context *ctxt) - : gimple_opt_pass (pass_data_build_ssa, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *fun) - { - /* Do nothing for funcions that was produced already in SSA form. */ - return !(fun->curr_properties & PROP_ssa); - } - - unsigned int execute () { return rewrite_into_ssa (); } - -}; // class pass_build_ssa - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c index 0a154127f177..5fff7be5bd86 100644 --- a/gcc/tree-loop-distribution.c +++ b/gcc/tree-loop-distribution.c @@ -1669,15 +1669,49 @@ distribute_loop (struct loop *loop, vec stmts, /* Distribute all loops in the current function. */ -static unsigned int -tree_loop_distribution (void) +namespace { + +const pass_data pass_data_loop_distribution = +{ + GIMPLE_PASS, /* type */ + "ldist", /* name */ + OPTGROUP_LOOP, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_LOOP_DISTRIBUTION, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_verify_ssa, /* todo_flags_finish */ +}; + +class pass_loop_distribution : public gimple_opt_pass +{ +public: + pass_loop_distribution (gcc::context *ctxt) + : gimple_opt_pass (pass_data_loop_distribution, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) + { + return flag_tree_loop_distribution + || flag_tree_loop_distribute_patterns; + } + + virtual unsigned int execute (function *); + +}; // class pass_loop_distribution + +unsigned int +pass_loop_distribution::execute (function *fun) { struct loop *loop; bool changed = false; basic_block bb; control_dependences *cd = NULL; - FOR_ALL_BB_FN (bb, cfun) + FOR_ALL_BB_FN (bb, fun) { gimple_stmt_iterator gsi; for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) @@ -1715,7 +1749,7 @@ tree_loop_distribution (void) if (virtual_operand_p (gimple_phi_result (phi))) continue; /* Distribute stmts which have defs that are used outside of - the loop. */ + the loop. */ if (!stmt_has_scalar_dependences_outside_loop (loop, phi)) continue; work_list.safe_push (phi); @@ -1725,7 +1759,7 @@ tree_loop_distribution (void) gimple stmt = gsi_stmt (gsi); /* If there is a stmt with side-effects bail out - we - cannot and should not distribute this loop. */ + cannot and should not distribute this loop. */ if (gimple_has_side_effects (stmt)) { work_list.truncate (0); @@ -1733,7 +1767,7 @@ tree_loop_distribution (void) } /* Distribute stmts which have defs that are used outside of - the loop. */ + the loop. */ if (stmt_has_scalar_dependences_outside_loop (loop, stmt)) ; /* Otherwise only distribute stores for now. */ @@ -1779,7 +1813,7 @@ out: if (changed) { - mark_virtual_operands_for_renaming (cfun); + mark_virtual_operands_for_renaming (fun); rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); } @@ -1790,40 +1824,6 @@ out: return 0; } -namespace { - -const pass_data pass_data_loop_distribution = -{ - GIMPLE_PASS, /* type */ - "ldist", /* name */ - OPTGROUP_LOOP, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_LOOP_DISTRIBUTION, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_verify_ssa, /* todo_flags_finish */ -}; - -class pass_loop_distribution : public gimple_opt_pass -{ -public: - pass_loop_distribution (gcc::context *ctxt) - : gimple_opt_pass (pass_data_loop_distribution, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) - { - return flag_tree_loop_distribution - || flag_tree_loop_distribute_patterns; - } - - unsigned int execute () { return tree_loop_distribution (); } - -}; // class pass_loop_distribution - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c index 71f8d68fc3d1..45b16f4f4018 100644 --- a/gcc/tree-nrv.c +++ b/gcc/tree-nrv.c @@ -113,8 +113,38 @@ finalize_nrv_r (tree *tp, int *walk_subtrees, void *data) then we could either have the languages register the optimization or we could change the gating function to check the current language. */ -static unsigned int -tree_nrv (void) +namespace { + +const pass_data pass_data_nrv = +{ + GIMPLE_PASS, /* type */ + "nrv", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_NRV, /* tv_id */ + ( PROP_ssa | PROP_cfg ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_nrv : public gimple_opt_pass +{ +public: + pass_nrv (gcc::context *ctxt) + : gimple_opt_pass (pass_data_nrv, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) { return optimize > 0; } + + virtual unsigned int execute (function *); + +}; // class pass_nrv + +unsigned int +pass_nrv::execute (function *fun) { tree result = DECL_RESULT (current_function_decl); tree result_type = TREE_TYPE (result); @@ -144,7 +174,7 @@ tree_nrv (void) return 0; /* Look through each block for assignments to the RESULT_DECL. */ - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { @@ -238,7 +268,7 @@ tree_nrv (void) RESULT. */ data.var = found; data.result = result; - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); ) { @@ -272,36 +302,6 @@ tree_nrv (void) return 0; } -namespace { - -const pass_data pass_data_nrv = -{ - GIMPLE_PASS, /* type */ - "nrv", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_NRV, /* tv_id */ - ( PROP_ssa | PROP_cfg ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_nrv : public gimple_opt_pass -{ -public: - pass_nrv (gcc::context *ctxt) - : gimple_opt_pass (pass_data_nrv, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) { return optimize > 0; } - - unsigned int execute () { return tree_nrv (); } - -}; // class pass_nrv - } // anon namespace gimple_opt_pass * @@ -347,35 +347,6 @@ dest_safe_for_nrv_p (gimple call) escaped prior to the call. If it has, modifications to the local variable will produce visible changes elsewhere, as in PR c++/19317. */ -static unsigned int -execute_return_slot_opt (void) -{ - basic_block bb; - - FOR_EACH_BB_FN (bb, cfun) - { - gimple_stmt_iterator gsi; - for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) - { - gimple stmt = gsi_stmt (gsi); - bool slot_opt_p; - - if (is_gimple_call (stmt) - && gimple_call_lhs (stmt) - && !gimple_call_return_slot_opt_p (stmt) - && aggregate_value_p (TREE_TYPE (gimple_call_lhs (stmt)), - gimple_call_fndecl (stmt))) - { - /* Check if the location being assigned to is - clobbered by the call. */ - slot_opt_p = dest_safe_for_nrv_p (stmt); - gimple_call_set_return_slot_opt (stmt, slot_opt_p); - } - } - } - return 0; -} - namespace { const pass_data pass_data_return_slot = @@ -400,10 +371,39 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return execute_return_slot_opt (); } + virtual unsigned int execute (function *); }; // class pass_return_slot +unsigned int +pass_return_slot::execute (function *fun) +{ + basic_block bb; + + FOR_EACH_BB_FN (bb, fun) + { + gimple_stmt_iterator gsi; + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + bool slot_opt_p; + + if (is_gimple_call (stmt) + && gimple_call_lhs (stmt) + && !gimple_call_return_slot_opt_p (stmt) + && aggregate_value_p (TREE_TYPE (gimple_call_lhs (stmt)), + gimple_call_fndecl (stmt))) + { + /* Check if the location being assigned to is + clobbered by the call. */ + slot_opt_p = dest_safe_for_nrv_p (stmt); + gimple_call_set_return_slot_opt (stmt, slot_opt_p); + } + } + } + return 0; +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c index 23f7250ac7be..ec50709e86e0 100644 --- a/gcc/tree-object-size.c +++ b/gcc/tree-object-size.c @@ -66,7 +66,6 @@ static bool merge_object_sizes (struct object_size_info *, tree, tree, unsigned HOST_WIDE_INT); static bool plus_stmt_object_size (struct object_size_info *, tree, gimple); static bool cond_expr_object_size (struct object_size_info *, tree, gimple); -static unsigned int compute_object_sizes (void); static void init_offset_limit (void); static void check_for_plus_in_loops (struct object_size_info *, tree); static void check_for_plus_in_loops_1 (struct object_size_info *, tree, @@ -1207,11 +1206,40 @@ fini_object_sizes (void) /* Simple pass to optimize all __builtin_object_size () builtins. */ -static unsigned int -compute_object_sizes (void) +namespace { + +const pass_data pass_data_object_sizes = +{ + GIMPLE_PASS, /* type */ + "objsz", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_NONE, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_verify_ssa, /* todo_flags_finish */ +}; + +class pass_object_sizes : public gimple_opt_pass +{ +public: + pass_object_sizes (gcc::context *ctxt) + : gimple_opt_pass (pass_data_object_sizes, ctxt) + {} + + /* opt_pass methods: */ + opt_pass * clone () { return new pass_object_sizes (m_ctxt); } + virtual unsigned int execute (function *); + +}; // class pass_object_sizes + +unsigned int +pass_object_sizes::execute (function *fun) { basic_block bb; - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { gimple_stmt_iterator i; for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i)) @@ -1281,35 +1309,6 @@ compute_object_sizes (void) return 0; } -namespace { - -const pass_data pass_data_object_sizes = -{ - GIMPLE_PASS, /* type */ - "objsz", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_NONE, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_verify_ssa, /* todo_flags_finish */ -}; - -class pass_object_sizes : public gimple_opt_pass -{ -public: - pass_object_sizes (gcc::context *ctxt) - : gimple_opt_pass (pass_data_object_sizes, ctxt) - {} - - /* opt_pass methods: */ - opt_pass * clone () { return new pass_object_sizes (m_ctxt); } - unsigned int execute () { return compute_object_sizes (); } - -}; // class pass_object_sizes - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c index a46fa51d05e8..79b327b02c0b 100644 --- a/gcc/tree-parloops.c +++ b/gcc/tree-parloops.c @@ -2253,17 +2253,6 @@ parallelize_loops (void) /* Parallelization. */ -static unsigned -tree_parallelize_loops (void) -{ - if (number_of_loops (cfun) <= 1) - return 0; - - if (parallelize_loops ()) - return TODO_cleanup_cfg | TODO_rebuild_alias; - return 0; -} - namespace { const pass_data pass_data_parallelize_loops = @@ -2289,10 +2278,21 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_tree_parallelize_loops > 1; } - unsigned int execute () { return tree_parallelize_loops (); } + virtual unsigned int execute (function *); }; // class pass_parallelize_loops +unsigned +pass_parallelize_loops::execute (function *fun) +{ + if (number_of_loops (fun) <= 1) + return 0; + + if (parallelize_loops ()) + return TODO_cleanup_cfg | TODO_rebuild_alias; + return 0; +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 9de2822cccec..e63f3069068c 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -96,7 +96,7 @@ public: be sub-passes otherwise this pass does nothing. The return value contains TODOs to execute in addition to those in TODO_flags_finish. */ - virtual unsigned int execute (); + virtual unsigned int execute (function *fun); protected: opt_pass (const pass_data&, gcc::context *); diff --git a/gcc/tree-predcom.c b/gcc/tree-predcom.c index 7dd86e166910..4d77401c706f 100644 --- a/gcc/tree-predcom.c +++ b/gcc/tree-predcom.c @@ -2598,7 +2598,10 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_predictive_commoning != 0; } - unsigned int execute () { return run_tree_predictive_commoning (); } + virtual unsigned int execute (function *) + { + return run_tree_predictive_commoning (); + } }; // class pass_predcom diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c index b7d04661eeb1..deefa8b992ae 100644 --- a/gcc/tree-profile.c +++ b/gcc/tree-profile.c @@ -688,7 +688,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *); - unsigned int execute () { return tree_profiling (); } + virtual unsigned int execute (function *) { return tree_profiling (); } }; // class pass_ipa_tree_profile diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 27f71a37366f..890234ff23b0 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -3525,7 +3525,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return gate_intra_sra (); } - unsigned int execute () { return early_intra_sra (); } + virtual unsigned int execute (function *) { return early_intra_sra (); } }; // class pass_sra_early @@ -3562,7 +3562,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return gate_intra_sra (); } - unsigned int execute () { return late_intra_sra (); } + virtual unsigned int execute (function *) { return late_intra_sra (); } }; // class pass_sra @@ -5076,7 +5076,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_ipa_sra && dbg_cnt (eipa_sra); } - unsigned int execute () { return ipa_early_sra (); } + virtual unsigned int execute (function *) { return ipa_early_sra (); } }; // class pass_early_ipa_sra diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index c4a5c71f530a..257d108ec31a 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -2314,7 +2314,7 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_ccp (m_ctxt); } virtual bool gate (function *) { return flag_tree_ccp != 0; } - unsigned int execute () { return do_ssa_ccp (); } + virtual unsigned int execute (function *) { return do_ssa_ccp (); } }; // class pass_ccp @@ -2559,14 +2559,43 @@ optimize_unreachable (gimple_stmt_iterator i) /* A simple pass that attempts to fold all builtin functions. This pass is run after we've propagated as many constants as we can. */ -static unsigned int -execute_fold_all_builtins (void) +namespace { + +const pass_data pass_data_fold_builtins = +{ + GIMPLE_PASS, /* type */ + "fab", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_NONE, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_verify_ssa | TODO_update_ssa ), /* todo_flags_finish */ +}; + +class pass_fold_builtins : public gimple_opt_pass +{ +public: + pass_fold_builtins (gcc::context *ctxt) + : gimple_opt_pass (pass_data_fold_builtins, ctxt) + {} + + /* opt_pass methods: */ + opt_pass * clone () { return new pass_fold_builtins (m_ctxt); } + virtual unsigned int execute (function *); + +}; // class pass_fold_builtins + +unsigned int +pass_fold_builtins::execute (function *fun) { bool cfg_changed = false; basic_block bb; unsigned int todoflags = 0; - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { gimple_stmt_iterator i; for (i = gsi_start_bb (bb); !gsi_end_p (i); ) @@ -2608,7 +2637,7 @@ execute_fold_all_builtins (void) result = gimple_fold_builtin (stmt); if (result) - gimple_remove_stmt_histograms (cfun, stmt); + gimple_remove_stmt_histograms (fun, stmt); if (!result) switch (DECL_FUNCTION_CODE (callee)) @@ -2703,36 +2732,6 @@ execute_fold_all_builtins (void) return todoflags; } - -namespace { - -const pass_data pass_data_fold_builtins = -{ - GIMPLE_PASS, /* type */ - "fab", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_NONE, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_verify_ssa | TODO_update_ssa ), /* todo_flags_finish */ -}; - -class pass_fold_builtins : public gimple_opt_pass -{ -public: - pass_fold_builtins (gcc::context *ctxt) - : gimple_opt_pass (pass_data_fold_builtins, ctxt) - {} - - /* opt_pass methods: */ - opt_pass * clone () { return new pass_fold_builtins (m_ctxt); } - unsigned int execute () { return execute_fold_all_builtins (); } - -}; // class pass_fold_builtins - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c index bd6ac04edbb8..6e3a5693aa77 100644 --- a/gcc/tree-ssa-copy.c +++ b/gcc/tree-ssa-copy.c @@ -671,7 +671,7 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_copy_prop (m_ctxt); } virtual bool gate (function *) { return flag_tree_copy_prop != 0; } - unsigned int execute () { return execute_copy_prop (); } + virtual unsigned int execute (function *) { return execute_copy_prop (); } }; // class pass_copy_prop diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c index 65d80449c29b..b9c9ba399508 100644 --- a/gcc/tree-ssa-copyrename.c +++ b/gcc/tree-ssa-copyrename.c @@ -299,14 +299,44 @@ copy_rename_partition_coalesce (var_map map, tree var1, tree var2, FILE *debug) } +namespace { + +const pass_data pass_data_rename_ssa_copies = +{ + GIMPLE_PASS, /* type */ + "copyrename", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_COPY_RENAME, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_verify_ssa, /* todo_flags_finish */ +}; + +class pass_rename_ssa_copies : public gimple_opt_pass +{ +public: + pass_rename_ssa_copies (gcc::context *ctxt) + : gimple_opt_pass (pass_data_rename_ssa_copies, ctxt) + {} + + /* opt_pass methods: */ + opt_pass * clone () { return new pass_rename_ssa_copies (m_ctxt); } + virtual bool gate (function *) { return flag_tree_copyrename != 0; } + virtual unsigned int execute (function *); + +}; // class pass_rename_ssa_copies + /* This function will make a pass through the IL, and attempt to coalesce any SSA versions which occur in PHI's or copies. Coalescing is accomplished by changing the underlying root variable of all coalesced version. This will then cause the SSA->normal pass to attempt to coalesce them all to the same variable. */ -static unsigned int -rename_ssa_copies (void) +unsigned int +pass_rename_ssa_copies::execute (function *fun) { var_map map; basic_block bb; @@ -325,7 +355,7 @@ rename_ssa_copies (void) map = init_var_map (num_ssa_names); - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { /* Scan for real copies. */ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) @@ -341,7 +371,7 @@ rename_ssa_copies (void) } } - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { /* Treat PHI nodes as copies between the result and each argument. */ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) @@ -429,42 +459,12 @@ rename_ssa_copies (void) replace_ssa_name_symbol (var, SSA_NAME_VAR (part_var)); } - statistics_counter_event (cfun, "copies coalesced", + statistics_counter_event (fun, "copies coalesced", stats.coalesced); delete_var_map (map); return 0; } -namespace { - -const pass_data pass_data_rename_ssa_copies = -{ - GIMPLE_PASS, /* type */ - "copyrename", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_COPY_RENAME, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_verify_ssa, /* todo_flags_finish */ -}; - -class pass_rename_ssa_copies : public gimple_opt_pass -{ -public: - pass_rename_ssa_copies (gcc::context *ctxt) - : gimple_opt_pass (pass_data_rename_ssa_copies, ctxt) - {} - - /* opt_pass methods: */ - opt_pass * clone () { return new pass_rename_ssa_copies (m_ctxt); } - virtual bool gate (function *) { return flag_tree_copyrename != 0; } - unsigned int execute () { return rename_ssa_copies (); } - -}; // class pass_rename_ssa_copies - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c index e5799b96d14f..6389f2386041 100644 --- a/gcc/tree-ssa-dce.c +++ b/gcc/tree-ssa-dce.c @@ -1530,7 +1530,7 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_dce (m_ctxt); } virtual bool gate (function *) { return flag_tree_dce != 0; } - unsigned int execute () { return tree_ssa_dce (); } + virtual unsigned int execute (function *) { return tree_ssa_dce (); } }; // class pass_dce @@ -1568,7 +1568,7 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_dce_loop (m_ctxt); } virtual bool gate (function *) { return flag_tree_dce != 0; } - unsigned int execute () { return tree_ssa_dce_loop (); } + virtual unsigned int execute (function *) { return tree_ssa_dce_loop (); } }; // class pass_dce_loop @@ -1606,7 +1606,7 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_cd_dce (m_ctxt); } virtual bool gate (function *) { return flag_tree_dce != 0; } - unsigned int execute () { return tree_ssa_cd_dce (); } + virtual unsigned int execute (function *) { return tree_ssa_cd_dce (); } }; // class pass_cd_dce diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c index b9cc5cc433df..15c4fb07596a 100644 --- a/gcc/tree-ssa-dom.c +++ b/gcc/tree-ssa-dom.c @@ -832,8 +832,40 @@ private: every new symbol exposed, its corresponding bit will be set in VARS_TO_RENAME. */ -static unsigned int -tree_ssa_dominator_optimize (void) +namespace { + +const pass_data pass_data_dominator = +{ + GIMPLE_PASS, /* type */ + "dom", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_SSA_DOMINATOR_OPTS, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_cleanup_cfg | TODO_update_ssa + | TODO_verify_ssa + | TODO_verify_flow ), /* todo_flags_finish */ +}; + +class pass_dominator : public gimple_opt_pass +{ +public: + pass_dominator (gcc::context *ctxt) + : gimple_opt_pass (pass_data_dominator, ctxt) + {} + + /* opt_pass methods: */ + opt_pass * clone () { return new pass_dominator (m_ctxt); } + virtual bool gate (function *) { return flag_tree_dom != 0; } + virtual unsigned int execute (function *); + +}; // class pass_dominator + +unsigned int +pass_dominator::execute (function *fun) { memset (&opt_stats, 0, sizeof (opt_stats)); @@ -867,12 +899,12 @@ tree_ssa_dominator_optimize (void) mark_dfs_back_edges (); /* Recursively walk the dominator tree optimizing statements. */ - dom_opt_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr); + dom_opt_dom_walker (CDI_DOMINATORS).walk (fun->cfg->x_entry_block_ptr); { gimple_stmt_iterator gsi; basic_block bb; - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) update_stmt_if_modified (gsi_stmt (gsi)); @@ -908,13 +940,13 @@ tree_ssa_dominator_optimize (void) iterator. */ EXECUTE_IF_SET_IN_BITMAP (need_eh_cleanup, 0, i, bi) { - basic_block bb = BASIC_BLOCK_FOR_FN (cfun, i); + basic_block bb = BASIC_BLOCK_FOR_FN (fun, i); if (bb == NULL) continue; while (single_succ_p (bb) && (single_succ_edge (bb)->flags & EDGE_EH) == 0) bb = single_succ (bb); - if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun)) + if (bb == EXIT_BLOCK_PTR_FOR_FN (fun)) continue; if ((unsigned) bb->index != i) bitmap_set_bit (need_eh_cleanup, bb->index); @@ -924,11 +956,11 @@ tree_ssa_dominator_optimize (void) bitmap_clear (need_eh_cleanup); } - statistics_counter_event (cfun, "Redundant expressions eliminated", + statistics_counter_event (fun, "Redundant expressions eliminated", opt_stats.num_re); - statistics_counter_event (cfun, "Constants propagated", + statistics_counter_event (fun, "Constants propagated", opt_stats.num_const_prop); - statistics_counter_event (cfun, "Copies propagated", + statistics_counter_event (fun, "Copies propagated", opt_stats.num_copy_prop); /* Debugging dumps. */ @@ -952,38 +984,6 @@ tree_ssa_dominator_optimize (void) return 0; } -namespace { - -const pass_data pass_data_dominator = -{ - GIMPLE_PASS, /* type */ - "dom", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_SSA_DOMINATOR_OPTS, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_cleanup_cfg | TODO_update_ssa - | TODO_verify_ssa - | TODO_verify_flow ), /* todo_flags_finish */ -}; - -class pass_dominator : public gimple_opt_pass -{ -public: - pass_dominator (gcc::context *ctxt) - : gimple_opt_pass (pass_data_dominator, ctxt) - {} - - /* opt_pass methods: */ - opt_pass * clone () { return new pass_dominator (m_ctxt); } - virtual bool gate (function *) { return flag_tree_dom != 0; } - unsigned int execute () { return tree_ssa_dominator_optimize (); } - -}; // class pass_dominator - } // anon namespace gimple_opt_pass * @@ -3025,8 +3025,40 @@ eliminate_degenerate_phis_1 (basic_block bb, bitmap interesting_names) pick up the secondary optimization opportunities with minimal cost. */ -static unsigned int -eliminate_degenerate_phis (void) +namespace { + +const pass_data pass_data_phi_only_cprop = +{ + GIMPLE_PASS, /* type */ + "phicprop", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_PHI_CPROP, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_cleanup_cfg | TODO_verify_ssa + | TODO_verify_stmts + | TODO_update_ssa ), /* todo_flags_finish */ +}; + +class pass_phi_only_cprop : public gimple_opt_pass +{ +public: + pass_phi_only_cprop (gcc::context *ctxt) + : gimple_opt_pass (pass_data_phi_only_cprop, ctxt) + {} + + /* opt_pass methods: */ + opt_pass * clone () { return new pass_phi_only_cprop (m_ctxt); } + virtual bool gate (function *) { return flag_tree_dom != 0; } + virtual unsigned int execute (function *); + +}; // class pass_phi_only_cprop + +unsigned int +pass_phi_only_cprop::execute (function *fun) { bitmap interesting_names; bitmap interesting_names1; @@ -3059,7 +3091,7 @@ eliminate_degenerate_phis (void) phase in dominator order. Presumably this is because walking in dominator order leaves fewer PHIs for later examination by the worklist phase. */ - eliminate_degenerate_phis_1 (ENTRY_BLOCK_PTR_FOR_FN (cfun), + eliminate_degenerate_phis_1 (ENTRY_BLOCK_PTR_FOR_FN (fun), interesting_names); /* Second phase. Eliminate second order degenerate PHIs as well @@ -3109,38 +3141,6 @@ eliminate_degenerate_phis (void) return 0; } -namespace { - -const pass_data pass_data_phi_only_cprop = -{ - GIMPLE_PASS, /* type */ - "phicprop", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_PHI_CPROP, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_cleanup_cfg | TODO_verify_ssa - | TODO_verify_stmts - | TODO_update_ssa ), /* todo_flags_finish */ -}; - -class pass_phi_only_cprop : public gimple_opt_pass -{ -public: - pass_phi_only_cprop (gcc::context *ctxt) - : gimple_opt_pass (pass_data_phi_only_cprop, ctxt) - {} - - /* opt_pass methods: */ - opt_pass * clone () { return new pass_phi_only_cprop (m_ctxt); } - virtual bool gate (function *) { return flag_tree_dom != 0; } - unsigned int execute () { return eliminate_degenerate_phis (); } - -}; // class pass_phi_only_cprop - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c index b6fbdaf55059..af69063bd205 100644 --- a/gcc/tree-ssa-dse.c +++ b/gcc/tree-ssa-dse.c @@ -80,8 +80,6 @@ along with GCC; see the file COPYING3. If not see remove their dead edges eventually. */ static bitmap need_eh_cleanup; -static unsigned int tree_ssa_dse (void); - /* A helper of dse_optimize_stmt. Given a GIMPLE_ASSIGN in STMT, find a candidate statement *USE_STMT that @@ -327,10 +325,38 @@ dse_dom_walker::before_dom_children (basic_block bb) } } -/* Main entry point. */ +namespace { + +const pass_data pass_data_dse = +{ + GIMPLE_PASS, /* type */ + "dse", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_DSE, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_verify_ssa, /* todo_flags_finish */ +}; + +class pass_dse : public gimple_opt_pass +{ +public: + pass_dse (gcc::context *ctxt) + : gimple_opt_pass (pass_data_dse, ctxt) + {} + + /* opt_pass methods: */ + opt_pass * clone () { return new pass_dse (m_ctxt); } + virtual bool gate (function *) { return flag_tree_dse != 0; } + virtual unsigned int execute (function *); + +}; // class pass_dse -static unsigned int -tree_ssa_dse (void) +unsigned int +pass_dse::execute (function *fun) { need_eh_cleanup = BITMAP_ALLOC (NULL); @@ -345,7 +371,7 @@ tree_ssa_dse (void) /* Dead store elimination is fundamentally a walk of the post-dominator tree and a backwards walk of statements within each block. */ - dse_dom_walker (CDI_POST_DOMINATORS).walk (cfun->cfg->x_exit_block_ptr); + dse_dom_walker (CDI_POST_DOMINATORS).walk (fun->cfg->x_exit_block_ptr); /* Removal of stores may make some EH edges dead. Purge such edges from the CFG as needed. */ @@ -362,36 +388,6 @@ tree_ssa_dse (void) return 0; } -namespace { - -const pass_data pass_data_dse = -{ - GIMPLE_PASS, /* type */ - "dse", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_DSE, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_verify_ssa, /* todo_flags_finish */ -}; - -class pass_dse : public gimple_opt_pass -{ -public: - pass_dse (gcc::context *ctxt) - : gimple_opt_pass (pass_data_dse, ctxt) - {} - - /* opt_pass methods: */ - opt_pass * clone () { return new pass_dse (m_ctxt); } - virtual bool gate (function *) { return flag_tree_dse != 0; } - unsigned int execute () { return tree_ssa_dse (); } - -}; // class pass_dse - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c index 8d5ca5f12527..a623005318e2 100644 --- a/gcc/tree-ssa-forwprop.c +++ b/gcc/tree-ssa-forwprop.c @@ -3567,15 +3567,45 @@ simplify_mult (gimple_stmt_iterator *gsi) /* Main entry point for the forward propagation and statement combine optimizer. */ -static unsigned int -ssa_forward_propagate_and_combine (void) +namespace { + +const pass_data pass_data_forwprop = +{ + GIMPLE_PASS, /* type */ + "forwprop", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_FORWPROP, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */ +}; + +class pass_forwprop : public gimple_opt_pass +{ +public: + pass_forwprop (gcc::context *ctxt) + : gimple_opt_pass (pass_data_forwprop, ctxt) + {} + + /* opt_pass methods: */ + opt_pass * clone () { return new pass_forwprop (m_ctxt); } + virtual bool gate (function *) { return flag_tree_forwprop; } + virtual unsigned int execute (function *); + +}; // class pass_forwprop + +unsigned int +pass_forwprop::execute (function *fun) { basic_block bb; unsigned int todoflags = 0; cfg_changed = false; - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { gimple_stmt_iterator gsi; @@ -3660,7 +3690,7 @@ ssa_forward_propagate_and_combine (void) else if (TREE_CODE_CLASS (code) == tcc_comparison) { if (forward_propagate_comparison (&gsi)) - cfg_changed = true; + cfg_changed = true; } else gsi_next (&gsi); @@ -3831,36 +3861,6 @@ ssa_forward_propagate_and_combine (void) return todoflags; } -namespace { - -const pass_data pass_data_forwprop = -{ - GIMPLE_PASS, /* type */ - "forwprop", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_FORWPROP, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */ -}; - -class pass_forwprop : public gimple_opt_pass -{ -public: - pass_forwprop (gcc::context *ctxt) - : gimple_opt_pass (pass_data_forwprop, ctxt) - {} - - /* opt_pass methods: */ - opt_pass * clone () { return new pass_forwprop (m_ctxt); } - virtual bool gate (function *) { return flag_tree_forwprop; } - unsigned int execute () { return ssa_forward_propagate_and_combine (); } - -}; // class pass_forwprop - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c index b901f379c6b8..0ce02a04f08c 100644 --- a/gcc/tree-ssa-ifcombine.c +++ b/gcc/tree-ssa-ifcombine.c @@ -723,8 +723,36 @@ tree_ssa_ifcombine_bb (basic_block inner_cond_bb) /* Main entry for the tree if-conversion pass. */ -static unsigned int -tree_ssa_ifcombine (void) +namespace { + +const pass_data pass_data_tree_ifcombine = +{ + GIMPLE_PASS, /* type */ + "ifcombine", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_IFCOMBINE, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */ +}; + +class pass_tree_ifcombine : public gimple_opt_pass +{ +public: + pass_tree_ifcombine (gcc::context *ctxt) + : gimple_opt_pass (pass_data_tree_ifcombine, ctxt) + {} + + /* opt_pass methods: */ + virtual unsigned int execute (function *); + +}; // class pass_tree_ifcombine + +unsigned int +pass_tree_ifcombine::execute (function *fun) { basic_block *bbs; bool cfg_changed = false; @@ -741,7 +769,7 @@ tree_ssa_ifcombine (void) inner ones, and also that we do not try to visit a removed block. This is opposite of PHI-OPT, because we cascade the combining rather than cascading PHIs. */ - for (i = n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS - 1; i >= 0; i--) + for (i = n_basic_blocks_for_fn (fun) - NUM_FIXED_BLOCKS - 1; i >= 0; i--) { basic_block bb = bbs[i]; gimple stmt = last_stmt (bb); @@ -756,34 +784,6 @@ tree_ssa_ifcombine (void) return cfg_changed ? TODO_cleanup_cfg : 0; } -namespace { - -const pass_data pass_data_tree_ifcombine = -{ - GIMPLE_PASS, /* type */ - "ifcombine", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_IFCOMBINE, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */ -}; - -class pass_tree_ifcombine : public gimple_opt_pass -{ -public: - pass_tree_ifcombine (gcc::context *ctxt) - : gimple_opt_pass (pass_data_tree_ifcombine, ctxt) - {} - - /* opt_pass methods: */ - unsigned int execute () { return tree_ssa_ifcombine (); } - -}; // class pass_tree_ifcombine - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c index 34d1f7023cca..fb86de4a7b06 100644 --- a/gcc/tree-ssa-loop-ch.c +++ b/gcc/tree-ssa-loop-ch.c @@ -131,8 +131,38 @@ do_while_loop_p (struct loop *loop) of the loop. This is beneficial since it increases efficiency of code motion optimizations. It also saves one jump on entry to the loop. */ -static unsigned int -copy_loop_headers (void) +namespace { + +const pass_data pass_data_ch = +{ + GIMPLE_PASS, /* type */ + "ch", /* name */ + OPTGROUP_LOOP, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_CH, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_cleanup_cfg | TODO_verify_ssa + | TODO_verify_flow ), /* todo_flags_finish */ +}; + +class pass_ch : public gimple_opt_pass +{ +public: + pass_ch (gcc::context *ctxt) + : gimple_opt_pass (pass_data_ch, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) { return flag_tree_ch != 0; } + virtual unsigned int execute (function *); + +}; // class pass_ch + +unsigned int +pass_ch::execute (function *fun) { struct loop *loop; basic_block header; @@ -143,15 +173,15 @@ copy_loop_headers (void) loop_optimizer_init (LOOPS_HAVE_PREHEADERS | LOOPS_HAVE_SIMPLE_LATCHES); - if (number_of_loops (cfun) <= 1) + if (number_of_loops (fun) <= 1) { loop_optimizer_finalize (); return 0; } - bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun)); - copied_bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun)); - bbs_size = n_basic_blocks_for_fn (cfun); + bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun)); + copied_bbs = XNEWVEC (basic_block, n_basic_blocks_for_fn (fun)); + bbs_size = n_basic_blocks_for_fn (fun); FOR_EACH_LOOP (loop, 0) { @@ -257,36 +287,6 @@ copy_loop_headers (void) return 0; } -namespace { - -const pass_data pass_data_ch = -{ - GIMPLE_PASS, /* type */ - "ch", /* name */ - OPTGROUP_LOOP, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_CH, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_cleanup_cfg | TODO_verify_ssa - | TODO_verify_flow ), /* todo_flags_finish */ -}; - -class pass_ch : public gimple_opt_pass -{ -public: - pass_ch (gcc::context *ctxt) - : gimple_opt_pass (pass_data_ch, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) { return flag_tree_ch != 0; } - unsigned int execute () { return copy_loop_headers (); } - -}; // class pass_ch - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c index f38ee95933b5..0b44c977fdd5 100644 --- a/gcc/tree-ssa-loop-im.c +++ b/gcc/tree-ssa-loop-im.c @@ -2529,15 +2529,6 @@ tree_ssa_lim (void) /* Loop invariant motion pass. */ -static unsigned int -tree_ssa_loop_im (void) -{ - if (number_of_loops (cfun) <= 1) - return 0; - - return tree_ssa_lim (); -} - namespace { const pass_data pass_data_lim = @@ -2564,10 +2555,19 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_lim (m_ctxt); } virtual bool gate (function *) { return flag_tree_loop_im != 0; } - unsigned int execute () { return tree_ssa_loop_im (); } + virtual unsigned int execute (function *); }; // class pass_lim +unsigned int +pass_lim::execute (function *fun) +{ + if (number_of_loops (fun) <= 1) + return 0; + + return tree_ssa_lim (); +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c index df8281602413..54ebe25c40de 100644 --- a/gcc/tree-ssa-loop-ivcanon.c +++ b/gcc/tree-ssa-loop-ivcanon.c @@ -1256,15 +1256,6 @@ tree_unroll_loops_completely (bool may_increase_size, bool unroll_outer) /* Canonical induction variable creation pass. */ -static unsigned int -tree_ssa_loop_ivcanon (void) -{ - if (number_of_loops (cfun) <= 1) - return 0; - - return canonicalize_induction_variables (); -} - namespace { const pass_data pass_data_iv_canon = @@ -1290,10 +1281,19 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_tree_loop_ivcanon != 0; } - unsigned int execute () { return tree_ssa_loop_ivcanon (); } + virtual unsigned int execute (function *fun); }; // class pass_iv_canon +unsigned int +pass_iv_canon::execute (function *fun) +{ + if (number_of_loops (fun) <= 1) + return 0; + + return canonicalize_induction_variables (); +} + } // anon namespace gimple_opt_pass * @@ -1304,17 +1304,6 @@ make_pass_iv_canon (gcc::context *ctxt) /* Complete unrolling of loops. */ -static unsigned int -tree_complete_unroll (void) -{ - if (number_of_loops (cfun) <= 1) - return 0; - - return tree_unroll_loops_completely (flag_unroll_loops - || flag_peel_loops - || optimize >= 3, true); -} - namespace { const pass_data pass_data_complete_unroll = @@ -1339,10 +1328,21 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return tree_complete_unroll (); } + virtual unsigned int execute (function *); }; // class pass_complete_unroll +unsigned int +pass_complete_unroll::execute (function *fun) +{ + if (number_of_loops (fun) <= 1) + return 0; + + return tree_unroll_loops_completely (flag_unroll_loops + || flag_peel_loops + || optimize >= 3, true); +} + } // anon namespace gimple_opt_pass * @@ -1353,25 +1353,6 @@ make_pass_complete_unroll (gcc::context *ctxt) /* Complete unrolling of inner loops. */ -static unsigned int -tree_complete_unroll_inner (void) -{ - unsigned ret = 0; - - loop_optimizer_init (LOOPS_NORMAL - | LOOPS_HAVE_RECORDED_EXITS); - if (number_of_loops (cfun) > 1) - { - scev_initialize (); - ret = tree_unroll_loops_completely (optimize >= 3, false); - free_numbers_of_iterations_estimates (); - scev_finalize (); - } - loop_optimizer_finalize (); - - return ret; -} - namespace { const pass_data pass_data_complete_unrolli = @@ -1397,10 +1378,29 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return optimize >= 2; } - unsigned int execute () { return tree_complete_unroll_inner (); } + virtual unsigned int execute (function *); }; // class pass_complete_unrolli +unsigned int +pass_complete_unrolli::execute (function *fun) +{ + unsigned ret = 0; + + loop_optimizer_init (LOOPS_NORMAL + | LOOPS_HAVE_RECORDED_EXITS); + if (number_of_loops (fun) > 1) + { + scev_initialize (); + ret = tree_unroll_loops_completely (optimize >= 3, false); + free_numbers_of_iterations_estimates (); + scev_finalize (); + } + loop_optimizer_finalize (); + + return ret; +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c index 17b13d11d71c..1cf650a71e0b 100644 --- a/gcc/tree-ssa-loop-prefetch.c +++ b/gcc/tree-ssa-loop-prefetch.c @@ -2004,15 +2004,6 @@ tree_ssa_prefetch_arrays (void) /* Prefetching. */ -static unsigned int -tree_ssa_loop_prefetch (void) -{ - if (number_of_loops (cfun) <= 1) - return 0; - - return tree_ssa_prefetch_arrays (); -} - namespace { const pass_data pass_data_loop_prefetch = @@ -2038,10 +2029,19 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_prefetch_loop_arrays > 0; } - unsigned int execute () { return tree_ssa_loop_prefetch (); } + virtual unsigned int execute (function *); }; // class pass_loop_prefetch +unsigned int +pass_loop_prefetch::execute (function *fun) +{ + if (number_of_loops (fun) <= 1) + return 0; + + return tree_ssa_prefetch_arrays (); +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c index 90bb205a5a6b..a9a27d7e7083 100644 --- a/gcc/tree-ssa-loop-unswitch.c +++ b/gcc/tree-ssa-loop-unswitch.c @@ -402,15 +402,6 @@ tree_unswitch_loop (struct loop *loop, /* Loop unswitching pass. */ -static unsigned int -tree_ssa_loop_unswitch (void) -{ - if (number_of_loops (cfun) <= 1) - return 0; - - return tree_ssa_unswitch_loops (); -} - namespace { const pass_data pass_data_tree_unswitch = @@ -436,10 +427,19 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_unswitch_loops != 0; } - unsigned int execute () { return tree_ssa_loop_unswitch (); } + virtual unsigned int execute (function *); }; // class pass_tree_unswitch +unsigned int +pass_tree_unswitch::execute (function *fun) +{ + if (number_of_loops (fun) <= 1) + return 0; + + return tree_ssa_unswitch_loops (); +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c index 38e7b13575c7..ccc812152cfc 100644 --- a/gcc/tree-ssa-loop.c +++ b/gcc/tree-ssa-loop.c @@ -82,23 +82,6 @@ make_pass_tree_loop (gcc::context *ctxt) /* Loop optimizer initialization. */ -static unsigned int -tree_ssa_loop_init (void) -{ - loop_optimizer_init (LOOPS_NORMAL - | LOOPS_HAVE_RECORDED_EXITS); - rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); - - /* We might discover new loops, e.g. when turning irreducible - regions into reducible. */ - scev_initialize (); - - if (number_of_loops (cfun) <= 1) - return 0; - - return 0; -} - namespace { const pass_data pass_data_tree_loop_init = @@ -123,10 +106,27 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return tree_ssa_loop_init (); } + virtual unsigned int execute (function *); }; // class pass_tree_loop_init +unsigned int +pass_tree_loop_init::execute (function *fun) +{ + loop_optimizer_init (LOOPS_NORMAL + | LOOPS_HAVE_RECORDED_EXITS); + rewrite_into_loop_closed_ssa (NULL, TODO_update_ssa); + + /* We might discover new loops, e.g. when turning irreducible + regions into reducible. */ + scev_initialize (); + + if (number_of_loops (fun) <= 1) + return 0; + + return 0; +} + } // anon namespace gimple_opt_pass * @@ -137,15 +137,6 @@ make_pass_tree_loop_init (gcc::context *ctxt) /* Loop autovectorization. */ -static unsigned int -tree_loop_vectorize (void) -{ - if (number_of_loops (cfun) <= 1) - return 0; - - return vectorize_loops (); -} - namespace { const pass_data pass_data_vectorize = @@ -175,10 +166,19 @@ public: return flag_tree_loop_vectorize || fun->has_force_vectorize_loops; } - unsigned int execute () { return tree_loop_vectorize (); } + virtual unsigned int execute (function *); }; // class pass_vectorize +unsigned int +pass_vectorize::execute (function *fun) +{ + if (number_of_loops (fun) <= 1) + return 0; + + return vectorize_loops (); +} + } // anon namespace gimple_opt_pass * @@ -189,16 +189,6 @@ make_pass_vectorize (gcc::context *ctxt) /* Check the correctness of the data dependence analyzers. */ -static unsigned int -check_data_deps (void) -{ - if (number_of_loops (cfun) <= 1) - return 0; - - tree_check_data_deps (); - return 0; -} - namespace { const pass_data pass_data_check_data_deps = @@ -224,10 +214,20 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_check_data_deps != 0; } - unsigned int execute () { return check_data_deps (); } + virtual unsigned int execute (function *); }; // class pass_check_data_deps +unsigned int +pass_check_data_deps::execute (function *fun) +{ + if (number_of_loops (fun) <= 1) + return 0; + + tree_check_data_deps (); + return 0; +} + } // anon namespace gimple_opt_pass * @@ -264,7 +264,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_tree_scev_cprop; } - unsigned int execute () { return scev_const_prop (); } + virtual unsigned int execute (function *) { return scev_const_prop (); } }; // class pass_scev_cprop @@ -278,17 +278,6 @@ make_pass_scev_cprop (gcc::context *ctxt) /* Record bounds on numbers of iterations of loops. */ -static unsigned int -tree_ssa_loop_bounds (void) -{ - if (number_of_loops (cfun) <= 1) - return 0; - - estimate_numbers_of_iterations (); - scev_reset (); - return 0; -} - namespace { const pass_data pass_data_record_bounds = @@ -313,10 +302,21 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return tree_ssa_loop_bounds (); } + virtual unsigned int execute (function *); }; // class pass_record_bounds +unsigned int +pass_record_bounds::execute (function *fun) +{ + if (number_of_loops (fun) <= 1) + return 0; + + estimate_numbers_of_iterations (); + scev_reset (); + return 0; +} + } // anon namespace gimple_opt_pass * @@ -327,16 +327,6 @@ make_pass_record_bounds (gcc::context *ctxt) /* Induction variable optimizations. */ -static unsigned int -tree_ssa_loop_ivopts (void) -{ - if (number_of_loops (cfun) <= 1) - return 0; - - tree_ssa_iv_optimize (); - return 0; -} - namespace { const pass_data pass_data_iv_optimize = @@ -362,10 +352,20 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_ivopts != 0; } - unsigned int execute () { return tree_ssa_loop_ivopts (); } + virtual unsigned int execute (function *); }; // class pass_iv_optimize +unsigned int +pass_iv_optimize::execute (function *fun) +{ + if (number_of_loops (fun) <= 1) + return 0; + + tree_ssa_iv_optimize (); + return 0; +} + } // anon namespace gimple_opt_pass * @@ -409,7 +409,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return tree_ssa_loop_done (); } + virtual unsigned int execute (function *) { return tree_ssa_loop_done (); } }; // class pass_tree_loop_done diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c index fef1b1e65986..b965ad1b7f36 100644 --- a/gcc/tree-ssa-math-opts.c +++ b/gcc/tree-ssa-math-opts.c @@ -506,35 +506,65 @@ execute_cse_reciprocals_1 (gimple_stmt_iterator *def_gsi, tree def) /* Go through all the floating-point SSA_NAMEs, and call execute_cse_reciprocals_1 on each of them. */ -static unsigned int -execute_cse_reciprocals (void) +namespace { + +const pass_data pass_data_cse_reciprocals = +{ + GIMPLE_PASS, /* type */ + "recip", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_NONE, /* tv_id */ + PROP_ssa, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_update_ssa | TODO_verify_ssa + | TODO_verify_stmts ), /* todo_flags_finish */ +}; + +class pass_cse_reciprocals : public gimple_opt_pass +{ +public: + pass_cse_reciprocals (gcc::context *ctxt) + : gimple_opt_pass (pass_data_cse_reciprocals, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) { return optimize && flag_reciprocal_math; } + virtual unsigned int execute (function *); + +}; // class pass_cse_reciprocals + +unsigned int +pass_cse_reciprocals::execute (function *fun) { basic_block bb; tree arg; occ_pool = create_alloc_pool ("dominators for recip", sizeof (struct occurrence), - n_basic_blocks_for_fn (cfun) / 3 + 1); + n_basic_blocks_for_fn (fun) / 3 + 1); memset (&reciprocal_stats, 0, sizeof (reciprocal_stats)); calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_POST_DOMINATORS); #ifdef ENABLE_CHECKING - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) gcc_assert (!bb->aux); #endif - for (arg = DECL_ARGUMENTS (cfun->decl); arg; arg = DECL_CHAIN (arg)) + for (arg = DECL_ARGUMENTS (fun->decl); arg; arg = DECL_CHAIN (arg)) if (FLOAT_TYPE_P (TREE_TYPE (arg)) && is_gimple_reg (arg)) { - tree name = ssa_default_def (cfun, arg); + tree name = ssa_default_def (fun, arg); if (name) execute_cse_reciprocals_1 (NULL, name); } - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { gimple_stmt_iterator gsi; gimple phi; @@ -636,9 +666,9 @@ execute_cse_reciprocals (void) } } - statistics_counter_event (cfun, "reciprocal divs inserted", + statistics_counter_event (fun, "reciprocal divs inserted", reciprocal_stats.rdivs_inserted); - statistics_counter_event (cfun, "reciprocal functions inserted", + statistics_counter_event (fun, "reciprocal functions inserted", reciprocal_stats.rfuncs_inserted); free_dominance_info (CDI_DOMINATORS); @@ -647,36 +677,6 @@ execute_cse_reciprocals (void) return 0; } -namespace { - -const pass_data pass_data_cse_reciprocals = -{ - GIMPLE_PASS, /* type */ - "recip", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_NONE, /* tv_id */ - PROP_ssa, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_update_ssa | TODO_verify_ssa - | TODO_verify_stmts ), /* todo_flags_finish */ -}; - -class pass_cse_reciprocals : public gimple_opt_pass -{ -public: - pass_cse_reciprocals (gcc::context *ctxt) - : gimple_opt_pass (pass_data_cse_reciprocals, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) { return optimize && flag_reciprocal_math; } - unsigned int execute () { return execute_cse_reciprocals (); } - -}; // class pass_cse_reciprocals - } // anon namespace gimple_opt_pass * @@ -1403,8 +1403,44 @@ gimple_expand_builtin_cabs (gimple_stmt_iterator *gsi, location_t loc, tree arg) on the SSA_NAME argument of each of them. Also expand powi(x,n) into an optimal number of multiplies, when n is a constant. */ -static unsigned int -execute_cse_sincos (void) +namespace { + +const pass_data pass_data_cse_sincos = +{ + GIMPLE_PASS, /* type */ + "sincos", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_NONE, /* tv_id */ + PROP_ssa, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_update_ssa | TODO_verify_ssa + | TODO_verify_stmts ), /* todo_flags_finish */ +}; + +class pass_cse_sincos : public gimple_opt_pass +{ +public: + pass_cse_sincos (gcc::context *ctxt) + : gimple_opt_pass (pass_data_cse_sincos, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) + { + /* We no longer require either sincos or cexp, since powi expansion + piggybacks on this pass. */ + return optimize; + } + + virtual unsigned int execute (function *); + +}; // class pass_cse_sincos + +unsigned int +pass_cse_sincos::execute (function *fun) { basic_block bb; bool cfg_changed = false; @@ -1412,7 +1448,7 @@ execute_cse_sincos (void) calculate_dominance_info (CDI_DOMINATORS); memset (&sincos_stats, 0, sizeof (sincos_stats)); - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { gimple_stmt_iterator gsi; bool cleanup_eh = false; @@ -1549,49 +1585,13 @@ execute_cse_sincos (void) cfg_changed |= gimple_purge_dead_eh_edges (bb); } - statistics_counter_event (cfun, "sincos statements inserted", + statistics_counter_event (fun, "sincos statements inserted", sincos_stats.inserted); free_dominance_info (CDI_DOMINATORS); return cfg_changed ? TODO_cleanup_cfg : 0; } -namespace { - -const pass_data pass_data_cse_sincos = -{ - GIMPLE_PASS, /* type */ - "sincos", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_NONE, /* tv_id */ - PROP_ssa, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_update_ssa | TODO_verify_ssa - | TODO_verify_stmts ), /* todo_flags_finish */ -}; - -class pass_cse_sincos : public gimple_opt_pass -{ -public: - pass_cse_sincos (gcc::context *ctxt) - : gimple_opt_pass (pass_data_cse_sincos, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) - { - /* We no longer require either sincos or cexp, since powi expansion - piggybacks on this pass. */ - return optimize; - } - - unsigned int execute () { return execute_cse_sincos (); } - -}; // class pass_cse_sincos - } // anon namespace gimple_opt_pass * @@ -1893,8 +1893,41 @@ find_bswap (gimple stmt) /* Find manual byte swap implementations and turn them into a bswap builtin invokation. */ -static unsigned int -execute_optimize_bswap (void) +namespace { + +const pass_data pass_data_optimize_bswap = +{ + GIMPLE_PASS, /* type */ + "bswap", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_NONE, /* tv_id */ + PROP_ssa, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_optimize_bswap : public gimple_opt_pass +{ +public: + pass_optimize_bswap (gcc::context *ctxt) + : gimple_opt_pass (pass_data_optimize_bswap, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) + { + return flag_expensive_optimizations && optimize; + } + + virtual unsigned int execute (function *); + +}; // class pass_optimize_bswap + +unsigned int +pass_optimize_bswap::execute (function *fun) { basic_block bb; bool bswap16_p, bswap32_p, bswap64_p; @@ -1940,7 +1973,7 @@ execute_optimize_bswap (void) memset (&bswap_stats, 0, sizeof (bswap_stats)); - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { gimple_stmt_iterator gsi; @@ -2046,50 +2079,17 @@ execute_optimize_bswap (void) } } - statistics_counter_event (cfun, "16-bit bswap implementations found", + statistics_counter_event (fun, "16-bit bswap implementations found", bswap_stats.found_16bit); - statistics_counter_event (cfun, "32-bit bswap implementations found", + statistics_counter_event (fun, "32-bit bswap implementations found", bswap_stats.found_32bit); - statistics_counter_event (cfun, "64-bit bswap implementations found", + statistics_counter_event (fun, "64-bit bswap implementations found", bswap_stats.found_64bit); return (changed ? TODO_update_ssa | TODO_verify_ssa | TODO_verify_stmts : 0); } -namespace { - -const pass_data pass_data_optimize_bswap = -{ - GIMPLE_PASS, /* type */ - "bswap", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_NONE, /* tv_id */ - PROP_ssa, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_optimize_bswap : public gimple_opt_pass -{ -public: - pass_optimize_bswap (gcc::context *ctxt) - : gimple_opt_pass (pass_data_optimize_bswap, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) - { - return flag_expensive_optimizations && optimize; - } - - unsigned int execute () { return execute_optimize_bswap (); } - -}; // class pass_optimize_bswap - } // anon namespace gimple_opt_pass * @@ -2775,15 +2775,49 @@ convert_mult_to_fma (gimple mul_stmt, tree op1, tree op2) smaller types, and replace the MULT_EXPR with a WIDEN_MULT_EXPR where appropriate. */ -static unsigned int -execute_optimize_widening_mul (void) +namespace { + +const pass_data pass_data_optimize_widening_mul = +{ + GIMPLE_PASS, /* type */ + "widening_mul", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_NONE, /* tv_id */ + PROP_ssa, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_verify_ssa | TODO_verify_stmts + | TODO_update_ssa ), /* todo_flags_finish */ +}; + +class pass_optimize_widening_mul : public gimple_opt_pass +{ +public: + pass_optimize_widening_mul (gcc::context *ctxt) + : gimple_opt_pass (pass_data_optimize_widening_mul, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) + { + return flag_expensive_optimizations && optimize; + } + + virtual unsigned int execute (function *); + +}; // class pass_optimize_widening_mul + +unsigned int +pass_optimize_widening_mul::execute (function *fun) { basic_block bb; bool cfg_changed = false; memset (&widen_mul_stats, 0, sizeof (widen_mul_stats)); - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { gimple_stmt_iterator gsi; @@ -2854,50 +2888,16 @@ execute_optimize_widening_mul (void) } } - statistics_counter_event (cfun, "widening multiplications inserted", + statistics_counter_event (fun, "widening multiplications inserted", widen_mul_stats.widen_mults_inserted); - statistics_counter_event (cfun, "widening maccs inserted", + statistics_counter_event (fun, "widening maccs inserted", widen_mul_stats.maccs_inserted); - statistics_counter_event (cfun, "fused multiply-adds inserted", + statistics_counter_event (fun, "fused multiply-adds inserted", widen_mul_stats.fmas_inserted); return cfg_changed ? TODO_cleanup_cfg : 0; } -namespace { - -const pass_data pass_data_optimize_widening_mul = -{ - GIMPLE_PASS, /* type */ - "widening_mul", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_NONE, /* tv_id */ - PROP_ssa, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_verify_ssa | TODO_verify_stmts - | TODO_update_ssa ), /* todo_flags_finish */ -}; - -class pass_optimize_widening_mul : public gimple_opt_pass -{ -public: - pass_optimize_widening_mul (gcc::context *ctxt) - : gimple_opt_pass (pass_data_optimize_widening_mul, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) - { - return flag_expensive_optimizations && optimize; - } - - unsigned int execute () { return execute_optimize_widening_mul (); } - -}; // class pass_optimize_widening_mul - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c index 1ee39a544420..9b5b563886db 100644 --- a/gcc/tree-ssa-phiopt.c +++ b/gcc/tree-ssa-phiopt.c @@ -59,7 +59,6 @@ along with GCC; see the file COPYING3. If not see #define HAVE_conditional_move (0) #endif -static unsigned int tree_ssa_phiopt (void); static unsigned int tree_ssa_phiopt_worker (bool, bool); static bool conditional_replacement (basic_block, basic_block, edge, edge, gimple, tree, tree); @@ -80,162 +79,6 @@ static void hoist_adjacent_loads (basic_block, basic_block, basic_block, basic_block); static bool gate_hoist_loads (void); -/* This pass tries to replaces an if-then-else block with an - assignment. We have four kinds of transformations. Some of these - transformations are also performed by the ifcvt RTL optimizer. - - Conditional Replacement - ----------------------- - - This transformation, implemented in conditional_replacement, - replaces - - bb0: - if (cond) goto bb2; else goto bb1; - bb1: - bb2: - x = PHI <0 (bb1), 1 (bb0), ...>; - - with - - bb0: - x' = cond; - goto bb2; - bb2: - x = PHI ; - - We remove bb1 as it becomes unreachable. This occurs often due to - gimplification of conditionals. - - Value Replacement - ----------------- - - This transformation, implemented in value_replacement, replaces - - bb0: - if (a != b) goto bb2; else goto bb1; - bb1: - bb2: - x = PHI ; - - with - - bb0: - bb2: - x = PHI ; - - This opportunity can sometimes occur as a result of other - optimizations. - - - Another case caught by value replacement looks like this: - - bb0: - t1 = a == CONST; - t2 = b > c; - t3 = t1 & t2; - if (t3 != 0) goto bb1; else goto bb2; - bb1: - bb2: - x = PHI (CONST, a) - - Gets replaced with: - bb0: - bb2: - t1 = a == CONST; - t2 = b > c; - t3 = t1 & t2; - x = a; - - ABS Replacement - --------------- - - This transformation, implemented in abs_replacement, replaces - - bb0: - if (a >= 0) goto bb2; else goto bb1; - bb1: - x = -a; - bb2: - x = PHI ; - - with - - bb0: - x' = ABS_EXPR< a >; - bb2: - x = PHI ; - - MIN/MAX Replacement - ------------------- - - This transformation, minmax_replacement replaces - - bb0: - if (a <= b) goto bb2; else goto bb1; - bb1: - bb2: - x = PHI ; - - with - - bb0: - x' = MIN_EXPR (a, b) - bb2: - x = PHI ; - - A similar transformation is done for MAX_EXPR. - - - This pass also performs a fifth transformation of a slightly different - flavor. - - Adjacent Load Hoisting - ---------------------- - - This transformation replaces - - bb0: - if (...) goto bb2; else goto bb1; - bb1: - x1 = ().field1; - goto bb3; - bb2: - x2 = ().field2; - bb3: - # x = PHI ; - - with - - bb0: - x1 = ().field1; - x2 = ().field2; - if (...) goto bb2; else goto bb1; - bb1: - goto bb3; - bb2: - bb3: - # x = PHI ; - - The purpose of this transformation is to enable generation of conditional - move instructions such as Intel CMOVE or PowerPC ISEL. Because one of - the loads is speculative, the transformation is restricted to very - specific cases to avoid introducing a page fault. We are looking for - the common idiom: - - if (...) - x = y->left; - else - x = y->right; - - where left and right are typically adjacent pointers in a tree structure. */ - -static unsigned int -tree_ssa_phiopt (void) -{ - return tree_ssa_phiopt_worker (false, gate_hoist_loads ()); -} - /* This pass tries to transform conditional stores into unconditional ones, enabling further simplifications with the simpler then and else blocks. In particular it replaces this: @@ -2200,8 +2043,155 @@ gate_hoist_loads (void) && HAVE_conditional_move); } -/* Always do these optimizations if we have SSA - trees to work on. */ +/* This pass tries to replaces an if-then-else block with an + assignment. We have four kinds of transformations. Some of these + transformations are also performed by the ifcvt RTL optimizer. + + Conditional Replacement + ----------------------- + + This transformation, implemented in conditional_replacement, + replaces + + bb0: + if (cond) goto bb2; else goto bb1; + bb1: + bb2: + x = PHI <0 (bb1), 1 (bb0), ...>; + + with + + bb0: + x' = cond; + goto bb2; + bb2: + x = PHI ; + + We remove bb1 as it becomes unreachable. This occurs often due to + gimplification of conditionals. + + Value Replacement + ----------------- + + This transformation, implemented in value_replacement, replaces + + bb0: + if (a != b) goto bb2; else goto bb1; + bb1: + bb2: + x = PHI ; + + with + + bb0: + bb2: + x = PHI ; + + This opportunity can sometimes occur as a result of other + optimizations. + + + Another case caught by value replacement looks like this: + + bb0: + t1 = a == CONST; + t2 = b > c; + t3 = t1 & t2; + if (t3 != 0) goto bb1; else goto bb2; + bb1: + bb2: + x = PHI (CONST, a) + + Gets replaced with: + bb0: + bb2: + t1 = a == CONST; + t2 = b > c; + t3 = t1 & t2; + x = a; + + ABS Replacement + --------------- + + This transformation, implemented in abs_replacement, replaces + + bb0: + if (a >= 0) goto bb2; else goto bb1; + bb1: + x = -a; + bb2: + x = PHI ; + + with + + bb0: + x' = ABS_EXPR< a >; + bb2: + x = PHI ; + + MIN/MAX Replacement + ------------------- + + This transformation, minmax_replacement replaces + + bb0: + if (a <= b) goto bb2; else goto bb1; + bb1: + bb2: + x = PHI ; + + with + + bb0: + x' = MIN_EXPR (a, b) + bb2: + x = PHI ; + + A similar transformation is done for MAX_EXPR. + + + This pass also performs a fifth transformation of a slightly different + flavor. + + Adjacent Load Hoisting + ---------------------- + + This transformation replaces + + bb0: + if (...) goto bb2; else goto bb1; + bb1: + x1 = ().field1; + goto bb3; + bb2: + x2 = ().field2; + bb3: + # x = PHI ; + + with + + bb0: + x1 = ().field1; + x2 = ().field2; + if (...) goto bb2; else goto bb1; + bb1: + goto bb3; + bb2: + bb3: + # x = PHI ; + + The purpose of this transformation is to enable generation of conditional + move instructions such as Intel CMOVE or PowerPC ISEL. Because one of + the loads is speculative, the transformation is restricted to very + specific cases to avoid introducing a page fault. We are looking for + the common idiom: + + if (...) + x = y->left; + else + x = y->right; + + where left and right are typically adjacent pointers in a tree structure. */ namespace { @@ -2229,7 +2219,10 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_phiopt (m_ctxt); } - unsigned int execute () { return tree_ssa_phiopt (); } + virtual unsigned int execute (function *) + { + return tree_ssa_phiopt_worker (false, gate_hoist_loads ()); + } }; // class pass_phiopt @@ -2267,7 +2260,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_tree_cselim; } - unsigned int execute () { return tree_ssa_cs_elim (); } + virtual unsigned int execute (function *) { return tree_ssa_cs_elim (); } }; // class pass_cselim diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c index cbdbc6ea4295..0154b47af742 100644 --- a/gcc/tree-ssa-phiprop.c +++ b/gcc/tree-ssa-phiprop.c @@ -374,8 +374,37 @@ next:; /* Main entry for phiprop pass. */ -static unsigned int -tree_ssa_phiprop (void) +namespace { + +const pass_data pass_data_phiprop = +{ + GIMPLE_PASS, /* type */ + "phiprop", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_PHIPROP, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */ +}; + +class pass_phiprop : public gimple_opt_pass +{ +public: + pass_phiprop (gcc::context *ctxt) + : gimple_opt_pass (pass_data_phiprop, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) { return flag_tree_phiprop; } + virtual unsigned int execute (function *); + +}; // class pass_phiprop + +unsigned int +pass_phiprop::execute (function *fun) { vec bbs; struct phiprop_d *phivn; @@ -393,7 +422,7 @@ tree_ssa_phiprop (void) /* Walk the dominator tree in preorder. */ bbs = get_all_dominated_blocks (CDI_DOMINATORS, - single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun))); + single_succ (ENTRY_BLOCK_PTR_FOR_FN (fun))); FOR_EACH_VEC_ELT (bbs, i, bb) for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) did_something |= propagate_with_phi (bb, gsi_stmt (gsi), phivn, n); @@ -409,35 +438,6 @@ tree_ssa_phiprop (void) return 0; } -namespace { - -const pass_data pass_data_phiprop = -{ - GIMPLE_PASS, /* type */ - "phiprop", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_PHIPROP, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */ -}; - -class pass_phiprop : public gimple_opt_pass -{ -public: - pass_phiprop (gcc::context *ctxt) - : gimple_opt_pass (pass_data_phiprop, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) { return flag_tree_phiprop; } - unsigned int execute () { return tree_ssa_phiprop (); } - -}; // class pass_phiprop - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index cda315a63792..b5785d88c544 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -4690,15 +4690,44 @@ fini_pre () free_dominance_info (CDI_POST_DOMINATORS); } -/* Gate and execute functions for PRE. */ +namespace { -static unsigned int -do_pre (void) +const pass_data pass_data_pre = +{ + GIMPLE_PASS, /* type */ + "pre", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_PRE, /* tv_id */ + /* PROP_no_crit_edges is ensured by placing pass_split_crit_edges before + pass_pre. */ + ( PROP_no_crit_edges | PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + PROP_no_crit_edges, /* properties_destroyed */ + TODO_rebuild_alias, /* todo_flags_start */ + TODO_verify_ssa, /* todo_flags_finish */ +}; + +class pass_pre : public gimple_opt_pass +{ +public: + pass_pre (gcc::context *ctxt) + : gimple_opt_pass (pass_data_pre, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) { return flag_tree_pre != 0; } + virtual unsigned int execute (function *); + +}; // class pass_pre + +unsigned int +pass_pre::execute (function *fun) { unsigned int todo = 0; do_partial_partial = - flag_tree_partial_pre && optimize_function_for_speed_p (cfun); + flag_tree_partial_pre && optimize_function_for_speed_p (fun); /* This has to happen before SCCVN runs because loop_optimizer_init may create new phis, etc. */ @@ -4721,7 +4750,7 @@ do_pre (void) fixed, don't run it when he have an incredibly large number of bb's. If we aren't going to run insert, there is no point in computing ANTIC, either, even though it's plenty fast. */ - if (n_basic_blocks_for_fn (cfun) < 4000) + if (n_basic_blocks_for_fn (fun) < 4000) { compute_antic (); insert (); @@ -4736,10 +4765,10 @@ do_pre (void) /* Remove all the redundant expressions. */ todo |= eliminate (); - statistics_counter_event (cfun, "Insertions", pre_stats.insertions); - statistics_counter_event (cfun, "PA inserted", pre_stats.pa_insert); - statistics_counter_event (cfun, "New PHIs", pre_stats.phis); - statistics_counter_event (cfun, "Eliminated", pre_stats.eliminations); + statistics_counter_event (fun, "Insertions", pre_stats.insertions); + statistics_counter_event (fun, "PA inserted", pre_stats.pa_insert); + statistics_counter_event (fun, "New PHIs", pre_stats.phis); + statistics_counter_event (fun, "Eliminated", pre_stats.eliminations); clear_expression_ids (); remove_dead_inserted_code (); @@ -4771,37 +4800,6 @@ do_pre (void) return todo; } -namespace { - -const pass_data pass_data_pre = -{ - GIMPLE_PASS, /* type */ - "pre", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_PRE, /* tv_id */ - /* PROP_no_crit_edges is ensured by placing pass_split_crit_edges before - pass_pre. */ - ( PROP_no_crit_edges | PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - PROP_no_crit_edges, /* properties_destroyed */ - TODO_rebuild_alias, /* todo_flags_start */ - TODO_verify_ssa, /* todo_flags_finish */ -}; - -class pass_pre : public gimple_opt_pass -{ -public: - pass_pre (gcc::context *ctxt) - : gimple_opt_pass (pass_data_pre, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) { return flag_tree_pre != 0; } - unsigned int execute () { return do_pre (); } - -}; // class pass_pre - } // anon namespace gimple_opt_pass * @@ -4810,32 +4808,6 @@ make_pass_pre (gcc::context *ctxt) return new pass_pre (ctxt); } - -/* Gate and execute functions for FRE. */ - -static unsigned int -execute_fre (void) -{ - unsigned int todo = 0; - - if (!run_scc_vn (VN_WALKREWRITE)) - return 0; - - memset (&pre_stats, 0, sizeof (pre_stats)); - - /* Remove all the redundant expressions. */ - todo |= eliminate (); - - todo |= fini_eliminate (); - - free_scc_vn (); - - statistics_counter_event (cfun, "Insertions", pre_stats.insertions); - statistics_counter_event (cfun, "Eliminated", pre_stats.eliminations); - - return todo; -} - namespace { const pass_data pass_data_fre = @@ -4862,10 +4834,33 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_fre (m_ctxt); } virtual bool gate (function *) { return flag_tree_fre != 0; } - unsigned int execute () { return execute_fre (); } + virtual unsigned int execute (function *); }; // class pass_fre +unsigned int +pass_fre::execute (function *fun) +{ + unsigned int todo = 0; + + if (!run_scc_vn (VN_WALKREWRITE)) + return 0; + + memset (&pre_stats, 0, sizeof (pre_stats)); + + /* Remove all the redundant expressions. */ + todo |= eliminate (); + + todo |= fini_eliminate (); + + free_scc_vn (); + + statistics_counter_event (fun, "Insertions", pre_stats.insertions); + statistics_counter_event (fun, "Eliminated", pre_stats.eliminations); + + return todo; +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c index 57f260775d71..0ea04a3bbbe9 100644 --- a/gcc/tree-ssa-reassoc.c +++ b/gcc/tree-ssa-reassoc.c @@ -4722,7 +4722,7 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_reassoc (m_ctxt); } virtual bool gate (function *) { return flag_tree_reassoc != 0; } - unsigned int execute () { return execute_reassoc (); } + virtual unsigned int execute (function *) { return execute_reassoc (); } }; // class pass_reassoc diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c index 6803160ff774..7992ced11dc6 100644 --- a/gcc/tree-ssa-sink.c +++ b/gcc/tree-ssa-sink.c @@ -563,31 +563,6 @@ sink_code_in_bb (basic_block bb) Note that this reduces the number of computations of a = b + c to 1 when we take the else edge, instead of 2. */ -static void -execute_sink_code (void) -{ - loop_optimizer_init (LOOPS_NORMAL); - split_critical_edges (); - connect_infinite_loops_to_exit (); - memset (&sink_stats, 0, sizeof (sink_stats)); - calculate_dominance_info (CDI_DOMINATORS); - calculate_dominance_info (CDI_POST_DOMINATORS); - sink_code_in_bb (EXIT_BLOCK_PTR_FOR_FN (cfun)); - statistics_counter_event (cfun, "Sunk statements", sink_stats.sunk); - free_dominance_info (CDI_POST_DOMINATORS); - remove_fake_exit_edges (); - loop_optimizer_finalize (); -} - -/* Gate and execute functions for PRE. */ - -static unsigned int -do_sink (void) -{ - execute_sink_code (); - return 0; -} - namespace { const pass_data pass_data_sink_code = @@ -598,7 +573,7 @@ const pass_data pass_data_sink_code = true, /* has_execute */ TV_TREE_SINK, /* tv_id */ /* PROP_no_crit_edges is ensured by running split_critical_edges in - execute_sink_code. */ + pass_data_sink_code::execute (). */ ( PROP_cfg | PROP_ssa ), /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ @@ -616,10 +591,28 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_tree_sink != 0; } - unsigned int execute () { return do_sink (); } + virtual unsigned int execute (function *); }; // class pass_sink_code +unsigned int +pass_sink_code::execute (function *fun) +{ + loop_optimizer_init (LOOPS_NORMAL); + split_critical_edges (); + connect_infinite_loops_to_exit (); + memset (&sink_stats, 0, sizeof (sink_stats)); + calculate_dominance_info (CDI_DOMINATORS); + calculate_dominance_info (CDI_POST_DOMINATORS); + sink_code_in_bb (EXIT_BLOCK_PTR_FOR_FN (fun)); + statistics_counter_event (fun, "Sunk statements", sink_stats.sunk); + free_dominance_info (CDI_POST_DOMINATORS); + remove_fake_exit_edges (); + loop_optimizer_finalize (); + + return 0; +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index fb83093cca5a..1cc36d81e362 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -2061,34 +2061,6 @@ strlen_dom_walker::after_dom_children (basic_block bb) /* Main entry point. */ -static unsigned int -tree_ssa_strlen (void) -{ - ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names); - max_stridx = 1; - strinfo_pool = create_alloc_pool ("strinfo_struct pool", - sizeof (struct strinfo_struct), 64); - - calculate_dominance_info (CDI_DOMINATORS); - - /* String length optimization is implemented as a walk of the dominator - tree and a forward walk of statements within each block. */ - strlen_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr); - - ssa_ver_to_stridx.release (); - free_alloc_pool (strinfo_pool); - if (decl_to_stridxlist_htab.is_created ()) - { - obstack_free (&stridx_obstack, NULL); - decl_to_stridxlist_htab.dispose (); - } - laststmt.stmt = NULL; - laststmt.len = NULL_TREE; - laststmt.stridx = 0; - - return 0; -} - namespace { const pass_data pass_data_strlen = @@ -2114,10 +2086,38 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_optimize_strlen != 0; } - unsigned int execute () { return tree_ssa_strlen (); } + virtual unsigned int execute (function *); }; // class pass_strlen +unsigned int +pass_strlen::execute (function *fun) +{ + ssa_ver_to_stridx.safe_grow_cleared (num_ssa_names); + max_stridx = 1; + strinfo_pool = create_alloc_pool ("strinfo_struct pool", + sizeof (struct strinfo_struct), 64); + + calculate_dominance_info (CDI_DOMINATORS); + + /* String length optimization is implemented as a walk of the dominator + tree and a forward walk of statements within each block. */ + strlen_dom_walker (CDI_DOMINATORS).walk (fun->cfg->x_entry_block_ptr); + + ssa_ver_to_stridx.release (); + free_alloc_pool (strinfo_pool); + if (decl_to_stridxlist_htab.is_created ()) + { + obstack_free (&stridx_obstack, NULL); + decl_to_stridxlist_htab.dispose (); + } + laststmt.stmt = NULL; + laststmt.len = NULL_TREE; + laststmt.stridx = 0; + + return 0; +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index 3548ac544b77..2686ba69ff42 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -7444,7 +7444,7 @@ public: && !seen_error ()); } - unsigned int execute () { return ipa_pta_execute (); } + virtual unsigned int execute (function *) { return ipa_pta_execute (); } }; // class pass_ipa_pta diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c index e39ce8898136..52c568a749a2 100644 --- a/gcc/tree-ssa-uncprop.c +++ b/gcc/tree-ssa-uncprop.c @@ -383,47 +383,6 @@ private: auto_vec m_equiv_stack; }; -/* Main driver for un-cprop. */ - -static unsigned int -tree_ssa_uncprop (void) -{ - basic_block bb; - - associate_equivalences_with_edges (); - - /* Create our global data structures. */ - val_ssa_equiv.create (1024); - - /* We're going to do a dominator walk, so ensure that we have - dominance information. */ - calculate_dominance_info (CDI_DOMINATORS); - - /* Recursively walk the dominator tree undoing unprofitable - constant/copy propagations. */ - uncprop_dom_walker (CDI_DOMINATORS).walk (cfun->cfg->x_entry_block_ptr); - - /* we just need to empty elements out of the hash table, and cleanup the - AUX field on the edges. */ - val_ssa_equiv.dispose (); - FOR_EACH_BB_FN (bb, cfun) - { - edge e; - edge_iterator ei; - - FOR_EACH_EDGE (e, ei, bb->succs) - { - if (e->aux) - { - free (e->aux); - e->aux = NULL; - } - } - } - return 0; -} - - /* We have finished processing the dominator children of BB, perform any finalization actions in preparation for leaving this node in the dominator tree. */ @@ -607,10 +566,48 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_uncprop (m_ctxt); } virtual bool gate (function *) { return flag_tree_dom != 0; } - unsigned int execute () { return tree_ssa_uncprop (); } + virtual unsigned int execute (function *); }; // class pass_uncprop +unsigned int +pass_uncprop::execute (function *fun) +{ + basic_block bb; + + associate_equivalences_with_edges (); + + /* Create our global data structures. */ + val_ssa_equiv.create (1024); + + /* We're going to do a dominator walk, so ensure that we have + dominance information. */ + calculate_dominance_info (CDI_DOMINATORS); + + /* Recursively walk the dominator tree undoing unprofitable + constant/copy propagations. */ + uncprop_dom_walker (CDI_DOMINATORS).walk (fun->cfg->x_entry_block_ptr); + + /* we just need to empty elements out of the hash table, and cleanup the + AUX field on the edges. */ + val_ssa_equiv.dispose (); + FOR_EACH_BB_FN (bb, fun) + { + edge e; + edge_iterator ei; + + FOR_EACH_EDGE (e, ei, bb->succs) + { + if (e->aux) + { + free (e->aux); + e->aux = NULL; + } + } + } + return 0; +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c index 89acd9b6b4b2..ae251ccd6ba8 100644 --- a/gcc/tree-ssa-uninit.c +++ b/gcc/tree-ssa-uninit.c @@ -2281,11 +2281,44 @@ warn_uninitialized_phi (gimple phi, vec *worklist, } +static bool +gate_warn_uninitialized (void) +{ + return warn_uninitialized || warn_maybe_uninitialized; +} -/* Entry point to the late uninitialized warning pass. */ +namespace { -static unsigned int -execute_late_warn_uninitialized (void) +const pass_data pass_data_late_warn_uninitialized = +{ + GIMPLE_PASS, /* type */ + "uninit", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_NONE, /* tv_id */ + PROP_ssa, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_late_warn_uninitialized : public gimple_opt_pass +{ +public: + pass_late_warn_uninitialized (gcc::context *ctxt) + : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt) + {} + + /* opt_pass methods: */ + opt_pass * clone () { return new pass_late_warn_uninitialized (m_ctxt); } + virtual bool gate (function *) { return gate_warn_uninitialized (); } + virtual unsigned int execute (function *); + +}; // class pass_late_warn_uninitialized + +unsigned int +pass_late_warn_uninitialized::execute (function *fun) { basic_block bb; gimple_stmt_iterator gsi; @@ -2305,34 +2338,34 @@ execute_late_warn_uninitialized (void) added_to_worklist = pointer_set_create (); /* Initialize worklist */ - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi)) { - gimple phi = gsi_stmt (gsi); - size_t n, i; - - n = gimple_phi_num_args (phi); - - /* Don't look at virtual operands. */ - if (virtual_operand_p (gimple_phi_result (phi))) - continue; - - for (i = 0; i < n; ++i) - { - tree op = gimple_phi_arg_def (phi, i); - if (TREE_CODE (op) == SSA_NAME - && uninit_undefined_value_p (op)) - { - worklist.safe_push (phi); + gimple phi = gsi_stmt (gsi); + size_t n, i; + + n = gimple_phi_num_args (phi); + + /* Don't look at virtual operands. */ + if (virtual_operand_p (gimple_phi_result (phi))) + continue; + + for (i = 0; i < n; ++i) + { + tree op = gimple_phi_arg_def (phi, i); + if (TREE_CODE (op) == SSA_NAME + && uninit_undefined_value_p (op)) + { + worklist.safe_push (phi); pointer_set_insert (added_to_worklist, phi); - if (dump_file && (dump_flags & TDF_DETAILS)) - { - fprintf (dump_file, "[WORKLIST]: add to initial list: "); - print_gimple_stmt (dump_file, phi, 0, 0); - } - break; - } - } + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fprintf (dump_file, "[WORKLIST]: add to initial list: "); + print_gimple_stmt (dump_file, phi, 0, 0); + } + break; + } + } } while (worklist.length () != 0) @@ -2351,42 +2384,6 @@ execute_late_warn_uninitialized (void) return 0; } -static bool -gate_warn_uninitialized (void) -{ - return warn_uninitialized || warn_maybe_uninitialized; -} - -namespace { - -const pass_data pass_data_late_warn_uninitialized = -{ - GIMPLE_PASS, /* type */ - "uninit", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_NONE, /* tv_id */ - PROP_ssa, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_late_warn_uninitialized : public gimple_opt_pass -{ -public: - pass_late_warn_uninitialized (gcc::context *ctxt) - : gimple_opt_pass (pass_data_late_warn_uninitialized, ctxt) - {} - - /* opt_pass methods: */ - opt_pass * clone () { return new pass_late_warn_uninitialized (m_ctxt); } - virtual bool gate (function *) { return gate_warn_uninitialized (); } - unsigned int execute () { return execute_late_warn_uninitialized (); } - -}; // class pass_late_warn_uninitialized - } // anon namespace gimple_opt_pass * @@ -2441,7 +2438,10 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return gate_warn_uninitialized (); } - unsigned int execute () { return execute_early_warn_uninitialized (); } + virtual unsigned int execute (function *) + { + return execute_early_warn_uninitialized (); + } }; // class pass_early_warn_uninitialized diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c index 52126ca07105..1ea639d9f42b 100644 --- a/gcc/tree-ssa.c +++ b/gcc/tree-ssa.c @@ -1169,7 +1169,10 @@ public: return !(fun->curr_properties & PROP_ssa); } - unsigned int execute () { return execute_init_datastructures (); } + virtual unsigned int execute (function *) + { + return execute_init_datastructures (); + } }; // class pass_init_datastructures diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c index b18b688ff600..02db6a5627d9 100644 --- a/gcc/tree-ssanames.c +++ b/gcc/tree-ssanames.c @@ -569,39 +569,6 @@ replace_ssa_name_symbol (tree ssa_name, tree sym) /* Return SSA names that are unused to GGC memory and compact the SSA version namespace. This is used to keep footprint of compiler during interprocedural optimization. */ -static unsigned int -release_dead_ssa_names (void) -{ - unsigned i, j; - int n = vec_safe_length (FREE_SSANAMES (cfun)); - - /* Now release the freelist. */ - vec_free (FREE_SSANAMES (cfun)); - - /* And compact the SSA number space. We make sure to not change the - relative order of SSA versions. */ - for (i = 1, j = 1; i < cfun->gimple_df->ssa_names->length (); ++i) - { - tree name = ssa_name (i); - if (name) - { - if (i != j) - { - SSA_NAME_VERSION (name) = j; - (*cfun->gimple_df->ssa_names)[j] = name; - } - j++; - } - } - cfun->gimple_df->ssa_names->truncate (j); - - statistics_counter_event (cfun, "SSA names released", n); - statistics_counter_event (cfun, "SSA name holes removed", i - j); - if (dump_file) - fprintf (dump_file, "Released %i names, %.2f%%, removed %i holes\n", - n, n * 100.0 / num_ssa_names, i - j); - return 0; -} namespace { @@ -627,10 +594,44 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return release_dead_ssa_names (); } + virtual unsigned int execute (function *); }; // class pass_release_ssa_names +unsigned int +pass_release_ssa_names::execute (function *fun) +{ + unsigned i, j; + int n = vec_safe_length (FREE_SSANAMES (fun)); + + /* Now release the freelist. */ + vec_free (FREE_SSANAMES (fun)); + + /* And compact the SSA number space. We make sure to not change the + relative order of SSA versions. */ + for (i = 1, j = 1; i < fun->gimple_df->ssa_names->length (); ++i) + { + tree name = ssa_name (i); + if (name) + { + if (i != j) + { + SSA_NAME_VERSION (name) = j; + (*fun->gimple_df->ssa_names)[j] = name; + } + j++; + } + } + fun->gimple_df->ssa_names->truncate (j); + + statistics_counter_event (fun, "SSA names released", n); + statistics_counter_event (fun, "SSA name holes removed", i - j); + if (dump_file) + fprintf (dump_file, "Released %i names, %.2f%%, removed %i holes\n", + n, n * 100.0 / num_ssa_names, i - j); + return 0; +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c index 710711bcda6a..1cdf0edd82b2 100644 --- a/gcc/tree-stdarg.c +++ b/gcc/tree-stdarg.c @@ -663,10 +663,43 @@ check_all_va_list_escapes (struct stdarg_info *si) return false; } -/* Entry point to the stdarg optimization pass. */ -static unsigned int -execute_optimize_stdarg (void) +namespace { + +const pass_data pass_data_stdarg = +{ + GIMPLE_PASS, /* type */ + "stdarg", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_NONE, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_stdarg : public gimple_opt_pass +{ +public: + pass_stdarg (gcc::context *ctxt) + : gimple_opt_pass (pass_data_stdarg, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *fun) + { + /* This optimization is only for stdarg functions. */ + return fun->stdarg != 0; + } + + virtual unsigned int execute (function *); + +}; // class pass_stdarg + +unsigned int +pass_stdarg::execute (function *fun) { basic_block bb; bool va_list_escapes = false; @@ -676,8 +709,8 @@ execute_optimize_stdarg (void) const char *funcname = NULL; tree cfun_va_list; - cfun->va_list_gpr_size = 0; - cfun->va_list_fpr_size = 0; + fun->va_list_gpr_size = 0; + fun->va_list_fpr_size = 0; memset (&si, 0, sizeof (si)); si.va_list_vars = BITMAP_ALLOC (NULL); si.va_list_escape_vars = BITMAP_ALLOC (NULL); @@ -685,13 +718,13 @@ execute_optimize_stdarg (void) if (dump_file) funcname = lang_hooks.decl_printable_name (current_function_decl, 2); - cfun_va_list = targetm.fn_abi_va_list (cfun->decl); + cfun_va_list = targetm.fn_abi_va_list (fun->decl); va_list_simple_ptr = POINTER_TYPE_P (cfun_va_list) && (TREE_TYPE (cfun_va_list) == void_type_node || TREE_TYPE (cfun_va_list) == char_type_node); gcc_assert (is_gimple_reg_type (cfun_va_list) == va_list_simple_ptr); - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { gimple_stmt_iterator i; @@ -740,7 +773,7 @@ execute_optimize_stdarg (void) ap = TREE_OPERAND (ap, 0); } if (TYPE_MAIN_VARIANT (TREE_TYPE (ap)) - != TYPE_MAIN_VARIANT (targetm.fn_abi_va_list (cfun->decl)) + != TYPE_MAIN_VARIANT (targetm.fn_abi_va_list (fun->decl)) || TREE_CODE (ap) != VAR_DECL) { va_list_escapes = true; @@ -795,13 +828,13 @@ execute_optimize_stdarg (void) /* For void * or char * va_list there is just one counter (va_list itself). Use VA_LIST_GPR_SIZE for it. */ if (va_list_simple_ptr) - cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE; + fun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE; calculate_dominance_info (CDI_DOMINATORS); memset (&wi, 0, sizeof (wi)); wi.info = si.va_list_vars; - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { gimple_stmt_iterator i; @@ -962,8 +995,8 @@ execute_optimize_stdarg (void) finish: if (va_list_escapes) { - cfun->va_list_gpr_size = VA_LIST_MAX_GPR_SIZE; - cfun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE; + fun->va_list_gpr_size = VA_LIST_MAX_GPR_SIZE; + fun->va_list_fpr_size = VA_LIST_MAX_FPR_SIZE; } BITMAP_FREE (si.va_list_vars); BITMAP_FREE (si.va_list_escape_vars); @@ -972,12 +1005,12 @@ finish: { fprintf (dump_file, "%s: va_list escapes %d, needs to save ", funcname, (int) va_list_escapes); - if (cfun->va_list_gpr_size >= VA_LIST_MAX_GPR_SIZE) + if (fun->va_list_gpr_size >= VA_LIST_MAX_GPR_SIZE) fputs ("all", dump_file); else fprintf (dump_file, "%d", cfun->va_list_gpr_size); fputs (" GPR units and ", dump_file); - if (cfun->va_list_fpr_size >= VA_LIST_MAX_FPR_SIZE) + if (fun->va_list_fpr_size >= VA_LIST_MAX_FPR_SIZE) fputs ("all", dump_file); else fprintf (dump_file, "%d", cfun->va_list_fpr_size); @@ -986,41 +1019,6 @@ finish: return 0; } - -namespace { - -const pass_data pass_data_stdarg = -{ - GIMPLE_PASS, /* type */ - "stdarg", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_NONE, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - 0, /* todo_flags_finish */ -}; - -class pass_stdarg : public gimple_opt_pass -{ -public: - pass_stdarg (gcc::context *ctxt) - : gimple_opt_pass (pass_data_stdarg, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *fun) - { - /* This optimization is only for stdarg functions. */ - return fun->stdarg != 0; - } - - unsigned int execute () { return execute_optimize_stdarg (); } - -}; // class pass_stdarg - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c index a0f9d19c0737..34edc64baee8 100644 --- a/gcc/tree-switch-conversion.c +++ b/gcc/tree-switch-conversion.c @@ -1414,12 +1414,43 @@ process_switch (gimple swtch) /* The main function of the pass scans statements for switches and invokes process_switch on them. */ -static unsigned int -do_switchconv (void) +namespace { + +const pass_data pass_data_convert_switch = +{ + GIMPLE_PASS, /* type */ + "switchconv", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_SWITCH_CONVERSION, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_update_ssa | TODO_verify_ssa + | TODO_verify_stmts + | TODO_verify_flow ), /* todo_flags_finish */ +}; + +class pass_convert_switch : public gimple_opt_pass +{ +public: + pass_convert_switch (gcc::context *ctxt) + : gimple_opt_pass (pass_data_convert_switch, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) { return flag_tree_switch_conversion != 0; } + virtual unsigned int execute (function *); + +}; // class pass_convert_switch + +unsigned int +pass_convert_switch::execute (function *fun) { basic_block bb; - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { const char *failure_reason; gimple stmt = last_stmt (bb); @@ -1465,37 +1496,6 @@ do_switchconv (void) return 0; } -namespace { - -const pass_data pass_data_convert_switch = -{ - GIMPLE_PASS, /* type */ - "switchconv", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_SWITCH_CONVERSION, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_update_ssa | TODO_verify_ssa - | TODO_verify_stmts - | TODO_verify_flow ), /* todo_flags_finish */ -}; - -class pass_convert_switch : public gimple_opt_pass -{ -public: - pass_convert_switch (gcc::context *ctxt) - : gimple_opt_pass (pass_data_convert_switch, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) { return flag_tree_switch_conversion != 0; } - unsigned int execute () { return do_switchconv (); } - -}; // class pass_convert_switch - } // anon namespace gimple_opt_pass * diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index 84cdbde94118..11a29659bc5b 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -1065,12 +1065,6 @@ tree_optimize_tail_calls_1 (bool opt_tailcalls) return 0; } -static unsigned int -execute_tail_recursion (void) -{ - return tree_optimize_tail_calls_1 (false); -} - static bool gate_tail_calls (void) { @@ -1109,7 +1103,10 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_tail_recursion (m_ctxt); } virtual bool gate (function *) { return gate_tail_calls (); } - unsigned int execute () { return execute_tail_recursion (); } + virtual unsigned int execute (function *) + { + return tree_optimize_tail_calls_1 (false); + } }; // class pass_tail_recursion @@ -1146,7 +1143,7 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return gate_tail_calls (); } - unsigned int execute () { return execute_tail_calls (); } + virtual unsigned int execute (function *) { return execute_tail_calls (); } }; // class pass_tail_calls diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c index 4274417bd6b2..d8b220001661 100644 --- a/gcc/tree-vect-generic.c +++ b/gcc/tree-vect-generic.c @@ -1585,7 +1585,10 @@ public: return !(fun->curr_properties & PROP_gimple_lvec); } - unsigned int execute () { return expand_vector_operations (); } + virtual unsigned int execute (function *) + { + return expand_vector_operations (); + } }; // class pass_lower_vector @@ -1625,7 +1628,10 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_lower_vector_ssa (m_ctxt); } - unsigned int execute () { return expand_vector_operations (); } + virtual unsigned int execute (function *) + { + return expand_vector_operations (); + } }; // class pass_lower_vector_ssa diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c index 7b5691a3464a..d7de964fa377 100644 --- a/gcc/tree-vectorizer.c +++ b/gcc/tree-vectorizer.c @@ -586,33 +586,6 @@ vectorize_loops (void) /* Entry point to basic block SLP phase. */ -static unsigned int -execute_vect_slp (void) -{ - basic_block bb; - - init_stmt_vec_info_vec (); - - FOR_EACH_BB_FN (bb, cfun) - { - vect_location = find_bb_location (bb); - - if (vect_slp_analyze_bb (bb)) - { - if (!dbg_cnt (vect_slp)) - break; - - vect_slp_transform_bb (bb); - if (dump_enabled_p ()) - dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location, - "basic block vectorized\n"); - } - } - - free_stmt_vec_info_vec (); - return 0; -} - namespace { const pass_data pass_data_slp_vectorize = @@ -639,10 +612,37 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return flag_tree_slp_vectorize != 0; } - unsigned int execute () { return execute_vect_slp (); } + virtual unsigned int execute (function *); }; // class pass_slp_vectorize +unsigned int +pass_slp_vectorize::execute (function *fun) +{ + basic_block bb; + + init_stmt_vec_info_vec (); + + FOR_EACH_BB_FN (bb, fun) + { + vect_location = find_bb_location (bb); + + if (vect_slp_analyze_bb (bb)) + { + if (!dbg_cnt (vect_slp)) + break; + + vect_slp_transform_bb (bb); + if (dump_enabled_p ()) + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location, + "basic block vectorized\n"); + } + } + + free_stmt_vec_info_vec (); + return 0; +} + } // anon namespace gimple_opt_pass * @@ -725,7 +725,7 @@ public: return flag_section_anchors && flag_tree_loop_vectorize; } - unsigned int execute () { return increase_alignment (); } + virtual unsigned int execute (function *) { return increase_alignment (); } }; // class pass_ipa_increase_alignment diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 80f3888c1065..34255ced1b9c 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -9922,7 +9922,7 @@ public: /* opt_pass methods: */ opt_pass * clone () { return new pass_vrp (m_ctxt); } virtual bool gate (function *) { return flag_tree_vrp != 0; } - unsigned int execute () { return execute_vrp (); } + virtual unsigned int execute (function *) { return execute_vrp (); } }; // class pass_vrp diff --git a/gcc/tree.c b/gcc/tree.c index b8979881f5c5..8b44ecc70882 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5642,7 +5642,7 @@ public: {} /* opt_pass methods: */ - unsigned int execute () { return free_lang_data (); } + virtual unsigned int execute (function *) { return free_lang_data (); } }; // class pass_ipa_free_lang_data diff --git a/gcc/tsan.c b/gcc/tsan.c index b413bb50edd2..d9f5718ee7ec 100644 --- a/gcc/tsan.c +++ b/gcc/tsan.c @@ -762,7 +762,7 @@ public: return (flag_sanitize & SANITIZE_THREAD) != 0; } - unsigned int execute () { return tsan_pass (); } + virtual unsigned int execute (function *) { return tsan_pass (); } }; // class pass_tsan @@ -803,7 +803,7 @@ public: return (flag_sanitize & SANITIZE_THREAD) != 0 && !optimize; } - unsigned int execute () { return tsan_pass (); } + virtual unsigned int execute (function *) { return tsan_pass (); } }; // class pass_tsan_O0 diff --git a/gcc/ubsan.c b/gcc/ubsan.c index 8e7dda54efea..cf25aa3edf60 100644 --- a/gcc/ubsan.c +++ b/gcc/ubsan.c @@ -859,17 +859,49 @@ instrument_bool_enum_load (gimple_stmt_iterator *gsi) gsi_insert_before (&gsi2, g, GSI_SAME_STMT); } -/* Gate and execute functions for ubsan pass. */ +namespace { -static unsigned int -ubsan_pass (void) +const pass_data pass_data_ubsan = +{ + GIMPLE_PASS, /* type */ + "ubsan", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_TREE_UBSAN, /* tv_id */ + ( PROP_cfg | PROP_ssa ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + TODO_update_ssa, /* todo_flags_finish */ +}; + +class pass_ubsan : public gimple_opt_pass +{ +public: + pass_ubsan (gcc::context *ctxt) + : gimple_opt_pass (pass_data_ubsan, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) + { + return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW + | SANITIZE_BOOL | SANITIZE_ENUM); + } + + virtual unsigned int execute (function *); + +}; // class pass_ubsan + +unsigned int +pass_ubsan::execute (function *fun) { basic_block bb; gimple_stmt_iterator gsi; initialize_sanitizer_builtins (); - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_FN (bb, fun) { for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi);) { @@ -902,40 +934,6 @@ ubsan_pass (void) return 0; } -namespace { - -const pass_data pass_data_ubsan = -{ - GIMPLE_PASS, /* type */ - "ubsan", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_TREE_UBSAN, /* tv_id */ - ( PROP_cfg | PROP_ssa ), /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_update_ssa, /* todo_flags_finish */ -}; - -class pass_ubsan : public gimple_opt_pass -{ -public: - pass_ubsan (gcc::context *ctxt) - : gimple_opt_pass (pass_data_ubsan, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) - { - return flag_sanitize & (SANITIZE_NULL | SANITIZE_SI_OVERFLOW - | SANITIZE_BOOL | SANITIZE_ENUM); - } - - unsigned int execute () { return ubsan_pass (); } - -}; // class pass_ubsan - } // anon namespace gimple_opt_pass * diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 4586afc4b208..39373401d4b5 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -10373,7 +10373,10 @@ public: return (flag_var_tracking && !targetm.delay_vartrack); } - unsigned int execute () { return variable_tracking_main (); } + virtual unsigned int execute (function *) + { + return variable_tracking_main (); + } }; // class pass_variable_tracking diff --git a/gcc/vtable-verify.c b/gcc/vtable-verify.c index 601b2ced8dd8..b99ff6cf8964 100644 --- a/gcc/vtable-verify.c +++ b/gcc/vtable-verify.c @@ -723,23 +723,6 @@ verify_bb_vtables (basic_block bb) } } -/* Main function, called from pass->excute(). Loop through all the - basic blocks in the current function, passing them to - verify_bb_vtables, which searches for virtual calls, and inserts - calls to __VLTVerifyVtablePointer. */ - -unsigned int -vtable_verify_main (void) -{ - unsigned int ret = 1; - basic_block bb; - - FOR_ALL_BB_FN (bb, cfun) - verify_bb_vtables (bb); - - return ret; -} - /* Definition of this optimization pass. */ namespace { @@ -767,10 +750,26 @@ public: /* opt_pass methods: */ virtual bool gate (function *) { return (flag_vtable_verify); } - unsigned int execute () { return vtable_verify_main (); } + virtual unsigned int execute (function *); }; // class pass_vtable_verify +/* Loop through all the basic blocks in the current function, passing them to + verify_bb_vtables, which searches for virtual calls, and inserts + calls to __VLTVerifyVtablePointer. */ + +unsigned int +pass_vtable_verify::execute (function *fun) +{ + unsigned int ret = 1; + basic_block bb; + + FOR_ALL_BB_FN (bb, fun) + verify_bb_vtables (bb); + + return ret; +} + } // anon namespace gimple_opt_pass * diff --git a/gcc/web.c b/gcc/web.c index 50fc9e6b920a..46a6ff7448d3 100644 --- a/gcc/web.c +++ b/gcc/web.c @@ -325,10 +325,37 @@ replace_ref (df_ref ref, rtx reg) } -/* Main entry point. */ +namespace { + +const pass_data pass_data_web = +{ + RTL_PASS, /* type */ + "web", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + true, /* has_execute */ + TV_WEB, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */ +}; + +class pass_web : public rtl_opt_pass +{ +public: + pass_web (gcc::context *ctxt) + : rtl_opt_pass (pass_data_web, ctxt) + {} + + /* opt_pass methods: */ + virtual bool gate (function *) { return (optimize > 0 && flag_web); } + virtual unsigned int execute (function *); -static unsigned int -web_main (void) +}; // class pass_web + +unsigned int +pass_web::execute (function *fun) { struct web_entry *def_entry; struct web_entry *use_entry; @@ -345,7 +372,7 @@ web_main (void) df_set_flags (DF_DEFER_INSN_RESCAN); /* Assign ids to the uses. */ - FOR_ALL_BB_FN (bb, cfun) + FOR_ALL_BB_FN (bb, fun) FOR_BB_INSNS (bb, insn) { unsigned int uid = INSN_UID (insn); @@ -373,7 +400,7 @@ web_main (void) use_entry = XCNEWVEC (struct web_entry, uses_num); /* Produce the web. */ - FOR_ALL_BB_FN (bb, cfun) + FOR_ALL_BB_FN (bb, fun) FOR_BB_INSNS (bb, insn) { unsigned int uid = INSN_UID (insn); @@ -398,7 +425,7 @@ web_main (void) /* Update the instruction stream, allocating new registers for split pseudos in progress. */ - FOR_ALL_BB_FN (bb, cfun) + FOR_ALL_BB_FN (bb, fun) FOR_BB_INSNS (bb, insn) { unsigned int uid = INSN_UID (insn); @@ -443,35 +470,6 @@ web_main (void) return 0; } -namespace { - -const pass_data pass_data_web = -{ - RTL_PASS, /* type */ - "web", /* name */ - OPTGROUP_NONE, /* optinfo_flags */ - true, /* has_execute */ - TV_WEB, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */ -}; - -class pass_web : public rtl_opt_pass -{ -public: - pass_web (gcc::context *ctxt) - : rtl_opt_pass (pass_data_web, ctxt) - {} - - /* opt_pass methods: */ - virtual bool gate (function *) { return (optimize > 0 && flag_web); } - unsigned int execute () { return web_main (); } - -}; // class pass_web - } // anon namespace rtl_opt_pass * -- 2.39.5