This is the mail archive of the gcc@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]

[pph] Merge from trunk rev 180687. Fix for skipped line tables


This merge was quite convoluted.  It brought in the new macro
location features which required several changes in the line
table routines.

With it, I fixed the bug I had introduced with the PPH skipping
that left holes in the line map table.  Instead of saving
absolute index numbers for the includer fields, we now write
relative indices.  These are later relocated during read.  This
way, it doesn't matter where individual line tables are inserted
(patch below).

Tested on x86_64.  Committed to branch.


2011-11-22   Diego Novillo  <dnovillo@google.com>

	* pph-streamer-in.c (pph_in_int): New.
	(pph_in_line_map_ordinary): New.
	(pph_in_line_map): Call it.
	(pph_in_line_table_and_includes): Re-write to account for
	new macro location changes.
	(pph_prepend_to_chain): Fix warnings.
	* pph-streamer-out.c (pph_out_int): New.
	(pph_out_line_map_ordinary): New.
	(pph_out_line_map): Call it.
	(pph_out_line_table_and_includes): Re-write to account for
	new macro location changes.
	(pph_out_location): Likewise.
	* pph.c (pph_file_change_handler): Likewise.

Index: cp/pph-streamer-in.c
===================================================================
--- cp/pph-streamer-in.c	(revision 181521)
+++ cp/pph-streamer-in.c	(working copy)
@@ -148,6 +148,17 @@ pph_in_hwi (pph_stream *stream)
 }
 
 
+/* Read an int from STREAM.  */
+
+static inline int
+pph_in_int (pph_stream *stream)
+{
+  HOST_WIDE_INT n = streamer_read_hwi (stream->encoder.r.ib);
+  gcc_assert (n == (int) n);
+  return (int) n;
+}
+
+
 /* Read an unsigned HOST_WIDE_INT from STREAM.  */
 
 static inline unsigned HOST_WIDE_INT
@@ -243,26 +254,44 @@ pph_in_linetable_marker (pph_stream *str
 }
 
 
+
+/* Read all the fields of struct line_map LM from STREAM.  LM is assumed
+   to be an ordinary line map.  */
+
+static void
+pph_in_line_map_ordinary (pph_stream *stream, struct line_map *lm)
+{
+  struct bitpack_d bp;
+
+  ORDINARY_MAP_FILE_NAME (lm) = pph_in_string (stream);
+  ORDINARY_MAP_STARTING_LINE_NUMBER (lm) = pph_in_linenum_type (stream);
+
+  /* Note that this index is an offset indicating the distance from LM
+     to the line map entry for LM's includer.  It needs to be adjusted
+     while reading the line table in pph_in_line_table_and_includes.  */
+  ORDINARY_MAP_INCLUDER_FILE_INDEX (lm) = pph_in_int (stream);
+  bp = pph_in_bitpack (stream);
+  ORDINARY_MAP_IN_SYSTEM_HEADER_P (lm)
+      = (unsigned char) bp_unpack_value (&bp, CHAR_BIT);
+  ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (lm) = bp_unpack_value (&bp,
+							     COLUMN_BITS_BIT);
+}
+
+
 /* Read a line_map from STREAM into LM.  */
 
 static void
 pph_in_line_map (pph_stream *stream, struct line_map *lm)
 {
-  struct bitpack_d bp;
+  struct lto_input_block *ib = stream->encoder.r.ib;
 
-  lm->to_file = pph_in_string (stream);
-  lm->to_line = pph_in_linenum_type (stream);
   lm->start_location = pph_in_source_location (stream);
-  lm->included_from = (int) pph_in_uint (stream);
+  lm->reason = streamer_read_enum (ib, lc_reason, LC_ENTER_MACRO);
 
-  bp = pph_in_bitpack (stream);
-  lm->reason = (enum lc_reason) bp_unpack_value (&bp, LC_REASON_BIT);
-  gcc_assert (lm->reason == LC_ENTER
-              || lm->reason == LC_LEAVE
-              || lm->reason == LC_RENAME
-              || lm->reason == LC_RENAME_VERBATIM);
-  lm->sysp = (unsigned char) bp_unpack_value (&bp, CHAR_BIT);
-  lm->column_bits = bp_unpack_value (&bp, COLUMN_BITS_BIT);
+  /* FIXME pph.  We currently do not support location tracking for
+     macros in PPH images.  */
+  gcc_assert (lm->reason != LC_ENTER_MACRO);
+  pph_in_line_map_ordinary (stream, lm);
 }
 
 
