hppa: Add LRA support

LRA is not enabled as default since there are some new test fails
remaining to resolve.

2024-10-18  John David Anglin  <danglin@gcc.gnu.org>

gcc/ChangeLog:

	PR target/113933
	* config/pa/pa.cc (pa_use_lra_p): Declare.
	(TARGET_LRA_P): Change define to pa_use_lra_p.
	(pa_use_lra_p): New function.
	(legitimize_pic_address): Also check lra_in_progress.
	(pa_emit_move_sequence): Likewise.
	(pa_legitimate_constant_p): Likewise.
	(pa_legitimate_address_p): Likewise.
	(pa_secondary_reload): For floating-point loads and stores,
	return NO_REGS for REG and SUBREG operands.  Return
	GENERAL_REGS for some shift register spills.
	* config/pa/pa.opt: Add mlra option.
	* config/pa/predicates.md (integer_store_memory_operand):
	Also check lra_in_progress.
	(floating_point_store_memory_operand): Likewise.
	(reg_before_reload_operand): Likewise.
This commit is contained in:
John David Anglin 2024-10-18 11:28:23 -04:00
parent b039d06c9a
commit 44a81aaf73
3 changed files with 66 additions and 38 deletions

View file

@ -209,6 +209,7 @@ static bool pa_can_change_mode_class (machine_mode, machine_mode, reg_class_t);
static HOST_WIDE_INT pa_starting_frame_offset (void);
static section* pa_elf_select_rtx_section(machine_mode, rtx, unsigned HOST_WIDE_INT) ATTRIBUTE_UNUSED;
static void pa_atomic_assign_expand_fenv (tree *, tree *, tree *);
static bool pa_use_lra_p (void);
/* The following extra sections are only used for SOM. */
static GTY(()) section *som_readonly_data_section;
@ -412,7 +413,7 @@ static size_t n_deferred_plabels = 0;
#define TARGET_LEGITIMATE_ADDRESS_P pa_legitimate_address_p
#undef TARGET_LRA_P
#define TARGET_LRA_P hook_bool_void_false
#define TARGET_LRA_P pa_use_lra_p
#undef TARGET_HARD_REGNO_NREGS
#define TARGET_HARD_REGNO_NREGS pa_hard_regno_nregs
@ -973,7 +974,7 @@ legitimize_pic_address (rtx orig, machine_mode mode, rtx reg)
/* During and after reload, we need to generate a REG_LABEL_OPERAND note
and update LABEL_NUSES because this is not done automatically. */
if (reload_in_progress || reload_completed)
if (lra_in_progress || reload_in_progress || reload_completed)
{
/* Extract LABEL_REF. */
if (GET_CODE (orig) == CONST)
@ -998,7 +999,7 @@ legitimize_pic_address (rtx orig, machine_mode mode, rtx reg)
/* Before reload, allocate a temporary register for the intermediate
result. This allows the sequence to be deleted when the final
result is unused and the insns are trivially dead. */
tmp_reg = ((reload_in_progress || reload_completed)
tmp_reg = ((lra_in_progress || reload_in_progress || reload_completed)
? reg : gen_reg_rtx (Pmode));
if (function_label_operand (orig, VOIDmode))
@ -1959,11 +1960,13 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
copy_to_mode_reg (Pmode, XEXP (operand1, 0)));
if (scratch_reg
&& reload_in_progress && GET_CODE (operand0) == REG
&& reload_in_progress
&& GET_CODE (operand0) == REG
&& REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
operand0 = reg_equiv_mem (REGNO (operand0));
else if (scratch_reg
&& reload_in_progress && GET_CODE (operand0) == SUBREG
&& reload_in_progress
&& GET_CODE (operand0) == SUBREG
&& GET_CODE (SUBREG_REG (operand0)) == REG
&& REGNO (SUBREG_REG (operand0)) >= FIRST_PSEUDO_REGISTER)
{
@ -1976,11 +1979,13 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
}
if (scratch_reg
&& reload_in_progress && GET_CODE (operand1) == REG
&& reload_in_progress
&& GET_CODE (operand1) == REG
&& REGNO (operand1) >= FIRST_PSEUDO_REGISTER)
operand1 = reg_equiv_mem (REGNO (operand1));
else if (scratch_reg
&& reload_in_progress && GET_CODE (operand1) == SUBREG
&& reload_in_progress
&& GET_CODE (operand1) == SUBREG
&& GET_CODE (SUBREG_REG (operand1)) == REG
&& REGNO (SUBREG_REG (operand1)) >= FIRST_PSEUDO_REGISTER)
{
@ -1992,12 +1997,16 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
operand1 = alter_subreg (&temp, true);
}
if (scratch_reg && reload_in_progress && GET_CODE (operand0) == MEM
if (scratch_reg
&& (lra_in_progress || reload_in_progress)
&& GET_CODE (operand0) == MEM
&& ((tem = find_replacement (&XEXP (operand0, 0)))
!= XEXP (operand0, 0)))
operand0 = replace_equiv_address (operand0, tem);
if (scratch_reg && reload_in_progress && GET_CODE (operand1) == MEM
if (scratch_reg
&& (lra_in_progress || reload_in_progress)
&& GET_CODE (operand1) == MEM
&& ((tem = find_replacement (&XEXP (operand1, 0)))
!= XEXP (operand1, 0)))
operand1 = replace_equiv_address (operand1, tem);
@ -2255,7 +2264,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
else if (GET_CODE (operand0) == MEM)
{
if (mode == DFmode && operand1 == CONST0_RTX (mode)
&& !(reload_in_progress || reload_completed))
&& !(lra_in_progress || reload_in_progress || reload_completed))
{
rtx temp = gen_reg_rtx (DFmode);
@ -2269,7 +2278,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
emit_insn (gen_rtx_SET (operand0, operand1));
return 1;
}
if (! (reload_in_progress || reload_completed))
if (! (lra_in_progress || reload_in_progress || reload_completed))
{
operands[0] = validize_mem (operand0);
operands[1] = operand1 = force_reg (mode, operand1);
@ -2309,7 +2318,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
rtx temp, const_part;
/* Figure out what (if any) scratch register to use. */
if (reload_in_progress || reload_completed)
if (lra_in_progress || reload_in_progress || reload_completed)
{
scratch_reg = scratch_reg ? scratch_reg : operand0;
/* SCRATCH_REG will hold an address and maybe the actual
@ -2367,7 +2376,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
rtx_insn *insn;
rtx temp;
if (reload_in_progress || reload_completed)
if (lra_in_progress || reload_in_progress || reload_completed)
{
temp = scratch_reg ? scratch_reg : operand0;
/* TEMP will hold an address and maybe the actual
@ -2411,7 +2420,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
{
rtx temp, set;
if (reload_in_progress || reload_completed)
if (lra_in_progress || reload_in_progress || reload_completed)
{
temp = scratch_reg ? scratch_reg : operand0;
/* TEMP will hold an address and maybe the actual
@ -2502,7 +2511,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg)
}
}
if (reload_in_progress || reload_completed)
if (lra_in_progress || reload_in_progress || reload_completed)
temp = scratch_reg ? scratch_reg : operand0;
else
temp = gen_reg_rtx (mode);
@ -6408,24 +6417,21 @@ pa_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
if (regno >= FIRST_PSEUDO_REGISTER || GET_CODE (x) == SUBREG)
regno = true_regnum (x);
/* Handle reloads for floating point loads and stores. */
if ((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
&& FP_REG_CLASS_P (rclass))
/* Handle reloads for floating-point loads and stores. */
if (regno < 0 && FP_REG_CLASS_P (rclass))
{
if (MEM_P (x))
{
x = XEXP (x, 0);
if (REG_P (x) || GET_CODE (x) == SUBREG)
return NO_REGS;
/* We don't need a secondary reload for indexed memory addresses.
/* We don't need a secondary reload for indexed memory addresses.
When INT14_OK_STRICT is true, it might appear that we could
directly allow register indirect memory addresses. However,
this doesn't work because we don't support SUBREGs in
floating-point register copies and reload doesn't tell us
when it's going to use a SUBREG. */
if (IS_INDEX_ADDR_P (x))
return NO_REGS;
}
When INT14_OK_STRICT is true, it might appear that we could
directly allow register indirect memory addresses. However,
this doesn't work because we don't support SUBREGs in
floating-point register copies and reload doesn't tell us
when it's going to use a SUBREG. */
if (MEM_P (x) && IS_INDEX_ADDR_P (XEXP (x, 0)))
return NO_REGS;
/* Request a secondary reload with a general scratch register
for everything else. ??? Could symbolic operands be handled
@ -6442,8 +6448,14 @@ pa_secondary_reload (bool in_p, rtx x, reg_class_t rclass_i,
if (rclass == SHIFT_REGS)
{
/* Handle spill. */
if (regno >= FIRST_PSEUDO_REGISTER || regno < 0)
if (regno < 0)
{
if (REG_P (x) || GET_CODE (x) == SUBREG)
return GENERAL_REGS;
if (TARGET_64BIT && GET_CODE (x) == CONST_INT)
return GENERAL_REGS;
sri->icode = (in_p
? direct_optab_handler (reload_in_optab, mode)
: direct_optab_handler (reload_out_optab, mode));
@ -10875,6 +10887,7 @@ pa_legitimate_constant_p (machine_mode mode, rtx x)
if (TARGET_64BIT
&& HOST_BITS_PER_WIDE_INT > 32
&& GET_CODE (x) == CONST_INT
&& !lra_in_progress
&& !reload_in_progress
&& !reload_completed
&& !LEGITIMATE_64BIT_CONST_INT_P (INTVAL (x))
@ -11026,7 +11039,8 @@ pa_legitimate_address_p (machine_mode mode, rtx x, bool strict, code_helper)
reload on targets with non-equivalent space registers. */
&& (TARGET_NO_SPACE_REGS
|| reload_completed
|| (reload_in_progress && HARD_REGISTER_P (base))
|| ((lra_in_progress || reload_in_progress)
&& HARD_REGISTER_P (base))
|| REG_POINTER (base))
&& GET_CODE (index) == MULT
&& REG_P (XEXP (index, 0))
@ -11334,4 +11348,12 @@ pa_atomic_assign_expand_fenv (tree *hold, tree *clear, tree *update)
reload_fenv, restore_fnenv), update_call);
}
/* Implement TARGET_LRA_P. */
static bool
pa_use_lra_p ()
{
return pa_lra_p;
}
#include "gt-pa.h"

View file

@ -86,6 +86,10 @@ mlong-calls
Target Mask(LONG_CALLS)
Always generate long calls.
mlra
Target Var(pa_lra_p) Init(0)
Use LRA instead of reload (transitional).
mlong-load-store
Target Mask(LONG_LOAD_STORE)
Emit long load/store sequences.

View file

@ -300,7 +300,7 @@
(define_predicate "integer_store_memory_operand"
(match_code "reg,mem")
{
if (reload_in_progress
if ((lra_in_progress || reload_in_progress)
&& REG_P (op)
&& REGNO (op) >= FIRST_PSEUDO_REGISTER
&& reg_renumber [REGNO (op)] < 0)
@ -312,7 +312,7 @@
REG+D instructions in pa_emit_move_sequence. Further, the Q
constraint is used in more than simple move instructions. So,
we must return true and let reload handle the reload. */
if (reload_in_progress)
if (lra_in_progress || reload_in_progress)
return true;
/* Extract CONST_INT operand. */
@ -326,7 +326,8 @@
if (!MEM_P (op))
return false;
return ((reload_in_progress || memory_address_p (mode, XEXP (op, 0)))
return ((lra_in_progress || reload_in_progress
|| memory_address_p (mode, XEXP (op, 0)))
&& !IS_LO_SUM_DLT_ADDR_P (XEXP (op, 0))
&& !IS_INDEX_ADDR_P (XEXP (op, 0)));
})
@ -346,7 +347,7 @@
(define_predicate "floating_point_store_memory_operand"
(match_code "reg,mem")
{
if (reload_in_progress
if ((lra_in_progress || reload_in_progress)
&& REG_P (op)
&& REGNO (op) >= FIRST_PSEUDO_REGISTER
&& reg_renumber [REGNO (op)] < 0)
@ -366,7 +367,8 @@
if (!MEM_P (op))
return false;
return ((reload_in_progress || memory_address_p (mode, XEXP (op, 0)))
return ((lra_in_progress || reload_in_progress
|| memory_address_p (mode, XEXP (op, 0)))
&& (INT14_OK_STRICT || !symbolic_memory_operand (op, VOIDmode))
&& !IS_LO_SUM_DLT_ADDR_P (XEXP (op, 0))
&& !IS_INDEX_ADDR_P (XEXP (op, 0)));
@ -555,7 +557,7 @@
if (register_operand (op, mode))
return true;
if (!reload_in_progress && !reload_completed)
if (!lra_in_progress && !reload_in_progress && !reload_completed)
return false;
if (! MEM_P (op))