This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [VTA, PR41473] drop NULL locations from lists
- From: Jack Howarth <howarth at bromo dot med dot uc dot edu>
- To: Alexandre Oliva <aoliva at redhat dot com>
- Cc: gcc-patches at gcc dot gnu dot org
- Date: Mon, 23 Nov 2009 18:06:46 -0500
- Subject: Re: [VTA, PR41473] drop NULL locations from lists
- References: <orljhxt302.fsf@livre.localdomain>
On Mon, Nov 23, 2009 at 06:11:57PM -0200, Alexandre Oliva wrote:
> Entries in location lists whose RTL is NULL or not representable end up
> causing us to waste debug info space emitting empty DW_AT_location.
>
> This patch optimizes the debug information, omitting the useless
> DW_AT_location. This should work around the bug in Darwin's dsymutil.
>
> While at that, I arranged for entries in location lists that are not
> representable in debug info to not waste an entry in the output location
> list.
>
> The patch also fixes the handling of CONST_DOUBLEs and CONST_VECTORs
> within CONCAT and CONCATN, that was currently disabled because mode was
> specified as VOIDmode by the handlers of these RTL forms. Even with
> -gdwarf-4, we'd still have failed to emit them.
>
> Ok to install if this passes regstrap?
>
> for gcc/ChangeLog
> from Alexandre Oliva <aoliva@redhat.com>
>
> PR debug/41473
> * dwarf2out.c (loc_descriptor): Infer mode from CONST_DOUBLEs
> and CONST_VECTORs.
> (dw_loc_list): Don't create entries without location. Don't
> special-case the first node of the list.
> (loc_list_from_tree): Don't use DECL_RTL if loc_list is nonempty.
>
> Index: gcc/dwarf2out.c
> ===================================================================
> --- gcc/dwarf2out.c.orig 2009-11-23 17:16:14.000000000 -0200
> +++ gcc/dwarf2out.c 2009-11-23 17:52:38.000000000 -0200
> @@ -13650,15 +13650,17 @@ loc_descriptor (rtx rtl, enum machine_mo
> break;
>
> case CONST_DOUBLE:
> + if (mode == VOIDmode)
> + mode = GET_MODE (rtl);
> +
> if (mode != VOIDmode && (dwarf_version >= 4 || !dwarf_strict))
> {
> + gcc_assert (mode == GET_MODE (rtl));
> +
> /* Note that a CONST_DOUBLE rtx could represent either an integer
> or a floating-point constant. A CONST_DOUBLE is used whenever
> the constant requires more than one word in order to be
> adequately represented. We output CONST_DOUBLEs as blocks. */
> - if (GET_MODE (rtl) != VOIDmode)
> - mode = GET_MODE (rtl);
> -
> loc_result = new_loc_descr (DW_OP_implicit_value,
> GET_MODE_SIZE (mode), 0);
> if (SCALAR_FLOAT_MODE_P (mode))
> @@ -13684,6 +13686,9 @@ loc_descriptor (rtx rtl, enum machine_mo
> break;
>
> case CONST_VECTOR:
> + if (mode == VOIDmode)
> + mode = GET_MODE (rtl);
> +
> if (mode != VOIDmode && (dwarf_version >= 4 || !dwarf_strict))
> {
> unsigned int elt_size = GET_MODE_UNIT_SIZE (GET_MODE (rtl));
> @@ -13692,7 +13697,7 @@ loc_descriptor (rtx rtl, enum machine_mo
> unsigned int i;
> unsigned char *p;
>
> - mode = GET_MODE (rtl);
> + gcc_assert (mode == GET_MODE (rtl));
> switch (GET_MODE_CLASS (mode))
> {
> case MODE_VECTOR_INT:
> @@ -13928,20 +13933,21 @@ dw_loc_list_1 (tree loc, rtx varloc, int
> return descr;
> }
>
> -/* Return dwarf representation of location list representing for
> - LOC_LIST of DECL. WANT_ADDRESS has the same meaning as in
> - loc_list_from_tree function. */
> +/* Return the dwarf representation of the location list LOC_LIST of
> + DECL. WANT_ADDRESS has the same meaning as in loc_list_from_tree
> + function. */
>
> static dw_loc_list_ref
> -dw_loc_list (var_loc_list * loc_list, tree decl, int want_address)
> +dw_loc_list (var_loc_list *loc_list, tree decl, int want_address)
> {
> const char *endname, *secname;
> - dw_loc_list_ref list;
> rtx varloc;
> enum var_init_status initialized;
> struct var_loc_node *node;
> dw_loc_descr_ref descr;
> char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
> + dw_loc_list_ref list = NULL;
> + dw_loc_list_ref *listp = &list;
>
> /* Now that we know what section we are using for a base,
> actually construct the list of locations.
> @@ -13954,26 +13960,9 @@ dw_loc_list (var_loc_list * loc_list, tr
> This means we have to special case the last node, and generate
> a range of [last location start, end of function label]. */
>
> - node = loc_list->first;
> secname = secname_for_decl (decl);
>
> - if (NOTE_VAR_LOCATION_LOC (node->var_loc_note))
> - initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
> - else
> - initialized = VAR_INIT_STATUS_INITIALIZED;
> - varloc = NOTE_VAR_LOCATION (node->var_loc_note);
> - descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
> -
> - if (loc_list && loc_list->first != loc_list->last)
> - list = new_loc_list (descr, node->label, node->next->label, secname, 1);
> - else
> - return single_element_loc_list (descr);
> - node = node->next;
> -
> - if (!node)
> - return NULL;
> -
> - for (; node->next; node = node->next)
> + for (node = loc_list->first; node->next; node = node->next)
> if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX)
> {
> /* The variable has a location between NODE->LABEL and
> @@ -13981,28 +13970,48 @@ dw_loc_list (var_loc_list * loc_list, tr
> initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
> varloc = NOTE_VAR_LOCATION (node->var_loc_note);
> descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
> - add_loc_descr_to_loc_list (&list, descr,
> - node->label, node->next->label, secname);
> + if (descr)
> + {
> + if (list)
> + add_loc_descr_to_loc_list (listp, descr,
> + node->label, node->next->label,
> + secname);
> + else
> + *listp = new_loc_list (descr, node->label, node->next->label,
> + secname, 1);
> + /* Speed up the next insertion. */
> + listp = &(*listp)->dw_loc_next;
> + }
> }
>
> /* If the variable has a location at the last label
> it keeps its location until the end of function. */
> if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX)
> {
> - if (!current_function_decl)
> - endname = text_end_label;
> - else
> - {
> - ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
> - current_function_funcdef_no);
> - endname = ggc_strdup (label_id);
> - }
> -
> initialized = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
> varloc = NOTE_VAR_LOCATION (node->var_loc_note);
> descr = dw_loc_list_1 (decl, varloc, want_address, initialized);
> - add_loc_descr_to_loc_list (&list, descr, node->label, endname, secname);
> + if (descr)
> + {
> + if (!current_function_decl)
> + endname = text_end_label;
> + else
> + {
> + ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
> + current_function_funcdef_no);
> + endname = ggc_strdup (label_id);
> + }
> +
> + if (*listp)
> + add_loc_descr_to_loc_list (listp, descr,
> + node->label, endname,
> + secname);
> + else
> + *listp = new_loc_list (descr, node->label, endname,
> + secname, 1);
> + }
> }
> +
> return list;
> }
>
> @@ -14312,9 +14321,9 @@ loc_list_from_tree (tree loc, int want_a
> rtx rtl;
> var_loc_list *loc_list = lookup_decl_loc (loc);
>
> - if (loc_list && loc_list->first
> - && (list_ret = dw_loc_list (loc_list, loc, want_address)))
> + if (loc_list && loc_list->first)
> {
> + list_ret = dw_loc_list (loc_list, loc, want_address);
> have_address = want_address != 0;
> break;
> }
>
> --
> Alexandre Oliva, freedom fighter http://FSFLA.org/~lxoliva/
> You must be the change you wish to see in the world. -- Gandhi
> Be Free! -- http://FSFLA.org/ FSF Latin America board member
> Free Software Evangelist Red Hat Brazil Compiler Engineer
Alexandre,
It appears that we still must be missing some cases were
AT_location is being set to zero but this definitely is an improvement.
Before this patch, dsymutil asserted on...
libgcj.11.dylib
libgcj-tools.11.dylib
libgfortran.3.dylib
libgomp.1.dylib
libobjc-gnu.2.dylib
libssp.0.dylib
libstdc++.6.dylib
The proposed patch with r154473 eliminates the asserts in dsymutil
for libgcj.11.dylib, libgcj-tools.11.dylib, libobjc-gnu.2.dylib and
libgomp.1.dylib so we are heading in the right direction. We still
get...
Assertion failed: (orig_str), function FixReferences, file /SourceCache/dwarf_utilities/dwarf_utilities-70/source/DWARFdSYM.cpp, line 3641.
Abort
for libgfortran.3.dylib, libssp.0.dylib and libstdc++.6.dylib though.
Jack