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]

Fix problem with variable tracking and lcoation lists


Hello,

When the variable has only one location and it holds its location
until end of function, the code producing the location list in
add_location_or_const_value_attribute () will not trigger because
the loc_list has only one element.
This patch fixes it by emiting a special note (NOTE_INSN_VAR_LOCATION
with decl == NULL) and when dwarf2out code sees it
it adds a "terminator" node to loc_list for each variable.
As the result the loc_list has at least 2 elements and the location list
is emitted.

Bootstrapped/regtested x86-64.

Josef

2004-03-26  Josef Zlomek  <zlomekj@suse.cz>

	* dwarf2out.c (add_var_loc_end_to_decl): New function.
	(add_location_or_const_value_attribute): Situation where the last
	location in location chain is not NULL can't happen.
	(dwarf2out_var_location): Fix the consistency test as
	NOTE_VAR_LOCATION_DECL (loc_note) can be NULL now.
	If NOTE_VAR_LOCATION_DECL (loc_note) is NULL add the terminator
	node to loc_list for each variable.
	* print-rtl.c (print_rtx): Print note with
	NOTE_VAR_LOCATION_DECL == NULL correctly.
	* var-tracking.c (vt_emit_notes): Emit a note with decl == NULL
	for the end of function.

Index: dwarf2out.c
===================================================================
RCS file: /cvs/gcc-cvs/gcc/gcc/dwarf2out.c,v
retrieving revision 1.509
diff -c -p -c -3 -p -r1.509 dwarf2out.c
*** dwarf2out.c	22 Mar 2004 20:56:59 -0000	1.509
--- dwarf2out.c	27 Mar 2004 08:48:30 -0000
*************** static int decl_loc_table_eq (const void
*** 3725,3730 ****
--- 3725,3731 ----
  static var_loc_list *lookup_decl_loc (tree);
  static void equate_decl_number_to_die (tree, dw_die_ref);
  static void add_var_loc_to_decl (tree, struct var_loc_node *);
+ static int add_var_loc_end_to_decl (void **, void *);
  static void print_spaces (FILE *);
  static void print_die (dw_die_ref, FILE *);
  static void print_dwarf_line_table (FILE *);
*************** add_var_loc_to_decl (tree decl, struct v
*** 5383,5388 ****
--- 5384,5412 ----
        temp->last = loc;
      }
  }
+ 
+ /* Add a variable location node X ending the location list *SLOT
+    at the end of a function.  */
+ 
+ static int
+ add_var_loc_end_to_decl (void **slot, void *x)
+ {
+   var_loc_list *temp = *slot;
+   struct var_loc_node *loc = x;
+ 
+   if (temp->last)
+     {
+       /* If the location list is already terminated we have nothing to do.  */
+       if (NOTE_VAR_LOCATION_LOC (temp->last->var_loc_note))
+ 	{
+ 	  /* Add LOC to the end of list and update LAST.  */
+ 	  temp->last->next = loc;
+ 	  temp->last = loc;
+ 	}
+     }
+ 
+   return 1;
+ }
  
  /* Keep track of the number of spaces used to indent the
     output of the debugging routines that print the structure of
*************** add_location_or_const_value_attribute (d
*** 9849,9855 ****
    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;
--- 9873,9878 ----
*************** add_location_or_const_value_attribute (d
*** 9907,9932 ****
  				       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
! 	    {
! 	      ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL,
! 					   current_function_funcdef_no);
! 	      endname = ggc_strdup (label_id);
! 	    }
! 	  add_loc_descr_to_loc_list (&list,
! 				     loc_descriptor (varloc,
! 						     attr != DW_AT_frame_base),
! 				     node->label, endname, secname);
! 	}
  
        /* Finally, add the location list to the DIE, and we are done.  */
        add_AT_loc_list (die, attr, list);
--- 9930,9942 ----
  				       node->label, node->next->label, secname);
  	  }
  
! #ifdef ENABLE_CHECKING
!       /* Each location chain should be terminated by a node whose
! 	 NOTE_VAR_LOCATION_LOC (node->var_loc_note) == NULL_RTX
! 	 in add_var_loc_end_to_decl.  */
        if (NOTE_VAR_LOCATION_LOC (node->var_loc_note) != NULL_RTX)
