lto-streamer-out.c (lto_string_index): break out from...; offset by 1 so 0 means...
authorJan Hubicka <jh@suse.cz>
Fri, 27 May 2011 09:57:40 +0000 (11:57 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 27 May 2011 09:57:40 +0000 (09:57 +0000)
* lto-streamer-out.c (lto_string_index): break out from...; offset by 1
so 0 means NULL string.
(lto_output_string_with_length): ... here.
(lto_output_string, output_string_cst, output_identifier): Update handling
of NULL strings.
(lto_output_location_bitpack): New function.
(lto_output_location): Use it.
(lto_output_tree_ref): Use output_record_start.
(pack_ts_type_common_value_fields): Pack aliagn & alias set in var len values.
* lto-streamer-in.c (string_for_index): Break out from ...; offset values by 1.
(input_string_internal): ... here;
(input_string_cst, input_identifier, lto_input_string): Update handling of
NULL strings.
(lto_input_location_bitpack): New function
(lto_input_location): Use it.
(unpack_ts_type_common_value_fields): Pack align & alias in var len values.
* lto-streamer.h (bp_pack_val_len_unsigned, bp_pack_val_len_int,
bp_unpack_val_len_unsigned, bp_unpack_val_len_int): Declare.
(bp_pack_value): Sanity check the value range.
* lto-section-in.c (bp_unpack_val_len_unsigned, bp_unpack_val_len_int):
New functions.
* lto-section-out.h (bp_pack_val_len_unsigned, bp_pack_val_len_int):
New functions.

From-SVN: r174325

gcc/ChangeLog
gcc/lto-section-in.c
gcc/lto-section-out.c
gcc/lto-streamer-in.c
gcc/lto-streamer-out.c
gcc/lto-streamer.h

index 43cce51e977f52fe669b0ec1d16f56d48d2a25d2..2bc9180eb08efa50ab10116959509fc3ebd5d041 100644 (file)
@@ -1,3 +1,29 @@
+2011-05-27  Jan Hubicka  <jh@suse.cz>
+
+       * lto-streamer-out.c (lto_string_index): break out from...; offset by 1
+       so 0 means NULL string.
+       (lto_output_string_with_length): ... here.
+       (lto_output_string, output_string_cst, output_identifier): Update handling
+       of NULL strings.
+       (lto_output_location_bitpack): New function.
+       (lto_output_location): Use it.
+       (lto_output_tree_ref): Use output_record_start.
+       (pack_ts_type_common_value_fields): Pack aliagn & alias set in var len values.
+       * lto-streamer-in.c (string_for_index): Break out from ...; offset values by 1.
+       (input_string_internal): ... here; 
+       (input_string_cst, input_identifier, lto_input_string): Update handling of
+       NULL strings.
+       (lto_input_location_bitpack): New function
+       (lto_input_location): Use it.
+       (unpack_ts_type_common_value_fields): Pack align & alias in var len values.
+       * lto-streamer.h (bp_pack_val_len_unsigned, bp_pack_val_len_int,
+       bp_unpack_val_len_unsigned, bp_unpack_val_len_int): Declare.
+       (bp_pack_value): Sanity check the value range.
+       * lto-section-in.c (bp_unpack_val_len_unsigned, bp_unpack_val_len_int):
+       New functions.
+       * lto-section-out.h (bp_pack_val_len_unsigned, bp_pack_val_len_int):
+       New functions.
+
 2011-05-27  Hariharan Sandanagobalane <hariharan@picochip.com>
 
        * config/picochip/picochip.c (reorder_var_tracking_notes): Drop
index b6277a35532d9d0d6b450869f17719e0aa135ca8..0c2c4c0f1c0fdabfb4f6b767f8b50f9fb8f5cce3 100644 (file)
@@ -127,6 +127,51 @@ lto_input_sleb128 (struct lto_input_block *ib)
 }
 
 
