diff mbox series

[pushed,LRA] : Implement output stack pointer reloads

Message ID 8eda93dc-9cf8-c221-0f37-4cd604cc8808@redhat.com
State New
Headers show
Series [pushed,LRA] : Implement output stack pointer reloads | expand

Commit Message

Vladimir Makarov Aug. 11, 2023, 3:32 p.m. UTC
Sorry, I had some problems with email.  Therefore there are email 
duplication and they were sent to gcc@gcc.gnu.org instead of 
gcc-patches@gcc.gnu.org


On 8/9/23 16:54, Vladimir Makarov wrote:


>
> On 8/9/23 07:15, SenthilKumar.Selvaraj@microchip.com wrote:
>> Hi,
>>
>>    After turning on FP -> SP elimination after Vlad fixed
>>    an elimination issue in 
>> https://gcc.gnu.org/git?p=gcc.git;a=commit;h=2971ff7b1d564ac04b537d907c70e6093af70832,
>>    I'm now running into reload failure if arithmetic is done on SP.
>>
> I think we can permit to stack pointer output reloads.  The only thing 
> we need to update sp offset accurately for the original and reload 
> insns.  I'll try to make the patch on this week.
>
>
The following patch fixes the problem.  The patch was successfully 
bootstrapped and tested on x86_64, aarch64, and ppc64le.

The test case is actually one from GCC test suite.
diff mbox series

Patch

commit c0121083d07ffd4a8424f4be50de769d9ad0386d
Author: Vladimir N. Makarov <vmakarov@redhat.com>
Date:   Fri Aug 11 07:57:37 2023 -0400

    [LRA]: Implement output stack pointer reloads
    
    LRA prohibited output stack pointer reloads but it resulted in LRA
    failure for AVR target which has no arithmetic insns working with the
    stack pointer register.  Given patch implements the output stack
    pointer reloads.
    
    gcc/ChangeLog:
    
            * lra-constraints.cc (goal_alt_out_sp_reload_p): New flag.
            (process_alt_operands): Set the flag.
            (curr_insn_transform): Modify stack pointer offsets if output
            stack pointer reload is generated.

diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc
index 09ff6de1657..26239908747 100644
--- a/gcc/lra-constraints.cc
+++ b/gcc/lra-constraints.cc
@@ -1466,6 +1466,8 @@  static int goal_alt_dont_inherit_ops[MAX_RECOG_OPERANDS];
 static bool goal_alt_swapped;
 /* The chosen insn alternative.	 */
 static int goal_alt_number;
+/* True if output reload of the stack pointer should be generated.  */
+static bool goal_alt_out_sp_reload_p;
 
 /* True if the corresponding operand is the result of an equivalence
    substitution.  */
@@ -2128,6 +2130,9 @@  process_alt_operands (int only_alternative)
   int curr_alt_dont_inherit_ops_num;
   /* Numbers of operands whose reload pseudos should not be inherited.	*/
   int curr_alt_dont_inherit_ops[MAX_RECOG_OPERANDS];
+  /* True if output stack pointer reload should be generated for the current
+     alternative.  */
+  bool curr_alt_out_sp_reload_p;
   rtx op;
   /* The register when the operand is a subreg of register, otherwise the
      operand itself.  */
@@ -2211,7 +2216,8 @@  process_alt_operands (int only_alternative)
 	}
       reject += static_reject;
       early_clobbered_regs_num = 0;
-
+      curr_alt_out_sp_reload_p = false;
+      
       for (nop = 0; nop < n_operands; nop++)
 	{
 	  const char *p;
@@ -2682,12 +2688,10 @@  process_alt_operands (int only_alternative)
 	      bool no_regs_p;
 
 	      reject += op_reject;
-	      /* Never do output reload of stack pointer.  It makes
-		 impossible to do elimination when SP is changed in
-		 RTL.  */
-	      if (op == stack_pointer_rtx && ! frame_pointer_needed
+	      /* Mark output reload of the stack pointer.  */
+	      if (op == stack_pointer_rtx
 		  && curr_static_id->operand[nop].type != OP_IN)
-		goto fail;
+		curr_alt_out_sp_reload_p = true;
 
 	      /* If this alternative asks for a specific reg class, see if there
 		 is at least one allocatable register in that class.  */
@@ -3317,6 +3321,7 @@  process_alt_operands (int only_alternative)
 	  for (nop = 0; nop < curr_alt_dont_inherit_ops_num; nop++)
 	    goal_alt_dont_inherit_ops[nop] = curr_alt_dont_inherit_ops[nop];
 	  goal_alt_swapped = curr_swapped;
+	  goal_alt_out_sp_reload_p = curr_alt_out_sp_reload_p;
 	  best_overall = overall;
 	  best_losers = losers;
 	  best_reload_nregs = reload_nregs;
@@ -4836,6 +4841,27 @@  curr_insn_transform (bool check_only_p)
 	lra_asm_insn_error (curr_insn);
     }
   lra_process_new_insns (curr_insn, before, after, "Inserting insn reload");
+  if (goal_alt_out_sp_reload_p)
+    {
+      /* We have an output stack pointer reload -- update sp offset: */
+      rtx set;
+      bool done_p = false;
+      poly_int64 sp_offset = curr_id->sp_offset;
+      for (rtx_insn *insn = after; insn != NULL_RTX; insn = NEXT_INSN (insn))
+	if ((set = single_set (insn)) != NULL_RTX
+	    && SET_DEST (set) == stack_pointer_rtx)
+	  {
+	    lra_assert (!done_p);
+	    curr_id->sp_offset = 0;
+	    lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
+	    id->sp_offset = sp_offset;
+	    if (lra_dump_file != NULL)
+	      fprintf (lra_dump_file,
+		       "            Moving sp offset from insn %u to %u\n",
+		       INSN_UID (curr_insn), INSN_UID (insn));
+	  }
+      lra_assert (!done_p);
+    }
   return change_p;
 }