diff mbox series

[1/3,amdgcn] Update CFI configuration

Message ID 20210622171443.1287801-2-abidh@codesourcery.com
State New
Headers show
Series Improve debug support. | expand

Commit Message

Hafiz Abid Qadeer June 22, 2021, 5:14 p.m. UTC
Currently we don't get any call frame information for the amdgcn target.
This patch makes necessary adjustments to generate CFI that can work with
ROCGDB (ROCm 3.8+).

gcc/

	* config/gcn/gcn.c (move_callee_saved_registers): Emit CFI notes for
	prologue register saves.
	(gcn_debug_unwind_info): Use UI_DWARF2.
	(gcn_dwarf_register_number): Map DWARF_LINK_REGISTER to DWARF PC.
	(gcn_dwarf_register_span): DWARF_LINK_REGISTER doesn't span.
	* config/gcn/gcn.h: (DWARF_FRAME_RETURN_COLUMN): New define.
	(DWARF_LINK_REGISTER): New define.
	(FIRST_PSEUDO_REGISTER): Increment.
	(FIXED_REGISTERS): Add entry for DWARF_LINK_REGISTER.
	(CALL_USED_REGISTERS): Likewise.
	(REGISTER_NAMES): Likewise.
---
 gcc/config/gcn/gcn.c | 82 ++++++++++++++++++++++++++++++++++++++++----
 gcc/config/gcn/gcn.h | 10 +++---
 2 files changed, 81 insertions(+), 11 deletions(-)

Comments

