aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2018-04-09 18:33:51 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2018-04-09 16:33:51 +0000
commit687d5dfe165f705cb0b863fbe1f80bf77c1b6559 (patch)
treedce4694dfb3079937dc98a9e1ac671479324509d /gcc
parent13c60208d0428ad14b4bd41a63a47d67bd35253f (diff)
downloadgcc-687d5dfe165f705cb0b863fbe1f80bf77c1b6559.zip
gcc-687d5dfe165f705cb0b863fbe1f80bf77c1b6559.tar.gz
gcc-687d5dfe165f705cb0b863fbe1f80bf77c1b6559.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/cfgcleanup.c41
-rw-r--r--gcc/cfgrtl.c15
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 <jh@suse.cz>
+
+ 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 <abrodkin@synopsys.com>
* 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;