summaryrefslogtreecommitdiff
path: root/gcc/shrink-wrap.c
diff options
context:
space:
mode:
authorsegher <segher@138bc75d-0d04-0410-961f-82ee72b054a4>2016-05-04 20:57:08 +0000
committersegher <segher@138bc75d-0d04-0410-961f-82ee72b054a4>2016-05-04 20:57:08 +0000
commitf8b733224f3766dd202dd9700920b08abb52e53b (patch)
tree53ca7afba7ccf5fb7e23ff3ec271f118e9df2844 /gcc/shrink-wrap.c
parent01b8ebb6e5940eca6d158dc793424a6580c90998 (diff)
downloadgcc-f8b733224f3766dd202dd9700920b08abb52e53b.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@235905 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/shrink-wrap.c')
-rw-r--r--gcc/shrink-wrap.c171
1 files changed, 14 insertions, 157 deletions
diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c
index fe795196709..0ba1fedf161 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);
- }
- }
-}