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]

Avoid code duplication in loc list handling in dwarf2out


Hi,
this patch removes code duplication in between
add_location_or_const_value_attribute and loc_list_from_tree.  It also adds return
values to these functions to return true when expansion suceeded. I need it for further
patch handling the DEBUG_EXPR expressions.

This also fixes bug in loc_by_reference being called on possibly DW_OP_piece
that is already fixed in loc_list_from_tree.

Bootstrapped/regtested x86_64-linux and tested it has no effect on generated
dwarf for GCC modules.

OK?
Honza

	* dwarf2out.c (add_const_value_attribute): Return true if successful.
	(add_location_or_const_value_attribute): Rewrite using loc_list_from_tree.
	(tree_add_const_value_attribute): Return true if successful.
	(tree_add_const_value_attribute_for_decl): Likewise.
Index: dwarf2out.c
===================================================================
*** dwarf2out.c	(revision 151837)
--- dwarf2out.c	(working copy)
*************** static HOST_WIDE_INT field_byte_offset (
*** 5961,5974 ****
  static void add_AT_location_description	(dw_die_ref, enum dwarf_attribute,
  					 dw_loc_list_ref);
  static void add_data_member_location_attribute (dw_die_ref, tree);
! static void add_const_value_attribute (dw_die_ref, rtx);
  static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *);
  static void insert_float (const_rtx, unsigned char *);
  static rtx rtl_for_decl_location (tree);
! static void add_location_or_const_value_attribute (dw_die_ref, tree,
  						   enum dwarf_attribute);
! static void tree_add_const_value_attribute (dw_die_ref, tree);
! static void tree_add_const_value_attribute_for_decl (dw_die_ref, tree);
  static void add_name_attribute (dw_die_ref, const char *);
  static void add_comp_dir_attribute (dw_die_ref);
  static void add_bound_info (dw_die_ref, enum dwarf_attribute, tree);
--- 5961,5974 ----
  static void add_AT_location_description	(dw_die_ref, enum dwarf_attribute,
  					 dw_loc_list_ref);
  static void add_data_member_location_attribute (dw_die_ref, tree);
! static bool add_const_value_attribute (dw_die_ref, rtx);
  static void insert_int (HOST_WIDE_INT, unsigned, unsigned char *);
  static void insert_float (const_rtx, unsigned char *);
  static rtx rtl_for_decl_location (tree);
! static bool add_location_or_const_value_attribute (dw_die_ref, tree,
  						   enum dwarf_attribute);
! static bool tree_add_const_value_attribute (dw_die_ref, tree);
! static bool tree_add_const_value_attribute_for_decl (dw_die_ref, tree);
  static void add_name_attribute (dw_die_ref, const char *);
  static void add_comp_dir_attribute (dw_die_ref);
  static void add_bound_info (dw_die_ref, enum dwarf_attribute, tree);
