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]

[rtlopt] variable tracking: end the range when variable disappears


Hi,

when the variable loses its location the range of its location is
terminated by this patch.
It also speeds up generating variable location lists because it does not
go through the linked list to the end but instead it remembers the last
node of the linked list to access it fast.

Bootstrapped x86-64.

Joe

2003-02-20  Josef Zlomek  <zlomekj at suse dot cz>

	* var-tracking.c (note_insn_var_location_emit): When variable is not
	complete emit note with NULL_RTX in the location part, coding style.
	* dwarf2out.c (struct var_loc_list_def): New structure.
	(decl_loc_table): Changed to be an array of var_loc_list.
	(lookup_decl_loc): Now returns var_loc_list *.
	(add_var_loc_to_decl): Use direct pointer to the last node for adding
	a node to the end of list.
	(add_location_or_const_value_attribute): Do not add the empty
	locations to loc list, finish the range of variable location instead.
	(dwarf2out_init): Coding style.

Index: var-tracking.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/var-tracking.c,v
retrieving revision 1.1.4.22
diff -c -3 -p -r1.1.4.22 var-tracking.c
*** var-tracking.c	19 Feb 2003 12:22:53 -0000	1.1.4.22
--- var-tracking.c	20 Feb 2003 16:27:37 -0000
*************** note_insn_var_location_emit (insn, where
*** 1151,1177 ****
    if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
      complete = false;
  
-   /* If the variable is not complete a note with empty location should be
-      emitted to specify the end of variable location range.
-      The following test is a temporary workaround because dwarf2out.c does not
-      handle empty location yet.  */
-   if (!complete)
-     return;
- 
    if (where == EMIT_NOTE_AFTER_INSN)
      note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
    else
      note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
  
!   if (var->n_location_parts == 1)
      {
        rtx expr_list
  	= gen_rtx_EXPR_LIST (VOIDmode,
  			     var->location_part[0].loc,
  			     GEN_INT (var->location_part[0].offset));
  
!       NOTE_VAR_LOCATION (note)
! 	= gen_rtx_VAR_LOCATION (VOIDmode, var->decl, expr_list);
      }
    else if (var->n_location_parts)
      {
--- 1151,1175 ----
    if ((unsigned HOST_WIDE_INT) last_limit < TREE_INT_CST_LOW (type_size_unit))
      complete = false;
  
    if (where == EMIT_NOTE_AFTER_INSN)
      note = emit_note_after (NOTE_INSN_VAR_LOCATION, insn);
    else
      note = emit_note_before (NOTE_INSN_VAR_LOCATION, insn);
  
!   if (!complete)
!     {
!       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
! 						       NULL_RTX);
!     }
!   else if (var->n_location_parts == 1)
      {
        rtx expr_list
  	= gen_rtx_EXPR_LIST (VOIDmode,
  			     var->location_part[0].loc,
  			     GEN_INT (var->location_part[0].offset));
  
!       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
! 						       expr_list);
      }
    else if (var->n_location_parts)
      {
*************** note_insn_var_location_emit (insn, where
*** 1184,1191 ****
  				     GEN_INT (var->location_part[i].offset));
        parallel = gen_rtx_PARALLEL (VOIDmode,
  				   gen_rtvec_v (var->n_location_parts, argp));
!       NOTE_VAR_LOCATION (note)
! 	= gen_rtx_VAR_LOCATION (VOIDmode, var->decl, parallel);
      }
  }
  
--- 1182,1189 ----
  				     GEN_INT (var->location_part[i].offset));
        parallel = gen_rtx_PARALLEL (VOIDmode,
  				   gen_rtvec_v (var->n_location_parts, argp));
!       NOTE_VAR_LOCATION (note) = gen_rtx_VAR_LOCATION (VOIDmode, var->decl,
! 						       parallel);
      }
  }
  
Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/dwarf2out.c,v
retrieving revision 1.382.2.10
diff -c -3 -p -r1.382.2.10 dwarf2out.c
*** dwarf2out.c	19 Feb 2003 19:22:40 -0000	1.382.2.10
--- dwarf2out.c	20 Feb 2003 16:27:38 -0000
*************** static unsigned decl_die_table_in_use;
*** 3480,3485 ****
--- 3480,3486 ----
     decl_die_table.  */
  #define DECL_DIE_TABLE_INCREMENT 256
  
