diff options
author | Segher Boessenkool <segher@kernel.crashing.org> | 2016-05-18 13:07:20 +0200 |
---|---|---|
committer | Segher Boessenkool <segher@gcc.gnu.org> | 2016-05-18 13:07:20 +0200 |
commit | fb42ed990fa449b71f9afd6c423127578358e859 (patch) | |
tree | 7f29f422924d83a8d9eba64f0e6bd57907edd544 /gcc/function.c | |
parent | 63d0f6ab560336d34b0a8f9b9b111c4a17e8737f (diff) | |
download | gcc-fb42ed990fa449b71f9afd6c423127578358e859.zip gcc-fb42ed990fa449b71f9afd6c423127578358e859.tar.gz gcc-fb42ed990fa449b71f9afd6c423127578358e859.tar.bz2 |
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
Diffstat (limited to 'gcc/function.c')
-rw-r--r-- | gcc/function.c | 162 |
1 files changed, 93 insertions, 69 deletions
diff --git a/gcc/function.c b/gcc/function.c index 9cbe71f..1c56253 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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 { |