*************** insert_float (const_rtx rtl, unsigned ch
*** 13170,13176 ****
     to an inlined function.  They can also arise in C++ where declared
     constants do not necessarily get memory "homes".  */
  
! static void
  add_const_value_attribute (dw_die_ref die, rtx rtl)
  {
    switch (GET_CODE (rtl))
--- 13170,13176 ----
     to an inlined function.  They can also arise in C++ where declared
     constants do not necessarily get memory "homes".  */
  
! static bool
  add_const_value_attribute (dw_die_ref die, rtx rtl)
  {
    switch (GET_CODE (rtl))
*************** add_const_value_attribute (dw_die_ref di
*** 13184,13190 ****
  	else
  	  add_AT_unsigned (die, DW_AT_const_value, (unsigned HOST_WIDE_INT) val);
        }
!       break;
  
      case CONST_DOUBLE:
        /* Note that a CONST_DOUBLE rtx could represent either an integer or a
--- 13184,13190 ----
  	else
  	  add_AT_unsigned (die, DW_AT_const_value, (unsigned HOST_WIDE_INT) val);
        }
!       return true;
  
      case CONST_DOUBLE:
        /* Note that a CONST_DOUBLE rtx could represent either an integer or a
*************** add_const_value_attribute (dw_die_ref di
*** 13205,13211 ****
  	else
  	  add_AT_long_long (die, DW_AT_const_value, rtl);
        }
!       break;
  
      case CONST_VECTOR:
        {
--- 13205,13211 ----
  	else
  	  add_AT_long_long (die, DW_AT_const_value, rtl);
        }
!       return true;
  
      case CONST_VECTOR:
        {
*************** add_const_value_attribute (dw_die_ref di
*** 13273,13299 ****
  
  	add_AT_vec (die, DW_AT_const_value, length, elt_size, array);
        }
!       break;
  
      case CONST_STRING:
        add_AT_string (die, DW_AT_const_value, XSTR (rtl, 0));
!       break;
  
      case CONST:
        if (CONSTANT_P (XEXP (rtl, 0)))
  	{
  	  add_const_value_attribute (die, XEXP (rtl, 0));
! 	  return;
  	}
        /* FALLTHROUGH */
      case SYMBOL_REF:
        if (GET_CODE (rtl) == SYMBOL_REF
  	  && SYMBOL_REF_TLS_MODEL (rtl) != TLS_MODEL_NONE)
! 	break;
      case LABEL_REF:
        add_AT_addr (die, DW_AT_const_value, rtl);
        VEC_safe_push (rtx, gc, used_rtx_array, rtl);
!       break;
  
      case PLUS:
        /* In cases where an inlined instance of an inline function is passed
--- 13273,13299 ----
  
  	add_AT_vec (die, DW_AT_const_value, length, elt_size, array);
        }
!       return true;
  
      case CONST_STRING:
        add_AT_string (die, DW_AT_const_value, XSTR (rtl, 0));
!       return true;
  
      case CONST:
        if (CONSTANT_P (XEXP (rtl, 0)))
  	{
  	  add_const_value_attribute (die, XEXP (rtl, 0));
! 	  return true;
  	}
        /* FALLTHROUGH */
      case SYMBOL_REF:
        if (GET_CODE (rtl) == SYMBOL_REF
  	  && SYMBOL_REF_TLS_MODEL (rtl) != TLS_MODEL_NONE)
! 	return false;
      case LABEL_REF:
        add_AT_addr (die, DW_AT_const_value, rtl);
        VEC_safe_push (rtx, gc, used_rtx_array, rtl);
!       return true;
  
      case PLUS:
        /* In cases where an inlined instance of an inline function is passed
*************** add_const_value_attribute (dw_die_ref di
*** 13307,13319 ****
  	 *value* which the artificial local variable always has during its
  	 lifetime.  We currently have no way to represent such quasi-constant
  	 values in Dwarf, so for now we just punt and generate nothing.  */
!       break;
  
      default:
        /* No other kinds of rtx should be possible here.  */
        gcc_unreachable ();
      }
! 
  }
  
  /* Determine whether the evaluation of EXPR references any variables
--- 13307,13319 ----
  	 *value* which the artificial local variable always has during its
  	 lifetime.  We currently have no way to represent such quasi-constant
  	 values in Dwarf, so for now we just punt and generate nothing.  */
!       return false;
  
      default:
        /* No other kinds of rtx should be possible here.  */
        gcc_unreachable ();
      }
!   return false;
  }
  
  /* Determine whether the evaluation of EXPR references any variables
*************** fortran_common (tree decl, HOST_WIDE_INT
*** 13706,13856 ****
     pointer.  This can happen for example if an actual argument in an inlined
     function call evaluates to a compile-time constant address.  */
  
