From 687d5dfe165f705cb0b863fbe1f80bf77c1b6559 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Mon, 9 Apr 2018 18:33:51 +0200 Subject: [PATCH] re PR rtl-optimization/84058 (RTl partitioning fixup should drag very small blocks back to hot partition) PR rtl/84058 * cfgcleanup.c (try_forward_edges): Do not give up on crossing jumps; choose last target that matches the criteria (i.e. no partition changes for non-crossing jumps). * cfgrtl.c (cfg_layout_redirect_edge_and_branch): Add basic support for redirecting crossing jumps to non-crossing. From-SVN: r259244 --- gcc/ChangeLog | 9 +++++++++ gcc/cfgcleanup.c | 41 +++++++++-------------------------------- gcc/cfgrtl.c | 15 ++++++++++++++- 3 files changed, 32 insertions(+), 33 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 102acd7..601a9ab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2018-04-09 Jan Hubicka + + PR rtl/84058 + * cfgcleanup.c (try_forward_edges): Do not give up on crossing + jumps; choose last target that matches the criteria (i.e. + no partition changes for non-crossing jumps). + * cfgrtl.c (cfg_layout_redirect_edge_and_branch): Add basic + support for redirecting crossing jumps to non-crossing. + 2018-04-09 Alexey Brodkin * config/arc/arc.c (arc_expand_prologue): Set stack usage info diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c index 4f72153..4a5dc29 100644 --- a/gcc/cfgcleanup.c +++ b/gcc/cfgcleanup.c @@ -394,19 +394,6 @@ try_forward_edges (int mode, basic_block b) edge_iterator ei; edge e, *threaded_edges = NULL; - /* If we are partitioning hot/cold basic blocks, we don't want to - mess up unconditional or indirect jumps that cross between hot - and cold sections. - - Basic block partitioning may result in some jumps that appear to - be optimizable (or blocks that appear to be mergeable), but which really - must be left untouched (they are required to make it safely across - partition boundaries). See the comments at the top of - bb-reorder.c:partition_hot_cold_basic_blocks for complete details. */ - - if (JUMP_P (BB_END (b)) && CROSSING_JUMP_P (BB_END (b))) - return false; - for (ei = ei_start (b->succs); (e = ei_safe_edge (ei)); ) { basic_block target, first; @@ -415,6 +402,7 @@ try_forward_edges (int mode, basic_block b) bool threaded = false; int nthreaded_edges = 0; bool may_thread = first_pass || (b->flags & BB_MODIFIED) != 0; + bool new_target_threaded = false; /* Skip complex edges because we don't know how to update them. @@ -431,29 +419,12 @@ try_forward_edges (int mode, basic_block b) counter = NUM_FIXED_BLOCKS; goto_locus = e->goto_locus; - /* If we are partitioning hot/cold basic_blocks, we don't want to mess - up jumps that cross between hot/cold sections. - - Basic block partitioning may result in some jumps that appear - to be optimizable (or blocks that appear to be mergeable), but which - really must be left untouched (they are required to make it safely - across partition boundaries). See the comments at the top of - bb-reorder.c:partition_hot_cold_basic_blocks for complete - details. */ - - if (first != EXIT_BLOCK_PTR_FOR_FN (cfun) - && JUMP_P (BB_END (first)) - && CROSSING_JUMP_P (BB_END (first))) - return changed; - while (counter < n_basic_blocks_for_fn (cfun)) { basic_block new_target = NULL; - bool new_target_threaded = false; may_thread |= (target->flags & BB_MODIFIED) != 0; if (FORWARDER_BLOCK_P (target) - && !(single_succ_edge (target)->flags & EDGE_CROSSING) && single_succ (target) != EXIT_BLOCK_PTR_FOR_FN (cfun)) { /* Bypass trivial infinite loops. */ @@ -543,8 +514,14 @@ try_forward_edges (int mode, basic_block b) break; counter++; - target = new_target; - threaded |= new_target_threaded; + /* Do not turn non-crossing jump to crossing. Depending on target + it may require different instruction pattern. */ + if ((e->flags & EDGE_CROSSING) + || BB_PARTITION (first) == BB_PARTITION (new_target)) + { + target = new_target; + threaded |= new_target_threaded; + } } if (counter >= n_basic_blocks_for_fn (cfun)) diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index fd095ac..de704ce 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -4361,6 +4361,18 @@ cfg_layout_redirect_edge_and_branch (edge e, basic_block dest) if (e->dest == dest) return e; + if (e->flags & EDGE_CROSSING + && BB_PARTITION (e->src) == BB_PARTITION (dest) + && simplejump_p (BB_END (src))) + { + if (dump_file) + fprintf (dump_file, + "Removing crossing jump while redirecting edge form %i to %i\n", + e->src->index, dest->index); + delete_insn (BB_END (src)); + e->flags |= EDGE_FALLTHRU; + } + if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun) && (ret = try_redirect_by_replacing_jump (e, dest, true))) { @@ -4424,8 +4436,9 @@ cfg_layout_redirect_edge_and_branch (edge e, basic_block dest) else ret = redirect_branch_edge (e, dest); + fixup_partition_crossing (ret); /* We don't want simplejumps in the insn stream during cfglayout. */ - gcc_assert (!simplejump_p (BB_END (src))); + gcc_assert (!simplejump_p (BB_END (src)) || CROSSING_JUMP_P (BB_END (src))); df_set_bb_dirty (src); return ret; -- 2.7.4