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]

Re: [VTA, PR41473] drop NULL locations from lists


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



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