! static void
  add_location_or_const_value_attribute (dw_die_ref die, tree decl,
  				       enum dwarf_attribute attr)
  {
    rtx rtl;
!   dw_loc_descr_ref descr;
!   dw_loc_list_ref descr_list;
!   var_loc_list *loc_list;
!   struct var_loc_node *node;
    if (TREE_CODE (decl) == ERROR_MARK)
!     return;
  
    gcc_assert (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL
  	      || TREE_CODE (decl) == RESULT_DECL);
  
-   /* See if we possibly have multiple locations for this variable.  */
-   loc_list = lookup_decl_loc (decl);
- 
-   /* If it truly has multiple locations, the first and last node will
-      differ.  */
-   if (loc_list && loc_list->first != loc_list->last)
-     {
-       const char *endname, *secname;
-       dw_loc_list_ref list;
-       rtx varloc;
-       enum var_init_status initialized;
- 
-       /* Now that we know what section we are using for a base,
- 	 actually construct the list of locations.
- 	 The first location information is what is passed to the
- 	 function that creates the location list, and the remaining
- 	 locations just get added on to that list.
- 	 Note that we only know the start address for a location
- 	 (IE location changes), so to build the range, we use
- 	 the range [current location start, next location start].
- 	 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;
-       varloc = NOTE_VAR_LOCATION (node->var_loc_note);
-       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;
- 
-       descr = loc_by_reference (loc_descriptor (varloc, DECL_MODE (decl),
- 						initialized), decl);
-       list = new_loc_list (descr, node->label, node->next->label, secname, 1);
-       node = node->next;
- 
-       for (; 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
- 	       NODE->NEXT->LABEL.  */
- 	    enum var_init_status initialized =
- 	      NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
- 	    varloc = NOTE_VAR_LOCATION (node->var_loc_note);
- 	    descr = loc_by_reference (loc_descriptor (varloc, DECL_MODE (decl),
- 				      initialized), decl);
- 	    add_loc_descr_to_loc_list (&list, descr,
- 				       node->label, node->next->label, secname);
- 	  }
- 
-       /* 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)
- 	{
- 	  char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
- 	  enum var_init_status initialized =
- 	    NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
- 
- 	  varloc = NOTE_VAR_LOCATION (node->var_loc_note);
- 	  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);
- 	    }
- 	  descr = loc_by_reference (loc_descriptor (varloc,
- 						    DECL_MODE (decl),
- 						    initialized),
- 				    decl);
- 	  add_loc_descr_to_loc_list (&list, descr,
- 				     node->label, endname, secname);
- 	}
- 
-       /* Finally, add the location list to the DIE, and we are done.  */
-       add_AT_loc_list (die, attr, list);
-       return;
-     }
- 
    /* Try to get some constant RTL for this decl, and use that as the value of
       the location.  */
  
    rtl = rtl_for_decl_location (decl);
!   if (rtl && (CONSTANT_P (rtl) || GET_CODE (rtl) == CONST_STRING))
!     {
!       add_const_value_attribute (die, rtl);
!       return;
!     }
! 
!   /* If we have tried to generate the location otherwise, and it
!      didn't work out (we wouldn't be here if we did), and we have a one entry
!      location list, try generating a location from that.  */
!   if (loc_list && loc_list->first)
!     {
!       enum var_init_status status;
!       node = loc_list->first;
!       status = NOTE_VAR_LOCATION_STATUS (node->var_loc_note);
!       rtl = NOTE_VAR_LOCATION (node->var_loc_note);
!       if (GET_CODE (rtl) == VAR_LOCATION
! 	  && GET_CODE (XEXP (rtl, 1)) != PARALLEL)
! 	rtl = XEXP (XEXP (rtl, 1), 0);
!       if (CONSTANT_P (rtl) || GET_CODE (rtl) == CONST_STRING)
! 	{
! 	  add_const_value_attribute (die, rtl);
! 	  return;
! 	}
!       descr = loc_descriptor (NOTE_VAR_LOCATION (node->var_loc_note),
! 			      DECL_MODE (decl), status);
!       if (descr)
! 	{
! 	  descr = loc_by_reference (descr, decl);
! 	  add_AT_location_description (die, attr, single_element_loc_list (descr));
! 	  return;
! 	}
!     }
! 
!   /* We couldn't get any rtl, so try directly generating the location
!      description from the tree.  */
!   descr_list = loc_list_from_tree (decl, 2);
!   if (descr_list)
      {
!       descr = loc_by_reference (descr, decl);
!       add_AT_location_description (die, attr, descr_list);
!       return;
      }
    /* None of that worked, so it must not really have a location;
       try adding a constant value attribute from the DECL_INITIAL.  */
!   tree_add_const_value_attribute_for_decl (die, decl);
  }
  
  /* Add VARIABLE and DIE into deferred locations list.  */
--- 13706,13740 ----
     pointer.  This can happen for example if an actual argument in an inlined
     function call evaluates to a compile-time constant address.  */
  
! static bool
  add_location_or_const_value_attribute (dw_die_ref die, tree decl,
  				       enum dwarf_attribute attr)
  {
    rtx rtl;
!   dw_loc_list_ref list;
! 
    if (TREE_CODE (decl) == ERROR_MARK)
!     return false;
  
    gcc_assert (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL
  	      || TREE_CODE (decl) == RESULT_DECL);
  
    /* Try to get some constant RTL for this decl, and use that as the value of
       the location.  */
  
    rtl = rtl_for_decl_location (decl);
!   if (rtl && (CONSTANT_P (rtl) || GET_CODE (rtl) == CONST_STRING)
!       && add_const_value_attribute (die, rtl))
!     return true;
!   list = loc_list_from_tree (decl, decl_by_reference_p (decl) ? 0 : 2);
!   if (list)
      {
!       add_AT_location_description (die, attr, list);
!       return true;
      }
    /* None of that worked, so it must not really have a location;
       try adding a constant value attribute from the DECL_INITIAL.  */
!   return tree_add_const_value_attribute_for_decl (die, decl);
  }
  
  /* Add VARIABLE and DIE into deferred locations list.  */
