lto-streamer-out.c (lto_string_index): break out from...; offset by 1 so 0 means NULL string.

* 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
This commit is contained in:
Jan Hubicka 2011-05-27 11:57:40 +02:00 committed by Jan Hubicka
parent dc38fc2e8a
commit 51a9ed47c9
6 changed files with 267 additions and 86 deletions

View 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> 2011-05-27 Hariharan Sandanagobalane <hariharan@picochip.com>
* config/picochip/picochip.c (reorder_var_tracking_notes): Drop * config/picochip/picochip.c (reorder_var_tracking_notes): Drop

View 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 /* Hooks so that the ipa passes can call into the lto front end to get
sections. */ sections. */

View 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 /* 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 ENCODER for NAME with the next available index of ENCODER, then
print the index to OBS. True is returned if NAME was added to print the index to OBS. True is returned if NAME was added to

View File

@ -132,19 +132,22 @@ eq_string_slot_node (const void *p1, const void *p2)
IB. Write the length to RLEN. */ IB. Write the length to RLEN. */
static const char * static const char *
input_string_internal (struct data_in *data_in, struct lto_input_block *ib, string_for_index (struct data_in *data_in,
unsigned int *rlen) unsigned int loc,
unsigned int *rlen)
{ {
struct lto_input_block str_tab; struct lto_input_block str_tab;
unsigned int len; unsigned int len;
unsigned int loc;
const char *result; const char *result;
/* Read the location of the string from IB. */ if (!loc)
loc = lto_input_uleb128 (ib); {
*rlen = 0;
return NULL;
}
/* Get the string stored at location LOC in DATA_IN->STRINGS. */ /* 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); len = lto_input_uleb128 (&str_tab);
*rlen = len; *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 /* Read a STRING_CST from the string table in DATA_IN using input
block IB. */ block IB. */
@ -165,13 +179,10 @@ input_string_cst (struct data_in *data_in, struct lto_input_block *ib)
{ {
unsigned int len; unsigned int len;
const char * ptr; 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); ptr = input_string_internal (data_in, ib, &len);
if (!ptr)
return NULL;
return build_string (len, ptr); return build_string (len, ptr);
} }
@ -184,13 +195,10 @@ input_identifier (struct data_in *data_in, struct lto_input_block *ib)
{ {
unsigned int len; unsigned int len;
const char *ptr; 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); ptr = input_string_internal (data_in, ib, &len);
if (!ptr)
return NULL;
return get_identifier_with_length (ptr, len); 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; unsigned int len;
const char *ptr; 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); ptr = input_string_internal (data_in, ib, &len);
if (!ptr)
return NULL;
if (ptr[len - 1] != '\0') if (ptr[len - 1] != '\0')
internal_error ("bytecode stream: found non-null terminated string"); internal_error ("bytecode stream: found non-null terminated string");
@ -284,37 +289,57 @@ clear_line_info (struct data_in *data_in)
} }
/* Read a location bitpack from input block IB. */
static location_t
lto_input_location_bitpack (struct data_in *data_in, struct bitpack_d *bp)
{
bool file_change, line_change, column_change;
unsigned len;
bool prev_file = data_in->current_file != NULL;
if (bp_unpack_value (bp, 1))
return UNKNOWN_LOCATION;
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);
column_change = bp_unpack_value (bp, 1);
if (column_change)
data_in->current_col = bp_unpack_var_len_unsigned (bp);
if (file_change)
{
if (prev_file)
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
linemap_add (line_table, LC_ENTER, false, data_in->current_file,
data_in->current_line);
}
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);
}
/* Read a location from input block IB. */ /* Read a location from input block IB. */
static location_t static location_t
lto_input_location (struct lto_input_block *ib, struct data_in *data_in) lto_input_location (struct lto_input_block *ib, struct data_in *data_in)
{ {
expanded_location xloc; struct bitpack_d bp;
xloc.file = lto_input_string (data_in, ib); bp = lto_input_bitpack (ib);
if (xloc.file == NULL) return lto_input_location_bitpack (data_in, &bp);
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);
if (data_in->current_file != xloc.file)
{
if (data_in->current_file)
linemap_add (line_table, LC_LEAVE, false, NULL, 0);
linemap_add (line_table, LC_ENTER, xloc.sysp, xloc.file, xloc.line);
}
else if (data_in->current_line != xloc.line)
linemap_line_start (line_table, xloc.line, xloc.column);
data_in->current_file = xloc.file;
data_in->current_line = xloc.line;
data_in->current_col = xloc.column;
return linemap_position_for_column (line_table, xloc.column);
} }
@ -1766,8 +1791,8 @@ unpack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
= (unsigned) bp_unpack_value (bp, 2); = (unsigned) bp_unpack_value (bp, 2);
TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1); TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
TYPE_READONLY (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_ALIGN (expr) = bp_unpack_var_len_unsigned (bp);
TYPE_ALIAS_SET (expr) = bp_unpack_value (bp, HOST_BITS_PER_INT); TYPE_ALIAS_SET (expr) = bp_unpack_var_len_int (bp);
} }

