diff options
author | Segher Boessenkool <segher@gcc.gnu.org> | 2016-05-20 00:17:53 +0200 |
---|---|---|
committer | Segher Boessenkool <segher@gcc.gnu.org> | 2016-05-20 00:17:53 +0200 |
commit | 33fec8d5b3c94cc8f73838abd27a4f0cfa2b3fd6 (patch) | |
tree | 925e8358e6a8300855c5228c2a225afc376e6b67 /gcc/shrink-wrap.c | |
parent | 6befaff6662e3a750c8de2239ded13032994baf4 (diff) | |
download | gcc-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.c | 88 |
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); } |