+ /* Node of the variable location list.  */
  struct var_loc_node GTY ((chain_next ("%h.next")))
  {
    rtx GTY (()) var_loc_note;
*************** struct var_loc_node GTY ((chain_next ("%
*** 3487,3497 ****
    struct var_loc_node * GTY (()) next;
  };
  
  /* Unique label counter.  */
  static unsigned int loclabel_num = 0;
  
  /* Table of decl location linked lists.  */
! static GTY ((length ("decl_loc_table_allocated"))) struct var_loc_node **decl_loc_table;
  
  /* Number of elements in the decl_loc_table that are allocated.  */
  static unsigned decl_loc_table_allocated;
--- 3488,3506 ----
    struct var_loc_node * GTY (()) next;
  };
  
+ /* Variable location list.  */
+ struct var_loc_list_def GTY (())
+ {
+   struct var_loc_node * GTY (()) first;
+   struct var_loc_node * GTY (()) last;
+ };
+ typedef struct var_loc_list_def var_loc_list;
+ 
  /* Unique label counter.  */
  static unsigned int loclabel_num = 0;
  
  /* Table of decl location linked lists.  */
! static GTY ((length ("decl_loc_table_allocated"))) var_loc_list *decl_loc_table;
  
  /* Number of elements in the decl_loc_table that are allocated.  */
  static unsigned decl_loc_table_allocated;
*************** static dw_die_ref new_die		PARAMS ((enum
*** 3709,3715 ****
--- 3718,3726 ----
  static dw_die_ref lookup_type_die	PARAMS ((tree));
  static void equate_type_number_to_die	PARAMS ((tree, dw_die_ref));
  static dw_die_ref lookup_decl_die	PARAMS ((tree));
+ static var_loc_list *lookup_decl_loc	PARAMS ((tree));
  static void equate_decl_number_to_die	PARAMS ((tree, dw_die_ref));
+ static void add_var_loc_to_decl		PARAMS ((tree, struct var_loc_node *));
  static void print_spaces		PARAMS ((FILE *));
  static void print_die			PARAMS ((dw_die_ref, FILE *));
  static void print_dwarf_line_table	PARAMS ((FILE *));
*************** lookup_decl_die (decl)
*** 5305,5322 ****
    return (decl_id < decl_die_table_in_use ? decl_die_table[decl_id] : NULL);
  }
  
- static struct var_loc_node * lookup_decl_loc PARAMS ((tree));
- static void add_var_loc_to_decl PARAMS ((tree, struct var_loc_node *));
- 
  /* Return the var_loc list associated with a given declaration.  */
  
! static inline struct var_loc_node *
  lookup_decl_loc (decl)
       tree decl;
  {
    unsigned decl_id = DECL_UID (decl);
    
!   return (decl_id < decl_loc_table_in_use ? decl_loc_table[decl_id] : NULL);
  }
  
  /* Equate a DIE to a particular declaration.  */
--- 5316,5330 ----
    return (decl_id < decl_die_table_in_use ? decl_die_table[decl_id] : NULL);
  }
  
  /* Return the var_loc list associated with a given declaration.  */
  
! static inline var_loc_list *
  lookup_decl_loc (decl)
       tree decl;
  {
    unsigned decl_id = DECL_UID (decl);
    
!   return (decl_id < decl_loc_table_in_use ? &decl_loc_table[decl_id] : NULL);
  }
  
  /* Equate a DIE to a particular declaration.  */
*************** add_var_loc_to_decl (decl, loc)
*** 5359,5405 ****
  {
    unsigned int decl_id = DECL_UID (decl);
    unsigned int num_allocated;
!   struct var_loc_node *temp;
  
    if (decl_id >= decl_loc_table_allocated)
      {
!       num_allocated
!         = ((decl_id + 1 + DECL_LOC_TABLE_INCREMENT - 1)
!            / DECL_LOC_TABLE_INCREMENT)
!           * DECL_LOC_TABLE_INCREMENT;
! 
!       decl_loc_table
!         = (struct var_loc_node **) ggc_realloc (decl_loc_table,
!                                    sizeof (struct var_loc_node *) * num_allocated);
! 
!       memset ((char *) &decl_loc_table[decl_loc_table_allocated], 0,
!              (num_allocated - decl_loc_table_allocated) * sizeof (struct var_loc_node *));
        decl_loc_table_allocated = num_allocated;
      }
  
    if (decl_id >= decl_loc_table_in_use)
!     decl_loc_table_in_use = (decl_id + 1);
  
!   temp = decl_loc_table[decl_id];
!   if (!temp)
      {
!       decl_loc_table[decl_id] = loc;
!       loc->next = NULL;
      }
!   else
      {
!       /* Get to the end of the list */
!       while (temp->next != NULL)
! 	temp = temp->next;
! 
!       /* If the current location is the same as the end of the list,
! 	 just extend the range of the location at the end of the
! 	 list.  */ 
!       if (rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->var_loc_note), 
! 		       NOTE_VAR_LOCATION_LOC (loc->var_loc_note)))
! 	temp->label = loc->label;
!       else
! 	temp->next = loc;
      }
  }
  