View File

@ -143,16 +143,14 @@ destroy_output_block (struct output_block *ob)
free (ob); free (ob);
} }
/* Return index used to reference STRING of LEN characters in the string table
/* Output STRING of LEN characters to the string in OB. The string might or might not include a trailing '\0'.
table in OB. The string might or might not include a trailing '\0'.
Then put the index onto the INDEX_STREAM. */ Then put the index onto the INDEX_STREAM. */
void static unsigned
lto_output_string_with_length (struct output_block *ob, lto_string_index (struct output_block *ob,
struct lto_output_stream *index_stream, const char *s,
const char *s, unsigned int len)
unsigned int len)
{ {
struct string_slot **slot; struct string_slot **slot;
struct string_slot s_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.len = len;
s_slot.slot_num = 0; 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, slot = (struct string_slot **) htab_find_slot (ob->string_hash_table,
&s_slot, INSERT); &s_slot, INSERT);
if (*slot == NULL) if (*slot == NULL)
@ -180,18 +175,33 @@ lto_output_string_with_length (struct output_block *ob,
new_slot->len = len; new_slot->len = len;
new_slot->slot_num = start; new_slot->slot_num = start;
*slot = new_slot; *slot = new_slot;
lto_output_uleb128_stream (index_stream, start);
lto_output_uleb128_stream (string_stream, len); lto_output_uleb128_stream (string_stream, len);
lto_output_data_stream (string_stream, string, len); lto_output_data_stream (string_stream, string, len);
return start + 1;
} }
else else
{ {
struct string_slot *old_slot = *slot; struct string_slot *old_slot = *slot;
lto_output_uleb128_stream (index_stream, old_slot->slot_num);
free (string); 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 /* Output the '\0' terminated STRING to the string
table in OB. Then put the index onto the INDEX_STREAM. */ 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, lto_output_string_with_length (ob, index_stream, string,
strlen (string) + 1); strlen (string) + 1);
else 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_POINTER (string),
TREE_STRING_LENGTH (string )); TREE_STRING_LENGTH (string ));
else 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_POINTER (id),
IDENTIFIER_LENGTH (id)); IDENTIFIER_LENGTH (id));
else else
lto_output_uleb128_stream (index_stream, 1); lto_output_1_stream (index_stream, 0);
} }
/* Write a zero to the output stream. */ /* Write a zero to the output stream. */
static void 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_CONTAINS_PLACEHOLDER_INTERNAL (expr), 2);
bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1); bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
bp_pack_value (bp, TYPE_READONLY (expr), 1); bp_pack_value (bp, TYPE_READONLY (expr), 1);
bp_pack_value (bp, TYPE_ALIGN (expr), HOST_BITS_PER_INT); bp_pack_var_len_unsigned (bp, TYPE_ALIGN (expr));
bp_pack_value (bp, TYPE_ALIAS_SET (expr) == 0 ? 0 : -1, HOST_BITS_PER_INT); bp_pack_var_len_int (bp, TYPE_ALIAS_SET (expr) == 0 ? 0 : -1);
} }
@ -587,29 +598,52 @@ 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 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)
return;
xloc = expand_location (loc);
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 static void
lto_output_location (struct output_block *ob, location_t loc) lto_output_location (struct output_block *ob, location_t loc)
{ {
expanded_location xloc; struct bitpack_d bp = bitpack_create (ob->main_stream);
lto_output_location_bitpack (&bp, ob, loc);
if (loc == UNKNOWN_LOCATION) lto_output_bitpack (&bp);
{
lto_output_string (ob, ob->main_stream, NULL);
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);
ob->current_file = xloc.file;
ob->current_line = xloc.line;
ob->current_col = xloc.column;
} }
@ -642,7 +676,7 @@ lto_output_tree_ref (struct output_block *ob, tree expr)
if (expr == NULL_TREE) if (expr == NULL_TREE)
{ {
output_zero (ob); output_record_start (ob, LTO_null);
return; return;
} }

View File

@ -774,6 +774,10 @@ extern void lto_section_overrun (struct lto_input_block *) ATTRIBUTE_NORETURN;
extern void lto_value_range_error (const char *, extern void lto_value_range_error (const char *,
HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT,
HOST_WIDE_INT) ATTRIBUTE_NORETURN; 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 */ /* In lto-section-out.c */
extern hashval_t lto_hash_decl_slot_node (const void *); 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; bitpack_word_t word = bp->word;
int pos = bp->pos; 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 /* If val does not fit into the current bitpack word switch to the
next one. */ next one. */
if (pos + nbits > BITS_PER_BITPACK_WORD) if (pos + nbits > BITS_PER_BITPACK_WORD)