On 15/07/2021 13:09, Richard Biener wrote: > On Thu, Jul 15, 2021 at 12:35 PM Hafiz Abid Qadeer > <abid_qad...@mentor.com> wrote: >> >> On 15/07/2021 11:33, Thomas Schwinge wrote: >>> >>>> Note that the "parent" should be abstract but I don't think dwarf has a >>>> way to express a fully abstract parent of a concrete instance child - or >>>> at least how GCC expresses this causes consumers to "misinterpret" >>>> that. I wonder if adding a DW_AT_declaration to the late DWARF >>>> emitted "parent" would fix things as well here? >>> >>> (I suppose not, Abid?) >>> >> >> Yes, adding DW_AT_declaration does not fix the problem. > > Does emitting > > DW_TAG_compile_unit > DW_AT_name ("<artificial>") > > DW_TAG_subprogram // notional parent function (foo) with no code range > DW_AT_declaration 1 > a: DW_TAG_subprogram // offload function foo._omp_fn.0 > DW_AT_declaration 1 > > DW_TAG_subprogram // offload function > DW_AT_abstract_origin a > ... > > do the trick? The following would do this, flattening function definitions > for the concrete copies: > > diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c > index 82783c4968b..a9c8bc43e88 100644 > --- a/gcc/dwarf2out.c > +++ b/gcc/dwarf2out.c > @@ -6076,6 +6076,11 @@ maybe_create_die_with_external_ref (tree decl) > /* Peel types in the context stack. */ > while (ctx && TYPE_P (ctx)) > ctx = TYPE_CONTEXT (ctx); > + /* For functions peel the context up to namespace/TU scope. The abstract > + copies reveal the true nesting. */ > + if (TREE_CODE (decl) == FUNCTION_DECL) > + while (ctx && TREE_CODE (ctx) == FUNCTION_DECL) > + ctx = DECL_CONTEXT (ctx); > /* Likewise namespaces in case we do not want to emit DIEs for them. */ > if (debug_info_level <= DINFO_LEVEL_TERSE) > while (ctx && TREE_CODE (ctx) == NAMESPACE_DECL) > @@ -6099,8 +6104,7 @@ maybe_create_die_with_external_ref (tree decl) > /* Leave function local entities parent determination to when > we process scope vars. */ > ; > - else > - parent = lookup_decl_die (ctx); > + parent = lookup_decl_die (ctx); > } > else > /* In some cases the FEs fail to set DECL_CONTEXT properly. >
Thanks. This solves the problem. Only the first hunk was required. Second hunk actually causes an ICE when TREE_CODE (ctx) == BLOCK. OK to commit the attached patch? -- Hafiz Abid Qadeer Mentor, a Siemens Business
>From 8e886f8502784d3aafdaf7e9778ce21b8c8f3b93 Mon Sep 17 00:00:00 2001 From: Hafiz Abid Qadeer <ab...@codesourcery.com> Date: Fri, 16 Jul 2021 21:00:37 +0100 Subject: [PATCH] [DWARF] Fix hierarchy of debug information for offload kernels. Currently, if we look at the debug information for offload kernel regions, it looks something like this: void foo (void) { { } } DW_TAG_compile_unit DW_AT_name ("<artificial>") DW_TAG_subprogram // notional parent function (foo) with no code range DW_TAG_subprogram // offload function foo._omp_fn.0 There is an artificial compile unit. It contains a parent subprogram which has the offload function as its child. The parent function makes sense in host code where it actually exists and does have an address range. But in offload code, it does not exist and neither the generated dwarf has an address range for this function. When debugger read the dwarf for offload code, they see a function with no address range and discard it alongwith its children which include offload function. This results in a poor debug experience of offload code. This patch was suggested by Richard and it solves this problem by peeling the parent function from the concrete copies. gcc/ * gcc/dwarf2out.c (maybe_create_die_with_external_ref): Remove function from the context chain. --- gcc/dwarf2out.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 561f8b23517..e2893bd91ed 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -6121,6 +6121,11 @@ maybe_create_die_with_external_ref (tree decl) /* Peel types in the context stack. */ while (ctx && TYPE_P (ctx)) ctx = TYPE_CONTEXT (ctx); + /* For functions peel the context up to namespace/TU scope. The abstract + copies reveal the true nesting. */ + if (TREE_CODE (decl) == FUNCTION_DECL) + while (ctx && TREE_CODE (ctx) == FUNCTION_DECL) + ctx = DECL_CONTEXT (ctx); /* Likewise namespaces in case we do not want to emit DIEs for them. */ if (debug_info_level <= DINFO_LEVEL_TERSE) while (ctx && TREE_CODE (ctx) == NAMESPACE_DECL) -- 2.25.1