--- 5367,5410 ----
  {
    unsigned int decl_id = DECL_UID (decl);
    unsigned int num_allocated;
!   var_loc_list *temp;
  
    if (decl_id >= decl_loc_table_allocated)
      {
!       num_allocated = ((decl_id + 1 + DECL_LOC_TABLE_INCREMENT - 1)
! 		       / DECL_LOC_TABLE_INCREMENT)
! 		      * DECL_LOC_TABLE_INCREMENT;
! 
!       decl_loc_table = ggc_realloc (decl_loc_table,
! 				    sizeof (var_loc_list) * num_allocated);
! 
!       memset (&decl_loc_table[decl_loc_table_allocated], 0,
! 	      (num_allocated - decl_loc_table_allocated)
! 	      * sizeof (var_loc_list));
        decl_loc_table_allocated = num_allocated;
      }
  
    if (decl_id >= decl_loc_table_in_use)
!     decl_loc_table_in_use = decl_id + 1;
  
!   temp = &decl_loc_table[decl_id];
!   if (temp->last)
      {
!       /* If the current location is the same as the end of the list,
! 	 we have nothing to do.  */
!       if (!rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->last->var_loc_note), 
! 			NOTE_VAR_LOCATION_LOC (loc->var_loc_note)))
! 	{
! 	  /* Add LOC to the end of list and update LAST.  */
! 	  temp->last->next = loc;
! 	  temp->last = loc;
! 	}
      }
!   /* Do not add empty location to the beginning of the list.  */
!   else if (NOTE_VAR_LOCATION_LOC (loc->var_loc_note) != NULL_RTX)
      {
!       temp->first = loc;
!       temp->last = loc;
      }
  }
  