+/* Unpack VAL from BP in a variant of uleb format.  */
+
+unsigned HOST_WIDE_INT
+bp_unpack_var_len_unsigned (struct bitpack_d *bp)
+{
+  unsigned HOST_WIDE_INT result = 0;
+  int shift = 0;
+  unsigned HOST_WIDE_INT half_byte;
+
+  while (true)
+    {
+      half_byte = bp_unpack_value (bp, 4);
+      result |= (half_byte & 0x7) << shift;
+      shift += 3;
+      if ((half_byte & 0x8) == 0)
+       return result;
+    }
+}
+
+
+/* Unpack VAL from BP in a variant of sleb format.  */
+
+HOST_WIDE_INT
+bp_unpack_var_len_int (struct bitpack_d *bp)
+{
+  HOST_WIDE_INT result = 0;
+  int shift = 0;
+  unsigned HOST_WIDE_INT half_byte;
+
+  while (true)
+    {
+      half_byte = bp_unpack_value (bp, 4);
+      result |= (half_byte & 0x7) << shift;
+      shift += 3;
+      if ((half_byte & 0x8) == 0)
+       {
+         if ((shift < HOST_BITS_PER_WIDE_INT) && (half_byte & 0x4))
+           result |= - ((HOST_WIDE_INT)1 << shift);
+
+         return result;
+       }
+    }
+}
+
+
 /* Hooks so that the ipa passes can call into the lto front end to get
    sections.  */
 
index 234d63eaabdd20faf022dd11a1c4fc3bc60f9b86..55c9d8d165fcacef4477a606c9f4073498a5fdc9 100644 (file)
@@ -330,6 +330,48 @@ lto_output_sleb128_stream (struct lto_output_stream *obs, HOST_WIDE_INT work)
 }
 
 
+/* Pack WORK into BP in a variant of uleb format.  */
+
+void
+bp_pack_var_len_unsigned (struct bitpack_d *bp, unsigned HOST_WIDE_INT work)
+{
+  do
+    {
+      unsigned int half_byte = (work & 0x7);
+      work >>= 3;
+      if (work != 0)
+       /* More half_bytes to follow.  */
+       half_byte |= 0x8;
+
+      bp_pack_value (bp, half_byte, 4);
+    }
+  while (work != 0);
+}
+
+
+/* Pack WORK into BP in a variant of sleb format.  */
+
+void
+bp_pack_var_len_int (struct bitpack_d *bp, HOST_WIDE_INT work)
+{
+  int more, half_byte;
+
+  do
+    {
+      half_byte = (work & 0x7);
+      /* arithmetic shift */
+      work >>= 3;
+      more = !((work == 0 && (half_byte & 0x4) == 0)
+              || (work == -1 && (half_byte & 0x4) != 0));
+      if (more)
+       half_byte |= 0x8;
+
+      bp_pack_value (bp, half_byte, 4);
+    }
+  while (more);
+}
+
+
 /* Lookup NAME in ENCODER.  If NAME is not found, create a new entry in
    ENCODER for NAME with the next available index of ENCODER,  then
    print the index to OBS.  True is returned if NAME was added to
index dd14c0cedf94874d33e710660e777bb918c8c006..d2e4ed3ec205653a58ae9e9fa3a7e82186625c5d 100644 (file)
@@ -132,19 +132,22 @@ eq_string_slot_node (const void *p1, const void *p2)
    IB.  Write the length to RLEN.  */
 
 static const char *
