aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Stubbs <ams@codesourcery.com>2021-03-04 23:12:17 +0000
committerAndrew Stubbs <ams@codesourcery.com>2021-03-06 15:48:24 +0000
commitd556f783e9947fece98537f2a335a9af70b52e3b (patch)
tree11082fb446298e4d714af0ceb8e02bd48e2dff87
parent58def69b6d68276745e5cc14d6ca24ad47be5d27 (diff)
downloadgcc-d556f783e9947fece98537f2a335a9af70b52e3b.zip
gcc-d556f783e9947fece98537f2a335a9af70b52e3b.tar.gz
gcc-d556f783e9947fece98537f2a335a9af70b52e3b.tar.bz2
DWARF: late code range fixup
Ensure that the parent DWARF subprograms of offload kernel functions have a code range, and are therefore not discarded by GDB. This is only necessary when the parent function does not actually exist in the final binary, which is commonly the case within the offload device's binary. This patch replaces 808bdf1bb29 and fdcb23540a2. It should be squashed with those before being posted upstream. gcc/ * gcc/dwarf2out.c (notional_parents_list): New file variable. (gen_subprogram_die): Record offload kernel functions in notional_parents_list. (fixup_notional_parents): New function. (dwarf2out_finish): Call fixup_notional_parents. (dwarf2out_c_finalize): Reset notional_parents_list.
-rw-r--r--gcc/dwarf2out.c78
1 files changed, 55 insertions, 23 deletions
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 1d7cb62..d6796ca 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -3427,6 +3427,12 @@ static GTY(()) limbo_die_node *limbo_die_list;
DW_AT_{,MIPS_}linkage_name once their DECL_ASSEMBLER_NAMEs are set. */
static GTY(()) limbo_die_node *deferred_asm_name;
+/* A list of DIEs for which we may have to add a notional code range to the
+ parent DIE. This happens for parents of nested offload kernels, and is
+ necessary because the parents don't exist on the offload target, yet GDB
+ expects parents of real functions to also appear to exist. */
+static GTY(()) limbo_die_node *notional_parents_list;
+
struct dwarf_file_hasher : ggc_ptr_hash<dwarf_file_data>
{
typedef const char *compare_type;
@@ -23085,34 +23091,25 @@ gen_subprogram_die (tree decl, dw_die_ref context_die)
dw_fde_ref fde = fun->fde;
if (fde->dw_fde_begin)
{
- dw_attr_node *low = get_AT (subr_die, DW_AT_low_pc);
- dw_attr_node *high = get_AT (subr_die, DW_AT_high_pc);
- if (low && high)
- {
- /* Replace the existing value, it will have come from
- the "omp target entrypoint" case below. */
- free (low->dw_attr_val.v.val_lbl_id);
- low->dw_attr_val.v.val_lbl_id = xstrdup (fde->dw_fde_begin);
- free (high->dw_attr_val.v.val_lbl_id);
- high->dw_attr_val.v.val_lbl_id = xstrdup (fde->dw_fde_end);
- }
- else
- /* We have already generated the labels. */
- add_AT_low_high_pc (subr_die, fde->dw_fde_begin,
- fde->dw_fde_end, false);
+ /* 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). */
+ we give the parent a code range. We can't do it here because
+ that breaks the case where the parent actually does exist (as
+ it does on the host-side), so we defer the fixup for later. */
if (lookup_attribute ("omp target entrypoint",
- DECL_ATTRIBUTES (decl))
- && subr_die->die_parent
- && subr_die->die_parent->die_tag == DW_TAG_subprogram
- && !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);
+ DECL_ATTRIBUTES (decl)))
+ {
+ limbo_die_node *node = ggc_cleared_alloc<limbo_die_node> ();
+ node->die = subr_die;
+ node->created_for = decl;
+ node->next = notional_parents_list;
+ notional_parents_list = node;
+ }
}
else
{
@@ -31348,6 +31345,37 @@ flush_limbo_die_list (void)
}
}
+/* Add a code range to the notional parent function (which does not actually
+ exist) so that GDB does not ignore all the child functions. The actual
+ values do not matter, but need to be valid labels, so we simply copy those
+ from the child function.
+
+ Typically this occurs when we have an offload kernel, where the parent
+ function only exists in the host-side portion of the code. */
+
+static void
+fixup_notional_parents (void)
+{
+ limbo_die_node *node;
+
+ while ((node = notional_parents_list))
+ {
+ dw_die_ref die = node->die;
+ dw_die_ref parent = die->die_parent;
+ notional_parents_list = node->next;
+
+ if (parent
+ && parent->die_tag == DW_TAG_subprogram
+ && !get_AT_low_pc (parent))
+ {
+ dw_attr_node *low = get_AT (die, DW_AT_low_pc);
+ dw_attr_node *high = get_AT (die, DW_AT_high_pc);
+
+ add_AT_low_high_pc (parent, AT_lbl (low), AT_lbl (high), false);
+ }
+ }
+}
+
/* Reset DIEs so we can output them again. */
static void
@@ -31378,6 +31406,9 @@ dwarf2out_finish (const char *filename)
/* Flush out any latecomers to the limbo party. */
flush_limbo_die_list ();
+ /* Insert an notional parent code ranges. */
+ fixup_notional_parents ();
+
if (inline_entry_data_table)
gcc_assert (inline_entry_data_table->is_empty ());
@@ -32394,6 +32425,7 @@ dwarf2out_c_finalize (void)
single_comp_unit_die = NULL;
comdat_type_list = NULL;
limbo_die_list = NULL;
+ notional_parents_list = NULL;
file_table = NULL;
decl_die_table = NULL;
common_block_die_table = NULL;