@@ -297,28 +326,30 @@ pph_in_include (pph_stream *stream)
 }
 
 
-/* Read the line_table from STREAM and merge it in the current line_table.  At
-   the same time load includes in the order they were originally included by
-   loading them at the point they were referenced in the line_table.
-
-   Returns the source_location of line 1 / col 0 for this include.
+/* Read the line_table from STREAM and merge it in the current
+   line_table.  At the same time load includes in the order they were
+   originally included by loading them at the point they were
+   referenced in the line_table.
 
-   FIXME pph: The line_table is now identical to the non-pph line_table, the
-   only problem is that we load line_table entries twice for headers that are
-   re-included and are #ifdef guarded; thus shouldn't be replayed.  This is
-   a known current issue, so I didn't bother working around it here for now.  */
+   Returns the source_location of line 1 / col 0 for this include.  */
 
 static source_location
 pph_in_line_table_and_includes (pph_stream *stream)
 {
-  unsigned int old_depth;
+  unsigned int used_before, old_depth;
   bool first;
-  int includer_ix = -1;
-  unsigned int used_before = line_table->used;
-  int entries_offset = line_table->used - PPH_NUM_IGNORED_LINE_TABLE_ENTRIES;
-  enum pph_linetable_marker next_lt_marker = pph_in_linetable_marker (stream);
+  enum pph_linetable_marker next_lt_marker;
+  int top_includer_ix;
 
-  for (first = true; next_lt_marker != PPH_LINETABLE_END;
+  used_before = LINEMAPS_ORDINARY_USED (line_table);
+  first = true;
+
+  /* All line map entries that have -1 as the includer, will now be
+     relocated to the current last line map entry in the line table.  */
+  top_includer_ix = used_before - 1;
+
+  for (next_lt_marker = pph_in_linetable_marker (stream);
+       next_lt_marker != PPH_LINETABLE_END;
        next_lt_marker = pph_in_linetable_marker (stream))
     {
       if (next_lt_marker == PPH_LINETABLE_REFERENCE)
@@ -329,41 +360,43 @@ pph_in_line_table_and_includes (pph_stre
       else
 	{
 	  struct line_map *lm;
+	  int last_entry_ix;
 
-	  linemap_ensure_extra_space_available (line_table);
-
-	  lm = &line_table->maps[line_table->used];
-
+	  lm = linemap_new_map (line_table, LC_ENTER);
 	  pph_in_line_map (stream, lm);
 
+	  /* All the entries that we read from STREAM will be appended
+	     to the end of line_table.  Calculate the index for the
+	     last entry so that we can resolve the relative indices
+	     for all the includer file index entries we read from
+	     STREAM.  Note that LAST_ENTRY_IX is the index of the line
+	     map LM that we have just read.  */
+	  last_entry_ix = LINEMAPS_ORDINARY_USED (line_table) - 1;
+
 	  if (first)
 	    {
 	      first = false;
-
 	      pph_loc_offset = (line_table->highest_location + 1)
 		               - lm->start_location;
-
-	      includer_ix = line_table->used - 1;
-
-	      gcc_assert (lm->included_from == -1);
+	      gcc_assert (ORDINARY_MAP_INCLUDER_FILE_INDEX (lm) == -1);
 	    }
 
-	  gcc_assert (includer_ix != -1);
+	  /* Relocate the includer file index.  For most entries, the
+	     writer wrote ORDINARY_MAP_INCLUDER_FILE_INDEX as a
+	     relative offset between this entry and the original
+	     includer file index (see pph_out_line_map_ordinary).
+	     Convert that relative index into an absolute index in the
+	     current line_table.
 
-	  /* When parsing the pph: the header itself wasn't included by
-	    anything, now it's included by the file just before it in
-	    the current include tree.  */
-	  if (lm->included_from == -1)
-	    lm->included_from = includer_ix;
-	  /* For the other entries in the pph's line_table which were included
-	     from another entry, reflect their included_from to the new position
-	     of the entry which they were included from.  */
+	     A relocation value of -1 means that line map LM is
+	     included by the current top includer (i.e., STREAM), so
+	     we use the value TOP_INCLUDER_IX for it.  */
+	  if (ORDINARY_MAP_INCLUDER_FILE_INDEX (lm) == -1)
+	    ORDINARY_MAP_INCLUDER_FILE_INDEX (lm) = top_includer_ix;
 	  else
-	    lm->included_from += entries_offset;
+	    ORDINARY_MAP_INCLUDER_FILE_INDEX (lm) -= last_entry_ix;
 
 	  lm->start_location += pph_loc_offset;
-
-	  line_table->used++;
 	}
     }
 
@@ -386,8 +419,8 @@ pph_in_line_table_and_includes (pph_stre
      Instead of insisting on getting EXPECTED_IN entries, we expect at
      most EXPECTED_IN entries.  */
   {
-    unsigned int expected_in = pph_in_uint (stream);
-    gcc_assert (line_table->used - used_before <= expected_in);
+    unsigned int expected = pph_in_uint (stream);
+    gcc_assert (LINEMAPS_ORDINARY_USED (line_table) - used_before <= expected);
   }
 
   line_table->highest_location = pph_loc_offset + pph_in_uint (stream);
@@ -406,7 +439,7 @@ pph_in_line_table_and_includes (pph_stre
   linemap_add (line_table, LC_LEAVE, 0, NULL, 0);
   gcc_assert (line_table->depth == old_depth);
 
-  return line_table->maps[used_before].start_location;
+  return MAP_START_LOCATION (LINEMAPS_ORDINARY_MAP_AT (line_table, used_before));
 }
 
 
@@ -899,8 +932,13 @@ pph_prepend_to_chain (tree expr, tree *c
 static tree
 pph_merge_into_chain (tree expr, const char *name, tree *chain)
 {
-  merge_toc_entry key = { expr, chain, name };
-  tree found = pph_toc_lookup (merge_toc, &key);
+  merge_toc_entry key;
+  tree found;
+
+  key.expr = expr;
+  key.context = chain;
+  key.name = name;
+  found = pph_toc_lookup (merge_toc, &key);
   if (!found)
     {
       pph_toc_add (merge_toc, &key);
Index: cp/pph-streamer-out.c
===================================================================
--- cp/pph-streamer-out.c	(revision 181521)
+++ cp/pph-streamer-out.c	(working copy)
@@ -101,6 +101,15 @@ pph_out_hwi (pph_stream *stream, HOST_WI
 }
 
 
+/* Write an int VALUE to stream.  */
+
+static inline void
+pph_out_int (pph_stream *stream, int value)
+{
+  streamer_write_hwi (stream->encoder.w.ob, value);
+}
+
+
 /* Write an unsigned HOST_WIDE_INT VALUE to STREAM.  */
 
 static inline void
@@ -190,26 +199,66 @@ pph_out_linetable_marker (pph_stream *st
 }
 
 
-/* Emit all information contained in LM to STREAM.  */
+/* Emit all the fields of struct line_map_ordinary LM to STREAM.  IX
+   is the slot number in the line table where LM is stored.  */
 
 static void
-pph_out_line_map (pph_stream *stream, struct line_map *lm)
+pph_out_line_map_ordinary (pph_stream *stream, struct line_map *lm, int ix)
 {
   struct bitpack_d bp;
+  int rel_includer_ix, includer_ix;
 
-  pph_out_string (stream, lm->to_file);
-  pph_out_linenum_type (stream, lm->to_line);
-  pph_out_source_location (stream, lm->start_location);
-  pph_out_uint (stream, (unsigned int) lm->included_from);
+  pph_out_string (stream, ORDINARY_MAP_FILE_NAME (lm));
+  pph_out_linenum_type (stream, ORDINARY_MAP_STARTING_LINE_NUMBER (lm));
+
+  /* To support relocating this table into other translation units,
+     emit a relative index to LM's includer.  All the relative indices
+     are positive values indicating the distance from LM to the line
+     map for its includer.  */
+  includer_ix = ORDINARY_MAP_INCLUDER_FILE_INDEX (lm);
+  if (includer_ix >= 0)
+    {
+      gcc_assert (includer_ix < ix);
+      rel_includer_ix = ix - includer_ix;
+    }
+  else
+    {
+      /* If LM is included by index -1, it means that this is a line map
+	 entry for the top level file being compiled (i.e., the PPH that
+	 we are currently generating).  The first time we find this index,
+	 the reader will remember the index of the current parent file
+	 and replace all the -1 entries with it.  */
+      gcc_assert (includer_ix == -1);
+      rel_includer_ix = includer_ix;
+    }
+
+  pph_out_int (stream, rel_includer_ix);
 
   bp = bitpack_create (stream->encoder.w.ob->main_stream);
-  bp_pack_value (&bp, lm->reason, CHAR_BIT);
-  bp_pack_value (&bp, lm->sysp, CHAR_BIT);
-  bp_pack_value (&bp, lm->column_bits, COLUMN_BITS_BIT);
+  bp_pack_value (&bp, ORDINARY_MAP_IN_SYSTEM_HEADER_P (lm), CHAR_BIT);
+  bp_pack_value (&bp, ORDINARY_MAP_NUMBER_OF_COLUMN_BITS (lm), COLUMN_BITS_BIT);
   pph_out_bitpack (stream, &bp);
 }
 
 
+/* Emit all information contained in LM to STREAM.  IX is the slot number
+   in the line table where LM is stored.  */
+
+static void
+pph_out_line_map (pph_stream *stream, struct line_map *lm, int ix)
+{
+  struct output_block *ob = stream->encoder.w.ob;
+
+  pph_out_source_location (stream, lm->start_location);
+  streamer_write_enum (ob->main_stream, lc_reason, LC_ENTER_MACRO, lm->reason);
+
+  /* FIXME pph.  We currently do not support location tracking for
+     macros in PPH images.  */
+  gcc_assert (lm->reason != LC_ENTER_MACRO);
+  pph_out_line_map_ordinary (stream, lm, ix);
+}
+
+
 /* Write a reference of INCLUDE to STREAM.  Also write the START_LOCATION of
    this include in the current line_table.  */
 
@@ -286,7 +335,8 @@ pph_get_next_include (pph_stream *stream
 static void
 pph_out_line_table_and_includes (pph_stream *stream)
 {
-  unsigned int ix, next_incl_ix = 0;
+  unsigned int next_incl_ix = 0;
+  int ix;
   pph_stream *current_include;
 
   /* Any #include should have been fully parsed and exited at this point.  */
@@ -294,55 +344,85 @@ pph_out_line_table_and_includes (pph_str
 
   current_include = pph_get_next_include (stream, &next_incl_ix);
 
-  for (ix = PPH_NUM_IGNORED_LINE_TABLE_ENTRIES; ix < line_table->used; ix++)
+  for (ix = PPH_NUM_IGNORED_LINE_TABLE_ENTRIES;
+       ix < (int) LINEMAPS_ORDINARY_USED (line_table);
+       ix++)
     {
-      struct line_map *lm = &line_table->maps[ix];
+      struct line_map *lm = LINEMAPS_ORDINARY_MAP_AT (line_table, ix);
+
+      /* FIXME pph.  We currently do not support location tracking for
+	 macros in PPH images.  */
+      gcc_assert (lm->reason != LC_ENTER_MACRO);
 
       if (ix == PPH_NUM_IGNORED_LINE_TABLE_ENTRIES)
         {
-          /* The first non-ignored entry should be an LC_RENAME back in the
-            header after inserting the builtin and command-line entries.  When
-            reading the pph we want this to be a simple LC_ENTER as the builtin
-            and command_line entries will already exist and we are now entering
-	    a #include.  */
+	  /* The first non-ignored entry should be an LC_RENAME back
+	     in the header after inserting the builtin and
+	     command-line entries.  When reading the pph we want this
+	     to be a simple LC_ENTER as the builtin and command_line
+	     entries will already exist and we are now entering a
+             #include.  */
           gcc_assert (lm->reason == LC_RENAME);
           lm->reason = LC_ENTER;
         }
 
-      /* If this is an entry from a pph header, only output reference.  */
+      /* If LM is an entry for an included PPH image, output a line table
+	 reference to it, so the reader can load the included image at
+	 this point.  */
       if (current_include != NULL
-	  && pph_filename_eq_ignoring_path (lm->to_file, current_include->name))
+	  && pph_filename_eq_ignoring_path (LINEMAP_FILE (lm),
+	                                    current_include->name))
 	{
-	  int includer_level;
+	  struct line_map *included_from;
 
+	  /* Assert that we are entering a new header file from another.  */
 	  gcc_assert (lm->reason == LC_ENTER);
-	  gcc_assert (lm->included_from != -1);
+	  gcc_assert (ORDINARY_MAP_INCLUDER_FILE_INDEX (lm) != -1);
 
 	  pph_out_linetable_marker (stream, PPH_LINETABLE_REFERENCE);
 
 	  pph_out_include (stream, current_include, lm->start_location);
 
-	  /* Potentially lm could be included from a header other then the main
-	      one if a textual include includes a pph header (i.e. we can't
-	      simply rely on going back to included_from == -1).  */
-	  includer_level = INCLUDED_FROM (line_table, lm)->included_from;
+	  /* Since all the line table entries corresponding to
+	     CURRENT_INCLUDE and its #include children are emitted
+	     inside CURRENT_INCLUDE, we need to skip them so they do
+	     not get emitted in STREAM.
+
+	     To do this, we look for the next line map table that
+	     corresponds to an LC_LEAVE event back to the file that
+	     includes CURRENT_INCLUDE (which is represented by the
+	     line map LM).  */
+	  included_from = INCLUDED_FROM (line_table, lm);
+	  for (ix++; ix < (int) LINEMAPS_ORDINARY_USED (line_table); ix++)
+	    {
+	      struct line_map *map = LINEMAPS_ORDINARY_MAP_AT (line_table, ix);
+
+	      /* When we find an LC_LEAVE map, we have two ways of
+		 deciding if it is an LC_LEAVE event back to
+		 INCLUDED_FROM.  Either MAP goes to the same file name
+		 as INCLUDED_FROM or both MAP and INCLUDED_FROM are
+		 included by the same line map.  Since the latter is
+		 faster, we check it instead of doing a string
+		 comparison.  */
+	      if (map->reason == LC_LEAVE
+		  && ORDINARY_MAP_INCLUDER_FILE_INDEX (included_from)
+		     == ORDINARY_MAP_INCLUDER_FILE_INDEX (map))
+		break;
+	    }
 
-	  /* Skip all other linemap entries up to and including the LC_LEAVE
-	      from the referenced header back to the one including it.  */
-	  while (line_table->maps[++ix].included_from != includer_level)
 	    /* We should always leave this loop before the end of the
 		current line_table entries.  */
-	    gcc_assert (ix < line_table->used);
+	    gcc_assert (ix < (int) LINEMAPS_ORDINARY_USED (line_table));
 
 	  current_include = pph_get_next_include (stream, &next_incl_ix);
 	}
       else
 	{
 	  pph_out_linetable_marker (stream, PPH_LINETABLE_ENTRY);
-	  pph_out_line_map (stream, lm);
+	  pph_out_line_map (stream, lm, ix);
 	}
 
-      /* Restore changes made to first entry above if needed.  */
+      /* Restore changes made to the first entry above, if needed.  */
       if (ix == PPH_NUM_IGNORED_LINE_TABLE_ENTRIES)
 	lm->reason = LC_RENAME;
     }
@@ -350,7 +430,8 @@ pph_out_line_table_and_includes (pph_str
   pph_out_linetable_marker (stream, PPH_LINETABLE_END);
 
   /* Output the number of entries written to validate on input.  */
-  pph_out_uint (stream, line_table->used - PPH_NUM_IGNORED_LINE_TABLE_ENTRIES);
+  pph_out_uint (stream, LINEMAPS_ORDINARY_USED (line_table)
+                        - PPH_NUM_IGNORED_LINE_TABLE_ENTRIES);
 
   /* Every PPH header included should have been seen and skipped in the
      line_table streaming above.  */
@@ -686,26 +767,23 @@ pph_out_location (pph_stream *stream, lo
      streaming some builtins, we probably want to figure out what those are and
      simply add them to the cache in the preload.  */
   struct bitpack_d bp;
+  struct line_map *map;
+  location_t first_non_builtin_loc;
 
-  location_t first_non_builtin_loc =
-    line_table->maps[PPH_NUM_IGNORED_LINE_TABLE_ENTRIES].start_location;
+  map = LINEMAPS_ORDINARY_MAP_AT (line_table,
+				  PPH_NUM_IGNORED_LINE_TABLE_ENTRIES);
+  first_non_builtin_loc = MAP_START_LOCATION (map);
 
   bp = bitpack_create (stream->encoder.w.ob->main_stream);
   if (loc < first_non_builtin_loc)
     {
       /* We should never stream out trees with locations between builtins
 	 and user locations (e.g. <command-line>).  */
-      if (loc > BUILTINS_LOCATION)
-        gcc_unreachable ();
-
+      gcc_assert (loc <= BUILTINS_LOCATION);
       bp_pack_value (&bp, true, 1);
     }
   else
-    {
-      gcc_assert (loc >=
-        line_table->maps[PPH_NUM_IGNORED_LINE_TABLE_ENTRIES].start_location);
-      bp_pack_value (&bp, false, 1);
-    }
+    bp_pack_value (&bp, false, 1);
 
   pph_out_bitpack (stream, &bp);
   pph_out_uhwi (stream, loc);
Index: cp/pph.c
===================================================================
--- cp/pph.c	(revision 181521)
+++ cp/pph.c	(working copy)
@@ -342,9 +342,10 @@ pph_file_change_handler (cpp_reader *rea
 
 	DEPTH|SYSP|DNAME|CANONICAL-NAME|FULL-NAME|PPH-NAME
   */
-  flat = flatten_name (map->to_file);
-  fprintf (stderr, "%d|%d|%s|%s|%s|%s.pph\n", line_table->depth, map->sysp,
-	   tree_dumper.dname, tree_dumper.name, map->to_file, flat);
+  flat = flatten_name (map->d.ordinary.to_file);
+  fprintf (stderr, "%d|%d|%s|%s|%s|%s.pph\n", line_table->depth,
+	   map->d.ordinary.sysp, tree_dumper.dname, tree_dumper.name,
+	   map->d.ordinary.to_file, flat);
   free (flat);
   tree_dumper.dname = NULL;
   tree_dumper.name = NULL;


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