summaryrefslogtreecommitdiff
path: root/gcc/bb-reorder.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/bb-reorder.c')
-rw-r--r--gcc/bb-reorder.c231
1 files changed, 115 insertions, 116 deletions
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index 57103bd323a..db490f1f876 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -2302,26 +2302,6 @@ insert_section_boundary_note (void)
}
}
-static unsigned int
-rest_of_handle_reorder_blocks (void)
-{
- basic_block bb;
-
- /* Last attempt to optimize CFG, as scheduling, peepholing and insn
- splitting possibly introduced more crossjumping opportunities. */
- cfg_layout_initialize (CLEANUP_EXPENSIVE);
-
- reorder_basic_blocks ();
- cleanup_cfg (CLEANUP_EXPENSIVE);
-
- FOR_EACH_BB_FN (bb, cfun)
- if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
- bb->aux = bb->next_bb;
- cfg_layout_finalize ();
-
- return 0;
-}
-
namespace {
const pass_data pass_data_reorder_blocks =
@@ -2354,10 +2334,30 @@ public:
&& (flag_reorder_blocks || flag_reorder_blocks_and_partition));
}
- unsigned int execute () { return rest_of_handle_reorder_blocks (); }
+ virtual unsigned int execute (function *);
}; // class pass_reorder_blocks
+unsigned int
+pass_reorder_blocks::execute (function *fun)
+{
+ basic_block bb;
+
+ /* Last attempt to optimize CFG, as scheduling, peepholing and insn
+ splitting possibly introduced more crossjumping opportunities. */
+ cfg_layout_initialize (CLEANUP_EXPENSIVE);
+
+ reorder_basic_blocks ();
+ cleanup_cfg (CLEANUP_EXPENSIVE);
+
+ FOR_EACH_BB_FN (bb, fun)
+ if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (fun))
+ bb->aux = bb->next_bb;
+ cfg_layout_finalize ();
+
+ return 0;
+}
+
} // anon namespace
rtl_opt_pass *
@@ -2372,16 +2372,54 @@ make_pass_reorder_blocks (gcc::context *ctxt)
which can seriously pessimize code with many computed jumps in the source
code, such as interpreters. See e.g. PR15242. */
+namespace {
-static unsigned int
-duplicate_computed_gotos (void)
+const pass_data pass_data_duplicate_computed_gotos =
+{
+ RTL_PASS, /* type */
+ "compgotos", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_execute */
+ TV_REORDER_BLOCKS, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
+};
+
+class pass_duplicate_computed_gotos : public rtl_opt_pass
+{
+public:
+ pass_duplicate_computed_gotos (gcc::context *ctxt)
+ : rtl_opt_pass (pass_data_duplicate_computed_gotos, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ virtual bool gate (function *);
+ virtual unsigned int execute (function *);
+
+}; // class pass_duplicate_computed_gotos
+
+bool
+pass_duplicate_computed_gotos::gate (function *fun)
+{
+ if (targetm.cannot_modify_jumps_p ())
+ return false;
+ return (optimize > 0
+ && flag_expensive_optimizations
+ && ! optimize_function_for_size_p (fun));
+}
+
+unsigned int
+pass_duplicate_computed_gotos::execute (function *fun)
{
basic_block bb, new_bb;
bitmap candidates;
int max_size;
bool changed = false;
- if (n_basic_blocks_for_fn (cfun) <= NUM_FIXED_BLOCKS + 1)
+ if (n_basic_blocks_for_fn (fun) <= NUM_FIXED_BLOCKS + 1)
return 0;
clear_bb_flags ();
@@ -2400,7 +2438,7 @@ duplicate_computed_gotos (void)
/* Look for blocks that end in a computed jump, and see if such blocks
are suitable for unfactoring. If a block is a candidate for unfactoring,
mark it in the candidates. */
- FOR_EACH_BB_FN (bb, cfun)
+ FOR_EACH_BB_FN (bb, fun)
{
rtx insn;
edge e;
@@ -2408,7 +2446,7 @@ duplicate_computed_gotos (void)
int size, all_flags;
/* Build the reorder chain for the original order of blocks. */
- if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (cfun))
+ if (bb->next_bb != EXIT_BLOCK_PTR_FOR_FN (fun))
bb->aux = bb->next_bb;
/* Obviously the block has to end in a computed jump. */
@@ -2447,7 +2485,7 @@ duplicate_computed_gotos (void)
goto done;
/* Duplicate computed gotos. */
- FOR_EACH_BB_FN (bb, cfun)
+ FOR_EACH_BB_FN (bb, fun)
{
if (bb->flags & BB_VISITED)
continue;
@@ -2458,7 +2496,7 @@ duplicate_computed_gotos (void)
the exit block or the next block.
The destination must have more than one predecessor. */
if (!single_succ_p (bb)
- || single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (cfun)
+ || single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (fun)
|| single_succ (bb) == bb->next_bb
|| single_pred_p (single_succ (bb)))
continue;
@@ -2491,45 +2529,6 @@ done:
return 0;
}
-namespace {
-
-const pass_data pass_data_duplicate_computed_gotos =
-{
- RTL_PASS, /* type */
- "compgotos", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- true, /* has_execute */
- TV_REORDER_BLOCKS, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing, /* todo_flags_finish */
-};
-
-class pass_duplicate_computed_gotos : public rtl_opt_pass
-{
-public:
- pass_duplicate_computed_gotos (gcc::context *ctxt)
- : rtl_opt_pass (pass_data_duplicate_computed_gotos, ctxt)
- {}
-
- /* opt_pass methods: */
- virtual bool gate (function *);
- unsigned int execute () { return duplicate_computed_gotos (); }
-
-}; // class pass_duplicate_computed_gotos
-
-bool
-pass_duplicate_computed_gotos::gate (function *fun)
-{
- if (targetm.cannot_modify_jumps_p ())
- return false;
- return (optimize > 0
- && flag_expensive_optimizations
- && ! optimize_function_for_size_p (fun));
-}
-
} // anon namespace
rtl_opt_pass *
@@ -2627,12 +2626,57 @@ make_pass_duplicate_computed_gotos (gcc::context *ctxt)
Unconditional branches are dealt with by converting them into
indirect jumps. */
-static unsigned
-partition_hot_cold_basic_blocks (void)
+namespace {
+
+const pass_data pass_data_partition_blocks =
+{
+ RTL_PASS, /* type */
+ "bbpart", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_execute */
+ TV_REORDER_BLOCKS, /* tv_id */
+ PROP_cfglayout, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class pass_partition_blocks : public rtl_opt_pass
+{
+public:
+ pass_partition_blocks (gcc::context *ctxt)
+ : rtl_opt_pass (pass_data_partition_blocks, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ virtual bool gate (function *);
+ virtual unsigned int execute (function *);
+
+}; // class pass_partition_blocks
+
+bool
+pass_partition_blocks::gate (function *fun)
+{
+ /* The optimization to partition hot/cold basic blocks into separate
+ sections of the .o file does not work well with linkonce or with
+ user defined section attributes. Don't call it if either case
+ arises. */
+ return (flag_reorder_blocks_and_partition
+ && optimize
+ /* See gate_handle_reorder_blocks. We should not partition if
+ we are going to omit the reordering. */
+ && optimize_function_for_speed_p (fun)
+ && !DECL_ONE_ONLY (current_function_decl)
+ && !user_defined_section_attribute);
+}
+
+unsigned
+pass_partition_blocks::execute (function *fun)
{
vec<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 *