-input_string_internal (struct data_in *data_in, struct lto_input_block *ib,
-                      unsigned int *rlen)
+string_for_index (struct data_in *data_in,
+                 unsigned int loc,
+                 unsigned int *rlen)
 {
   struct lto_input_block str_tab;
   unsigned int len;
-  unsigned int loc;
   const char *result;
 
-  /* Read the location of the string from IB.  */
-  loc = lto_input_uleb128 (ib);
+  if (!loc)
+    {
+      *rlen = 0;
+      return NULL;
+    }
 
   /* Get the string stored at location LOC in DATA_IN->STRINGS.  */
-  LTO_INIT_INPUT_BLOCK (str_tab, data_in->strings, loc, data_in->strings_len);
+  LTO_INIT_INPUT_BLOCK (str_tab, data_in->strings, loc - 1, data_in->strings_len);
   len = lto_input_uleb128 (&str_tab);
   *rlen = len;
 
@@ -157,6 +160,17 @@ input_string_internal (struct data_in *data_in, struct lto_input_block *ib,
 }
 
 
+/* Read a string from the string table in DATA_IN using input block
+   IB.  Write the length to RLEN.  */
+
+static const char *
+input_string_internal (struct data_in *data_in, struct lto_input_block *ib,
+                      unsigned int *rlen)
+{
+  return string_for_index (data_in, lto_input_uleb128 (ib), rlen);
+}
+
+
 /* Read a STRING_CST from the string table in DATA_IN using input
    block IB.  */
 
@@ -165,13 +179,10 @@ input_string_cst (struct data_in *data_in, struct lto_input_block *ib)
 {
   unsigned int len;
   const char * ptr;
-  unsigned int is_null;
-
-  is_null = lto_input_uleb128 (ib);
-  if (is_null)
-    return NULL;
 
   ptr = input_string_internal (data_in, ib, &len);
+  if (!ptr)
+    return NULL;
   return build_string (len, ptr);
 }
 
@@ -184,13 +195,10 @@ input_identifier (struct data_in *data_in, struct lto_input_block *ib)
 {
   unsigned int len;
   const char *ptr;
-  unsigned int is_null;
-
-  is_null = lto_input_uleb128 (ib);
-  if (is_null)
-    return NULL;
 
   ptr = input_string_internal (data_in, ib, &len);
+  if (!ptr)
+    return NULL;
   return get_identifier_with_length (ptr, len);
 }
 
@@ -215,13 +223,10 @@ lto_input_string (struct data_in *data_in, struct lto_input_block *ib)
 {
   unsigned int len;
   const char *ptr;
-  unsigned int is_null;
-
-  is_null = lto_input_uleb128 (ib);
-  if (is_null)
-    return NULL;
 
   ptr = input_string_internal (data_in, ib, &len);
+  if (!ptr)
+    return NULL;
   if (ptr[len - 1] != '\0')
     internal_error ("bytecode stream: found non-null terminated string");
 
@@ -284,37 +289,57 @@ clear_line_info (struct data_in *data_in)
 }
 
 
-/* Read a location from input block IB.  */
+/* Read a location bitpack from input block IB.  */
 
 static location_t
-lto_input_location (struct lto_input_block *ib, struct data_in *data_in)
+lto_input_location_bitpack (struct data_in *data_in, struct bitpack_d *bp)
 {
-  expanded_location xloc;
+  bool file_change, line_change, column_change;
+  unsigned len;
+  bool prev_file = data_in->current_file != NULL;
 
-  xloc.file = lto_input_string (data_in, ib);
-  if (xloc.file == NULL)
+  if (bp_unpack_value (bp, 1))
     return UNKNOWN_LOCATION;
 
-  xloc.file = canon_file_name (xloc.file);
-  xloc.line = lto_input_sleb128 (ib);
-  xloc.column = lto_input_sleb128 (ib);
-  xloc.sysp = lto_input_sleb128 (ib);
+  file_change = bp_unpack_value (bp, 1);
+  if (file_change)
+    data_in->current_file = canon_file_name
+                             (string_for_index (data_in,
+                                                bp_unpack_var_len_unsigned (bp),
+                                                &len));
+
+  line_change = bp_unpack_value (bp, 1);
+  if (line_change)
+    data_in->current_line = bp_unpack_var_len_unsigned (bp);
 
-  if (data_in->current_file != xloc.file)
+  column_change = bp_unpack_value (bp, 1);
+  if (column_change)
+    data_in->current_col = bp_unpack_var_len_unsigned (bp);
+
+  if (file_change)
     {
-      if (data_in->current_file)
+      if (prev_file)
        linemap_add (line_table, LC_LEAVE, false, NULL, 0);
 
-      linemap_add (line_table, LC_ENTER, xloc.sysp, xloc.file, xloc.line);
+      linemap_add (line_table, LC_ENTER, false, data_in->current_file,
+                  data_in->current_line);
     }
-  else if (data_in->current_line != xloc.line)
-    linemap_line_start (line_table, xloc.line, xloc.column);
+  else if (line_change)
+    linemap_line_start (line_table, data_in->current_line, data_in->current_col);
+
+  return linemap_position_for_column (line_table, data_in->current_col);
+}
+
 
-  data_in->current_file = xloc.file;
-  data_in->current_line = xloc.line;
-  data_in->current_col = xloc.column;
+/* Read a location from input block IB.  */
 
-  return linemap_position_for_column (line_table, xloc.column);
+static location_t
+lto_input_location (struct lto_input_block *ib, struct data_in *data_in)
+{
+  struct bitpack_d bp;
+
+  bp = lto_input_bitpack (ib);
+  return lto_input_location_bitpack (data_in, &bp);
 }
 
 
@@ -1766,8 +1791,8 @@ unpack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
        = (unsigned) bp_unpack_value (bp, 2);
   TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
   TYPE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1);
-  TYPE_ALIGN (expr) = (unsigned) bp_unpack_value (bp, HOST_BITS_PER_INT);
-  TYPE_ALIAS_SET (expr) = bp_unpack_value (bp, HOST_BITS_PER_INT);
+  TYPE_ALIGN (expr) = bp_unpack_var_len_unsigned (bp);
+  TYPE_ALIAS_SET (expr) = bp_unpack_var_len_int (bp);
 }
 
 
index 0cfe25a5d266bdf063b9bad393bf9f0017af4ba8..b9ac6d03245ebcf9656ca8b8d87dacb5a845757c 100644 (file)
@@ -143,16 +143,14 @@ destroy_output_block (struct output_block *ob)
   free (ob);
 }
 
-
-/* Output STRING of LEN characters to the string
-   table in OB. The string might or might not include a trailing '\0'.
+/* Return index used to reference STRING of LEN characters in the string table
+   in OB.  The string might or might not include a trailing '\0'.
    Then put the index onto the INDEX_STREAM.  */
 
-void
-lto_output_string_with_length (struct output_block *ob,
-                              struct lto_output_stream *index_stream,
-                              const char *s,
-                              unsigned int len)
+static unsigned
+lto_string_index (struct output_block *ob,
+                 const char *s,
+                 unsigned int len)
 {
   struct string_slot **slot;
   struct string_slot s_slot;
@@ -164,9 +162,6 @@ lto_output_string_with_length (struct output_block *ob,
   s_slot.len = len;
   s_slot.slot_num = 0;
 
-  /* Indicate that this is not a NULL string.  */
-  lto_output_uleb128_stream (index_stream, 0);
-
   slot = (struct string_slot **) htab_find_slot (ob->string_hash_table,
                                                 &s_slot, INSERT);
   if (*slot == NULL)
@@ -180,18 +175,33 @@ lto_output_string_with_length (struct output_block *ob,
       new_slot->len = len;
       new_slot->slot_num = start;
       *slot = new_slot;
-      lto_output_uleb128_stream (index_stream, start);
       lto_output_uleb128_stream (string_stream, len);
       lto_output_data_stream (string_stream, string, len);
+      return start + 1;
     }
   else
     {
       struct string_slot *old_slot = *slot;
-      lto_output_uleb128_stream (index_stream, old_slot->slot_num);
       free (string);
+      return old_slot->slot_num + 1;
     }
 }
 
+
+/* Output STRING of LEN characters to the string
+   table in OB. The string might or might not include a trailing '\0'.
+   Then put the index onto the INDEX_STREAM.  */
+
+void
+lto_output_string_with_length (struct output_block *ob,
+                              struct lto_output_stream *index_stream,
+                              const char *s,
+                              unsigned int len)
+{
+  lto_output_uleb128_stream (index_stream,
+                            lto_string_index (ob, s, len));
+}
+
 /* Output the '\0' terminated STRING to the string
    table in OB.  Then put the index onto the INDEX_STREAM.  */
 
@@ -204,7 +214,7 @@ lto_output_string (struct output_block *ob,
     lto_output_string_with_length (ob, index_stream, string,
                                   strlen (string) + 1);
   else
-    lto_output_uleb128_stream (index_stream, 1);
+    lto_output_1_stream (index_stream, 0);
 }
 
 
@@ -221,7 +231,7 @@ output_string_cst (struct output_block *ob,
                                   TREE_STRING_POINTER (string),
                                   TREE_STRING_LENGTH (string ));
   else
-    lto_output_uleb128_stream (index_stream, 1);
+    lto_output_1_stream (index_stream, 0);
 }
 
 
@@ -238,9 +248,10 @@ output_identifier (struct output_block *ob,
                                   IDENTIFIER_POINTER (id),
                                   IDENTIFIER_LENGTH (id));
   else
-    lto_output_uleb128_stream (index_stream, 1);
+    lto_output_1_stream (index_stream, 0);
 }
 
+
 /* Write a zero to the output stream.  */
 
 static void
@@ -504,8 +515,8 @@ pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
   bp_pack_value (bp, TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr), 2);
   bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
   bp_pack_value (bp, TYPE_READONLY (expr), 1);
-  bp_pack_value (bp, TYPE_ALIGN (expr), HOST_BITS_PER_INT);
-  bp_pack_value (bp, TYPE_ALIAS_SET (expr) == 0 ? 0 : -1, HOST_BITS_PER_INT);
+  bp_pack_var_len_unsigned (bp, TYPE_ALIGN (expr));
+  bp_pack_var_len_int (bp, TYPE_ALIAS_SET (expr) == 0 ? 0 : -1);
 }
 
 
