diff options
author | Segher Boessenkool <segher@kernel.crashing.org> | 2016-05-04 22:57:08 +0200 |
---|---|---|
committer | Segher Boessenkool <segher@gcc.gnu.org> | 2016-05-04 22:57:08 +0200 |
commit | d07d21777f637293ebf91bff6377f2621a1e7a0c (patch) | |
tree | 53ca7afba7ccf5fb7e23ff3ec271f118e9df2844 /gcc/shrink-wrap.c | |
parent | 45676a7c8a09579a591fb8d20db90df92a1713b3 (diff) | |
download | gcc-d07d21777f637293ebf91bff6377f2621a1e7a0c.zip gcc-d07d21777f637293ebf91bff6377f2621a1e7a0c.tar.gz gcc-d07d21777f637293ebf91bff6377f2621a1e7a0c.tar.bz2 |
shrink-wrap: Remove complicated simple_return manipulations
Now that cfgcleanup knows how to optimize with return statements, the
epilogue insertion code doesn't have to deal with it itself anymore.
* function.c (emit_use_return_register_into_block): Delete.
(gen_return_pattern): Delete.
(emit_return_into_block): Delete.
(active_insn_between): Delete.
(convert_jumps_to_returns): Delete.
(emit_return_for_exit): Delete.
(thread_prologue_and_epilogue_insns): Delete all code dealing with
simple_return for shrink-wrapped blocks.
* shrink-wrap.c (try_shrink_wrapping): Insert simple_return at the
end of blocks that need one.
(get_unconverted_simple_return): Delete.
(convert_to_simple_return): Delete.
* shrink-wrap.c (get_unconverted_simple_return): Delete declaration.
(convert_to_simple_return): Ditto.
From-SVN: r235905
Diffstat (limited to 'gcc/shrink-wrap.c')
-rw-r--r-- | gcc/shrink-wrap.c | 171 |
1 files changed, 14 insertions, 157 deletions
diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c index fe79519..0ba1fed 100644 --- a/gcc/shrink-wrap.c +++ b/gcc/shrink-wrap.c @@ -946,10 +946,9 @@ try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_with, redirect_edge_and_branch_force (e, (basic_block) e->dest->aux); } - /* Change all the exits that should get a simple_return to FAKE. - They will be converted later. */ + /* Make a simple_return for those exits that run without prologue. */ - FOR_EACH_BB_FN (bb, cfun) + FOR_EACH_BB_REVERSE_FN (bb, cfun) if (!bitmap_bit_p (bb_with, bb->index)) FOR_EACH_EDGE (e, ei, bb->succs) if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun)) @@ -958,7 +957,18 @@ try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_with, e->flags &= ~EDGE_FALLTHRU; if (!(e->flags & EDGE_SIBCALL)) - e->flags |= EDGE_FAKE; + { + 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); } @@ -996,156 +1006,3 @@ try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_with, free_dominance_info (CDI_DOMINATORS); } - -/* If we're allowed to generate a simple return instruction, then by - definition we don't need a full epilogue. If the last basic - block before the exit block does not contain active instructions, - examine its predecessors and try to emit (conditional) return - instructions. */ - -edge -get_unconverted_simple_return (edge exit_fallthru_edge, bitmap_head bb_flags, - vec<edge> *unconverted_simple_returns, - rtx_insn **returnjump) -{ - if (optimize) - { - unsigned i, last; - - /* convert_jumps_to_returns may add to preds of the exit block - (but won't remove). Stop at end of current preds. */ - last = EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds); - for (i = 0; i < last; i++) - { - edge e = EDGE_I (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds, i); - if (LABEL_P (BB_HEAD (e->src)) - && !bitmap_bit_p (&bb_flags, e->src->index) - && !active_insn_between (BB_HEAD (e->src), BB_END (e->src))) - *unconverted_simple_returns - = convert_jumps_to_returns (e->src, true, - *unconverted_simple_returns); - } - } - - if (exit_fallthru_edge != NULL - && EDGE_COUNT (exit_fallthru_edge->src->preds) != 0 - && !bitmap_bit_p (&bb_flags, exit_fallthru_edge->src->index)) - { - basic_block last_bb; - - last_bb = emit_return_for_exit (exit_fallthru_edge, true); - *returnjump = BB_END (last_bb); - exit_fallthru_edge = NULL; - } - return exit_fallthru_edge; -} - -/* If there were branches to an empty LAST_BB which we tried to - convert to conditional simple_returns, but couldn't for some - reason, create a block to hold a simple_return insn and redirect - those remaining edges. */ - -void -convert_to_simple_return (edge entry_edge, edge orig_entry_edge, - bitmap_head bb_flags, rtx_insn *returnjump, - vec<edge> unconverted_simple_returns) -{ - edge e; - edge_iterator ei; - - if (!unconverted_simple_returns.is_empty ()) - { - basic_block simple_return_block_hot = NULL; - basic_block simple_return_block_cold = NULL; - edge pending_edge_hot = NULL; - edge pending_edge_cold = NULL; - basic_block exit_pred; - int i; - - gcc_assert (entry_edge != orig_entry_edge); - - /* See if we can reuse the last insn that was emitted for the - epilogue. */ - if (returnjump != NULL_RTX - && JUMP_LABEL (returnjump) == simple_return_rtx) - { - e = split_block (BLOCK_FOR_INSN (returnjump), PREV_INSN (returnjump)); - if (BB_PARTITION (e->src) == BB_HOT_PARTITION) - simple_return_block_hot = e->dest; - else - simple_return_block_cold = e->dest; - } - - /* Also check returns we might need to add to tail blocks. */ - FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) - if (EDGE_COUNT (e->src->preds) != 0 - && (e->flags & EDGE_FAKE) != 0 - && !bitmap_bit_p (&bb_flags, e->src->index)) - { - if (BB_PARTITION (e->src) == BB_HOT_PARTITION) - pending_edge_hot = e; - else - pending_edge_cold = e; - } - - /* Save a pointer to the exit's predecessor BB for use in - inserting new BBs at the end of the function. Do this - after the call to split_block above which may split - the original exit pred. */ - exit_pred = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb; - - FOR_EACH_VEC_ELT (unconverted_simple_returns, i, e) - { - basic_block *pdest_bb; - edge pending; - - if (BB_PARTITION (e->src) == BB_HOT_PARTITION) - { - pdest_bb = &simple_return_block_hot; - pending = pending_edge_hot; - } - else - { - pdest_bb = &simple_return_block_cold; - pending = pending_edge_cold; - } - - if (*pdest_bb == NULL && pending != NULL) - { - emit_return_into_block (true, pending->src); - pending->flags &= ~(EDGE_FALLTHRU | EDGE_FAKE); - *pdest_bb = pending->src; - } - else if (*pdest_bb == NULL) - { - basic_block bb; - - bb = create_basic_block (NULL, NULL, exit_pred); - BB_COPY_PARTITION (bb, e->src); - rtx_insn *ret = targetm.gen_simple_return (); - rtx_jump_insn *start = emit_jump_insn_after (ret, BB_END (bb)); - JUMP_LABEL (start) = simple_return_rtx; - emit_barrier_after (start); - - *pdest_bb = bb; - make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0); - } - redirect_edge_and_branch_force (e, *pdest_bb); - } - unconverted_simple_returns.release (); - } - - if (entry_edge != orig_entry_edge) - { - FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds) - if (EDGE_COUNT (e->src->preds) != 0 - && (e->flags & EDGE_FAKE) != 0 - && !bitmap_bit_p (&bb_flags, e->src->index)) - { - e = fix_fake_fallthrough_edge (e); - - emit_return_into_block (true, e->src); - e->flags &= ~(EDGE_FALLTHRU | EDGE_FAKE); - } - } -} |