Commit 47e4cba6 by Segher Boessenkool Committed by Segher Boessenkool

rs6000: Some rs6000_emit_epilogue improvements

This uses epilogue_type directly.  It also changes some ints to bools,
declares variables later, and simplifies some code.

There is one actual change:

   else if (info->push_p
           && DEFAULT_ABI != ABI_V4
-          && !crtl->calls_eh_return)
+          && epilogue_type != EPILOGUE_TYPE_EH_RETURN)
     {
       /* Prevent reordering memory accesses against stack pointer restore.  */

(different because calls_eh_return can be true for sibcalls).  This is
a bugfix.  The code was never exercised.

One place in the epilogue still uses crtl->calls_eh_return.  If that
is changed the prologue has to have a corresponding change, and the
emit_prologue function does not have an epilogue_type parameter, so
bail on changing this for now.  We might want to do this (saving the
CR fields to separate stack slots) always, not just for functions
calling eh_return, but that will require more investigation.


	* config/rs6000/rs6000.c (restore_saved_cr): Change a boolean
	argument to be type bool (was int before).
	(rs6000_emit_epilogue): Simplify some code.  Declare some variables
	at first use.  Use type bool for some variables.  Fix a theoretical
	eh_return bug for svr4.

From-SVN: r271361
parent d78ba518
2019-05-17 Segher Boessenkool <segher@kernel.crashing.org> 2019-05-17 Segher Boessenkool <segher@kernel.crashing.org>
* config/rs6000/rs6000.c (restore_saved_cr): Change a boolean
argument to be type bool (was int before).
(rs6000_emit_epilogue): Simplify some code. Declare some variables
at first use. Use type bool for some variables. Fix a theoretical
eh_return bug for svr4.
2019-05-17 Segher Boessenkool <segher@kernel.crashing.org>
* config/rs6000/rs6000.md (isa): New attribute. * config/rs6000/rs6000.md (isa): New attribute.
(enabled): New attribute. (enabled): New attribute.
......
...@@ -27712,7 +27712,7 @@ load_cr_save (int regno, rtx frame_reg_rtx, int offset, bool exit_func) ...@@ -27712,7 +27712,7 @@ load_cr_save (int regno, rtx frame_reg_rtx, int offset, bool exit_func)
/* Reload CR from REG. */ /* Reload CR from REG. */
static void static void
restore_saved_cr (rtx reg, int using_mfcr_multiple, bool exit_func) restore_saved_cr (rtx reg, bool using_mfcr_multiple, bool exit_func)
{ {
int count = 0; int count = 0;
int i; int i;
...@@ -27876,15 +27876,6 @@ emit_cfa_restores (rtx cfa_restores) ...@@ -27876,15 +27876,6 @@ emit_cfa_restores (rtx cfa_restores)
void void
rs6000_emit_epilogue (enum epilogue_type epilogue_type) rs6000_emit_epilogue (enum epilogue_type epilogue_type)
{ {
int sibcall = (epilogue_type == EPILOGUE_TYPE_SIBCALL);
rs6000_stack_t *info;
int restoring_GPRs_inline;
int restoring_FPRs_inline;
int using_load_multiple;
int using_mtcr_multiple;
int use_backchain_to_restore_sp;
int restore_lr;
int strategy;
HOST_WIDE_INT frame_off = 0; HOST_WIDE_INT frame_off = 0;
rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1); rtx sp_reg_rtx = gen_rtx_REG (Pmode, 1);
rtx frame_reg_rtx = sp_reg_rtx; rtx frame_reg_rtx = sp_reg_rtx;
...@@ -27896,30 +27887,38 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) ...@@ -27896,30 +27887,38 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
machine_mode fp_reg_mode = TARGET_HARD_FLOAT ? DFmode : SFmode; machine_mode fp_reg_mode = TARGET_HARD_FLOAT ? DFmode : SFmode;
int fp_reg_size = 8; int fp_reg_size = 8;
int i; int i;
bool exit_func;
unsigned ptr_regno; unsigned ptr_regno;
info = rs6000_stack_info (); rs6000_stack_t *info = rs6000_stack_info ();
strategy = info->savres_strategy; if (epilogue_type == EPILOGUE_TYPE_NORMAL && crtl->calls_eh_return)
using_load_multiple = strategy & REST_MULTIPLE; epilogue_type = EPILOGUE_TYPE_EH_RETURN;
restoring_FPRs_inline = sibcall || (strategy & REST_INLINE_FPRS);
restoring_GPRs_inline = sibcall || (strategy & REST_INLINE_GPRS); int strategy = info->savres_strategy;
using_mtcr_multiple = (rs6000_tune == PROCESSOR_PPC601 bool using_load_multiple = !!(strategy & REST_MULTIPLE);
bool restoring_GPRs_inline = !!(strategy & REST_INLINE_GPRS);
bool restoring_FPRs_inline = !!(strategy & REST_INLINE_FPRS);
if (epilogue_type == EPILOGUE_TYPE_SIBCALL)
{
restoring_GPRs_inline = true;
restoring_FPRs_inline = true;
}
bool using_mtcr_multiple = (rs6000_tune == PROCESSOR_PPC601
|| rs6000_tune == PROCESSOR_PPC603 || rs6000_tune == PROCESSOR_PPC603
|| rs6000_tune == PROCESSOR_PPC750 || rs6000_tune == PROCESSOR_PPC750
|| optimize_size); || optimize_size);
/* Restore via the backchain when we have a large frame, since this /* Restore via the backchain when we have a large frame, since this
is more efficient than an addis, addi pair. The second condition is more efficient than an addis, addi pair. The second condition
here will not trigger at the moment; We don't actually need a here will not trigger at the moment; We don't actually need a
frame pointer for alloca, but the generic parts of the compiler frame pointer for alloca, but the generic parts of the compiler
give us one anyway. */ give us one anyway. */
use_backchain_to_restore_sp = (info->total_size + (info->lr_save_p bool use_backchain_to_restore_sp
? info->lr_save_offset = (info->total_size + (info->lr_save_p ? info->lr_save_offset : 0) > 32767
: 0) > 32767 || (cfun->calls_alloca && !frame_pointer_needed));
|| (cfun->calls_alloca
&& !frame_pointer_needed)); bool restore_lr = (info->lr_save_p
restore_lr = (info->lr_save_p
&& (restoring_FPRs_inline && (restoring_FPRs_inline
|| (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR)) || (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR))
&& (restoring_GPRs_inline && (restoring_GPRs_inline
...@@ -27929,10 +27928,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) ...@@ -27929,10 +27928,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
if (WORLD_SAVE_P (info)) if (WORLD_SAVE_P (info))
{ {
int i, j; gcc_assert (epilogue_type != EPILOGUE_TYPE_SIBCALL);
char rname[30];
const char *alloc_rname;
rtvec p;
/* eh_rest_world_r10 will return to the location saved in the LR /* eh_rest_world_r10 will return to the location saved in the LR
stack slot (which is not likely to be our caller.) stack slot (which is not likely to be our caller.)
...@@ -27941,19 +27937,31 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) ...@@ -27941,19 +27937,31 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
The exception-handling stuff that was here in 2.95 is no The exception-handling stuff that was here in 2.95 is no
longer necessary. */ longer necessary. */
rtvec p;
p = rtvec_alloc (9 p = rtvec_alloc (9
+ 32 - info->first_gp_reg_save + 32 - info->first_gp_reg_save
+ LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save + LAST_ALTIVEC_REGNO + 1 - info->first_altivec_reg_save
+ 63 + 1 - info->first_fp_reg_save); + 63 + 1 - info->first_fp_reg_save);
strcpy (rname, ((crtl->calls_eh_return) ? const char *rname;
"*eh_rest_world_r10" : "*rest_world")); switch (epilogue_type)
alloc_rname = ggc_strdup (rname); {
case EPILOGUE_TYPE_NORMAL:
rname = ggc_strdup ("*rest_world");
break;
case EPILOGUE_TYPE_EH_RETURN:
rname = ggc_strdup ("*eh_rest_world_r10");
break;
j = 0; default:
gcc_unreachable ();
}
int j = 0;
RTVEC_ELT (p, j++) = ret_rtx; RTVEC_ELT (p, j++) = ret_rtx;
RTVEC_ELT (p, j++) RTVEC_ELT (p, j++)
= gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, alloc_rname)); = gen_rtx_USE (VOIDmode, gen_rtx_SYMBOL_REF (Pmode, rname));
/* The instruction pattern requires a clobber here; /* The instruction pattern requires a clobber here;
it is shared with the restVEC helper. */ it is shared with the restVEC helper. */
RTVEC_ELT (p, j++) = gen_hard_reg_clobber (Pmode, 11); RTVEC_ELT (p, j++) = gen_hard_reg_clobber (Pmode, 11);
...@@ -27972,6 +27980,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) ...@@ -27972,6 +27980,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
} }
} }
int i;
for (i = 0; i < 32 - info->first_gp_reg_save; i++) for (i = 0; i < 32 - info->first_gp_reg_save; i++)
{ {
rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i); rtx reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
...@@ -28196,7 +28205,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) ...@@ -28196,7 +28205,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
} }
else if (info->push_p else if (info->push_p
&& DEFAULT_ABI != ABI_V4 && DEFAULT_ABI != ABI_V4
&& !crtl->calls_eh_return) && epilogue_type != EPILOGUE_TYPE_EH_RETURN)
{ {
/* Prevent reordering memory accesses against stack pointer restore. */ /* Prevent reordering memory accesses against stack pointer restore. */
if (cfun->calls_alloca if (cfun->calls_alloca
...@@ -28356,7 +28365,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) ...@@ -28356,7 +28365,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
function will deallocate the stack, so we don't need to worry function will deallocate the stack, so we don't need to worry
about the unwinder restoring cr from an invalid stack frame about the unwinder restoring cr from an invalid stack frame
location. */ location. */
exit_func = (!restoring_FPRs_inline bool exit_func = (!restoring_FPRs_inline
|| (!restoring_GPRs_inline || (!restoring_GPRs_inline
&& info->first_fp_reg_save == 64)); && info->first_fp_reg_save == 64));
...@@ -28424,7 +28433,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) ...@@ -28424,7 +28433,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
restore_saved_lr (0, exit_func); restore_saved_lr (0, exit_func);
/* Load exception handler data registers, if needed. */ /* Load exception handler data registers, if needed. */
if (!sibcall && crtl->calls_eh_return) if (epilogue_type == EPILOGUE_TYPE_EH_RETURN)
{ {
unsigned int i, regno; unsigned int i, regno;
...@@ -28615,13 +28624,13 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) ...@@ -28615,13 +28624,13 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
RTX_FRAME_RELATED_P (insn) = 1; RTX_FRAME_RELATED_P (insn) = 1;
} }
if (!sibcall && crtl->calls_eh_return) if (epilogue_type == EPILOGUE_TYPE_EH_RETURN)
{ {
rtx sa = EH_RETURN_STACKADJ_RTX; rtx sa = EH_RETURN_STACKADJ_RTX;
emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa)); emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, sa));
} }
if (!sibcall && restoring_FPRs_inline) if (epilogue_type != EPILOGUE_TYPE_SIBCALL && restoring_FPRs_inline)
{ {
if (cfa_restores) if (cfa_restores)
{ {
...@@ -28646,7 +28655,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) ...@@ -28646,7 +28655,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
emit_jump_insn (targetm.gen_simple_return ()); emit_jump_insn (targetm.gen_simple_return ());
} }
if (!sibcall && !restoring_FPRs_inline) if (epilogue_type != EPILOGUE_TYPE_SIBCALL && !restoring_FPRs_inline)
{ {
bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0; bool lr = (strategy & REST_NOINLINE_FPRS_DOESNT_RESTORE_LR) == 0;
rtvec p = rtvec_alloc (3 + !!lr + 64 - info->first_fp_reg_save); rtvec p = rtvec_alloc (3 + !!lr + 64 - info->first_fp_reg_save);
...@@ -28685,7 +28694,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type) ...@@ -28685,7 +28694,7 @@ rs6000_emit_epilogue (enum epilogue_type epilogue_type)
if (cfa_restores) if (cfa_restores)
{ {
if (sibcall) if (epilogue_type == EPILOGUE_TYPE_SIBCALL)
/* Ensure the cfa_restores are hung off an insn that won't /* Ensure the cfa_restores are hung off an insn that won't
be reordered above other restores. */ be reordered above other restores. */
emit_insn (gen_blockage ()); emit_insn (gen_blockage ());
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment