[lto] Fix locus information in decls and expressions

Diego Novillo dnovillo@google.com
Fri May 15 17:43:00 GMT 2009


The logic to elide superfluous location information for
expressions and decls was faulty.  This patch simply removes it
for now.  I think it's not really necessary now that most
location information is stashed in gimple statements now.  I may
put it back if it's a problem space-wise.

The patch also checks whether there is enough space to encode
location information in flags.

We are still not emitting location information for statements.
That patch is coming up shortly.

Tested on x86_64.


Diego.



	* lto-function-out.c (output_tree_flags): Always emit
	location information for expressions and symbols that
	have them.
	Make sure that FLAGS has enough space left to encode
	location information.
	* lto-function-in.c (input_line_info): Change return type
	to void.
	Update all callers.
	Assert that FLAGS has LTO_SOURCE_HAS_LOC set.
	* lto-tags.h: Update comment describing the LTO_SOURCE_*
	flags.

Index: lto-function-out.c
===================================================================
--- lto-function-out.c	(revision 147576)
+++ lto-function-out.c	(working copy)
@@ -470,10 +470,12 @@ static void
 output_tree_flags (struct output_block *ob, enum tree_code code, tree expr, 
 		   bool force_loc)
 {
-  lto_flags_type flags = 0;
-  const char *file_to_write = NULL;
-  int line_to_write = -1;
-  int col_to_write = -1;
+  lto_flags_type flags;
+  const char *current_file;
+  int current_line;
+  int current_col;
+
+  flags = 0;
 
   if (code == 0 || TEST_BIT (lto_flags_needed_for, code))
     {
@@ -545,93 +547,82 @@ output_tree_flags (struct output_block *
 #undef END_EXPR_CASE
 #undef END_EXPR_SWITCH
 
+      /* Make sure that we have room to store the locus bits.  */
+      {
+	lto_flags_type mask;
+	mask = LTO_SOURCE_FILE 
+	       | LTO_SOURCE_LINE
+	       | LTO_SOURCE_COL
+	       | LTO_SOURCE_HAS_LOC;
+	mask <<= (HOST_BITS_PER_WIDEST_INT - LTO_SOURCE_LOC_BITS); 
+	gcc_assert ((flags & mask) == 0);
+      }
+
       flags <<= LTO_SOURCE_LOC_BITS;
+
+      current_file = NULL;
+      current_line = -1;
+      current_col = -1;
+
       if (expr)
 	{
-	  const char *current_file = NULL;
-	  int current_line = 0;
-	  int current_col = 0;
-	  if (EXPR_P (expr))
-	    {
-	      if (EXPR_HAS_LOCATION (expr))
-		{
-		  expanded_location xloc 
-		    = expand_location (EXPR_LOCATION (expr));
+	  expanded_location xloc;
 
-		  current_file = xloc.file;
-		  current_line = xloc.line;
-		  current_col = xloc.column;
-		  flags |= LTO_SOURCE_HAS_LOC;
-		}
-	    }
+	  memset (&xloc, 0, sizeof (xloc));
 
-	  /* We use force_loc here because we only want to put out the
-	     line number when we are writing the top level list of var
-	     and parm decls, not when we access them inside a
-	     function.  */
+	  if (EXPR_P (expr) && EXPR_HAS_LOCATION (expr))
+	    xloc = expand_location (EXPR_LOCATION (expr));
 	  else if (force_loc && DECL_P (expr))
 	    {
-	      expanded_location xloc 
-		= expand_location (DECL_SOURCE_LOCATION (expr));
-	      if (xloc.file)
-		{
-		  current_file = xloc.file;
-		  current_line = xloc.line;
-		  current_col = xloc.column;
-		  flags |= LTO_SOURCE_HAS_LOC;
-		}
+	      /* We use FORCE_LOC here because we only want to put out
+		 the line number when we are writing the top level
+		 list of var and parm decls, not when we access them
+		 inside a function.  */
+	      xloc = expand_location (DECL_SOURCE_LOCATION (expr));
 	    }
 
-	  if (current_file
-	      && (ob->current_file == NULL
-		  || strcmp (ob->current_file, current_file) != 0))
-	    {
-	      file_to_write = current_file;
-	      ob->current_file = current_file;
-	      flags |= LTO_SOURCE_FILE;
-	    }
-	  if (current_line != 0
-	      && ob->current_line != current_line)
-	    {
-	      line_to_write = current_line;
-	      ob->current_line = current_line;
-	      flags |= LTO_SOURCE_LINE;
-	    }
-	  if (current_col != 0
-	      && ob->current_col != current_col)
+	  if (xloc.file)
 	    {
-	      col_to_write = current_col;
-	      ob->current_col = current_col;
-	      flags |= LTO_SOURCE_COL;
+	      current_file = xloc.file;
+	      current_line = xloc.line;
+	      current_col = xloc.column;
+	      flags |= LTO_SOURCE_HAS_LOC;
 	    }
+
+	  if (current_file)
+	    flags |= LTO_SOURCE_FILE;
+
+	  if (current_line != -1)
+	    flags |= LTO_SOURCE_LINE;
+
+	  if (current_col != -1)
+	    flags |= LTO_SOURCE_COL;
 	}
 
       LTO_DEBUG_TOKEN ("flags");
       output_widest_uint_uleb128 (ob, flags);
-      /* Note that when we force flags with code == 0,
-         we cause the debugging info to be omitted.
-         I tried to fix this like so:
-           LTO_DEBUG_TREE_FLAGS (TREE_CODE (expr), flags);
-         This breaks input_local_var, however, which
-         expects the debug info to be missing.
-         Do the fix anyway, and fix input_local_var.  */
-      /* LTO_DEBUG_TREE_FLAGS (code, flags); */
+
       LTO_DEBUG_TREE_FLAGS (TREE_CODE (expr), flags);
 
-      if (file_to_write)
+      if (flags & LTO_SOURCE_FILE)
 	{
+	  ob->current_file = current_file;
 	  LTO_DEBUG_TOKEN ("file");
-	  output_string (ob, ob->main_stream, file_to_write);
+	  output_string (ob, ob->main_stream, current_file);
 	}
-      if (line_to_write != -1)
+
+      if (flags & LTO_SOURCE_LINE)
 	{
+	  ob->current_line = current_line;
 	  LTO_DEBUG_TOKEN ("line");
-	  output_uleb128 (ob, line_to_write);
+	  output_uleb128 (ob, current_line);
 	}
-      if (col_to_write != -1)
+
+      if (flags & LTO_SOURCE_COL)
 	{
+	  ob->current_col = current_col;
 	  LTO_DEBUG_TOKEN ("col");
-	  output_uleb128 (ob, col_to_write);
+	  output_uleb128 (ob, current_col);
 	}
     }
 }
Index: lto-function-in.c
===================================================================
--- lto-function-in.c	(revision 147576)
+++ lto-function-in.c	(working copy)
@@ -451,10 +451,12 @@ canon_file_name (const char *string)
 /* Based on FLAGS read in a file, a line and a column into the
    fields in DATA_IN using input block IB.  */
 
-static bool
+static void
 input_line_info (struct lto_input_block *ib, struct data_in *data_in, 
 		 lto_flags_type flags)
 {
+  gcc_assert (flags & LTO_SOURCE_HAS_LOC);
+
   if (flags & LTO_SOURCE_FILE)
     {
       if (data_in->current_file)
@@ -482,8 +484,6 @@ input_line_info (struct lto_input_block 
       LTO_DEBUG_TOKEN ("col");
       data_in->current_col = lto_input_uleb128 (ib);
     }
-
-  return (flags & LTO_SOURCE_HAS_LOC) != 0;
 }
 
 
@@ -524,7 +524,7 @@ input_expr_operand (struct lto_input_blo
   tree type = NULL_TREE;
   lto_flags_type flags;
   tree result = NULL_TREE;
-  bool needs_line_set = false;
+  bool needs_line_set;
 
   if (tag == LTO_type_ref)
     {
@@ -540,8 +540,9 @@ input_expr_operand (struct lto_input_blo
 
   flags = input_tree_flags (ib, code, false);
 
-  if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
-    needs_line_set = input_line_info (ib, data_in, flags);
+  needs_line_set = (flags & LTO_SOURCE_HAS_LOC);
+  if (needs_line_set)
+    input_line_info (ib, data_in, flags);
 
   switch (code)
     {
@@ -1070,10 +1071,13 @@ input_local_var_decl (struct lto_input_b
     }
 
   flags = input_tree_flags (ib, ERROR_MARK, true);
-
   LTO_DEBUG_TREE_FLAGS (TREE_CODE (result), flags);
-  if (input_line_info (ib, data_in, flags))
-    set_line_info (data_in, result);
+
+  if (flags & LTO_SOURCE_HAS_LOC)
+    {
+      input_line_info (ib, data_in, flags);
+      set_line_info (data_in, result);
+    }
 
   DECL_CONTEXT (result) = fn->decl;
 
@@ -2461,11 +2465,18 @@ input_tree_with_context (struct lto_inpu
 static tree
 input_field_decl (struct lto_input_block *ib, struct data_in *data_in)
 {
-  tree decl = make_node (FIELD_DECL);
+  tree decl;
+  lto_flags_type flags;
   
-  lto_flags_type flags = input_tree_flags (ib, FIELD_DECL, true);
-  if (input_line_info (ib, data_in, flags))
-    set_line_info (data_in, decl);
+  decl = make_node (FIELD_DECL);
+  
+  flags = input_tree_flags (ib, FIELD_DECL, true);
+  if (flags & LTO_SOURCE_HAS_LOC)
+    {
+      input_line_info (ib, data_in, flags);
+      set_line_info (data_in, decl);
+    }
+
   process_tree_flags (decl, flags);
 
   global_vector_enter (data_in, decl);
@@ -2528,11 +2539,18 @@ input_field_decl (struct lto_input_block
 static tree
 input_const_decl (struct lto_input_block *ib, struct data_in *data_in)
 {
-  tree decl = make_node (CONST_DECL);
+  tree decl;
+  lto_flags_type flags;
+
+  decl = make_node (CONST_DECL);
+
+  flags = input_tree_flags (ib, CONST_DECL, true);
+  if (flags & LTO_SOURCE_HAS_LOC)
+    {
+      input_line_info (ib, data_in, flags);
+      set_line_info (data_in, decl);
+    }
 
-  lto_flags_type flags = input_tree_flags (ib, CONST_DECL, true);
-  if (input_line_info (ib, data_in, flags))
-    set_line_info (data_in, decl);
   process_tree_flags (decl, flags);
 
   global_vector_enter (data_in, decl);
@@ -2644,9 +2662,14 @@ input_function_decl (struct lto_input_bl
     }
 
   decl = make_node (FUNCTION_DECL);
+
   flags = input_tree_flags (ib, FUNCTION_DECL, true);
-  if (input_line_info (ib, data_in, flags))
-    set_line_info (data_in, decl);
+  if (flags & LTO_SOURCE_HAS_LOC)
+    {
+      input_line_info (ib, data_in, flags);
+      set_line_info (data_in, decl);
+    }
+
   process_tree_flags (decl, flags);
 
   index = global_vector_enter (data_in, decl);
@@ -2751,12 +2774,18 @@ input_var_decl (struct lto_input_block *
 {
   unsigned index;
   lto_decl_flags_t decl_flags;
+  tree decl;
+  lto_flags_type flags;
 
-  tree decl = make_node (VAR_DECL);
+  decl = make_node (VAR_DECL);
+
+  flags = input_tree_flags (ib, VAR_DECL, true);
+  if (flags & LTO_SOURCE_HAS_LOC)
+    {
+      input_line_info (ib, data_in, flags);
+      set_line_info (data_in, decl);
+    }
 
-  lto_flags_type flags = input_tree_flags (ib, VAR_DECL, true);
-  if (input_line_info (ib, data_in, flags))
-    set_line_info (data_in, decl);
   process_tree_flags (decl, flags);
 
   /* Additional LTO decl flags. */
@@ -2850,11 +2879,18 @@ input_var_decl (struct lto_input_block *
 static tree
 input_parm_decl (struct lto_input_block *ib, struct data_in *data_in, tree fn)
 {
-  tree decl = make_node (PARM_DECL);
+  tree decl;
+  lto_flags_type flags;
+
+  decl = make_node (PARM_DECL);
+
+  flags = input_tree_flags (ib, PARM_DECL, true);
+  if (flags & LTO_SOURCE_HAS_LOC)
+    {
+      input_line_info (ib, data_in, flags);
+      set_line_info (data_in, decl);
+    }
 
-  lto_flags_type flags = input_tree_flags (ib, PARM_DECL, true);
-  if (input_line_info (ib, data_in, flags))
-    set_line_info (data_in, decl);
   process_tree_flags (decl, flags);
 
   global_vector_enter (data_in, decl);
@@ -2884,11 +2920,18 @@ static tree
 input_result_decl (struct lto_input_block *ib, struct data_in *data_in,
 		   tree fn)
 {
-  tree decl = make_node (RESULT_DECL);
+  tree decl;
+  lto_flags_type flags;
+
+  decl = make_node (RESULT_DECL);
+
+  flags = input_tree_flags (ib, RESULT_DECL, true);
+  if (flags & LTO_SOURCE_HAS_LOC)
+    {
+      input_line_info (ib, data_in, flags);
+      set_line_info (data_in, decl);
+    }
 
-  lto_flags_type flags = input_tree_flags (ib, RESULT_DECL, true);
-  if (input_line_info (ib, data_in, flags))
-    set_line_info (data_in, decl);
   process_tree_flags (decl, flags);
 
   global_vector_enter (data_in, decl);
@@ -2915,11 +2958,18 @@ input_result_decl (struct lto_input_bloc
 static tree
 input_type_decl (struct lto_input_block *ib, struct data_in *data_in)
 {
-  tree decl = make_node (TYPE_DECL);
+  tree decl;
+  lto_flags_type flags;
+
+  decl = make_node (TYPE_DECL);
+
+  flags = input_tree_flags (ib, TYPE_DECL, true);
+  if (flags & LTO_SOURCE_HAS_LOC)
+    {
+      input_line_info (ib, data_in, flags);
+      set_line_info (data_in, decl);
+    }
 
-  lto_flags_type flags = input_tree_flags (ib, TYPE_DECL, true);
-  if (input_line_info (ib, data_in, flags))
-    set_line_info (data_in, decl);
   process_tree_flags (decl, flags);
 
   global_vector_enter (data_in, decl);
@@ -2950,11 +3000,18 @@ input_type_decl (struct lto_input_block 
 static tree
 input_label_decl (struct lto_input_block *ib, struct data_in *data_in)
 {
-  tree decl = make_node (LABEL_DECL);
+  tree decl;
+  lto_flags_type flags;
+
+  decl = make_node (LABEL_DECL);
+
+  flags = input_tree_flags (ib, LABEL_DECL, true);
+  if (flags & LTO_SOURCE_HAS_LOC)
+    {
+      input_line_info (ib, data_in, flags);
+      set_line_info (data_in, decl);
+    }
 
-  lto_flags_type flags = input_tree_flags (ib, LABEL_DECL, true);
-  if (input_line_info (ib, data_in, flags))
-    set_line_info (data_in, decl);
   process_tree_flags (decl, flags);
 
   global_vector_enter (data_in, decl);
@@ -2979,11 +3036,18 @@ input_label_decl (struct lto_input_block
 static tree
 input_imported_decl (struct lto_input_block *ib, struct data_in *data_in)
 {
-  tree decl = make_node (IMPORTED_DECL);
+  tree decl;
+  lto_flags_type flags;
+
+  decl = make_node (IMPORTED_DECL);
+
+  flags = input_tree_flags (ib, IMPORTED_DECL, true);
+  if (flags & LTO_SOURCE_HAS_LOC)
+    {
+      input_line_info (ib, data_in, flags);
+      set_line_info (data_in, decl);
+    }
 
-  lto_flags_type flags = input_tree_flags (ib, IMPORTED_DECL, true);
-  if (input_line_info (ib, data_in, flags))
-    set_line_info (data_in, decl);
   process_tree_flags (decl, flags);
 
   global_vector_enter (data_in, decl);
@@ -3015,7 +3079,7 @@ input_binfo (struct lto_input_block *ib,
 
   binfo = make_tree_binfo (num_base_binfos);
 
-  gcc_assert (!input_line_info (ib, data_in, flags));
+  gcc_assert (!(flags & LTO_SOURCE_HAS_LOC));
   process_tree_flags (binfo, flags);
 
   global_vector_enter (data_in, binfo);
@@ -3239,8 +3303,9 @@ input_tree_operand (struct lto_input_blo
 
 
   /* Handlers for declarations currently handle line info themselves.  */
-  if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code)))
-    needs_line_set = input_line_info (ib, data_in, flags);
+  needs_line_set = flags & LTO_SOURCE_HAS_LOC;
+  if (needs_line_set)
+    input_line_info (ib, data_in, flags);
 
   switch (code)
     {
Index: lto-tags.h
===================================================================
--- lto-tags.h	(revision 147576)
+++ lto-tags.h	(working copy)
@@ -537,21 +537,12 @@ extern sbitmap lto_flags_needed_for;
 
 void lto_static_init (void);
 
-/* The serialization plan is that when any of the current file, line,
-   or col change (from the state last serialized), we write the
-   changed entity and only that entity into the stream.  We also
-   serialize the fact that the current node needs a line number.
-   Otherwise we end up putting line numbers on everything.  This takes
-   4 bits on every node and are added to the flags that are serialized
-   for the node.  
-
-   We waste a bit for the col even though we do not use the col except in
-   USE_MAPPED_LOCATION
-*/
-#define LTO_SOURCE_FILE    0x1
-#define LTO_SOURCE_LINE    0x2
-#define LTO_SOURCE_COL     0x4
-#define LTO_SOURCE_HAS_LOC 0x8
+/* Indicators for the presence of locus information on expressions and
+   symbols.  */
+#define LTO_SOURCE_FILE    1 << 0
+#define LTO_SOURCE_LINE    1 << 1
+#define LTO_SOURCE_COL     1 << 2
+#define LTO_SOURCE_HAS_LOC 1 << 3
 #define LTO_SOURCE_LOC_BITS 4
 
 /* The VAR_DECL tree code has more than 32 bits in flags.  On some hosts,



More information about the Gcc-patches mailing list