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. From-SVN: r209482
This commit is contained in:
parent
1a3d085cf2
commit
be55bfe6cf
|
@ -1,3 +1,41 @@
|
|||
2014-04-17 Trevor Saunders <tsaunders@mozilla.com>
|
||||
|
||||
* 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 <tsaunders@mozilla.com>
|
||||
|
||||
* passes.c (opt_pass::gate): Take function * argument.
|
||||
|
|
70
gcc/asan.c
70
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 *
|
||||
|
|
|
@ -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 *
|
||||
|
|
231
gcc/bb-reorder.c
231
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<edge> 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 *
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
136
gcc/cfgexpand.c
136
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 *
|
||||
|
|
85
gcc/cfgrtl.c
85
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 *
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
11
gcc/cse.c
11
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
|
||||
|
||||
|
|
10
gcc/dce.c
10
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
10
gcc/except.c
10
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
|
||||
|
||||
|
|
14
gcc/final.c
14
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
|
||||
|
||||
|
|
|
@ -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,41 +7191,6 @@ match_asm_constraints_1 (rtx insn, rtx *p_sets, int noutputs)
|
|||
df_insn_rescan (insn);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
rest_of_match_asm_constraints (void)
|
||||
{
|
||||
basic_block bb;
|
||||
rtx insn, pat, *p_sets;
|
||||
int noutputs;
|
||||
|
||||
if (!crtl->has_asm_statement)
|
||||
return 0;
|
||||
|
||||
df_set_flags (DF_DEFER_INSN_RESCAN);
|
||||
FOR_EACH_BB_FN (bb, cfun)
|
||||
{
|
||||
FOR_BB_INSNS (bb, insn)
|
||||
{
|
||||
if (!INSN_P (insn))
|
||||
continue;
|
||||
|
||||
pat = PATTERN (insn);
|
||||
if (GET_CODE (pat) == PARALLEL)
|
||||
p_sets = &XVECEXP (pat, 0, 0), noutputs = XVECLEN (pat, 0);
|
||||
else if (GET_CODE (pat) == SET)
|
||||
p_sets = &PATTERN (insn), noutputs = 1;
|
||||
else
|
||||
continue;
|
||||
|
||||
if (GET_CODE (*p_sets) == SET
|
||||
&& GET_CODE (SET_SRC (*p_sets)) == ASM_OPERANDS)
|
||||
match_asm_constraints_1 (insn, p_sets, noutputs);
|
||||
}
|
||||
}
|
||||
|
||||
return TODO_df_finish;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_match_asm_constraints =
|
||||
|
@ -7243,10 +7215,45 @@ public:
|
|||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
unsigned int execute () { return rest_of_match_asm_constraints (); }
|
||||
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;
|
||||
int noutputs;
|
||||
|
||||
if (!crtl->has_asm_statement)
|
||||
return 0;
|
||||
|
||||
df_set_flags (DF_DEFER_INSN_RESCAN);
|
||||
FOR_EACH_BB_FN (bb, fun)
|
||||
{
|
||||
FOR_BB_INSNS (bb, insn)
|
||||
{
|
||||
if (!INSN_P (insn))
|
||||
continue;
|
||||
|
||||
pat = PATTERN (insn);
|
||||
if (GET_CODE (pat) == PARALLEL)
|
||||
p_sets = &XVECEXP (pat, 0, 0), noutputs = XVECLEN (pat, 0);
|
||||
else if (GET_CODE (pat) == SET)
|
||||
p_sets = &PATTERN (insn), noutputs = 1;
|
||||
else
|
||||
continue;
|
||||
|
||||
if (GET_CODE (*p_sets) == SET
|
||||
&& GET_CODE (SET_SRC (*p_sets)) == ASM_OPERANDS)
|
||||
match_asm_constraints_1 (insn, p_sets, noutputs);
|
||||
}
|
||||
}
|
||||
|
||||
return TODO_df_finish;
|
||||
}
|
||||
|
||||
} // anon namespace
|
||||
|
||||
rtl_opt_pass *
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
31
gcc/ifcvt.c
31
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -2136,7 +2136,7 @@ public:
|
|||
&& optimize);
|
||||
}
|
||||
|
||||
unsigned int execute () { return ipa_devirt (); }
|
||||
virtual unsigned int execute (function *) { return ipa_devirt (); }
|
||||
|
||||
}; // class pass_ipa_devirt
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1190,7 +1190,7 @@ public:
|
|||
&& !seen_error ());
|
||||
}
|
||||
|
||||
unsigned int execute () { return propagate (); }
|
||||
virtual unsigned int execute (function *) { return propagate (); }
|
||||
|
||||
}; // class pass_ipa_reference
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
35
gcc/ipa.c
35
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
|
||||
|
||||
|
|
25
gcc/ira.c
25
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
135
gcc/loop-init.c
135
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 *
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
|
11
gcc/passes.c
11
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
170
gcc/predict.c
170
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 *
|
||||
|
|
48
gcc/recog.c
48
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
174
gcc/regcprop.c
174
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 *
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
18
gcc/reorg.c
18
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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 *
|
||||
|
|
59
gcc/tracer.c
59
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 *
|
||||
|
|
|
@ -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<tm_region_p> 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<tm_region_p> 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
|
||||
|
||||
|
|
|
@ -867,56 +867,6 @@ shrink_wrap_conditional_dead_built_in_calls (vec<gimple> calls)
|
|||
return changed;
|
||||
}
|
||||
|
||||
/* Pass entry points. */
|
||||
|
||||
static unsigned int
|
||||
tree_call_cdce (void)
|
||||
{
|
||||
basic_block bb;
|
||||
gimple_stmt_iterator i;
|
||||
bool something_changed = false;
|
||||
auto_vec<gimple> cond_dead_built_in_calls;
|
||||
FOR_EACH_BB_FN (bb, cfun)
|
||||
{
|
||||
/* Collect dead call candidates. */
|
||||
for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
|
||||
{
|
||||
gimple stmt = gsi_stmt (i);
|
||||
if (is_gimple_call (stmt)
|
||||
&& is_call_dce_candidate (stmt))
|
||||
{
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
fprintf (dump_file, "Found conditional dead call: ");
|
||||
print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
if (!cond_dead_built_in_calls.exists ())
|
||||
cond_dead_built_in_calls.create (64);
|
||||
cond_dead_built_in_calls.safe_push (stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cond_dead_built_in_calls.exists ())
|
||||
return 0;
|
||||
|
||||
something_changed
|
||||
= shrink_wrap_conditional_dead_built_in_calls (cond_dead_built_in_calls);
|
||||
|
||||
if (something_changed)
|
||||
{
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
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);
|
||||
return TODO_update_ssa;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_call_cdce =
|
||||
|
@ -950,10 +900,58 @@ public:
|
|||
&& optimize_function_for_speed_p (fun);
|
||||
}
|
||||
|
||||
unsigned int execute () { return tree_call_cdce (); }
|
||||
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<gimple> cond_dead_built_in_calls;
|
||||
FOR_EACH_BB_FN (bb, fun)
|
||||
{
|
||||
/* Collect dead call candidates. */
|
||||
for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
|
||||
{
|
||||
gimple stmt = gsi_stmt (i);
|
||||
if (is_gimple_call (stmt)
|
||||
&& is_call_dce_candidate (stmt))
|
||||
{
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
{
|
||||
fprintf (dump_file, "Found conditional dead call: ");
|
||||
print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
|
||||
fprintf (dump_file, "\n");
|
||||
}
|
||||
if (!cond_dead_built_in_calls.exists ())
|
||||
cond_dead_built_in_calls.create (64);
|
||||
cond_dead_built_in_calls.safe_push (stmt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cond_dead_built_in_calls.exists ())
|
||||
return 0;
|
||||
|
||||
something_changed
|
||||
= shrink_wrap_conditional_dead_built_in_calls (cond_dead_built_in_calls);
|
||||
|
||||
if (something_changed)
|
||||
{
|
||||
free_dominance_info (CDI_DOMINATORS);
|
||||
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 (fun);
|
||||
return TODO_update_ssa;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
|
|
136
gcc/tree-cfg.c
136
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, "%<noreturn%> 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, "%<noreturn%> 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
|
||||
|
||||
|
|
|
@ -944,17 +944,46 @@ remove_forwarder_block_with_phi (basic_block bb)
|
|||
<L10>:;
|
||||
*/
|
||||
|
||||
static unsigned int
|
||||
merge_phi_nodes (void)
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_merge_phi =
|
||||
{
|
||||
basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
|
||||
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); }
|
||||
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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
240
gcc/tree-eh.c
240
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,39 +3701,6 @@ lower_eh_dispatch (basic_block src, gimple stmt)
|
|||
return redirected;
|
||||
}
|
||||
|
||||
static unsigned
|
||||
execute_lower_eh_dispatch (void)
|
||||
{
|
||||
basic_block bb;
|
||||
int flags = 0;
|
||||
bool redirected = false;
|
||||
|
||||
assign_filter_values ();
|
||||
|
||||
FOR_EACH_BB_FN (bb, cfun)
|
||||
{
|
||||
gimple last = last_stmt (bb);
|
||||
if (last == NULL)
|
||||
continue;
|
||||
if (gimple_code (last) == GIMPLE_EH_DISPATCH)
|
||||
{
|
||||
redirected |= lower_eh_dispatch (bb, last);
|
||||
flags |= TODO_update_ssa_only_virtuals;
|
||||
}
|
||||
else if (gimple_code (last) == GIMPLE_RESX)
|
||||
{
|
||||
if (stmt_can_throw_external (last))
|
||||
optimize_clobbers (bb);
|
||||
else
|
||||
flags |= sink_clobbers (bb);
|
||||
}
|
||||
}
|
||||
|
||||
if (redirected)
|
||||
delete_unreachable_blocks ();
|
||||
return flags;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_lower_eh_dispatch =
|
||||
|
@ -3762,11 +3726,43 @@ public:
|
|||
|
||||
/* opt_pass methods: */
|
||||
virtual bool gate (function *fun) { return fun->eh->region_tree != NULL; }
|
||||
|
||||
unsigned int execute () { return execute_lower_eh_dispatch (); }
|
||||
virtual unsigned int execute (function *);
|
||||
|
||||
}; // class pass_lower_eh_dispatch
|
||||
|
||||
unsigned
|
||||
pass_lower_eh_dispatch::execute (function *fun)
|
||||
{
|
||||
basic_block bb;
|
||||
int flags = 0;
|
||||
bool redirected = false;
|
||||
|
||||
assign_filter_values ();
|
||||
|
||||
FOR_EACH_BB_FN (bb, fun)
|
||||
{
|
||||
gimple last = last_stmt (bb);
|
||||
if (last == NULL)
|
||||
continue;
|
||||
if (gimple_code (last) == GIMPLE_EH_DISPATCH)
|
||||
{
|
||||
redirected |= lower_eh_dispatch (bb, last);
|
||||
flags |= TODO_update_ssa_only_virtuals;
|
||||
}
|
||||
else if (gimple_code (last) == GIMPLE_RESX)
|
||||
{
|
||||
if (stmt_can_throw_external (last))
|
||||
optimize_clobbers (bb);
|
||||
else
|
||||
flags |= sink_clobbers (bb);
|
||||
}
|
||||
}
|
||||
|
||||
if (redirected)
|
||||
delete_unreachable_blocks ();
|
||||
return flags;
|
||||
}
|
||||
|
||||
} // 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 *
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -2299,72 +2299,6 @@ 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)
|
||||
{
|
||||
bitmap_head *dfs;
|
||||
basic_block bb;
|
||||
unsigned i;
|
||||
|
||||
/* Initialize operand data structures. */
|
||||
init_ssa_operands (cfun);
|
||||
|
||||
/* Initialize internal data needed by the renamer. */
|
||||
init_ssa_renamer ();
|
||||
|
||||
/* 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));
|
||||
bitmap_clear (interesting_blocks);
|
||||
|
||||
/* Initialize dominance frontier. */
|
||||
dfs = XNEWVEC (bitmap_head, last_basic_block_for_fn (cfun));
|
||||
FOR_EACH_BB_FN (bb, cfun)
|
||||
bitmap_initialize (&dfs[bb->index], &bitmap_default_obstack);
|
||||
|
||||
/* 1- Compute dominance frontiers. */
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
compute_dominance_frontiers (dfs);
|
||||
|
||||
/* 2- Find and mark definition sites. */
|
||||
mark_def_dom_walker (CDI_DOMINATORS).walk (cfun->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);
|
||||
|
||||
/* Free allocated memory. */
|
||||
FOR_EACH_BB_FN (bb, cfun)
|
||||
bitmap_clear (&dfs[bb->index]);
|
||||
free (dfs);
|
||||
|
||||
sbitmap_free (interesting_blocks);
|
||||
|
||||
fini_ssa_renamer ();
|
||||
|
||||
/* Try to get rid of all gimplifier generated temporaries by making
|
||||
its SSA names anonymous. This way we can garbage collect them
|
||||
all after removing unused locals which we do in our TODO. */
|
||||
for (i = 1; i < num_ssa_names; ++i)
|
||||
{
|
||||
tree decl, name = ssa_name (i);
|
||||
if (!name
|
||||
|| SSA_NAME_IS_DEFAULT_DEF (name))
|
||||
continue;
|
||||
decl = SSA_NAME_VAR (name);
|
||||
if (decl
|
||||
&& TREE_CODE (decl) == VAR_DECL
|
||||
&& !VAR_DECL_IS_VIRTUAL_OPERAND (decl)
|
||||
&& DECL_IGNORED_P (decl))
|
||||
SET_SSA_NAME_VAR_OR_IDENTIFIER (name, DECL_NAME (decl));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_build_ssa =
|
||||
|
@ -2395,10 +2329,76 @@ public:
|
|||
return !(fun->curr_properties & PROP_ssa);
|
||||
}
|
||||
|
||||
unsigned int execute () { return rewrite_into_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 (fun);
|
||||
|
||||
/* Initialize internal data needed by the renamer. */
|
||||
init_ssa_renamer ();
|
||||
|
||||
/* 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 (fun));
|
||||
bitmap_clear (interesting_blocks);
|
||||
|
||||
/* Initialize dominance frontier. */
|
||||
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. */
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
compute_dominance_frontiers (dfs);
|
||||
|
||||
/* 2- Find and mark definition sites. */
|
||||
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 (fun), REWRITE_ALL);
|
||||
|
||||
/* Free allocated memory. */
|
||||
FOR_EACH_BB_FN (bb, fun)
|
||||
bitmap_clear (&dfs[bb->index]);
|
||||
free (dfs);
|
||||
|
||||
sbitmap_free (interesting_blocks);
|
||||
|
||||
fini_ssa_renamer ();
|
||||
|
||||
/* Try to get rid of all gimplifier generated temporaries by making
|
||||
its SSA names anonymous. This way we can garbage collect them
|
||||
all after removing unused locals which we do in our TODO. */
|
||||
for (i = 1; i < num_ssa_names; ++i)
|
||||
{
|
||||
tree decl, name = ssa_name (i);
|
||||
if (!name
|
||||
|| SSA_NAME_IS_DEFAULT_DEF (name))
|
||||
continue;
|
||||
decl = SSA_NAME_VAR (name);
|
||||
if (decl
|
||||
&& TREE_CODE (decl) == VAR_DECL
|
||||
&& !VAR_DECL_IS_VIRTUAL_OPERAND (decl)
|
||||
&& DECL_IGNORED_P (decl))
|
||||
SET_SSA_NAME_VAR_OR_IDENTIFIER (name, DECL_NAME (decl));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
|
|
|
@ -1669,15 +1669,49 @@ distribute_loop (struct loop *loop, vec<gimple> 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 *
|
||||
|
|
128
gcc/tree-nrv.c
128
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 *
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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,41 +325,6 @@ dse_dom_walker::before_dom_children (basic_block bb)
|
|||
}
|
||||
}
|
||||
|
||||
/* Main entry point. */
|
||||
|
||||
static unsigned int
|
||||
tree_ssa_dse (void)
|
||||
{
|
||||
need_eh_cleanup = BITMAP_ALLOC (NULL);
|
||||
|
||||
renumber_gimple_stmt_uids ();
|
||||
|
||||
/* We might consider making this a property of each pass so that it
|
||||
can be [re]computed on an as-needed basis. Particularly since
|
||||
this pass could be seen as an extension of DCE which needs post
|
||||
dominators. */
|
||||
calculate_dominance_info (CDI_POST_DOMINATORS);
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Removal of stores may make some EH edges dead. Purge such edges from
|
||||
the CFG as needed. */
|
||||
if (!bitmap_empty_p (need_eh_cleanup))
|
||||
{
|
||||
gimple_purge_all_dead_eh_edges (need_eh_cleanup);
|
||||
cleanup_tree_cfg ();
|
||||
}
|
||||
|
||||
BITMAP_FREE (need_eh_cleanup);
|
||||
|
||||
/* For now, just wipe the post-dominator information. */
|
||||
free_dominance_info (CDI_POST_DOMINATORS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_dse =
|
||||
|
@ -388,10 +351,43 @@ public:
|
|||
/* 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 (); }
|
||||
virtual unsigned int execute (function *);
|
||||
|
||||
}; // class pass_dse
|
||||
|
||||
unsigned int
|
||||
pass_dse::execute (function *fun)
|
||||
{
|
||||
need_eh_cleanup = BITMAP_ALLOC (NULL);
|
||||
|
||||
renumber_gimple_stmt_uids ();
|
||||
|
||||
/* We might consider making this a property of each pass so that it
|
||||
can be [re]computed on an as-needed basis. Particularly since
|
||||
this pass could be seen as an extension of DCE which needs post
|
||||
dominators. */
|
||||
calculate_dominance_info (CDI_POST_DOMINATORS);
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
|
||||
/* 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 (fun->cfg->x_exit_block_ptr);
|
||||
|
||||
/* Removal of stores may make some EH edges dead. Purge such edges from
|
||||
the CFG as needed. */
|
||||
if (!bitmap_empty_p (need_eh_cleanup))
|
||||
{
|
||||
gimple_purge_all_dead_eh_edges (need_eh_cleanup);
|
||||
cleanup_tree_cfg ();
|
||||
}
|
||||
|
||||
BITMAP_FREE (need_eh_cleanup);
|
||||
|
||||
/* For now, just wipe the post-dominator information. */
|
||||
free_dominance_info (CDI_POST_DOMINATORS);
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -723,39 +723,6 @@ tree_ssa_ifcombine_bb (basic_block inner_cond_bb)
|
|||
|
||||
/* Main entry for the tree if-conversion pass. */
|
||||
|
||||
static unsigned int
|
||||
tree_ssa_ifcombine (void)
|
||||
{
|
||||
basic_block *bbs;
|
||||
bool cfg_changed = false;
|
||||
int i;
|
||||
|
||||
bbs = single_pred_before_succ_order ();
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
|
||||
/* Search every basic block for COND_EXPR we may be able to optimize.
|
||||
|
||||
We walk the blocks in order that guarantees that a block with
|
||||
a single predecessor is processed after the predecessor.
|
||||
This ensures that we collapse outter ifs before visiting the
|
||||
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--)
|
||||
{
|
||||
basic_block bb = bbs[i];
|
||||
gimple stmt = last_stmt (bb);
|
||||
|
||||
if (stmt
|
||||
&& gimple_code (stmt) == GIMPLE_COND)
|
||||
cfg_changed |= tree_ssa_ifcombine_bb (bb);
|
||||
}
|
||||
|
||||
free (bbs);
|
||||
|
||||
return cfg_changed ? TODO_cleanup_cfg : 0;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
const pass_data pass_data_tree_ifcombine =
|
||||
|
@ -780,10 +747,43 @@ public:
|
|||
{}
|
||||
|
||||
/* opt_pass methods: */
|
||||
unsigned int execute () { return tree_ssa_ifcombine (); }
|
||||
virtual unsigned int execute (function *);
|
||||
|
||||
}; // class pass_tree_ifcombine
|
||||
|
||||
unsigned int
|
||||
pass_tree_ifcombine::execute (function *fun)
|
||||
{
|
||||
basic_block *bbs;
|
||||
bool cfg_changed = false;
|
||||
int i;
|
||||
|
||||
bbs = single_pred_before_succ_order ();
|
||||
calculate_dominance_info (CDI_DOMINATORS);
|
||||
|
||||
/* Search every basic block for COND_EXPR we may be able to optimize.
|
||||
|
||||
We walk the blocks in order that guarantees that a block with
|
||||
a single predecessor is processed after the predecessor.
|
||||
This ensures that we collapse outter ifs before visiting the
|
||||
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 (fun) - NUM_FIXED_BLOCKS - 1; i >= 0; i--)
|
||||
{
|
||||
basic_block bb = bbs[i];
|
||||
gimple stmt = last_stmt (bb);
|
||||
|
||||
if (stmt
|
||||
&& gimple_code (stmt) == GIMPLE_COND)
|
||||
cfg_changed |= tree_ssa_ifcombine_bb (bb);
|
||||
}
|
||||
|
||||
free (bbs);
|
||||
|
||||
return cfg_changed ? TODO_cleanup_cfg : 0;
|
||||
}
|
||||
|
||||
} // anon namespace
|
||||
|
||||
gimple_opt_pass *
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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 *
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue