alpha.c (direct_return): Move down after struct machine_function definition...

* config/alpha/alpha.c (direct_return): Move down after
	struct machine_function definition; use saved frame_size;
	return bool.
	(struct machine_function): Add sa_mask, sa_size, frame_size.
	(alpha_sa_mask, alpha_sa_size, compute_frame_size): Merge into ...
	(alpha_compute_frame_layout): ... new function.
	(TARGET_COMPUTE_FRAME_LAYOUT): New.
	(alpha_initial_elimination_offset): Use saved sa_size.
	(alpha_vms_initial_elimination_offset): Likewise.
	(alpha_vms_can_eliminate): Remove alpha_sa_size call.
	(alpha_expand_prologue): Use saved frame data.  Merge integer
	and fp register save loops.
	(alpha_expand_epilogue): Likewise.
	(alpha_start_function): Use saved frame data.
	* config/alpha/alpha-protos.h (direct_return): Update.
	(alpha_sa_size): Remove.

From-SVN: r271970
This commit is contained in:
Richard Henderson 2019-06-05 11:16:18 -07:00 committed by Uros Bizjak
parent 6f0926e644
commit 0191520b2d
3 changed files with 128 additions and 187 deletions

View File

@ -1,3 +1,22 @@
2019-06-05 Richard Henderson <rth@twiddle.net>
* config/alpha/alpha.c (direct_return): Move down after
struct machine_function definition; use saved frame_size;
return bool.
(struct machine_function): Add sa_mask, sa_size, frame_size.
(alpha_sa_mask, alpha_sa_size, compute_frame_size): Merge into ...
(alpha_compute_frame_layout): ... new function.
(TARGET_COMPUTE_FRAME_LAYOUT): New.
(alpha_initial_elimination_offset): Use saved sa_size.
(alpha_vms_initial_elimination_offset): Likewise.
(alpha_vms_can_eliminate): Remove alpha_sa_size call.
(alpha_expand_prologue): Use saved frame data. Merge integer
and fp register save loops.
(alpha_expand_epilogue): Likewise.
(alpha_start_function): Use saved frame data.
* config/alpha/alpha-protos.h (direct_return): Update.
(alpha_sa_size): Remove.
2019-06-05 Eric Botcazou <ebotcazou@adacore.com> 2019-06-05 Eric Botcazou <ebotcazou@adacore.com>
* fold-const.c (extract_muldiv_1) <PLUS_EXPR>: Do not distribute a * fold-const.c (extract_muldiv_1) <PLUS_EXPR>: Do not distribute a

View File

@ -21,9 +21,8 @@ extern int alpha_next_sequence_number;
extern void literal_section (void); extern void literal_section (void);
extern int zap_mask (HOST_WIDE_INT); extern int zap_mask (HOST_WIDE_INT);
extern int direct_return (void); extern bool direct_return (void);
extern int alpha_sa_size (void);
extern HOST_WIDE_INT alpha_initial_elimination_offset (unsigned int, extern HOST_WIDE_INT alpha_initial_elimination_offset (unsigned int,
unsigned int); unsigned int);
extern void alpha_expand_prologue (void); extern void alpha_expand_prologue (void);

View File

@ -731,19 +731,6 @@ alpha_vector_mode_supported_p (machine_mode mode)
return mode == V8QImode || mode == V4HImode || mode == V2SImode; return mode == V8QImode || mode == V4HImode || mode == V2SImode;
} }
/* Return 1 if this function can directly return via $26. */
int
direct_return (void)
{
return (TARGET_ABI_OSF
&& reload_completed
&& alpha_sa_size () == 0
&& get_frame_size () == 0
&& crtl->outgoing_args_size == 0
&& crtl->args.pretend_args_size == 0);
}
/* Return the TLS model to use for SYMBOL. */ /* Return the TLS model to use for SYMBOL. */
static enum tls_model static enum tls_model
@ -4840,6 +4827,10 @@ struct GTY(()) alpha_links;
struct GTY(()) machine_function struct GTY(()) machine_function
{ {
unsigned HOST_WIDE_INT sa_mask;
HOST_WIDE_INT sa_size;
HOST_WIDE_INT frame_size;
/* For flag_reorder_blocks_and_partition. */ /* For flag_reorder_blocks_and_partition. */
rtx gp_save_rtx; rtx gp_save_rtx;
@ -7271,83 +7262,59 @@ static int vms_save_fp_regno;
/* Register number used to reference objects off our PV. */ /* Register number used to reference objects off our PV. */
static int vms_base_regno; static int vms_base_regno;
/* Compute register masks for saved registers. */ /* Compute register masks for saved registers, register save area size,
and total frame size. */
static void static void
alpha_sa_mask (unsigned long *imaskP, unsigned long *fmaskP) alpha_compute_frame_layout (void)
{ {
unsigned long imask = 0; unsigned HOST_WIDE_INT sa_mask = 0;
unsigned long fmask = 0; HOST_WIDE_INT frame_size;
unsigned int i; int sa_size;
/* When outputting a thunk, we don't have valid register life info, /* When outputting a thunk, we don't have valid register life info,
but assemble_start_function wants to output .frame and .mask but assemble_start_function wants to output .frame and .mask
directives. */ directives. */
if (cfun->is_thunk) if (!cfun->is_thunk)
{ {
*imaskP = 0; if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
*fmaskP = 0; sa_mask |= HOST_WIDE_INT_1U << HARD_FRAME_POINTER_REGNUM;
return;
}
if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK) /* One for every register we have to save. */
imask |= (1UL << HARD_FRAME_POINTER_REGNUM); for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (! fixed_regs[i] && ! call_used_regs[i]
&& df_regs_ever_live_p (i) && i != REG_RA)
sa_mask |= HOST_WIDE_INT_1U << i;
/* One for every register we have to save. */ /* We need to restore these for the handler. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (crtl->calls_eh_return)
if (! fixed_regs[i] && ! call_used_regs[i]
&& df_regs_ever_live_p (i) && i != REG_RA)
{
if (i < 32)
imask |= (1UL << i);
else
fmask |= (1UL << (i - 32));
}
/* We need to restore these for the handler. */
if (crtl->calls_eh_return)
{
for (i = 0; ; ++i)
{ {
unsigned regno = EH_RETURN_DATA_REGNO (i); for (unsigned i = 0; ; ++i)
if (regno == INVALID_REGNUM) {
break; unsigned regno = EH_RETURN_DATA_REGNO (i);
imask |= 1UL << regno; if (regno == INVALID_REGNUM)
break;
sa_mask |= HOST_WIDE_INT_1U << regno;
}
} }
/* If any register spilled, then spill the return address also. */
/* ??? This is required by the Digital stack unwind specification
and isn't needed if we're doing Dwarf2 unwinding. */
if (sa_mask || alpha_ra_ever_killed ())
sa_mask |= HOST_WIDE_INT_1U << REG_RA;
} }
/* If any register spilled, then spill the return address also. */ sa_size = popcount_hwi(sa_mask);
/* ??? This is required by the Digital stack unwind specification frame_size = get_frame_size ();
and isn't needed if we're doing Dwarf2 unwinding. */
if (imask || fmask || alpha_ra_ever_killed ())
imask |= (1UL << REG_RA);
*imaskP = imask;
*fmaskP = fmask;
}
int
alpha_sa_size (void)
{
unsigned long mask[2];
int sa_size = 0;
int i, j;
alpha_sa_mask (&mask[0], &mask[1]);
for (j = 0; j < 2; ++j)
for (i = 0; i < 32; ++i)
if ((mask[j] >> i) & 1)
sa_size++;
if (TARGET_ABI_OPEN_VMS) if (TARGET_ABI_OPEN_VMS)
{ {
/* Start with a stack procedure if we make any calls (REG_RA used), or /* Start with a stack procedure if we make any calls (REG_RA used), or
need a frame pointer, with a register procedure if we otherwise need need a frame pointer, with a register procedure if we otherwise need
at least a slot, and with a null procedure in other cases. */ at least a slot, and with a null procedure in other cases. */
if ((mask[0] >> REG_RA) & 1 || frame_pointer_needed) if ((sa_mask >> REG_RA) & 1 || frame_pointer_needed)
alpha_procedure_type = PT_STACK; alpha_procedure_type = PT_STACK;
else if (get_frame_size() != 0) else if (frame_size != 0)
alpha_procedure_type = PT_REGISTER; alpha_procedure_type = PT_REGISTER;
else else
alpha_procedure_type = PT_NULL; alpha_procedure_type = PT_NULL;
@ -7371,12 +7338,15 @@ alpha_sa_size (void)
/* If we want to copy PV into FP, we need to find some register /* If we want to copy PV into FP, we need to find some register
in which to save FP. */ in which to save FP. */
vms_save_fp_regno = -1; vms_save_fp_regno = -1;
if (vms_base_regno == HARD_FRAME_POINTER_REGNUM) if (vms_base_regno == HARD_FRAME_POINTER_REGNUM)
for (i = 0; i < 32; i++) for (unsigned i = 0; i < 32; i++)
if (! fixed_regs[i] && call_used_regs[i] && ! df_regs_ever_live_p (i)) if (! fixed_regs[i] && call_used_regs[i]
vms_save_fp_regno = i; && ! df_regs_ever_live_p (i))
{
vms_save_fp_regno = i;
break;
}
/* A VMS condition handler requires a stack procedure in our /* A VMS condition handler requires a stack procedure in our
implementation. (not required by the calling standard). */ implementation. (not required by the calling standard). */
@ -7401,8 +7371,34 @@ alpha_sa_size (void)
if (sa_size & 1) if (sa_size & 1)
sa_size++; sa_size++;
} }
sa_size *= 8;
return sa_size * 8; if (TARGET_ABI_OPEN_VMS)
frame_size = ALPHA_ROUND (sa_size
+ (alpha_procedure_type == PT_STACK ? 8 : 0)
+ frame_size
+ crtl->args.pretend_args_size);
else
frame_size = (ALPHA_ROUND (crtl->outgoing_args_size)
+ sa_size
+ ALPHA_ROUND (frame_size + crtl->args.pretend_args_size));
cfun->machine->sa_mask = sa_mask;
cfun->machine->sa_size = sa_size;
cfun->machine->frame_size = frame_size;
}
#undef TARGET_COMPUTE_FRAME_LAYOUT
#define TARGET_COMPUTE_FRAME_LAYOUT alpha_compute_frame_layout
/* Return 1 if this function can directly return via $26. */
bool
direct_return (void)
{
return (TARGET_ABI_OSF
&& reload_completed
&& cfun->machine->frame_size == 0);
} }
/* Define the offset between two registers, one to be eliminated, /* Define the offset between two registers, one to be eliminated,
@ -7414,7 +7410,7 @@ alpha_initial_elimination_offset (unsigned int from,
{ {
HOST_WIDE_INT ret; HOST_WIDE_INT ret;
ret = alpha_sa_size (); ret = cfun->machine->sa_size;
ret += ALPHA_ROUND (crtl->outgoing_args_size); ret += ALPHA_ROUND (crtl->outgoing_args_size);
switch (from) switch (from)
@ -7442,9 +7438,6 @@ alpha_initial_elimination_offset (unsigned int from,
static bool static bool
alpha_vms_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to) alpha_vms_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
{ {
/* We need the alpha_procedure_type to decide. Evaluate it now. */
alpha_sa_size ();
switch (alpha_procedure_type) switch (alpha_procedure_type)
{ {
case PT_NULL: case PT_NULL:
@ -7474,7 +7467,7 @@ alpha_vms_initial_elimination_offset (unsigned int from, unsigned int to)
on the proper computations and will need the register save area size on the proper computations and will need the register save area size
in most cases. */ in most cases. */
HOST_WIDE_INT sa_size = alpha_sa_size (); HOST_WIDE_INT sa_size = cfun->machine->sa_size;
/* PT_NULL procedures have no frame of their own and we only allow /* PT_NULL procedures have no frame of their own and we only allow
elimination to the stack pointer. This is the argument pointer and we elimination to the stack pointer. This is the argument pointer and we
@ -7706,24 +7699,6 @@ emit_frame_store (unsigned int regno, rtx base_reg,
emit_frame_store_1 (reg, base_reg, frame_bias, base_ofs, reg); emit_frame_store_1 (reg, base_reg, frame_bias, base_ofs, reg);
} }
/* Compute the frame size. SIZE is the size of the "naked" frame
and SA_SIZE is the size of the register save area. */
static HOST_WIDE_INT
compute_frame_size (HOST_WIDE_INT size, HOST_WIDE_INT sa_size)
{
if (TARGET_ABI_OPEN_VMS)
return ALPHA_ROUND (sa_size
+ (alpha_procedure_type == PT_STACK ? 8 : 0)
+ size
+ crtl->args.pretend_args_size);
else
return ALPHA_ROUND (crtl->outgoing_args_size)
+ sa_size
+ ALPHA_ROUND (size
+ crtl->args.pretend_args_size);
}
/* Write function prologue. */ /* Write function prologue. */
/* On vms we have two kinds of functions: /* On vms we have two kinds of functions:
@ -7745,22 +7720,17 @@ void
alpha_expand_prologue (void) alpha_expand_prologue (void)
{ {
/* Registers to save. */ /* Registers to save. */
unsigned long imask = 0; unsigned HOST_WIDE_INT sa_mask = cfun->machine->sa_mask;
unsigned long fmask = 0;
/* Stack space needed for pushing registers clobbered by us. */ /* Stack space needed for pushing registers clobbered by us. */
HOST_WIDE_INT sa_size, sa_bias; HOST_WIDE_INT sa_size = cfun->machine->sa_size;
/* Complete stack size needed. */ /* Complete stack size needed. */
HOST_WIDE_INT frame_size; HOST_WIDE_INT frame_size = cfun->machine->frame_size;
/* Probed stack size; it additionally includes the size of /* Probed stack size; it additionally includes the size of
the "reserve region" if any. */ the "reserve region" if any. */
HOST_WIDE_INT probed_size; HOST_WIDE_INT probed_size, sa_bias;
/* Offset from base reg to register save area. */ /* Offset from base reg to register save area. */
HOST_WIDE_INT reg_offset; HOST_WIDE_INT reg_offset;
rtx sa_reg; rtx sa_reg;
int i;
sa_size = alpha_sa_size ();
frame_size = compute_frame_size (get_frame_size (), sa_size);
if (flag_stack_usage_info) if (flag_stack_usage_info)
current_function_static_stack_size = frame_size; current_function_static_stack_size = frame_size;
@ -7770,8 +7740,6 @@ alpha_expand_prologue (void)
else else
reg_offset = ALPHA_ROUND (crtl->outgoing_args_size); reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
alpha_sa_mask (&imask, &fmask);
/* Emit an insn to reload GP, if needed. */ /* Emit an insn to reload GP, if needed. */
if (TARGET_ABI_OSF) if (TARGET_ABI_OSF)
{ {
@ -7910,29 +7878,15 @@ alpha_expand_prologue (void)
if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK) if (TARGET_ABI_OPEN_VMS && alpha_procedure_type == PT_STACK)
emit_frame_store (REG_PV, stack_pointer_rtx, 0, 0); emit_frame_store (REG_PV, stack_pointer_rtx, 0, 0);
/* Save register RA next. */ /* Save register RA next, followed by any other registers
if (imask & (1UL << REG_RA)) that need to be saved. */
for (unsigned i = REG_RA; sa_mask != 0; i = ctz_hwi(sa_mask))
{ {
emit_frame_store (REG_RA, sa_reg, sa_bias, reg_offset); emit_frame_store (i, sa_reg, sa_bias, reg_offset);
imask &= ~(1UL << REG_RA);
reg_offset += 8; reg_offset += 8;
sa_mask &= ~(HOST_WIDE_INT_1U << i);
} }
/* Now save any other registers required to be saved. */
for (i = 0; i < 31; i++)
if (imask & (1UL << i))
{
emit_frame_store (i, sa_reg, sa_bias, reg_offset);
reg_offset += 8;
}
for (i = 0; i < 31; i++)
if (fmask & (1UL << i))
{
emit_frame_store (i+32, sa_reg, sa_bias, reg_offset);
reg_offset += 8;
}
if (TARGET_ABI_OPEN_VMS) if (TARGET_ABI_OPEN_VMS)
{ {
/* Register frame procedures save the fp. */ /* Register frame procedures save the fp. */
@ -8019,14 +7973,11 @@ void
alpha_start_function (FILE *file, const char *fnname, alpha_start_function (FILE *file, const char *fnname,
tree decl ATTRIBUTE_UNUSED) tree decl ATTRIBUTE_UNUSED)
{ {
unsigned long imask = 0; unsigned long imask, fmask;
unsigned long fmask = 0;
/* Stack space needed for pushing registers clobbered by us. */
HOST_WIDE_INT sa_size;
/* Complete stack size needed. */ /* Complete stack size needed. */
unsigned HOST_WIDE_INT frame_size; HOST_WIDE_INT frame_size = cfun->machine->frame_size;
/* The maximum debuggable frame size. */ /* The maximum debuggable frame size. */
unsigned HOST_WIDE_INT max_frame_size = 1UL << 31; const HOST_WIDE_INT max_frame_size = HOST_WIDE_INT_1 << 31;
/* Offset from base reg to register save area. */ /* Offset from base reg to register save area. */
HOST_WIDE_INT reg_offset; HOST_WIDE_INT reg_offset;
char *entry_label = (char *) alloca (strlen (fnname) + 6); char *entry_label = (char *) alloca (strlen (fnname) + 6);
@ -8038,15 +7989,14 @@ alpha_start_function (FILE *file, const char *fnname,
#endif #endif
alpha_fnname = fnname; alpha_fnname = fnname;
sa_size = alpha_sa_size ();
frame_size = compute_frame_size (get_frame_size (), sa_size);
if (TARGET_ABI_OPEN_VMS) if (TARGET_ABI_OPEN_VMS)
reg_offset = 8 + 8 * cfun->machine->uses_condition_handler; reg_offset = 8 + 8 * cfun->machine->uses_condition_handler;
else else
reg_offset = ALPHA_ROUND (crtl->outgoing_args_size); reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
alpha_sa_mask (&imask, &fmask); imask = cfun->machine->sa_mask & 0xffffffffu;
fmask = cfun->machine->sa_mask >> 32;
/* Issue function start and label. */ /* Issue function start and label. */
if (TARGET_ABI_OPEN_VMS || !flag_inhibit_size_directive) if (TARGET_ABI_OPEN_VMS || !flag_inhibit_size_directive)
@ -8113,7 +8063,7 @@ alpha_start_function (FILE *file, const char *fnname,
fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26," fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,"
HOST_WIDE_INT_PRINT_DEC "\n", HOST_WIDE_INT_PRINT_DEC "\n",
vms_unwind_regno, vms_unwind_regno,
frame_size >= (1UL << 31) ? 0 : frame_size, frame_size >= max_frame_size ? 0 : frame_size,
reg_offset); reg_offset);
else if (!flag_inhibit_size_directive) else if (!flag_inhibit_size_directive)
fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n", fprintf (file, "\t.frame $%d," HOST_WIDE_INT_PRINT_DEC ",$26,%d\n",
@ -8193,12 +8143,11 @@ void
alpha_expand_epilogue (void) alpha_expand_epilogue (void)
{ {
/* Registers to save. */ /* Registers to save. */
unsigned long imask = 0; unsigned HOST_WIDE_INT sa_mask = cfun->machine->sa_mask;
unsigned long fmask = 0;
/* Stack space needed for pushing registers clobbered by us. */ /* Stack space needed for pushing registers clobbered by us. */
HOST_WIDE_INT sa_size; HOST_WIDE_INT sa_size = cfun->machine->sa_size;
/* Complete stack size needed. */ /* Complete stack size needed. */
HOST_WIDE_INT frame_size; HOST_WIDE_INT frame_size = cfun->machine->frame_size;
/* Offset from base reg to register save area. */ /* Offset from base reg to register save area. */
HOST_WIDE_INT reg_offset; HOST_WIDE_INT reg_offset;
int fp_is_frame_pointer, fp_offset; int fp_is_frame_pointer, fp_offset;
@ -8206,10 +8155,6 @@ alpha_expand_epilogue (void)
rtx sp_adj1, sp_adj2, mem, reg, insn; rtx sp_adj1, sp_adj2, mem, reg, insn;
rtx eh_ofs; rtx eh_ofs;
rtx cfa_restores = NULL_RTX; rtx cfa_restores = NULL_RTX;
int i;
sa_size = alpha_sa_size ();
frame_size = compute_frame_size (get_frame_size (), sa_size);
if (TARGET_ABI_OPEN_VMS) if (TARGET_ABI_OPEN_VMS)
{ {
@ -8221,8 +8166,6 @@ alpha_expand_epilogue (void)
else else
reg_offset = ALPHA_ROUND (crtl->outgoing_args_size); reg_offset = ALPHA_ROUND (crtl->outgoing_args_size);
alpha_sa_mask (&imask, &fmask);
fp_is_frame_pointer fp_is_frame_pointer
= (TARGET_ABI_OPEN_VMS = (TARGET_ABI_OPEN_VMS
? alpha_procedure_type == PT_STACK ? alpha_procedure_type == PT_STACK
@ -8261,43 +8204,23 @@ alpha_expand_epilogue (void)
} }
/* Restore registers in order, excepting a true frame pointer. */ /* Restore registers in order, excepting a true frame pointer. */
for (unsigned i = REG_RA; sa_mask != 0; i = ctz_hwi(sa_mask))
mem = gen_frame_mem (DImode, plus_constant (Pmode, sa_reg, reg_offset)); {
reg = gen_rtx_REG (DImode, REG_RA); if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer)
emit_move_insn (reg, mem); fp_offset = reg_offset;
cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores); else
{
reg_offset += 8; mem = gen_frame_mem (DImode,
imask &= ~(1UL << REG_RA); plus_constant (Pmode, sa_reg,
reg_offset));
for (i = 0; i < 31; ++i) reg = gen_rtx_REG (DImode, i);
if (imask & (1UL << i)) emit_move_insn (reg, mem);
{ cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
if (i == HARD_FRAME_POINTER_REGNUM && fp_is_frame_pointer) cfa_restores);
fp_offset = reg_offset; }
else reg_offset += 8;
{ sa_mask &= ~(HOST_WIDE_INT_1U << i);
mem = gen_frame_mem (DImode, }
plus_constant (Pmode, sa_reg,
reg_offset));
reg = gen_rtx_REG (DImode, i);
emit_move_insn (reg, mem);
cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg,
cfa_restores);
}
reg_offset += 8;
}
for (i = 0; i < 31; ++i)
if (fmask & (1UL << i))
{
mem = gen_frame_mem (DFmode, plus_constant (Pmode, sa_reg,
reg_offset));
reg = gen_rtx_REG (DFmode, i+32);
emit_move_insn (reg, mem);
cfa_restores = alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
reg_offset += 8;
}
} }
if (frame_size || eh_ofs) if (frame_size || eh_ofs)