This patch adjusts the DWARF emitted for OpenACC/OpenMP offload kernels such that the AMD rocgdb debugger can display the contents of variables within kernel code.

The problem was that GDB was discarding the kernel functions' debug info because it is represented as a nested function inside the host function, but in the offload binary the host function had only partial DWARF information.

By adding a code address to the parent function, in the offload binary, GDB works correctly. This patch simply duplicates the code range from the first kernel, to ensure that the addresses are valid, but the actual range doesn't matter because GDB will always choose the innermost function with that range.

This change should not affect the DWARF of the host binary at all (even though it has the same nested structure) because there the parent function has a full definition.

I'm not completely confident what the most correct pattern match should be for this issue, but the patch appear to DTRT in the cases I have observed.

OK to commit?

Andrew
Fix offload dwarf info

GCC represents offload kernels, in DWARF, as nested subprograms within a bare
representation of the host side function subprogram.  Unfortunately GDB then
disregards that, along with all the nested DIEs, because it has no address
range.

This function adds a notional address range to the parent subprogram, and
thus enables debug of offload kernels.

This change does not affect the DWARF for the host-program's representation of
the same function.

gcc/ChangeLog:

	* dwarf2out.c (gen_subprogram_die): Add PC address range for parents
	of offload kernels.

diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 0baa056447c..bee40972950 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -23150,6 +23150,22 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
 	      /* We have already generated the labels.  */
              add_AT_low_high_pc (subr_die, fde->dw_fde_begin,
                                  fde->dw_fde_end, false);
+
+	     /* Offload kernel functions are nested within a parent function
+	        that doesn't actually exist within the offload object.  GDB
+		will ignore the function and everything nested within unless
+		we give it a notional code range (the values aren't
+		important, as long as they are valid).
+		There's no specific marker for these(?), but they will be
+		artificial declarations with an abstract origin, and the
+		parent won't have many existing attributes.  */
+	     if (DECL_ARTIFICIAL (decl)
+		 && subr_die->die_parent
+		 && subr_die->die_parent->die_tag == DW_TAG_subprogram
+		 && get_AT_ref (subr_die->die_parent, DW_AT_abstract_origin)
+		 && !get_AT_low_pc (subr_die->die_parent))
+	       add_AT_low_high_pc (subr_die->die_parent, fde->dw_fde_begin,
+				   fde->dw_fde_end, false);
 	    }
 	  else
 	    {

Reply via email to