function: Factor out make_*logue_seq

Make new functions make_split_prologue_seq, make_prologue_seq, and
make_epilogue_seq.


	* function.c (make_split_prologue_seq, make_prologue_seq,
	make_epilogue_seq): New functions, factored out from...
	(thread_prologue_and_epilogue_insns): Here.

From-SVN: r236373
This commit is contained in:
Segher Boessenkool 2016-05-18 13:07:20 +02:00 committed by Segher Boessenkool
parent 63d0f6ab56
commit fb42ed990f
2 changed files with 99 additions and 69 deletions

View File

@ -1,3 +1,9 @@
2016-05-18 Segher Boessenkool <segher@kernel.crashing.org>
* function.c (make_split_prologue_seq, make_prologue_seq,
make_epilogue_seq): New functions, factored out from...
(thread_prologue_and_epilogue_insns): Here.
2016-05-18 Segher Boessenkool <segher@kernel.crashing.org>
* function.c (rest_of_handle_thread_prologue_and_epilogue): Call

View File

@ -5768,6 +5768,91 @@ set_return_jump_label (rtx_insn *returnjump)
JUMP_LABEL (returnjump) = ret_rtx;
}
/* Return a sequence to be used as the split prologue for the current
function, or NULL. */
static rtx_insn *
make_split_prologue_seq (void)
{
if (!flag_split_stack
|| lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (cfun->decl)))
return NULL;
start_sequence ();
emit_insn (targetm.gen_split_stack_prologue ());
rtx_insn *seq = get_insns ();
end_sequence ();
record_insns (seq, NULL, &prologue_insn_hash);
set_insn_locations (seq, prologue_location);
return seq;
}
/* Return a sequence to be used as the prologue for the current function,
or NULL. */
static rtx_insn *
make_prologue_seq (void)
{
if (!targetm.have_prologue ())
return NULL;
start_sequence ();
rtx_insn *seq = targetm.gen_prologue ();
emit_insn (seq);
/* Insert an explicit USE for the frame pointer
if the profiling is on and the frame pointer is required. */
if (crtl->profile && frame_pointer_needed)
emit_use (hard_frame_pointer_rtx);
/* Retain a map of the prologue insns. */
record_insns (seq, NULL, &prologue_insn_hash);
emit_note (NOTE_INSN_PROLOGUE_END);
/* Ensure that instructions are not moved into the prologue when
profiling is on. The call to the profiling routine can be
emitted within the live range of a call-clobbered register. */
if (!targetm.profile_before_prologue () && crtl->profile)
emit_insn (gen_blockage ());
seq = get_insns ();
end_sequence ();
set_insn_locations (seq, prologue_location);
return seq;
}
/* Return a sequence to be used as the epilogue for the current function,
or NULL. */
static rtx_insn *
make_epilogue_seq (rtx_insn **epilogue_end)
{
if (!targetm.have_epilogue ())
return NULL;
start_sequence ();
*epilogue_end = emit_note (NOTE_INSN_EPILOGUE_BEG);
rtx_insn *seq = targetm.gen_epilogue ();
if (seq)
emit_jump_insn (seq);
/* Retain a map of the epilogue insns. */
record_insns (seq, NULL, &epilogue_insn_hash);
set_insn_locations (seq, epilogue_location);
seq = get_insns ();
rtx_insn *returnjump = get_last_insn ();
end_sequence ();
if (JUMP_P (returnjump))
set_return_jump_label (returnjump);
return seq;
}
/* Generate the prologue and epilogue RTL if the machine supports it. Thread
this into place with notes indicating where the prologue ends and where
@ -5822,9 +5907,7 @@ thread_prologue_and_epilogue_insns (void)
{
bool inserted;
bitmap_head bb_flags;
rtx_insn *returnjump;
rtx_insn *epilogue_end ATTRIBUTE_UNUSED;
rtx_insn *prologue_seq ATTRIBUTE_UNUSED, *split_prologue_seq ATTRIBUTE_UNUSED;
edge e, entry_edge, orig_entry_edge, exit_fallthru_edge;
edge_iterator ei;
@ -5834,7 +5917,6 @@ thread_prologue_and_epilogue_insns (void)
inserted = false;
epilogue_end = NULL;
returnjump = NULL;
/* Can't deal with multiple successors of the entry block at the
moment. Function should always have at least one entry
@ -5843,46 +5925,9 @@ thread_prologue_and_epilogue_insns (void)
entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
orig_entry_edge = entry_edge;
split_prologue_seq = NULL;
if (flag_split_stack
&& (lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (cfun->decl))
== NULL))
{
start_sequence ();
emit_insn (targetm.gen_split_stack_prologue ());
split_prologue_seq = get_insns ();
end_sequence ();
record_insns (split_prologue_seq, NULL, &prologue_insn_hash);
set_insn_locations (split_prologue_seq, prologue_location);
}
prologue_seq = NULL;
if (targetm.have_prologue ())
{
start_sequence ();
rtx_insn *seq = targetm.gen_prologue ();
emit_insn (seq);
/* Insert an explicit USE for the frame pointer
if the profiling is on and the frame pointer is required. */
if (crtl->profile && frame_pointer_needed)
emit_use (hard_frame_pointer_rtx);
/* Retain a map of the prologue insns. */
record_insns (seq, NULL, &prologue_insn_hash);
emit_note (NOTE_INSN_PROLOGUE_END);
/* Ensure that instructions are not moved into the prologue when
profiling is on. The call to the profiling routine can be
emitted within the live range of a call-clobbered register. */
if (!targetm.profile_before_prologue () && crtl->profile)
emit_insn (gen_blockage ());
prologue_seq = get_insns ();
end_sequence ();
set_insn_locations (prologue_seq, prologue_location);
}
rtx_insn *split_prologue_seq = make_split_prologue_seq ();
rtx_insn *prologue_seq = make_prologue_seq ();
rtx_insn *epilogue_seq = make_epilogue_seq (&epilogue_end);
bitmap_initialize (&bb_flags, &bitmap_default_obstack);
@ -5915,7 +5960,9 @@ thread_prologue_and_epilogue_insns (void)
exit_fallthru_edge = find_fallthru_edge (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds);
if (targetm.have_return () && exit_fallthru_edge == NULL)
/* If nothing falls through into the exit block, we don't need an
epilogue. */
if (exit_fallthru_edge == NULL)
goto epilogue_done;
/* A small fib -- epilogue is not yet completed, but we wish to re-use
@ -5947,33 +5994,10 @@ thread_prologue_and_epilogue_insns (void)
emit_note_after (NOTE_INSN_EPILOGUE_BEG, prev);
}
/* If nothing falls through into the exit block, we don't need an
epilogue. */
if (exit_fallthru_edge == NULL)
goto epilogue_done;
if (targetm.have_epilogue ())
if (epilogue_seq)
{
start_sequence ();
epilogue_end = emit_note (NOTE_INSN_EPILOGUE_BEG);
rtx_insn *seq = targetm.gen_epilogue ();
if (seq)
emit_jump_insn (seq);
/* Retain a map of the epilogue insns. */
record_insns (seq, NULL, &epilogue_insn_hash);
set_insn_locations (seq, epilogue_location);
seq = get_insns ();
returnjump = get_last_insn ();
end_sequence ();
insert_insn_on_edge (seq, exit_fallthru_edge);
insert_insn_on_edge (epilogue_seq, exit_fallthru_edge);
inserted = true;
if (JUMP_P (returnjump))
set_return_jump_label (returnjump);
}
else
{