Tested on hppa-unknown-linux-gnu and hppa64-hp-hpux11.11.  Committed
to trunk.

Dave
---

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  <dang...@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.

diff --git a/gcc/config/pa/pa.cc b/gcc/config/pa/pa.cc
index 84aa4f1b1f2..62f8764b7ca 100644
--- a/gcc/config/pa/pa.cc
+++ b/gcc/config/pa/pa.cc
@@ -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"
diff --git a/gcc/config/pa/pa.opt b/gcc/config/pa/pa.opt
index 6863f917628..d4b3063674c 100644
--- a/gcc/config/pa/pa.opt
+++ b/gcc/config/pa/pa.opt
@@ -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.
diff --git a/gcc/config/pa/predicates.md b/gcc/config/pa/predicates.md
index 0c6e41be31f..0defd2282fb 100644
--- a/gcc/config/pa/predicates.md
+++ b/gcc/config/pa/predicates.md
@@ -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))

Attachment: signature.asc
Description: PGP signature

Reply via email to