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:
parent
b039d06c9a
commit
44a81aaf73
3 changed files with 66 additions and 38 deletions
|
@ -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"
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Add table
Reference in a new issue