*************** native_encode_initializer (tree init, un
*** 14014,14020 ****
  /* Attach a DW_AT_const_value attribute to DIE. The value of the
     attribute is the const value T.  */
  
! static void
  tree_add_const_value_attribute (dw_die_ref die, tree t)
  {
    tree init;
--- 13898,13904 ----
  /* Attach a DW_AT_const_value attribute to DIE. The value of the
     attribute is the const value T.  */
  
! static bool
  tree_add_const_value_attribute (dw_die_ref die, tree t)
  {
    tree init;
*************** tree_add_const_value_attribute (dw_die_r
*** 14022,14035 ****
    rtx rtl;
  
    if (!t || !TREE_TYPE (t) || TREE_TYPE (t) == error_mark_node)
!     return;
  
    init = t;
    gcc_assert (!DECL_P (init));
  
    rtl = rtl_for_decl_init (init, type);
    if (rtl)
!     add_const_value_attribute (die, rtl);
    /* If the host and target are sane, try harder.  */
    else if (CHAR_BIT == 8 && BITS_PER_UNIT == 8
  	   && initializer_constant_valid_p (init, type))
--- 13906,13922 ----
    rtx rtl;
  
    if (!t || !TREE_TYPE (t) || TREE_TYPE (t) == error_mark_node)
!     return false;
  
    init = t;
    gcc_assert (!DECL_P (init));
  
    rtl = rtl_for_decl_init (init, type);
    if (rtl)
!     {
!       add_const_value_attribute (die, rtl);
!       return true;
!     }
    /* If the host and target are sane, try harder.  */
    else if (CHAR_BIT == 8 && BITS_PER_UNIT == 8
  	   && initializer_constant_valid_p (init, type))
*************** tree_add_const_value_attribute (dw_die_r
*** 14040,14048 ****
  	  unsigned char *array = GGC_CNEWVEC (unsigned char, size);
  
  	  if (native_encode_initializer (init, array, size))
! 	    add_AT_vec (die, DW_AT_const_value, size, 1, array);
  	}
      }
  }
  
  /* Attach a DW_AT_const_value attribute to VAR_DIE. The value of the
--- 13927,13939 ----
  	  unsigned char *array = GGC_CNEWVEC (unsigned char, size);
  
  	  if (native_encode_initializer (init, array, size))
! 	    {
! 	      add_AT_vec (die, DW_AT_const_value, size, 1, array);
! 	      return true;
! 	    }
  	}
      }
+   return false;
  }
  
  /* Attach a DW_AT_const_value attribute to VAR_DIE. The value of the
*************** tree_add_const_value_attribute (dw_die_r
*** 14050,14072 ****
     variable with static storage duration
     (so it can't be a PARM_DECL or a RESULT_DECL).  */
  
! static void
  tree_add_const_value_attribute_for_decl (dw_die_ref var_die, tree decl)
  {
  
    if (!decl
        || (TREE_CODE (decl) != VAR_DECL
  	  && TREE_CODE (decl) != CONST_DECL))
!     return;
  
      if (TREE_READONLY (decl)
  	&& ! TREE_THIS_VOLATILE (decl)
  	&& DECL_INITIAL (decl))
        /* OK */;
      else
!       return;
  
!     tree_add_const_value_attribute (var_die, DECL_INITIAL (decl));
  }
  
  /* Convert the CFI instructions for the current function into a
--- 13941,13963 ----
     variable with static storage duration
     (so it can't be a PARM_DECL or a RESULT_DECL).  */
  
! static bool
  tree_add_const_value_attribute_for_decl (dw_die_ref var_die, tree decl)
  {
  
    if (!decl
        || (TREE_CODE (decl) != VAR_DECL
  	  && TREE_CODE (decl) != CONST_DECL))
!     return false;
  
      if (TREE_READONLY (decl)
  	&& ! TREE_THIS_VOLATILE (decl)
  	&& DECL_INITIAL (decl))
        /* OK */;
      else
!       return false;
  
!   return tree_add_const_value_attribute (var_die, DECL_INITIAL (decl));
  }
  
  /* Convert the CFI instructions for the current function into a


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