This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[VTA, PR41473] drop NULL locations from lists
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 23 Nov 2009 18:11:57 -0200
- Subject: [VTA, PR41473] drop NULL locations from lists
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