*************** add_location_or_const_value_attribute (d
*** 9644,9650 ****
  {
    rtx rtl;
    dw_loc_descr_ref descr;
!   struct var_loc_node *multiloc;
  
    if (TREE_CODE (decl) == ERROR_MARK)
      return;
--- 9649,9655 ----
  {
    rtx rtl;
    dw_loc_descr_ref descr;
!   var_loc_list *loc_list;
  
    if (TREE_CODE (decl) == ERROR_MARK)
      return;
*************** add_location_or_const_value_attribute (d
*** 9652,9667 ****
      abort ();
  
    /* See if we possibly have multiple locations for this variable.  */
!   multiloc = lookup_decl_loc (decl);
  
!   /* If it truly has multiple locations, it will have >1 list 
!      member.  */
!   if (multiloc && multiloc->next)
!     {     
        const char *secname;
        const char *endname;
        dw_loc_list_ref list;
        rtx varloc;
        
        /* We need to figure out what section we should use as the base
  	 for the address ranges where a given location is valid.
--- 9657,9673 ----
      abort ();
  
    /* 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 *secname;
        const char *endname;
        dw_loc_list_ref list;
        rtx varloc;
+       struct var_loc_node *node;
        
        /* We need to figure out what section we should use as the base
  	 for the address ranges where a given location is valid.
*************** add_location_or_const_value_attribute (d
*** 9697,9724 ****
  	 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].  */
- 	
  
!       varloc = NOTE_VAR_LOCATION (multiloc->var_loc_note);
!       
!       list = new_loc_list (loc_descriptor (varloc), multiloc->label, 
! 			   multiloc->next->label, secname, 1);
!       multiloc = multiloc->next;
  
!       while (multiloc->next)
  	{
- 	  varloc = NOTE_VAR_LOCATION (multiloc->var_loc_note);
- 	  add_loc_descr_to_loc_list (&list, loc_descriptor (varloc),
- 				     multiloc->label, multiloc->next->label,
- 				     secname);
- 	  multiloc = multiloc->next;
- 	}
-       
-       if (multiloc)
-         {
  	  char label_id[MAX_ARTIFICIAL_LABEL_BYTES];
  
! 	  varloc = NOTE_VAR_LOCATION (multiloc->var_loc_note);
  	  if (!current_function_decl)
  	    endname = text_end_label;
  	  else
--- 9703,9733 ----
  	 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);
!       list = new_loc_list (loc_descriptor (varloc), 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.  */
! 	    varloc = NOTE_VAR_LOCATION (node->var_loc_note);
! 	    add_loc_descr_to_loc_list (&list, loc_descriptor (varloc),
! 				       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];
  
! 	  varloc = NOTE_VAR_LOCATION (node->var_loc_note);
  	  if (!current_function_decl)
  	    endname = text_end_label;
  	  else
*************** add_location_or_const_value_attribute (d
*** 9728,9734 ****
  	      endname = ggc_strdup (label_id);
  	    }
  	  add_loc_descr_to_loc_list (&list, loc_descriptor (varloc),
! 				     multiloc->label, endname, secname);
  	}
  
        /* Finally, add the location list to the DIE, and we are done.  */
--- 9737,9743 ----
  	      endname = ggc_strdup (label_id);
  	    }
  	  add_loc_descr_to_loc_list (&list, loc_descriptor (varloc),
! 				     node->label, endname, secname);
  	}
  
        /* Finally, add the location list to the DIE, and we are done.  */
*************** dwarf2out_var_location (loc_note)
*** 12615,12620 ****
--- 12624,12630 ----
    ASM_OUTPUT_LABEL (asm_out_file, loclabel);  
    newloc->label = ggc_strdup (loclabel);
    newloc->var_loc_note = loc_note;
+   newloc->next = NULL;
  
    add_var_loc_to_decl (NOTE_VAR_LOCATION_DECL (loc_note), newloc);
  }
*************** dwarf2out_init (input_filename)
*** 12818,12825 ****
    decl_die_table_in_use = 0;
  
    /* Allocate the initial hunk of the decl_loc_table.  */
!   decl_loc_table
!     = (struct var_loc_node **) ggc_alloc_cleared (DECL_LOC_TABLE_INCREMENT * sizeof (struct var_loc_node *));
    decl_loc_table_allocated = DECL_LOC_TABLE_INCREMENT;
    decl_loc_table_in_use = 0;
    
--- 12828,12835 ----
    decl_die_table_in_use = 0;
  
    /* Allocate the initial hunk of the decl_loc_table.  */
!   decl_loc_table = ggc_alloc_cleared (DECL_LOC_TABLE_INCREMENT
! 				      * sizeof (var_loc_list));
    decl_loc_table_allocated = DECL_LOC_TABLE_INCREMENT;
    decl_loc_table_in_use = 0;
    


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