diff options
author | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-30 10:31:30 +0000 |
---|---|---|
committer | ebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-06-30 10:31:30 +0000 |
commit | f317b732d3c8a7ae724857662356eb55b5bab071 (patch) | |
tree | b97b5461a829ec280cef91bfec87507aa0ea48a1 /gcc/reorg.c | |
parent | 0717ec39a9d30b63907795856db1f0b4e78fbde8 (diff) | |
download | gcc-f317b732d3c8a7ae724857662356eb55b5bab071.tar.gz |
RTL prologue/epilogue for SPARC
* config/sparc/sparc-protos.h (sparc_emitting_epilogue): Delete.
(sparc_skip_caller_unimp): Likewise.
(load_pic_register): Likewise.
(leaf_return_peephole_ok): Likewise.
(compute_frame_size): Rename into sparc_compute_frame_size.
(sparc_expand_prologue): New prototype.
(sparc_expand_epilogue): Likewise.
(output_return): Likewise.
(eligible_for_epilogue_delay): Rename into eligible_for_return_delay.
* config/sparc/sparc.h (INITIAL_ELIMINATION_OFFSET): Adjust call to
compute_frame_size. Move comment up.
(DELAY_SLOTS_FOR_EPILOGUE): Delete.
(ELIGIBLE_FOR_EPILOGUE_DELAY): Likewise.
(EPILOGUE_USES): Return true for %g1 if the function uses EH return.
* config/sparc/sparc.md (UNSPECV_SAVEW): New constant.
(type attribute): Add 'return' and 'savew'.
(eligible_for_return_delay): New attribute.
(return): New delay_slot.
(sibcall_epilogue): Call sparc_expand_epilogue.
(prologue): Likewise. Move up.
(save_register_window): New expander.
(save_register_windowsi): New pattern.
(save_register_windowdi): Likewise.
(epilogue): New expander.
(return_internal): New pattern.
(Return peepholes): Delete.
* config/sparc/sparc.c (SIBCALL_SLOT_EMPTY_P): New macro.
(sparc_emitting_epilogue): Delete.
(sparc_skip_caller_unimp): Likewise.
(sparc_sr_alias_set): New global variable.
(frame_base_name): Delete.
(frame_base_reg): New global variable.
(sparc_override_options): Get new alias set for save/restore.
(leaf_return_peephole_ok): Delete.
(eligible_for_epilogue_delay): Rename into eligible_for_return_delay.
Factor out code into eligible_for_restore_insn_delay.
(eligible_for_restore_insn_delay): New function extraced from above.
Use IN_UNCOND_BRANCH_DELAY_TRUE instead of IN_BRANCH_DELAY_TRUE.
(eligible_for_sibcall_delay): Use SIBCALL_SLOT_EMPTY_P.
Factor out code into eligible_for_restore_insn_delay.
(load_pic_register): Make static. Remove check.
(save_regs): Delete.
(restore_regs): Likewise.
(compute_frame_size): Rename into sparc_compute_frame_size.
Rename leaf_function into leaf_function_p.
(build_big_number): Delete.
(save_or_restore_regs): New function.
(emit_save_regs): Likewise.
(emit_restore_regs): Likewise.
(emit_stack_pointer_increment ): Likewise.
(emit_stack_pointer_decrement): Likewise.
(sparc_expand_prologue): Likewise.
(sparc_function_prologue): Rename into sparc_asm_function_prologue.
Remove all code to emit instructions.
(sparc_expand_epilogue): New function.
(sparc_function_epilogue): Rename into sparc_asm_function_epilogue.
Remove all code to emit instructions.
(output_restore): New function.
(output_return): Likewise.
(output_sibcall): Factor out code into output_restore.
(print_operand): Adjust for frame_base_reg.
* target.h (struct gcc_target): New field 'late_rtl_prologue_epilogue'.
* target-def.h (TARGET_LATE_RTL_PROLOGUE_EPILOGUE): New define.
(TARGET_INITIALIZER): Add it.
* passes.c (rest_of_compilation): Set the conditional predicate
'current_function_uses_only_leaf_regs' before sched2. If target
has 'late_rtl_prologue_epilogue', emit RTL prologue/epilogue right
before sched2.
* reorg.c (return_insn_p): New predicate.
(find_end_label): Use it.
(relax_delay_slots): Do not thread an unconditional jump that points
to the end return label.
* doc/tm.texi (Registers) <Leaf Functions>: Clarify the validity
domain of 'current_function_uses_only_leaf_regs'.
(Stack and Calling) <Function Entry>: Document new target hook
TARGET_LATE_RTL_PROLOGUE_EPILOGUE.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@83901 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reorg.c')
-rw-r--r-- | gcc/reorg.c | 37 |
1 files changed, 28 insertions, 9 deletions
diff --git a/gcc/reorg.c b/gcc/reorg.c index 9b3c9fd6f2f..da4a1a03e83 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -317,6 +317,20 @@ insn_sets_resource_p (rtx insn, struct resources *res, mark_set_resources (insn, &insn_sets, 0, include_delayed_effects); return resource_conflicts_p (&insn_sets, res); } + +/* Return TRUE if INSN is a return, possibly with a filled delay slot. */ + +static bool +return_insn_p (rtx insn) +{ + if (GET_CODE (insn) == JUMP_INSN && GET_CODE (PATTERN (insn)) == RETURN) + return true; + + if (GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE) + return return_insn_p (XVECEXP (PATTERN (insn), 0, 0)); + + return false; +} /* Find a label at the end of the function or before a RETURN. If there is none, make one. */ @@ -344,15 +358,13 @@ find_end_label (void) /* When a target threads its epilogue we might already have a suitable return insn. If so put a label before it for the end_of_function_label. */ - if (GET_CODE (insn) == BARRIER - && GET_CODE (PREV_INSN (insn)) == JUMP_INSN - && GET_CODE (PATTERN (PREV_INSN (insn))) == RETURN) + if (GET_CODE (insn) == BARRIER && return_insn_p (PREV_INSN (insn))) { rtx temp = PREV_INSN (PREV_INSN (insn)); end_of_function_label = gen_label_rtx (); LABEL_NUSES (end_of_function_label) = 0; - /* Put the label before an USE insns that may proceed the RETURN insn. */ + /* Put the label before an USE insn that may precede the RETURN insn. */ while (GET_CODE (temp) == USE) temp = PREV_INSN (temp); @@ -368,8 +380,7 @@ find_end_label (void) /* If the basic block reorder pass moves the return insn to some other place try to locate it again and put our end_of_function_label there. */ - while (insn && ! (GET_CODE (insn) == JUMP_INSN - && (GET_CODE (PATTERN (insn)) == RETURN))) + while (insn && ! return_insn_p (insn)) insn = PREV_INSN (insn); if (insn) { @@ -3275,10 +3286,18 @@ relax_delay_slots (rtx first) { target_label = JUMP_LABEL (XVECEXP (PATTERN (trial), 0, 0)); if (target_label == 0) - target_label = find_end_label (); + { + target_label = find_end_label (); + /* The following condition may be true if TRIAL contains + the unique RETURN. In this case, threading would be + a nop and we would enter an infinite loop if we did it. */ + if (next_active_insn (target_label) == trial) + target_label = 0; + } - if (redirect_with_delay_slots_safe_p (delay_insn, target_label, - insn)) + if (target_label + && redirect_with_delay_slots_safe_p (delay_insn, target_label, + insn)) { reorg_redirect_jump (delay_insn, target_label); next = insn; |