This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]