https://gcc.gnu.org/g:ebd204090cd4c7938668b4e8ec69b63bf43bf6ad
commit ebd204090cd4c7938668b4e8ec69b63bf43bf6ad Author: Andrew Stubbs <a...@codesourcery.com> Date: Sun Dec 6 19:23:55 2020 +0000 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. gcc/ * dwarf2out.cc (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. Diff: --- gcc/ChangeLog.omp | 23 +++++++++++++++++++++ gcc/dwarf2out.cc | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog.omp b/gcc/ChangeLog.omp index e8ff6483444..dd70a08ff7d 100644 --- a/gcc/ChangeLog.omp +++ b/gcc/ChangeLog.omp @@ -1,3 +1,26 @@ +2021-03-04 Andrew Stubbs <a...@codesourcery.com> + + * dwarf2out.cc (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. + +2021-02-26 Andrew Stubbs <a...@codesourcery.com> + + * dwarf2out.cc (gen_subprogram_die): Replace existing low/high PC + attributes, rather than ICE. + +2021-01-16 Andrew Stubbs <a...@codesourcery.com> + + * dwarf2out.cc (gen_subprogram_die): Check offload attributes only. + +2021-01-15 Andrew Stubbs <a...@codesourcery.com> + + * dwarf2out.cc (gen_subprogram_die): Add high/low_pc attributes for + parents of offload kernels. + 2021-01-13 Julian Brown <jul...@codesourcery.com> * doc/tm.texi.in (TARGET_VECTORIZE_PREFER_GATHER_SCATTER): Add diff --git a/gcc/dwarf2out.cc b/gcc/dwarf2out.cc index 1b0e8b5a5b2..9f747e8fcee 100644 --- a/gcc/dwarf2out.cc +++ b/gcc/dwarf2out.cc @@ -3487,6 +3487,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; @@ -23883,8 +23889,24 @@ gen_subprogram_die (tree decl, dw_die_ref context_die) if (fde->dw_fde_begin) { /* We have already generated the labels. */ - add_AT_low_high_pc (subr_die, fde->dw_fde_begin, - fde->dw_fde_end, false); + 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 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))) + { + 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 { @@ -32219,6 +32241,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 @@ -32285,6 +32338,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 ()); @@ -33360,6 +33416,7 @@ dwarf2out_cc_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;