aboutsummaryrefslogtreecommitdiff
path: root/gcc/shrink-wrap.c
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@gcc.gnu.org>2016-05-20 00:17:53 +0200
committerSegher Boessenkool <segher@gcc.gnu.org>2016-05-20 00:17:53 +0200
commit33fec8d5b3c94cc8f73838abd27a4f0cfa2b3fd6 (patch)
tree925e8358e6a8300855c5228c2a225afc376e6b67 /gcc/shrink-wrap.c
parent6befaff6662e3a750c8de2239ded13032994baf4 (diff)
downloadgcc-33fec8d5b3c94cc8f73838abd27a4f0cfa2b3fd6.zip
gcc-33fec8d5b3c94cc8f73838abd27a4f0cfa2b3fd6.tar.gz
gcc-33fec8d5b3c94cc8f73838abd27a4f0cfa2b3fd6.tar.bz2
function: Restructure *logue insertion
This patch restructures how the prologues/epilogues are inserted. Sibcalls that run without prologue are now handled in shrink-wrap.c; it communicates what is already handled by setting the EDGE_IGNORE flag. The try_shrink_wrapping function then doesn't need to be passed the bb_flags anymore. * function.c (make_epilogue_seq): Remove epilogue_end parameter. (thread_prologue_and_epilogue_insns): Remove bb_flags. Restructure code. Ignore sibcalls on EDGE_IGNORE edges. * shrink-wrap.c (handle_simple_exit): New function. Set EDGE_IGNORE on edges for sibcalls that run without prologue. The rest of the function is combined from... (fix_fake_fallthrough_edge): ... this, and ... (try_shrink_wrapping): ... a part of this. Remove the bb_with function argument, make it a local variable. From-SVN: r236491
Diffstat (limited to 'gcc/shrink-wrap.c')
-rw-r--r--gcc/shrink-wrap.c88
1 files changed, 44 insertions, 44 deletions
diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c
index 0ba1fed..b85b1c3 100644
--- a/gcc/shrink-wrap.c
+++ b/gcc/shrink-wrap.c
@@ -529,30 +529,49 @@ can_dup_for_shrink_wrapping (basic_block bb, basic_block pro, unsigned max_size)
return true;
}
-/* If the source of edge E has more than one successor, the verifier for
- branch probabilities gets confused by the fake edges we make where
- simple_return statements will be inserted later (because those are not
- marked as fallthrough edges). Fix this by creating an extra block just
- for that fallthrough. */
+/* Do whatever needs to be done for exits that run without prologue.
+ Sibcalls need nothing done. Normal exits get a simple_return inserted. */
-static edge
-fix_fake_fallthrough_edge (edge e)
+static void
+handle_simple_exit (edge e)
{
- if (EDGE_COUNT (e->src->succs) <= 1)
- return e;
- basic_block old_bb = e->src;
- rtx_insn *end = BB_END (old_bb);
- rtx_note *note = emit_note_after (NOTE_INSN_DELETED, end);
- basic_block new_bb = create_basic_block (note, note, old_bb);
- BB_COPY_PARTITION (new_bb, old_bb);
- BB_END (old_bb) = end;
+ if (e->flags & EDGE_SIBCALL)
+ {
+ /* Tell function.c to take no further action on this edge. */
+ e->flags |= EDGE_IGNORE;
+
+ e->flags &= ~EDGE_FALLTHRU;
+ emit_barrier_after_bb (e->src);
+ return;
+ }
+
+ /* If the basic block the edge comes from has multiple successors,
+ split the edge. */
+ if (EDGE_COUNT (e->src->succs) > 1)
+ {
+ basic_block old_bb = e->src;
+ rtx_insn *end = BB_END (old_bb);
+ rtx_note *note = emit_note_after (NOTE_INSN_DELETED, end);
+ basic_block new_bb = create_basic_block (note, note, old_bb);
+ BB_COPY_PARTITION (new_bb, old_bb);
+ BB_END (old_bb) = end;
+
+ redirect_edge_succ (e, new_bb);
+ e->flags |= EDGE_FALLTHRU;
+
+ e = make_edge (new_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
+ }
- redirect_edge_succ (e, new_bb);
- e->flags |= EDGE_FALLTHRU;
- e->flags &= ~EDGE_FAKE;
+ e->flags &= ~EDGE_FALLTHRU;
+ rtx_jump_insn *ret = emit_jump_insn_after (targetm.gen_simple_return (),
+ BB_END (e->src));
+ JUMP_LABEL (ret) = simple_return_rtx;
+ emit_barrier_after_bb (e->src);
- return make_edge (new_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FAKE);
+ if (dump_file)
+ fprintf (dump_file, "Made simple_return with UID %d in bb %d\n",
+ INSN_UID (ret), e->src->index);
}
/* Try to perform a kind of shrink-wrapping, making sure the
@@ -610,13 +629,10 @@ fix_fake_fallthrough_edge (edge e)
(bb 4 is duplicated to 5; the prologue is inserted on the edge 5->3).
ENTRY_EDGE is the edge where the prologue will be placed, possibly
- changed by this function. BB_WITH is a bitmap that, if we do shrink-
- wrap, will on return contain the interesting blocks that run with
- prologue. PROLOGUE_SEQ is the prologue we will insert. */
+ changed by this function. PROLOGUE_SEQ is the prologue we will insert. */
void
-try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_with,
- rtx_insn *prologue_seq)
+try_shrink_wrapping (edge *entry_edge, rtx_insn *prologue_seq)
{
/* If we cannot shrink-wrap, are told not to shrink-wrap, or it makes
no sense to shrink-wrap: then do not shrink-wrap! */
@@ -739,6 +755,7 @@ try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_with,
reachable from PRO that we already found, and in VEC a stack of
those we still need to consider (to find successors). */
+ bitmap bb_with = BITMAP_ALLOC (NULL);
bitmap_set_bit (bb_with, pro->index);
vec<basic_block> vec;
@@ -851,6 +868,7 @@ try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_with,
if (pro == entry)
{
+ BITMAP_FREE (bb_with);
free_dominance_info (CDI_DOMINATORS);
return;
}
@@ -952,26 +970,7 @@ try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_with,
if (!bitmap_bit_p (bb_with, bb->index))
FOR_EACH_EDGE (e, ei, bb->succs)
if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
- {
- e = fix_fake_fallthrough_edge (e);
-
- e->flags &= ~EDGE_FALLTHRU;
- if (!(e->flags & EDGE_SIBCALL))
- {
- rtx_insn *ret = targetm.gen_simple_return ();
- rtx_insn *end = BB_END (e->src);
- rtx_jump_insn *start = emit_jump_insn_after (ret, end);
- JUMP_LABEL (start) = simple_return_rtx;
- e->flags &= ~EDGE_FAKE;
-
- if (dump_file)
- fprintf (dump_file,
- "Made simple_return with UID %d in bb %d\n",
- INSN_UID (start), e->src->index);
- }
-
- emit_barrier_after_bb (e->src);
- }
+ handle_simple_exit (e);
/* Finally, we want a single edge to put the prologue on. Make a new
block before the PRO block; the edge beteen them is the edge we want.
@@ -1004,5 +1003,6 @@ try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_with,
*entry_edge = make_single_succ_edge (new_bb, pro, EDGE_FALLTHRU);
force_nonfallthru (*entry_edge);
+ BITMAP_FREE (bb_with);
free_dominance_info (CDI_DOMINATORS);
}