! 	abort ();
! #endif
  
        /* Finally, add the location list to the DIE, and we are done.  */
        add_AT_loc_list (die, attr, list);
*************** dwarf2out_var_location (rtx loc_note)
*** 13009,13016 ****
    static rtx last_insn;
    static const char *last_label;
  
!   if (!DECL_P (NOTE_VAR_LOCATION_DECL (loc_note)))
!     return;
    prev_insn = PREV_INSN (loc_note);
  
    newloc = ggc_alloc_cleared (sizeof (struct var_loc_node));
--- 13019,13030 ----
    static rtx last_insn;
    static const char *last_label;
  
! #ifdef ENABLE_CHECKING
!   if (NOTE_VAR_LOCATION_DECL (loc_note)
!       && !DECL_P (NOTE_VAR_LOCATION_DECL (loc_note)))
!     abort ();
! #endif
! 
    prev_insn = PREV_INSN (loc_note);
  
    newloc = ggc_alloc_cleared (sizeof (struct var_loc_node));
*************** dwarf2out_var_location (rtx loc_note)
*** 13037,13043 ****
    last_insn = loc_note;
    last_label = newloc->label;
  
!   add_var_loc_to_decl (NOTE_VAR_LOCATION_DECL (loc_note), newloc);
  }
  
  /* We need to reset the locations at the beginning of each
--- 13051,13060 ----
    last_insn = loc_note;
    last_label = newloc->label;
  
!   if (NOTE_VAR_LOCATION_DECL (loc_note))
!     add_var_loc_to_decl (NOTE_VAR_LOCATION_DECL (loc_note), newloc);
!   else
!     htab_traverse (decl_loc_table, add_var_loc_end_to_decl, newloc);
  }
  
  /* We need to reset the locations at the beginning of each
Index: print-rtl.c
===================================================================
RCS file: /cvs/gcc-cvs/gcc/gcc/print-rtl.c,v
retrieving revision 1.106
diff -c -p -c -3 -p -r1.106 print-rtl.c
*** print-rtl.c	7 Feb 2004 14:14:51 -0000	1.106
--- print-rtl.c	26 Mar 2004 17:57:09 -0000
*************** print_rtx (rtx in_rtx)
*** 293,299 ****
  
  	      case NOTE_INSN_VAR_LOCATION:
  		fprintf (outfile, " (");
! 		print_mem_expr (outfile, NOTE_VAR_LOCATION_DECL (in_rtx));
  		fprintf (outfile, " ");
  		print_rtx (NOTE_VAR_LOCATION_LOC (in_rtx));
  		fprintf (outfile, ")");
--- 293,302 ----
  
  	      case NOTE_INSN_VAR_LOCATION:
  		fprintf (outfile, " (");
! 		if (NOTE_VAR_LOCATION_DECL (in_rtx))
! 		  print_mem_expr (outfile, NOTE_VAR_LOCATION_DECL (in_rtx));
! 		else
! 		  fprintf (outfile, " (all)");
  		fprintf (outfile, " ");
  		print_rtx (NOTE_VAR_LOCATION_LOC (in_rtx));
  		fprintf (outfile, ")");
Index: var-tracking.c
===================================================================
RCS file: /cvs/gcc-cvs/gcc/gcc/var-tracking.c,v
retrieving revision 2.12
diff -c -p -c -3 -p -r2.12 var-tracking.c
*** var-tracking.c	22 Mar 2004 02:57:27 -0000	2.12
--- var-tracking.c	25 Mar 2004 16:14:44 -0000
*************** vt_emit_notes (void)
*** 2418,2423 ****
--- 2418,2424 ----
    basic_block bb;
    dataflow_set *last_out;
    dataflow_set empty;
+   rtx note;
  
  #ifdef ENABLE_CHECKING
    if (htab_elements (changed_variables))
*************** vt_emit_notes (void)
*** 2443,2448 ****
--- 2444,2455 ----
        last_out = &VTI (bb)->out;
      }
    dataflow_set_destroy (&empty);
+ 
+   /* Emit the special note terminating all location lists.  */
+   note = emit_note_after (NOTE_INSN_VAR_LOCATION, get_last_insn ());
+   NOTE_VAR_LOCATION (note)
+     = gen_rtx_VAR_LOCATION (VOIDmode, NULL_TREE, NULL_RTX);
+ 
    emit_notes = false;
  }
  


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