1 /* Generic streaming support for various data types.
3 Copyright 2011 Free Software Foundation, Inc.
4 Contributed by Diego Novillo <dnovillo@google.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 #ifndef GCC_DATA_STREAMER_H
23 #define GCC_DATA_STREAMER_H
26 #include "lto-streamer.h"
28 /* Data structures used to pack values and bitflags into a vector of
29 words. Used to stream values of a fixed number of bits in a space
31 static unsigned const BITS_PER_BITPACK_WORD = HOST_BITS_PER_WIDE_INT;
33 typedef unsigned HOST_WIDE_INT bitpack_word_t;
34 DEF_VEC_I(bitpack_word_t);
35 DEF_VEC_ALLOC_I(bitpack_word_t, heap);
39 /* The position of the first unused or unconsumed bit in the word. */
42 /* The current word we are (un)packing. */
45 /* The lto_output_stream or the lto_input_block we are streaming to/from. */
55 unsigned int slot_num;
59 /* Returns a hash code for P. Adapted from libiberty's htab_hash_string
60 to support strings that may not end in '\0'. */
62 static inline hashval_t
63 hash_string_slot_node (const void *p)
65 const struct string_slot *ds = (const struct string_slot *) p;
66 hashval_t r = ds->len;
69 for (i = 0; i < ds->len; i++)
70 r = r * 67 + (unsigned)ds->s[i] - 113;
74 /* Returns nonzero if P1 and P2 are equal. */
77 eq_string_slot_node (const void *p1, const void *p2)
79 const struct string_slot *ds1 = (const struct string_slot *) p1;
80 const struct string_slot *ds2 = (const struct string_slot *) p2;
82 if (ds1->len == ds2->len)
83 return memcmp (ds1->s, ds2->s, ds1->len) == 0;
88 /* Returns a new bit-packing context for bit-packing into S. */
89 static inline struct bitpack_d
90 bitpack_create (struct lto_output_stream *s)
95 bp.stream = (void *)s;
99 /* Pack the NBITS bit sized value VAL into the bit-packing context BP. */
101 bp_pack_value (struct bitpack_d *bp, bitpack_word_t val, unsigned nbits)
103 bitpack_word_t word = bp->word;
106 /* Verify that VAL fits in the NBITS. */
107 gcc_checking_assert (nbits == BITS_PER_BITPACK_WORD
108 || !(val & ~(((bitpack_word_t)1<<nbits)-1)));
110 /* If val does not fit into the current bitpack word switch to the
112 if (pos + nbits > BITS_PER_BITPACK_WORD)
114 lto_output_uleb128_stream ((struct lto_output_stream *) bp->stream, word);
127 /* Finishes bit-packing of BP. */
129 lto_output_bitpack (struct bitpack_d *bp)
131 lto_output_uleb128_stream ((struct lto_output_stream *) bp->stream,
137 /* Returns a new bit-packing context for bit-unpacking from IB. */
138 static inline struct bitpack_d
139 lto_input_bitpack (struct lto_input_block *ib)
142 bp.word = lto_input_uleb128 (ib);
144 bp.stream = (void *)ib;
148 /* Unpacks NBITS bits from the bit-packing context BP and returns them. */
149 static inline bitpack_word_t
150 bp_unpack_value (struct bitpack_d *bp, unsigned nbits)
152 bitpack_word_t mask, val;
155 mask = (nbits == BITS_PER_BITPACK_WORD
156 ? (bitpack_word_t) -1
157 : ((bitpack_word_t) 1 << nbits) - 1);
159 /* If there are not continuous nbits in the current bitpack word
160 switch to the next one. */
161 if (pos + nbits > BITS_PER_BITPACK_WORD)
163 bp->word = val = lto_input_uleb128 ((struct lto_input_block *)bp->stream);
169 bp->pos = pos + nbits;
175 /* Write a character to the output block. */
178 lto_output_1_stream (struct lto_output_stream *obs, char c)
181 if (obs->left_in_block == 0)
182 lto_append_block (obs);
184 /* Write the actual character. */
185 *obs->current_pointer = c;
186 obs->current_pointer++;
188 obs->left_in_block--;
192 /* Read byte from the input block. */
194 static inline unsigned char
195 lto_input_1_unsigned (struct lto_input_block *ib)
197 if (ib->p >= ib->len)
198 lto_section_overrun (ib);
199 return (ib->data[ib->p++]);
202 /* Output VAL into OBS and verify it is in range MIN...MAX that is supposed
203 to be compile time constant.
204 Be host independent, limit range to 31bits. */
207 lto_output_int_in_range (struct lto_output_stream *obs,
212 HOST_WIDE_INT range = max - min;
214 gcc_checking_assert (val >= min && val <= max && range > 0
215 && range < 0x7fffffff);
218 lto_output_1_stream (obs, val & 255);
220 lto_output_1_stream (obs, (val >> 8) & 255);
222 lto_output_1_stream (obs, (val >> 16) & 255);
223 if (range >= 0xffffff)
224 lto_output_1_stream (obs, (val >> 24) & 255);
227 /* Input VAL into OBS and verify it is in range MIN...MAX that is supposed
228 to be compile time constant. PURPOSE is used for error reporting. */
230 static inline HOST_WIDE_INT
231 lto_input_int_in_range (struct lto_input_block *ib,
236 HOST_WIDE_INT range = max - min;
237 HOST_WIDE_INT val = lto_input_1_unsigned (ib);
239 gcc_checking_assert (range > 0 && range < 0x7fffffff);
242 val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 8;
244 val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 16;
245 if (range >= 0xffffff)
246 val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 24;
248 if (val < min || val > max)
249 lto_value_range_error (purpose, val, min, max);
253 /* Output VAL into BP and verify it is in range MIN...MAX that is supposed
254 to be compile time constant.
255 Be host independent, limit range to 31bits. */
258 bp_pack_int_in_range (struct bitpack_d *bp,
263 HOST_WIDE_INT range = max - min;
264 int nbits = floor_log2 (range) + 1;
266 gcc_checking_assert (val >= min && val <= max && range > 0
267 && range < 0x7fffffff);
270 bp_pack_value (bp, val, nbits);
273 /* Input VAL into BP and verify it is in range MIN...MAX that is supposed
274 to be compile time constant. PURPOSE is used for error reporting. */
276 static inline HOST_WIDE_INT
277 bp_unpack_int_in_range (struct bitpack_d *bp,
282 HOST_WIDE_INT range = max - min;
283 int nbits = floor_log2 (range) + 1;
284 HOST_WIDE_INT val = bp_unpack_value (bp, nbits);
286 gcc_checking_assert (range > 0 && range < 0x7fffffff);
288 if (val < min || val > max)
289 lto_value_range_error (purpose, val, min, max);
293 /* Output VAL of type "enum enum_name" into OBS.
294 Assume range 0...ENUM_LAST - 1. */
295 #define lto_output_enum(obs,enum_name,enum_last,val) \
296 lto_output_int_in_range ((obs), 0, (int)(enum_last) - 1, (int)(val))
298 /* Input enum of type "enum enum_name" from IB.
299 Assume range 0...ENUM_LAST - 1. */
300 #define lto_input_enum(ib,enum_name,enum_last) \
301 (enum enum_name)lto_input_int_in_range ((ib), #enum_name, 0, \
302 (int)(enum_last) - 1)
304 /* Output VAL of type "enum enum_name" into BP.
305 Assume range 0...ENUM_LAST - 1. */
306 #define bp_pack_enum(bp,enum_name,enum_last,val) \
307 bp_pack_int_in_range ((bp), 0, (int)(enum_last) - 1, (int)(val))
309 /* Input enum of type "enum enum_name" from BP.
310 Assume range 0...ENUM_LAST - 1. */
311 #define bp_unpack_enum(bp,enum_name,enum_last) \
312 (enum enum_name)bp_unpack_int_in_range ((bp), #enum_name, 0, \
313 (int)(enum_last) - 1)
315 /* Output the start of a record with TAG to output block OB. */
318 output_record_start (struct output_block *ob, enum LTO_tags tag)
320 lto_output_enum (ob->main_stream, LTO_tags, LTO_NUM_TAGS, tag);
323 /* Return the next tag in the input block IB. */
325 static inline enum LTO_tags
326 input_record_start (struct lto_input_block *ib)
328 return lto_input_enum (ib, LTO_tags, LTO_NUM_TAGS);
331 /* In data-streamer.c */
332 void bp_pack_var_len_unsigned (struct bitpack_d *, unsigned HOST_WIDE_INT);
333 void bp_pack_var_len_int (struct bitpack_d *, HOST_WIDE_INT);
334 unsigned HOST_WIDE_INT bp_unpack_var_len_unsigned (struct bitpack_d *);
335 HOST_WIDE_INT bp_unpack_var_len_int (struct bitpack_d *);
337 /* In data-streamer-out.c */
338 void output_zero (struct output_block *);
339 void output_uleb128 (struct output_block *, unsigned HOST_WIDE_INT);
340 void output_sleb128 (struct output_block *, HOST_WIDE_INT);
341 void lto_output_string (struct output_block *, struct lto_output_stream *,
343 unsigned lto_string_index (struct output_block *, const char *, unsigned int,
345 void lto_output_string_with_length (struct output_block *,
346 struct lto_output_stream *,
347 const char *, unsigned int, bool);
348 const char *input_string_internal (struct data_in *, struct lto_input_block *,
351 /* In data-streamer-in.c */
352 const char *string_for_index (struct data_in *, unsigned int, unsigned int *);
353 const char *lto_input_string (struct data_in *, struct lto_input_block *);
355 #endif /* GCC_DATA_STREAMER_H */