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]

[PATCH] Avoid many unused .LVLnn labels


Hi!

var-tracking.c can and in many cases does generate var_location notes
for the same variable with the same rtx, but dwarf2out_var_location
first creates the .LVLnn label (if there were any real insns since last
emitted label) and only then calls add_var_loc_to_decl which compares
it to the last recorded location.  When that figures out it is the same,
the newly generated .LVLnn label is emitted, but never used.
The following patch fixes that by doing add_var_loc_to_decl earlier
and not creating the label when it certainly won't be needed.
On a C++ testcase I've tried without this patch g++ created
.LVL0 through .LVL858 labels, out of which 218 .LVLnn labels were
just emitted, but never actually used.
With this patch 126 out of these 218 labels aren't emitted at all
(the remaining 92 ones can be e.g. for variables dwarf2out later figured
that it can't express its locations etc.), but assembled object
is still identical.

Ok for trunk if this bootstraps/regtests on x86_64-linux/i686-linux?

2010-02-17  Jakub Jelinek  <jakub@redhat.com>

	* dwarf2out.c (add_var_loc_to_decl): Change last argument to
	rtx, allocate struct var_loc_node here and return it to the
	caller, and only if it is actually needed.
	(dwarf2out_var_location): Adjust add_var_loc_to_decl caller,
	move it earlier and return immediately if it returns NULL.

--- gcc/dwarf2out.c.jj	2010-02-11 10:49:21.000000000 +0100
+++ gcc/dwarf2out.c	2010-02-17 21:04:31.000000000 +0100
@@ -5983,7 +5983,7 @@ static hashval_t decl_loc_table_hash (co
 static int decl_loc_table_eq (const void *, const void *);
 static var_loc_list *lookup_decl_loc (const_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 struct var_loc_node *add_var_loc_to_decl (tree, rtx);
 static void print_spaces (FILE *);
 static void print_die (dw_die_ref, FILE *);
 static void print_dwarf_line_table (FILE *);
@@ -7762,12 +7762,13 @@ equate_decl_number_to_die (tree decl, dw
 
 /* Add a variable location node to the linked list for DECL.  */
 
-static void
-add_var_loc_to_decl (tree decl, struct var_loc_node *loc)
+static struct var_loc_node *
+add_var_loc_to_decl (tree decl, rtx loc_note)
 {
   unsigned int decl_id = DECL_UID (decl);
   var_loc_list *temp;
   void **slot;
+  struct var_loc_node *loc = NULL;
 
   slot = htab_find_slot_with_hash (decl_loc_table, decl, decl_id, INSERT);
   if (*slot == NULL)
@@ -7785,24 +7786,27 @@ add_var_loc_to_decl (tree decl, struct v
 	 and either both or neither of the locations is uninitialized,
 	 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)))
+			 NOTE_VAR_LOCATION_LOC (loc_note)))
 	  || ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note)
-	       != NOTE_VAR_LOCATION_STATUS (loc->var_loc_note))
+	       != NOTE_VAR_LOCATION_STATUS (loc_note))
 	      && ((NOTE_VAR_LOCATION_STATUS (temp->last->var_loc_note)
 		   == VAR_INIT_STATUS_UNINITIALIZED)
-		  || (NOTE_VAR_LOCATION_STATUS (loc->var_loc_note)
+		  || (NOTE_VAR_LOCATION_STATUS (loc_note)
 		      == VAR_INIT_STATUS_UNINITIALIZED))))
 	{
 	  /* Add LOC to the end of list and update LAST.  */
+	  loc = GGC_CNEW (struct var_loc_node);
 	  temp->last->next = loc;
 	  temp->last = loc;
 	}
     }
   else
     {
+      loc = GGC_CNEW (struct var_loc_node);
       temp->first = loc;
       temp->last = loc;
     }
+  return loc;
 }
 
 /* Keep track of the number of spaces used to indent the
@@ -20252,7 +20256,11 @@ dwarf2out_var_location (rtx loc_note)
   if (next_real == NULL_RTX)
     return;
 
-  newloc = GGC_CNEW (struct var_loc_node);
+  decl = NOTE_VAR_LOCATION_DECL (loc_note);
+  newloc = add_var_loc_to_decl (decl, loc_note);
+  if (newloc == NULL)
+    return;
+
   /* If there were no real insns between note we processed last time
      and this note, use the label we emitted last time.  */
   if (last_var_location_insn == NULL_RTX
@@ -20287,8 +20295,6 @@ dwarf2out_var_location (rtx loc_note)
 
   last_var_location_insn = next_real;
   last_in_cold_section_p = in_cold_section_p;
-  decl = NOTE_VAR_LOCATION_DECL (loc_note);
-  add_var_loc_to_decl (decl, newloc);
 }
 
 /* We need to reset the locations at the beginning of each

	Jakub


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