@@ -587,32 +598,55 @@ pack_value_fields (struct bitpack_d *bp, tree expr)
 }
 
 
-/* Emit location LOC to output block OB.  */
+/* Output info about new location into bitpack BP.
+   After outputting bitpack, lto_output_location_data has
+   to be done to output actual data.  */
 
-static void
-lto_output_location (struct output_block *ob, location_t loc)
+static inline void
+lto_output_location_bitpack (struct bitpack_d *bp,
+                            struct output_block *ob,
+                            location_t loc)
 {
   expanded_location xloc;
 
+  bp_pack_value (bp, loc == UNKNOWN_LOCATION, 1);
   if (loc == UNKNOWN_LOCATION)
-    {
-      lto_output_string (ob, ob->main_stream, NULL);
-      return;
-    }
+    return;
 
   xloc = expand_location (loc);
 
-  lto_output_string (ob, ob->main_stream, xloc.file);
-  output_sleb128 (ob, xloc.line);
-  output_sleb128 (ob, xloc.column);
-  output_sleb128 (ob, xloc.sysp);
-
+  bp_pack_value (bp, ob->current_file != xloc.file, 1);
+  if (ob->current_file != xloc.file)
+    bp_pack_var_len_unsigned (bp, lto_string_index (ob,
+                                                 xloc.file,
+                                                 strlen (xloc.file) + 1));
   ob->current_file = xloc.file;
+
+  bp_pack_value (bp, ob->current_line != xloc.line, 1);
+  if (ob->current_line != xloc.line)
+    bp_pack_var_len_unsigned (bp, xloc.line);
   ob->current_line = xloc.line;
+
+  bp_pack_value (bp, ob->current_col != xloc.column, 1);
+  if (ob->current_col != xloc.column)
+    bp_pack_var_len_unsigned (bp, xloc.column);
   ob->current_col = xloc.column;
 }
 
 
+/* Emit location LOC to output block OB.
+   When bitpack is handy, it is more space effecient to call
+   lto_output_location_bitpack with existing bitpack.  */
+
+static void
+lto_output_location (struct output_block *ob, location_t loc)
+{
+  struct bitpack_d bp = bitpack_create (ob->main_stream);
+  lto_output_location_bitpack (&bp, ob, loc);
+  lto_output_bitpack (&bp);
+}
+
+
 /* Return true if tree node T is written to various tables.  For these
    nodes, we sometimes want to write their phyiscal representation
    (via lto_output_tree), and sometimes we need to emit an index
@@ -642,7 +676,7 @@ lto_output_tree_ref (struct output_block *ob, tree expr)
 
   if (expr == NULL_TREE)
     {
-      output_zero (ob);
+      output_record_start (ob, LTO_null);
       return;
     }
 
index 3389b5643741bbd7fc9427223f7da8d1f7c2cfe7..4508818a4a6f2208a490ec417f6bc7cd2ae410f0 100644 (file)
@@ -774,6 +774,10 @@ extern void lto_section_overrun (struct lto_input_block *) ATTRIBUTE_NORETURN;
 extern void lto_value_range_error (const char *,
                                   HOST_WIDE_INT, HOST_WIDE_INT,
                                   HOST_WIDE_INT) ATTRIBUTE_NORETURN;
+extern void bp_pack_var_len_unsigned (struct bitpack_d *, unsigned HOST_WIDE_INT);
+extern void bp_pack_var_len_int (struct bitpack_d *, HOST_WIDE_INT);
+extern unsigned HOST_WIDE_INT bp_unpack_var_len_unsigned (struct bitpack_d *);
+extern HOST_WIDE_INT bp_unpack_var_len_int (struct bitpack_d *);
 
 /* In lto-section-out.c  */
 extern hashval_t lto_hash_decl_slot_node (const void *);
@@ -1110,6 +1114,11 @@ bp_pack_value (struct bitpack_d *bp, bitpack_word_t val, unsigned nbits)
 {
   bitpack_word_t word = bp->word;
   int pos = bp->pos;
+
+  /* Verify that VAL fits in the NBITS.  */
+  gcc_checking_assert (nbits == BITS_PER_BITPACK_WORD
+                      || !(val & ~(((bitpack_word_t)1<<nbits)-1)));
+
   /* If val does not fit into the current bitpack word switch to the
      next one.  */
   if (pos + nbits > BITS_PER_BITPACK_WORD)