Andrew Stubbs June 23, 2021, 9:32 a.m. UTC | #1
On 22/06/2021 18:14, Hafiz Abid Qadeer wrote:
> Currently we don't get any call frame information for the amdgcn target.
> This patch makes necessary adjustments to generate CFI that can work with
> ROCGDB (ROCm 3.8+).
> 
> gcc/
> 
> 	* config/gcn/gcn.c (move_callee_saved_registers): Emit CFI notes for
> 	prologue register saves.
> 	(gcn_debug_unwind_info): Use UI_DWARF2.
> 	(gcn_dwarf_register_number): Map DWARF_LINK_REGISTER to DWARF PC.
> 	(gcn_dwarf_register_span): DWARF_LINK_REGISTER doesn't span.
> 	* config/gcn/gcn.h: (DWARF_FRAME_RETURN_COLUMN): New define.
> 	(DWARF_LINK_REGISTER): New define.
> 	(FIRST_PSEUDO_REGISTER): Increment.
> 	(FIXED_REGISTERS): Add entry for DWARF_LINK_REGISTER.
> 	(CALL_USED_REGISTERS): Likewise.
> 	(REGISTER_NAMES): Likewise.
> ---
>   gcc/config/gcn/gcn.c | 82 ++++++++++++++++++++++++++++++++++++++++----
>   gcc/config/gcn/gcn.h | 10 +++---
>   2 files changed, 81 insertions(+), 11 deletions(-)
> 
> diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c
> index 283a91fe50a..3ab16548aad 100644
> --- a/gcc/config/gcn/gcn.c
> +++ b/gcc/config/gcn/gcn.c
> @@ -2649,6 +2649,7 @@ move_callee_saved_registers (rtx sp, machine_function *offsets,
>     rtx as = gen_rtx_CONST_INT (VOIDmode, STACK_ADDR_SPACE);
>     HOST_WIDE_INT exec_set = 0;
>     int offreg_set = 0;
> +  auto_vec<int> saved_sgprs;
>   
>     start_sequence ();
>   
> @@ -2665,7 +2666,10 @@ move_callee_saved_registers (rtx sp, machine_function *offsets,
>   	int lane = saved_scalars % 64;
>   
>   	if (prologue)
> -	  emit_insn (gen_vec_setv64si (vreg, reg, GEN_INT (lane)));
> +	  {
> +	    emit_insn (gen_vec_setv64si (vreg, reg, GEN_INT (lane)));
> +	    saved_sgprs.safe_push (regno);
> +	  }
>   	else
>   	  emit_insn (gen_vec_extractv64sisi (reg, vreg, GEN_INT (lane)));
>   
> @@ -2698,7 +2702,7 @@ move_callee_saved_registers (rtx sp, machine_function *offsets,
>   				  gcn_gen_undef (V64SImode), exec));
>   
>     /* Move vectors.  */
> -  for (regno = FIRST_VGPR_REG, offset = offsets->pretend_size;
> +  for (regno = FIRST_VGPR_REG, offset = 0;
>          regno < FIRST_PSEUDO_REGISTER; regno++)
>       if ((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))
>   	|| (regno == VGPR_REGNO (6) && saved_scalars > 0)
> @@ -2719,8 +2723,67 @@ move_callee_saved_registers (rtx sp, machine_function *offsets,
>   	  }
>   
>   	if (prologue)
> -	  emit_insn (gen_scatterv64si_insn_1offset_exec (vsp, const0_rtx, reg,
> -							 as, const0_rtx, exec));
> +	  {
> +	    rtx insn = emit_insn (gen_scatterv64si_insn_1offset_exec
> +				  (vsp, const0_rtx, reg, as, const0_rtx,
> +				   exec));
> +
> +	    /* Add CFI metadata.  */
> +	    rtx note;
> +	    if (regno == VGPR_REGNO (6) || regno == VGPR_REGNO (7))
> +	      {
> +		int start = (regno == VGPR_REGNO (7) ? 64 : 0);
> +		int count = MIN (saved_scalars - start, 64);
> +		int add_lr = (regno == VGPR_REGNO (6)
> +			      && df_regs_ever_live_p (LINK_REGNUM));
> +		int lrdest = -1;
> +		rtvec seq = rtvec_alloc (count + add_lr);
> +
> +		/* Add an REG_FRAME_RELATED_EXPR entry for each scalar
> +		   register that was saved in this batch.  */
> +		for (int idx = 0; idx < count; idx++)
> +		  {
> +		    int stackaddr = offset + idx * 4;
> +		    rtx dest = gen_rtx_MEM (SImode,
> +					    gen_rtx_PLUS
> +					    (DImode, sp,
> +					     GEN_INT (stackaddr)));
> +		    rtx src = gen_rtx_REG (SImode, saved_sgprs[start + idx]);
> +		    rtx set = gen_rtx_SET (dest, src);
> +		    RTX_FRAME_RELATED_P (set) = 1;
> +		    RTVEC_ELT (seq, idx) = set;
> +
> +		    if (saved_sgprs[start + idx] == LINK_REGNUM)
> +		      lrdest = stackaddr;
> +		  }
> +
> +		/* Add an additional expression for DWARF_LINK_REGISTER if
> +		   LINK_REGNUM was saved.  */
> +		if (lrdest != -1)
> +		  {
> +		    rtx dest = gen_rtx_MEM (DImode,
> +					    gen_rtx_PLUS
> +					    (DImode, sp,
> +					     GEN_INT (lrdest)));
> +		    rtx src = gen_rtx_REG (DImode, DWARF_LINK_REGISTER);
> +		    rtx set = gen_rtx_SET (dest, src);
> +		    RTX_FRAME_RELATED_P (set) = 1;
> +		    RTVEC_ELT (seq, count) = set;
> +		  }
> +
> +		note = gen_rtx_SEQUENCE (VOIDmode, seq);
> +	      }
> +	    else
> +	      {
> +		rtx dest = gen_rtx_MEM (V64SImode,
> +					gen_rtx_PLUS (DImode, sp,
> +						      GEN_INT (offset)));
> +		rtx src = gen_rtx_REG (V64SImode, regno);
> +		note = gen_rtx_SET (dest, src);
> +	      }
> +	    RTX_FRAME_RELATED_P (insn) = 1;
> +	    add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
> +	  }
>   	else
>   	  emit_insn (gen_gatherv64si_insn_1offset_exec
>   		     (reg, vsp, const0_rtx, as, const0_rtx,
> @@ -3224,8 +3287,7 @@ gcn_cannot_copy_insn_p (rtx_insn *insn)
>   static enum unwind_info_type
>   gcn_debug_unwind_info ()
>   {
> -  /* No support for debug info, yet.  */
> -  return UI_NONE;
> +  return UI_DWARF2;
>   }
>   
>   /* Determine if there is a suitable hardware conversion instruction.
> @@ -6214,6 +6276,8 @@ gcn_dwarf_register_number (unsigned int regno)
>       return 768;  */
>     else if (regno == SCC_REG)
>       return 128;
> +  else if (regno == DWARF_LINK_REGISTER)
> +    return 16;
>     else if (SGPR_REGNO_P (regno))
>       {
>         if (regno - FIRST_SGPR_REG < 64)
> @@ -6243,8 +6307,12 @@ gcn_dwarf_register_span (rtx rtl)
>     if (GET_MODE_SIZE (mode) != 8)
>       return NULL_RTX;
>   
> -  rtx p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
>     unsigned regno = REGNO (rtl);
> +
> +  if (regno == DWARF_LINK_REGISTER)
> +    return NULL_RTX;
> +
> +  rtx p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
>     XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
>     XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
>   
> diff --git a/gcc/config/gcn/gcn.h b/gcc/config/gcn/gcn.h
> index eba4646f1bf..4992a4c02ef 100644
> --- a/gcc/config/gcn/gcn.h
> +++ b/gcc/config/gcn/gcn.h
> @@ -85,6 +85,7 @@
>   #define FIRST_PARM_OFFSET(FNDECL)    0
>   #define DYNAMIC_CHAIN_ADDRESS(FP)    plus_constant (Pmode, (FP), -16)
>   #define INCOMING_RETURN_ADDR_RTX     gen_rtx_REG (Pmode, LINK_REGNUM)
> +#define DWARF_FRAME_RETURN_COLUMN    16
>   #define STACK_DYNAMIC_OFFSET(FNDECL) (-crtl->outgoing_args_size)
>   #define ACCUMULATE_OUTGOING_ARGS     1
>   #define RETURN_ADDR_RTX(COUNT,FRAMEADDR) \
> @@ -135,7 +136,8 @@
>   #define WORK_ITEM_ID_Z_REG	  162
>   #define SOFT_ARG_REG		  416
>   #define FRAME_POINTER_REGNUM	  418
> -#define FIRST_PSEUDO_REGISTER	  420
> +#define DWARF_LINK_REGISTER	  420
> +#define FIRST_PSEUDO_REGISTER	  421
>   
>   #define FIRST_PARM_REG 24
>   #define NUM_PARM_REGS  6
> @@ -197,7 +199,7 @@
>       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>       /* Other registers.  */			    \
> -    1, 1, 1, 1					    \
> +    1, 1, 1, 1, 1				    \
>   }
>   
>   #define CALL_USED_REGISTERS {			    \
> @@ -235,7 +237,7 @@
>       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
>       /* Other registers.  */			    \
> -    1, 1, 1, 1					    \
> +    1, 1, 1, 1, 1				    \
>   }
>   
>   
> @@ -514,7 +516,7 @@ enum gcn_address_spaces
>       "v236", "v237", "v238", "v239", "v240", "v241", "v242", "v243", "v244", \
>       "v245", "v246", "v247", "v248", "v249", "v250", "v251", "v252", "v253", \
>       "v254", "v255",							    \
> -    "?ap0", "?ap1", "?fp0", "?fp1" }
> +    "?ap0", "?ap1", "?fp0", "?fp1", "?dwlr" }
>   
>   #define PRINT_OPERAND(FILE, X, CODE)  print_operand(FILE, X, CODE)
>   #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  print_operand_address (FILE, ADDR)
> 

OK.

Andrew
diff mbox series

Patch

diff --git a/gcc/config/gcn/gcn.c b/gcc/config/gcn/gcn.c
index 283a91fe50a..3ab16548aad 100644
--- a/gcc/config/gcn/gcn.c
+++ b/gcc/config/gcn/gcn.c
@@ -2649,6 +2649,7 @@  move_callee_saved_registers (rtx sp, machine_function *offsets,
   rtx as = gen_rtx_CONST_INT (VOIDmode, STACK_ADDR_SPACE);
   HOST_WIDE_INT exec_set = 0;
   int offreg_set = 0;
+  auto_vec<int> saved_sgprs;
 
   start_sequence ();
 
@@ -2665,7 +2666,10 @@  move_callee_saved_registers (rtx sp, machine_function *offsets,
 	int lane = saved_scalars % 64;
 
 	if (prologue)
-	  emit_insn (gen_vec_setv64si (vreg, reg, GEN_INT (lane)));
+	  {
+	    emit_insn (gen_vec_setv64si (vreg, reg, GEN_INT (lane)));
+	    saved_sgprs.safe_push (regno);
+	  }
 	else
 	  emit_insn (gen_vec_extractv64sisi (reg, vreg, GEN_INT (lane)));
 
@@ -2698,7 +2702,7 @@  move_callee_saved_registers (rtx sp, machine_function *offsets,
 				  gcn_gen_undef (V64SImode), exec));
 
   /* Move vectors.  */
-  for (regno = FIRST_VGPR_REG, offset = offsets->pretend_size;
+  for (regno = FIRST_VGPR_REG, offset = 0;
        regno < FIRST_PSEUDO_REGISTER; regno++)
     if ((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))
 	|| (regno == VGPR_REGNO (6) && saved_scalars > 0)
@@ -2719,8 +2723,67 @@  move_callee_saved_registers (rtx sp, machine_function *offsets,
 	  }
 
 	if (prologue)
-	  emit_insn (gen_scatterv64si_insn_1offset_exec (vsp, const0_rtx, reg,
-							 as, const0_rtx, exec));
+	  {
+	    rtx insn = emit_insn (gen_scatterv64si_insn_1offset_exec
+				  (vsp, const0_rtx, reg, as, const0_rtx,
+				   exec));
+
+	    /* Add CFI metadata.  */
+	    rtx note;
+	    if (regno == VGPR_REGNO (6) || regno == VGPR_REGNO (7))
+	      {
+		int start = (regno == VGPR_REGNO (7) ? 64 : 0);
+		int count = MIN (saved_scalars - start, 64);
+		int add_lr = (regno == VGPR_REGNO (6)
+			      && df_regs_ever_live_p (LINK_REGNUM));
+		int lrdest = -1;
+		rtvec seq = rtvec_alloc (count + add_lr);
+
+		/* Add an REG_FRAME_RELATED_EXPR entry for each scalar
+		   register that was saved in this batch.  */
+		for (int idx = 0; idx < count; idx++)
+		  {
+		    int stackaddr = offset + idx * 4;
+		    rtx dest = gen_rtx_MEM (SImode,
+					    gen_rtx_PLUS
+					    (DImode, sp,
+					     GEN_INT (stackaddr)));
+		    rtx src = gen_rtx_REG (SImode, saved_sgprs[start + idx]);
+		    rtx set = gen_rtx_SET (dest, src);
+		    RTX_FRAME_RELATED_P (set) = 1;
+		    RTVEC_ELT (seq, idx) = set;
+
+		    if (saved_sgprs[start + idx] == LINK_REGNUM)
+		      lrdest = stackaddr;
+		  }
+
+		/* Add an additional expression for DWARF_LINK_REGISTER if
+		   LINK_REGNUM was saved.  */
+		if (lrdest != -1)
+		  {
+		    rtx dest = gen_rtx_MEM (DImode,
+					    gen_rtx_PLUS
+					    (DImode, sp,
+					     GEN_INT (lrdest)));
+		    rtx src = gen_rtx_REG (DImode, DWARF_LINK_REGISTER);
+		    rtx set = gen_rtx_SET (dest, src);
+		    RTX_FRAME_RELATED_P (set) = 1;
+		    RTVEC_ELT (seq, count) = set;
+		  }
+
+		note = gen_rtx_SEQUENCE (VOIDmode, seq);
+	      }
+	    else
+	      {
+		rtx dest = gen_rtx_MEM (V64SImode,
+					gen_rtx_PLUS (DImode, sp,
+						      GEN_INT (offset)));
+		rtx src = gen_rtx_REG (V64SImode, regno);
+		note = gen_rtx_SET (dest, src);
+	      }
+	    RTX_FRAME_RELATED_P (insn) = 1;
+	    add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
+	  }
 	else
 	  emit_insn (gen_gatherv64si_insn_1offset_exec
 		     (reg, vsp, const0_rtx, as, const0_rtx,
@@ -3224,8 +3287,7 @@  gcn_cannot_copy_insn_p (rtx_insn *insn)
 static enum unwind_info_type
 gcn_debug_unwind_info ()
 {
-  /* No support for debug info, yet.  */
-  return UI_NONE;
+  return UI_DWARF2;
 }
 
 /* Determine if there is a suitable hardware conversion instruction.
@@ -6214,6 +6276,8 @@  gcn_dwarf_register_number (unsigned int regno)
     return 768;  */
   else if (regno == SCC_REG)
     return 128;
+  else if (regno == DWARF_LINK_REGISTER)
+    return 16;
   else if (SGPR_REGNO_P (regno))
     {
       if (regno - FIRST_SGPR_REG < 64)
@@ -6243,8 +6307,12 @@  gcn_dwarf_register_span (rtx rtl)
   if (GET_MODE_SIZE (mode) != 8)
     return NULL_RTX;
 
-  rtx p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
   unsigned regno = REGNO (rtl);
+
+  if (regno == DWARF_LINK_REGISTER)
+    return NULL_RTX;
+
+  rtx p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
   XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
   XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
 
diff --git a/gcc/config/gcn/gcn.h b/gcc/config/gcn/gcn.h
index eba4646f1bf..4992a4c02ef 100644
--- a/gcc/config/gcn/gcn.h
+++ b/gcc/config/gcn/gcn.h
@@ -85,6 +85,7 @@ 
 #define FIRST_PARM_OFFSET(FNDECL)    0
 #define DYNAMIC_CHAIN_ADDRESS(FP)    plus_constant (Pmode, (FP), -16)
 #define INCOMING_RETURN_ADDR_RTX     gen_rtx_REG (Pmode, LINK_REGNUM)
+#define DWARF_FRAME_RETURN_COLUMN    16
 #define STACK_DYNAMIC_OFFSET(FNDECL) (-crtl->outgoing_args_size)
 #define ACCUMULATE_OUTGOING_ARGS     1
 #define RETURN_ADDR_RTX(COUNT,FRAMEADDR) \
@@ -135,7 +136,8 @@ 
 #define WORK_ITEM_ID_Z_REG	  162
 #define SOFT_ARG_REG		  416
 #define FRAME_POINTER_REGNUM	  418
-#define FIRST_PSEUDO_REGISTER	  420
+#define DWARF_LINK_REGISTER	  420
+#define FIRST_PSEUDO_REGISTER	  421
 
 #define FIRST_PARM_REG 24
 #define NUM_PARM_REGS  6
@@ -197,7 +199,7 @@ 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     /* Other registers.  */			    \
-    1, 1, 1, 1					    \
+    1, 1, 1, 1, 1				    \
 }
 
 #define CALL_USED_REGISTERS {			    \
@@ -235,7 +237,7 @@ 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
     /* Other registers.  */			    \
-    1, 1, 1, 1					    \
+    1, 1, 1, 1, 1				    \
 }
 
 
@@ -514,7 +516,7 @@  enum gcn_address_spaces
     "v236", "v237", "v238", "v239", "v240", "v241", "v242", "v243", "v244", \
     "v245", "v246", "v247", "v248", "v249", "v250", "v251", "v252", "v253", \
     "v254", "v255",							    \
-    "?ap0", "?ap1", "?fp0", "?fp1" }
+    "?ap0", "?ap1", "?fp0", "?fp1", "?dwlr" }
 
 #define PRINT_OPERAND(FILE, X, CODE)  print_operand(FILE, X, CODE)
 #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  print_operand_address (FILE, ADDR)