[PATCH] LTO streamer reorg - try to reduce WPA memory use
Richard Biener
rguenther@suse.de
Tue Jul 29 13:57:00 GMT 2014
On Tue, 29 Jul 2014, Richard Biener wrote:
>
> This re-organizes the LTO streamer to do compression transparently
> in the data-streamer routines (and disables section compression
> by defaulting to -flto-compression-level=0). This avoids
> keeping the whole uncompressed sections in memory, only retaining
> the compressed ones.
>
> The downside is that we lose compression of at least the string
> parts (they are abusing the streaming interface quite awkwardly
> and doing random-accesses with offsets into the uncompressed
> section). With a little bit of surgery we can get that back I
> think (but we'd have to keep the uncompressed piece in memory
> somewhere which means losing the memory use advantage).
>
> Very lightly tested sofar (running lto.exp). I'll try a LTO
> bootstrap now.
>
> I wonder what the change is on WPA memory use for larger
> projects and what the effect on object file size is.
Updated patch passing LTO bootstrap (one warning fix) and
with a memory leak fixed.
I'll probably try to split out cleanups from this patch.
Richard.
Index: gcc/data-streamer-out.c
===================================================================
*** gcc/data-streamer-out.c.orig 2014-07-29 13:04:48.255073822 +0200
--- gcc/data-streamer-out.c 2014-07-29 14:35:22.908699653 +0200
*************** along with GCC; see the file COPYING3.
*** 22,27 ****
--- 22,32 ----
#include "config.h"
#include "system.h"
+ /* zlib.h includes other system headers. Those headers may test feature
+ test macros. config.h may define feature test macros. For this reason,
+ zlib.h needs to be included after, rather than before, config.h and
+ system.h. */
+ #include <zlib.h>
#include "coretypes.h"
#include "tree.h"
#include "basic-block.h"
*************** along with GCC; see the file COPYING3.
*** 32,37 ****
--- 37,194 ----
#include "gimple.h"
#include "data-streamer.h"
+
+ /* Finishes the last block, eventually compressing it, and returns the
+ total size of the stream. */
+
+ unsigned int
+ lto_output_stream::finish ()
+ {
+ if (compress
+ && current_pointer)
+ {
+ /* Compress the last (partial) block. */
+ compress_current_block (true);
+ left_in_block = zlib_stream->avail_out;
+ free (current_block);
+ current_block = NULL;
+ int status = deflateEnd (zlib_stream);
+ if (status != Z_OK)
+ internal_error ("compressed stream: %s", zError (status));
+ free (zlib_stream);
+ }
+ current_pointer = NULL;
+
+ unsigned int size = 0;
+ for (lto_char_ptr_base *b = first_block; b; b = (lto_char_ptr_base *)b->ptr)
+ size += block_size - sizeof (lto_char_ptr_base);
+ size -= left_in_block;
+ return size;
+ }
+
+ /* Returns a pointer to the first block of the chain of blocks to output. */
+
+ lto_char_ptr_base *
+ lto_output_stream::get_blocks ()
+ {
+ finish ();
+ return first_block;
+ }
+
+ /* Adds a new block to output stream OBS. */
+
+ void
+ lto_output_stream::append_block ()
+ {
+ struct lto_char_ptr_base *new_block;
+
+ gcc_assert (left_in_block == 0 && block_size > sizeof (lto_char_ptr_base));
+
+ if (first_block == NULL)
+ {
+ /* This is the first time the stream has been written into. */
+ new_block = (struct lto_char_ptr_base*) xmalloc (block_size);
+ first_block = new_block;
+ }
+ else
+ {
+ if (compress)
+ {
+ /* Compress the current block and link it into the list. */
+ compress_current_block (false);
+ /* Re-use the uncompressed buffer. */
+ new_block = current_block;
+ }
+ else
+ {
+ /* Get a new block and link it into the list. */
+ new_block = (struct lto_char_ptr_base*) xmalloc (block_size);
+ /* The first bytes of the block are reserved as a pointer to
+ the next block. Set the chain of the full block to the
+ pointer to the new block. */
+ lto_char_ptr_base *tptr = current_block;
+ tptr->ptr = (char *) new_block;
+ }
+ }
+
+ /* Set the place for the next char at the first position after the
+ chain to the next block. */
+ current_pointer
+ = ((char *) new_block) + sizeof (struct lto_char_ptr_base);
+ current_block = new_block;
+ /* Null out the newly allocated block's pointer to the next block. */
+ new_block->ptr = NULL;
+ left_in_block = block_size - sizeof (struct lto_char_ptr_base);
+ }
+
+ /* Return a zlib compression level that zlib will not reject. Normalizes
+ the compression level from the command line flag, clamping non-default
+ values to the appropriate end of their valid range. */
+
+ static int
+ lto_normalized_zlib_level (void)
+ {
+ int level = flag_lto_compression_level;
+
+ if (level != Z_DEFAULT_COMPRESSION)
+ {
+ if (level < Z_NO_COMPRESSION)
+ level = Z_NO_COMPRESSION;
+ else if (level > Z_BEST_COMPRESSION)
+ level = Z_BEST_COMPRESSION;
+ }
+
+ return level;
+ }
+
+ void
+ lto_output_stream::compress_current_block (bool last)
+ {
+ int status;
+
+ /* If this is the first block we compress, initialize compression. */
+ if (first_block == current_block)
+ {
+ zlib_stream = XCNEW (z_stream);
+ zlib_stream->zalloc = NULL;
+ zlib_stream->zfree = NULL;
+ zlib_stream->opaque = NULL;
+ status = deflateInit (zlib_stream, lto_normalized_zlib_level ());
+ if (status != Z_OK)
+ internal_error ("compressed stream: %s", zError (status));
+
+ current_z_block = first_block
+ = (lto_char_ptr_base *) xmalloc (block_size);
+ first_block->ptr = NULL;
+ zlib_stream->next_out = (unsigned char *)first_block + sizeof (lto_char_ptr_base);
+ zlib_stream->avail_out = block_size - sizeof (lto_char_ptr_base);
+ }
+
+ zlib_stream->next_in = (unsigned char *)current_block + sizeof (lto_char_ptr_base);
+ zlib_stream->avail_in
+ = block_size - sizeof (lto_char_ptr_base) - left_in_block;
+ do
+ {
+ status = deflate (zlib_stream, last ? Z_FINISH : Z_NO_FLUSH);
+ if (status != Z_OK && status != Z_STREAM_END && status != Z_BUF_ERROR)
+ internal_error ("compressed stream: %s", zError (status));
+
+ if (status == Z_OK
+ && zlib_stream->avail_out == 0)
+ {
+ lto_char_ptr_base *new_block
+ = (lto_char_ptr_base *) xmalloc (block_size);
+ current_z_block->ptr = (char *)new_block;
+ current_z_block = new_block;
+ current_z_block->ptr = NULL;
+ zlib_stream->next_out = (unsigned char *)new_block + sizeof (lto_char_ptr_base);
+ zlib_stream->avail_out = block_size - sizeof (lto_char_ptr_base);
+ }
+ }
+ while (zlib_stream->avail_in > 0);
+ gcc_assert (zlib_stream->avail_in == 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.
*************** streamer_string_index (struct output_blo
*** 71,77 ****
new_slot->slot_num = start;
*slot = new_slot;
streamer_write_uhwi_stream (string_stream, len);
! lto_output_data_stream (string_stream, string, len);
return start + 1;
}
else
--- 228,234 ----
new_slot->slot_num = start;
*slot = new_slot;
streamer_write_uhwi_stream (string_stream, len);
! streamer_write_data_stream (string_stream, string, len);
return start + 1;
}
else
*************** streamer_write_uhwi_stream (struct lto_o
*** 195,201 ****
unsigned HOST_WIDE_INT work)
{
if (obs->left_in_block == 0)
! lto_append_block (obs);
char *current_pointer = obs->current_pointer;
unsigned int left_in_block = obs->left_in_block;
unsigned int size = 0;
--- 352,358 ----
unsigned HOST_WIDE_INT work)
{
if (obs->left_in_block == 0)
! obs->append_block ();
char *current_pointer = obs->current_pointer;
unsigned int left_in_block = obs->left_in_block;
unsigned int size = 0;
*************** streamer_write_uhwi_stream (struct lto_o
*** 215,221 ****
if (work != 0)
{
obs->left_in_block = 0;
! lto_append_block (obs);
current_pointer = obs->current_pointer;
left_in_block = obs->left_in_block;
do
--- 372,378 ----
if (work != 0)
{
obs->left_in_block = 0;
! obs->append_block ();
current_pointer = obs->current_pointer;
left_in_block = obs->left_in_block;
do
*************** void
*** 244,250 ****
streamer_write_hwi_stream (struct lto_output_stream *obs, HOST_WIDE_INT work)
{
if (obs->left_in_block == 0)
! lto_append_block (obs);
char *current_pointer = obs->current_pointer;
unsigned int left_in_block = obs->left_in_block;
unsigned int size = 0;
--- 401,407 ----
streamer_write_hwi_stream (struct lto_output_stream *obs, HOST_WIDE_INT work)
{
if (obs->left_in_block == 0)
! obs->append_block ();
char *current_pointer = obs->current_pointer;
unsigned int left_in_block = obs->left_in_block;
unsigned int size = 0;
*************** streamer_write_hwi_stream (struct lto_ou
*** 270,276 ****
if (more)
{
obs->left_in_block = 0;
! lto_append_block (obs);
current_pointer = obs->current_pointer;
left_in_block = obs->left_in_block;
do
--- 427,433 ----
if (more)
{
obs->left_in_block = 0;
! obs->append_block ();
current_pointer = obs->current_pointer;
left_in_block = obs->left_in_block;
do
*************** streamer_write_gcov_count_stream (struct
*** 304,306 ****
--- 461,494 ----
gcc_assert ((HOST_WIDE_INT) work == work);
streamer_write_hwi_stream (obs, work);
}
+
+ /* Write raw DATA of length LEN to the output block OB. */
+
+ void
+ streamer_write_data_stream (struct lto_output_stream *obs, const void *data,
+ size_t len)
+ {
+ while (len)
+ {
+ size_t copy;
+
+ /* No space left. */
+ if (obs->left_in_block == 0)
+ obs->append_block ();
+
+ /* Determine how many bytes to copy in this loop. */
+ if (len <= obs->left_in_block)
+ copy = len;
+ else
+ copy = obs->left_in_block;
+
+ /* Copy the data and do bookkeeping. */
+ memcpy (obs->current_pointer, data, copy);
+ obs->current_pointer += copy;
+ obs->total_size += copy;
+ obs->left_in_block -= copy;
+ data = (const char *) data + copy;
+ len -= copy;
+ }
+ }
+
Index: gcc/lto-section-out.c
===================================================================
*** gcc/lto-section-out.c.orig 2014-07-29 13:04:48.255073822 +0200
--- gcc/lto-section-out.c 2014-07-29 13:09:05.036056143 +0200
*************** lto_end_section (void)
*** 105,120 ****
void
lto_write_stream (struct lto_output_stream *obs)
{
- unsigned int block_size = 1024;
struct lto_char_ptr_base *block;
struct lto_char_ptr_base *next_block;
- if (!obs->first_block)
- return;
! for (block = obs->first_block; block; block = next_block)
{
const char *base = ((char *)block) + sizeof (struct lto_char_ptr_base);
! unsigned int num_chars = block_size - sizeof (struct lto_char_ptr_base);
/* If this is not the last block, it is full. If it is the last
block, left_in_block indicates how many chars are unoccupied in
--- 105,117 ----
void
lto_write_stream (struct lto_output_stream *obs)
{
struct lto_char_ptr_base *block;
struct lto_char_ptr_base *next_block;
! for (block = obs->get_blocks (); block; block = next_block)
{
const char *base = ((char *)block) + sizeof (struct lto_char_ptr_base);
! size_t num_chars = obs->block_size - sizeof (struct lto_char_ptr_base);
/* If this is not the last block, it is full. If it is the last
block, left_in_block indicates how many chars are unoccupied in
*************** lto_write_stream (struct lto_output_stre
*** 134,213 ****
}
else
lang_hooks.lto.append_data (base, num_chars, block);
- block_size *= 2;
- }
- }
-
-
- /* Adds a new block to output stream OBS. */
-
- void
- lto_append_block (struct lto_output_stream *obs)
- {
- struct lto_char_ptr_base *new_block;
-
- gcc_assert (obs->left_in_block == 0);
-
- if (obs->first_block == NULL)
- {
- /* This is the first time the stream has been written
- into. */
- obs->block_size = 1024;
- new_block = (struct lto_char_ptr_base*) xmalloc (obs->block_size);
- obs->first_block = new_block;
- }
- else
- {
- struct lto_char_ptr_base *tptr;
- /* Get a new block that is twice as big as the last block
- and link it into the list. */
- obs->block_size *= 2;
- new_block = (struct lto_char_ptr_base*) xmalloc (obs->block_size);
- /* The first bytes of the block are reserved as a pointer to
- the next block. Set the chain of the full block to the
- pointer to the new block. */
- tptr = obs->current_block;
- tptr->ptr = (char *) new_block;
- }
-
- /* Set the place for the next char at the first position after the
- chain to the next block. */
- obs->current_pointer
- = ((char *) new_block) + sizeof (struct lto_char_ptr_base);
- obs->current_block = new_block;
- /* Null out the newly allocated block's pointer to the next block. */
- new_block->ptr = NULL;
- obs->left_in_block = obs->block_size - sizeof (struct lto_char_ptr_base);
- }
-
-
- /* Write raw DATA of length LEN to the output block OB. */
-
- void
- lto_output_data_stream (struct lto_output_stream *obs, const void *data,
- size_t len)
- {
- while (len)
- {
- size_t copy;
-
- /* No space left. */
- if (obs->left_in_block == 0)
- lto_append_block (obs);
-
- /* Determine how many bytes to copy in this loop. */
- if (len <= obs->left_in_block)
- copy = len;
- else
- copy = obs->left_in_block;
-
- /* Copy the data and do bookkeeping. */
- memcpy (obs->current_pointer, data, copy);
- obs->current_pointer += copy;
- obs->total_size += copy;
- obs->left_in_block -= copy;
- data = (const char *) data + copy;
- len -= copy;
}
}
--- 131,136 ----
*************** lto_create_simple_output_block (enum lto
*** 321,328 ****
ob->section_type = section_type;
ob->decl_state = lto_get_out_decl_state ();
! ob->main_stream = ((struct lto_output_stream *)
! xcalloc (1, sizeof (struct lto_output_stream)));
return ob;
}
--- 244,250 ----
ob->section_type = section_type;
ob->decl_state = lto_get_out_decl_state ();
! ob->main_stream = new lto_output_stream;
return ob;
}
*************** lto_destroy_simple_output_block (struct
*** 349,360 ****
header.compressed_size = 0;
! header.main_size = ob->main_stream->total_size;
! header_stream = XCNEW (struct lto_output_stream);
! lto_output_data_stream (header_stream, &header, sizeof header);
lto_write_stream (header_stream);
! free (header_stream);
lto_write_stream (ob->main_stream);
--- 271,282 ----
header.compressed_size = 0;
! header.main_size = ob->main_stream->finish ();
! header_stream = new lto_output_stream (2 * 1024 * 1024, false);
! streamer_write_data_stream (header_stream, &header, sizeof header);
lto_write_stream (header_stream);
! delete header_stream;
lto_write_stream (ob->main_stream);
*************** lto_destroy_simple_output_block (struct
*** 362,368 ****
writing lto info. */
lto_end_section ();
! free (ob->main_stream);
free (ob);
}
--- 284,290 ----
writing lto info. */
lto_end_section ();
! delete ob->main_stream;
free (ob);
}
Index: gcc/data-streamer.h
===================================================================
*** gcc/data-streamer.h.orig 2014-07-29 13:04:48.255073822 +0200
--- gcc/data-streamer.h 2014-07-29 13:09:05.037056143 +0200
*************** void streamer_write_uhwi_stream (struct
*** 70,75 ****
--- 70,77 ----
unsigned HOST_WIDE_INT);
void streamer_write_hwi_stream (struct lto_output_stream *, HOST_WIDE_INT);
void streamer_write_gcov_count_stream (struct lto_output_stream *, gcov_type);
+ void streamer_write_data_stream (struct lto_output_stream *, const void *,
+ size_t);
/* In data-streamer-in.c */
const char *string_for_index (struct data_in *, unsigned int, unsigned int *);
*************** streamer_write_char_stream (struct lto_o
*** 180,186 ****
{
/* No space left. */
if (obs->left_in_block == 0)
! lto_append_block (obs);
/* Write the actual character. */
char *current_pointer = obs->current_pointer;
--- 182,188 ----
{
/* No space left. */
if (obs->left_in_block == 0)
! obs->append_block ();
/* Write the actual character. */
char *current_pointer = obs->current_pointer;
*************** streamer_write_char_stream (struct lto_o
*** 196,204 ****
static inline unsigned char
streamer_read_uchar (struct lto_input_block *ib)
{
! if (ib->p >= ib->len)
! lto_section_overrun (ib);
! return (ib->data[ib->p++]);
}
/* Output VAL into OBS and verify it is in range MIN...MAX that is supposed
--- 198,207 ----
static inline unsigned char
streamer_read_uchar (struct lto_input_block *ib)
{
! if (ib->left_in_block == 0)
! ib->append_block ();
! ib->left_in_block--;
! return (*(ib->current_pointer++));
}
/* Output VAL into OBS and verify it is in range MIN...MAX that is supposed
Index: gcc/lto-opts.c
===================================================================
*** gcc/lto-opts.c.orig 2014-07-29 13:04:48.255073822 +0200
--- gcc/lto-opts.c 2014-07-29 13:09:05.037056143 +0200
*************** along with GCC; see the file COPYING3.
*** 37,42 ****
--- 37,43 ----
#include "common/common-target.h"
#include "diagnostic.h"
#include "lto-streamer.h"
+ #include "data-streamer.h"
#include "toplev.h"
/* Append the option piece OPT to the COLLECT_GCC_OPTIONS string
*************** append_to_collect_gcc_options (struct ob
*** 67,73 ****
void
lto_write_options (void)
{
! struct lto_output_stream stream;
char *section_name;
struct obstack temporary_obstack;
unsigned int i, j;
--- 68,74 ----
void
lto_write_options (void)
{
! lto_output_stream *stream = new lto_output_stream (2 * 1024 * 1024, false);
char *section_name;
struct obstack temporary_obstack;
unsigned int i, j;
*************** lto_write_options (void)
*** 76,82 ****
section_name = lto_get_section_name (LTO_section_opts, NULL, NULL);
lto_begin_section (section_name, false);
- memset (&stream, 0, sizeof (stream));
obstack_init (&temporary_obstack);
--- 77,82 ----
*************** lto_write_options (void)
*** 170,178 ****
}
obstack_grow (&temporary_obstack, "\0", 1);
args = XOBFINISH (&temporary_obstack, char *);
! lto_output_data_stream (&stream, args, strlen (args) + 1);
! lto_write_stream (&stream);
lto_end_section ();
obstack_free (&temporary_obstack, NULL);
--- 170,179 ----
}
obstack_grow (&temporary_obstack, "\0", 1);
args = XOBFINISH (&temporary_obstack, char *);
! streamer_write_data_stream (stream, args, strlen (args) + 1);
! lto_write_stream (stream);
! delete stream;
lto_end_section ();
obstack_free (&temporary_obstack, NULL);
Index: gcc/lto-streamer-out.c
===================================================================
*** gcc/lto-streamer-out.c.orig 2014-07-29 13:04:48.255073822 +0200
--- gcc/lto-streamer-out.c 2014-07-29 13:09:05.038056143 +0200
*************** create_output_block (enum lto_section_ty
*** 79,90 ****
ob->section_type = section_type;
ob->decl_state = lto_get_out_decl_state ();
! ob->main_stream = XCNEW (struct lto_output_stream);
! ob->string_stream = XCNEW (struct lto_output_stream);
ob->writer_cache = streamer_tree_cache_create (!flag_wpa, true, false);
if (section_type == LTO_section_function_body)
! ob->cfg_stream = XCNEW (struct lto_output_stream);
clear_line_info (ob);
--- 79,92 ----
ob->section_type = section_type;
ob->decl_state = lto_get_out_decl_state ();
! ob->main_stream = new lto_output_stream;
! // The way we use this stream prevents its compression as we basically
! // perform random access
! ob->string_stream = new lto_output_stream (2 * 1024 * 1024, false);
ob->writer_cache = streamer_tree_cache_create (!flag_wpa, true, false);
if (section_type == LTO_section_function_body)
! ob->cfg_stream = new lto_output_stream;
clear_line_info (ob);
*************** destroy_output_block (struct output_bloc
*** 105,114 ****
delete ob->string_hash_table;
ob->string_hash_table = NULL;
! free (ob->main_stream);
! free (ob->string_stream);
if (section_type == LTO_section_function_body)
! free (ob->cfg_stream);
streamer_tree_cache_delete (ob->writer_cache);
obstack_free (&ob->obstack, NULL);
--- 107,116 ----
delete ob->string_hash_table;
ob->string_hash_table = NULL;
! delete ob->main_stream;
! delete ob->string_stream;
if (section_type == LTO_section_function_body)
! delete ob->cfg_stream;
streamer_tree_cache_delete (ob->writer_cache);
obstack_free (&ob->obstack, NULL);
*************** produce_asm (struct output_block *ob, tr
*** 1895,1908 ****
header.compressed_size = 0;
if (section_type == LTO_section_function_body)
! header.cfg_size = ob->cfg_stream->total_size;
! header.main_size = ob->main_stream->total_size;
! header.string_size = ob->string_stream->total_size;
! header_stream = XCNEW (struct lto_output_stream);
! lto_output_data_stream (header_stream, &header, sizeof header);
lto_write_stream (header_stream);
! free (header_stream);
/* Put all of the gimple and the string table out the asm file as a
block of text. */
--- 1897,1910 ----
header.compressed_size = 0;
if (section_type == LTO_section_function_body)
! header.cfg_size = ob->cfg_stream->finish ();
! header.main_size = ob->main_stream->finish ();
! header.string_size = ob->string_stream->finish ();
! header_stream = new lto_output_stream (2 * 1024 * 1024, false);
! streamer_write_data_stream (header_stream, &header, sizeof header);
lto_write_stream (header_stream);
! delete header_stream;
/* Put all of the gimple and the string table out the asm file as a
block of text. */
*************** lto_output_toplevel_asms (void)
*** 2134,2146 ****
header.lto_header.major_version = LTO_major_version;
header.lto_header.minor_version = LTO_minor_version;
! header.main_size = ob->main_stream->total_size;
! header.string_size = ob->string_stream->total_size;
! header_stream = XCNEW (struct lto_output_stream);
! lto_output_data_stream (header_stream, &header, sizeof (header));
lto_write_stream (header_stream);
! free (header_stream);
/* Put all of the gimple and the string table out the asm file as a
block of text. */
--- 2136,2148 ----
header.lto_header.major_version = LTO_major_version;
header.lto_header.minor_version = LTO_minor_version;
! header.main_size = ob->main_stream->finish ();
! header.string_size = ob->string_stream->finish ();
! header_stream = new lto_output_stream (2 * 1024 * 1024, false);
! streamer_write_data_stream (header_stream, &header, sizeof (header));
lto_write_stream (header_stream);
! delete header_stream;
/* Put all of the gimple and the string table out the asm file as a
block of text. */
*************** copy_function_or_variable (struct symtab
*** 2160,2166 ****
{
tree function = node->decl;
struct lto_file_decl_data *file_data = node->lto_file_data;
! struct lto_output_stream *output_stream = XCNEW (struct lto_output_stream);
const char *data;
size_t len;
const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function));
--- 2162,2168 ----
{
tree function = node->decl;
struct lto_file_decl_data *file_data = node->lto_file_data;
! struct lto_output_stream *output_stream = new lto_output_stream (2 * 1024 * 1024, false);
const char *data;
size_t len;
const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (function));
*************** copy_function_or_variable (struct symtab
*** 2181,2187 ****
gcc_assert (data);
/* Do a bit copy of the function body. */
! lto_output_data_stream (output_stream, data, len);
lto_write_stream (output_stream);
/* Copy decls. */
--- 2183,2189 ----
gcc_assert (data);
/* Do a bit copy of the function body. */
! streamer_write_data_stream (output_stream, data, len);
lto_write_stream (output_stream);
/* Copy decls. */
*************** copy_function_or_variable (struct symtab
*** 2206,2212 ****
lto_free_section_data (file_data, LTO_section_function_body, name,
data, len);
! free (output_stream);
lto_end_section ();
}
--- 2208,2214 ----
lto_free_section_data (file_data, LTO_section_function_body, name,
data, len);
! delete output_stream;
lto_end_section ();
}
*************** write_global_references (struct output_b
*** 2356,2362 ****
const uint32_t size = lto_tree_ref_encoder_size (encoder);
/* Write size as 32-bit unsigned. */
! lto_output_data_stream (ref_stream, &size, sizeof (int32_t));
for (index = 0; index < size; index++)
{
--- 2358,2364 ----
const uint32_t size = lto_tree_ref_encoder_size (encoder);
/* Write size as 32-bit unsigned. */
! streamer_write_data_stream (ref_stream, &size, sizeof (int32_t));
for (index = 0; index < size; index++)
{
*************** write_global_references (struct output_b
*** 2365,2371 ****
t = lto_tree_ref_encoder_get_tree (encoder, index);
streamer_tree_cache_lookup (ob->writer_cache, t, &slot_num);
gcc_assert (slot_num != (unsigned)-1);
! lto_output_data_stream (ref_stream, &slot_num, sizeof slot_num);
}
}
--- 2367,2373 ----
t = lto_tree_ref_encoder_get_tree (encoder, index);
streamer_tree_cache_lookup (ob->writer_cache, t, &slot_num);
gcc_assert (slot_num != (unsigned)-1);
! streamer_write_data_stream (ref_stream, &slot_num, sizeof slot_num);
}
}
*************** lto_output_decl_state_refs (struct outpu
*** 2401,2407 ****
decl = (state->fn_decl) ? state->fn_decl : void_type_node;
streamer_tree_cache_lookup (ob->writer_cache, decl, &ref);
gcc_assert (ref != (unsigned)-1);
! lto_output_data_stream (out_stream, &ref, sizeof (uint32_t));
for (i = 0; i < LTO_N_DECL_STREAMS; i++)
write_global_references (ob, out_stream, &state->streams[i]);
--- 2403,2409 ----
decl = (state->fn_decl) ? state->fn_decl : void_type_node;
streamer_tree_cache_lookup (ob->writer_cache, decl, &ref);
gcc_assert (ref != (unsigned)-1);
! streamer_write_data_stream (out_stream, &ref, sizeof (uint32_t));
for (i = 0; i < LTO_N_DECL_STREAMS; i++)
write_global_references (ob, out_stream, &state->streams[i]);
*************** write_symbol (struct streamer_tree_cache
*** 2531,2544 ****
else
comdat = "";
! lto_output_data_stream (stream, name, strlen (name) + 1);
! lto_output_data_stream (stream, comdat, strlen (comdat) + 1);
c = (unsigned char) kind;
! lto_output_data_stream (stream, &c, 1);
c = (unsigned char) visibility;
! lto_output_data_stream (stream, &c, 1);
! lto_output_data_stream (stream, &size, 8);
! lto_output_data_stream (stream, &slot_num, 4);
}
/* Return true if NODE should appear in the plugin symbol table. */
--- 2533,2546 ----
else
comdat = "";
! streamer_write_data_stream (stream, name, strlen (name) + 1);
! streamer_write_data_stream (stream, comdat, strlen (comdat) + 1);
c = (unsigned char) kind;
! streamer_write_data_stream (stream, &c, 1);
c = (unsigned char) visibility;
! streamer_write_data_stream (stream, &c, 1);
! streamer_write_data_stream (stream, &size, 8);
! streamer_write_data_stream (stream, &slot_num, 4);
}
/* Return true if NODE should appear in the plugin symbol table. */
*************** produce_symtab (struct output_block *ob)
*** 2589,2595 ****
struct streamer_tree_cache_d *cache = ob->writer_cache;
char *section_name = lto_get_section_name (LTO_section_symtab, NULL, NULL);
struct pointer_set_t *seen;
! struct lto_output_stream stream;
lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
lto_symtab_encoder_iterator lsei;
--- 2591,2597 ----
struct streamer_tree_cache_d *cache = ob->writer_cache;
char *section_name = lto_get_section_name (LTO_section_symtab, NULL, NULL);
struct pointer_set_t *seen;
! lto_output_stream *stream = new lto_output_stream (2 * 1024 * 1024, false);
lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
lto_symtab_encoder_iterator lsei;
*************** produce_symtab (struct output_block *ob)
*** 2597,2603 ****
free (section_name);
seen = pointer_set_create ();
- memset (&stream, 0, sizeof (stream));
/* Write the symbol table.
First write everything defined and then all declarations.
--- 2599,2604 ----
*************** produce_symtab (struct output_block *ob)
*** 2609,2615 ****
if (!output_symbol_p (node) || DECL_EXTERNAL (node->decl))
continue;
! write_symbol (cache, &stream, node->decl, seen, false);
}
for (lsei = lsei_start (encoder);
!lsei_end_p (lsei); lsei_next (&lsei))
--- 2610,2616 ----
if (!output_symbol_p (node) || DECL_EXTERNAL (node->decl))
continue;
! write_symbol (cache, stream, node->decl, seen, false);
}
for (lsei = lsei_start (encoder);
!lsei_end_p (lsei); lsei_next (&lsei))
*************** produce_symtab (struct output_block *ob)
*** 2618,2627 ****
if (!output_symbol_p (node) || !DECL_EXTERNAL (node->decl))
continue;
! write_symbol (cache, &stream, node->decl, seen, false);
}
! lto_write_stream (&stream);
pointer_set_destroy (seen);
lto_end_section ();
--- 2619,2629 ----
if (!output_symbol_p (node) || !DECL_EXTERNAL (node->decl))
continue;
! write_symbol (cache, stream, node->decl, seen, false);
}
! lto_write_stream (stream);
! delete stream;
pointer_set_destroy (seen);
lto_end_section ();
*************** produce_asm_for_decls (void)
*** 2698,2717 ****
}
header.decl_state_size = decl_state_size;
! header.main_size = ob->main_stream->total_size;
! header.string_size = ob->string_stream->total_size;
! header_stream = XCNEW (struct lto_output_stream);
! lto_output_data_stream (header_stream, &header, sizeof header);
lto_write_stream (header_stream);
! free (header_stream);
/* Write the main out-decl state, followed by out-decl states of
functions. */
! decl_state_stream = XCNEW (struct lto_output_stream);
num_decl_states = num_fns + 1;
! lto_output_data_stream (decl_state_stream, &num_decl_states,
! sizeof (num_decl_states));
lto_output_decl_state_refs (ob, decl_state_stream, out_state);
for (idx = 0; idx < num_fns; idx++)
{
--- 2700,2719 ----
}
header.decl_state_size = decl_state_size;
! header.main_size = ob->main_stream->finish ();
! header.string_size = ob->string_stream->finish ();
! header_stream = new lto_output_stream (2 * 1024 * 1024, false);
! streamer_write_data_stream (header_stream, &header, sizeof header);
lto_write_stream (header_stream);
! delete header_stream;
/* Write the main out-decl state, followed by out-decl states of
functions. */
! decl_state_stream = new lto_output_stream (2 * 1024 * 1024, false);
num_decl_states = num_fns + 1;
! streamer_write_data_stream (decl_state_stream, &num_decl_states,
! sizeof (num_decl_states));
lto_output_decl_state_refs (ob, decl_state_stream, out_state);
for (idx = 0; idx < num_fns; idx++)
{
*************** produce_asm_for_decls (void)
*** 2720,2726 ****
lto_output_decl_state_refs (ob, decl_state_stream, fn_out_state);
}
lto_write_stream (decl_state_stream);
! free (decl_state_stream);
lto_write_stream (ob->main_stream);
lto_write_stream (ob->string_stream);
--- 2722,2728 ----
lto_output_decl_state_refs (ob, decl_state_stream, fn_out_state);
}
lto_write_stream (decl_state_stream);
! delete decl_state_stream;
lto_write_stream (ob->main_stream);
lto_write_stream (ob->string_stream);
Index: gcc/lto-streamer.h
===================================================================
*** gcc/lto-streamer.h.orig 2014-07-29 13:04:48.255073822 +0200
--- gcc/lto-streamer.h 2014-07-29 14:36:21.727695603 +0200
*************** typedef void (lto_free_section_data_f) (
*** 308,333 ****
size_t);
/* Structure used as buffer for reading an LTO file. */
! struct lto_input_block
{
const char *data;
unsigned int p;
unsigned int len;
};
! #define LTO_INIT_INPUT_BLOCK(BASE,D,P,L) \
! do { \
! BASE.data = D; \
! BASE.p = P; \
! BASE.len = L; \
! } while (0)
!
! #define LTO_INIT_INPUT_BLOCK_PTR(BASE,D,P,L) \
! do { \
! BASE->data = D; \
! BASE->p = P; \
! BASE->len = L; \
! } while (0)
/* The is the first part of the record for a function or constructor
--- 308,344 ----
size_t);
/* Structure used as buffer for reading an LTO file. */
! class lto_input_block
{
+ public:
+ /* Special constructor for the string table, it abuses this to
+ do random access but use the uhwi decoder. */
+ lto_input_block (const char *data_, unsigned int p_, unsigned int len_)
+ : current_pointer (data_ + p_), left_in_block (len_), compress (false),
+ data (NULL), p (0), len (0) {};
+ lto_input_block (const char *data_, unsigned int len_, bool compress_ = true)
+ : current_pointer (NULL), left_in_block (0), compress (compress_),
+ data (data_), p (0), len (len_), zbuf (NULL), zlib_stream (NULL) {};
+ ~lto_input_block ();
+ void append_block ();
+ inline bool eof ();
+ const char *current_pointer;
+ unsigned int left_in_block;
+
+ private:
+ const bool compress;
const char *data;
unsigned int p;
unsigned int len;
+ char *zbuf;
+ struct z_stream_s *zlib_stream;
};
! inline bool
! lto_input_block::eof ()
! {
! return left_in_block == 0 && len == p;
! }
/* The is the first part of the record for a function or constructor
*************** struct lto_char_ptr_base
*** 575,584 ****
The entire structure should be zeroed when created. The record
consists of a set of blocks. The first sizeof (ptr) bytes are used
as a chain, and the rest store the bytes to be written. */
! struct lto_output_stream
{
! /* The pointer to the first block in the stream. */
! struct lto_char_ptr_base * first_block;
/* The pointer to the last and current block in the stream. */
struct lto_char_ptr_base * current_block;
--- 586,608 ----
The entire structure should be zeroed when created. The record
consists of a set of blocks. The first sizeof (ptr) bytes are used
as a chain, and the rest store the bytes to be written. */
! class lto_output_stream
{
! public:
! lto_output_stream (size_t block_size_ = 2 * 1024 * 1024,
! bool compress_ = true)
! : current_block (NULL), current_pointer (NULL),
! left_in_block (0), block_size (block_size_), total_size (0),
! first_block (NULL), current_z_block (NULL), compress (compress_),
! zlib_stream (NULL)
! {
! gcc_assert (block_size > sizeof (lto_char_ptr_base));
! }
!
! unsigned int finish();
! lto_char_ptr_base *get_blocks ();
!
! void append_block ();
/* The pointer to the last and current block in the stream. */
struct lto_char_ptr_base * current_block;
*************** struct lto_output_stream
*** 589,599 ****
/* The number of characters left in the current block. */
unsigned int left_in_block;
! /* The block size of the last block allocated. */
! unsigned int block_size;
! /* The total number of characters written. */
unsigned int total_size;
};
/* The is the first part of the record in an LTO file for many of the
--- 613,636 ----
/* The number of characters left in the current block. */
unsigned int left_in_block;
! /* The block size to use. */
! const unsigned int block_size;
! /* The total number of uncompressed characters written. */
unsigned int total_size;
+
+ private:
+ void compress_current_block (bool);
+
+ /* The pointer to the first block in the stream. */
+ struct lto_char_ptr_base * first_block;
+
+ struct lto_char_ptr_base * current_z_block;
+
+ /* Whether to compress this stream. */
+ const bool compress;
+
+ struct z_stream_s *zlib_stream;
};
/* The is the first part of the record in an LTO file for many of the
*************** extern struct lto_in_decl_state *lto_get
*** 769,775 ****
struct lto_file_decl_data *, tree);
extern void lto_free_function_in_decl_state (struct lto_in_decl_state *);
extern void lto_free_function_in_decl_state_for_node (symtab_node *);
- 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;
--- 806,811 ----
*************** extern void lto_push_out_decl_state (str
*** 805,811 ****
extern struct lto_out_decl_state *lto_pop_out_decl_state (void);
extern void lto_record_function_out_decl_state (tree,
struct lto_out_decl_state *);
- extern void lto_append_block (struct lto_output_stream *);
/* In lto-streamer.c. */
--- 841,846 ----
Index: gcc/lto-section-in.c
===================================================================
*** gcc/lto-section-in.c.orig 2014-07-29 13:04:48.255073822 +0200
--- gcc/lto-section-in.c 2014-07-29 13:09:05.039056143 +0200
*************** lto_create_simple_input_block (struct lt
*** 227,245 ****
const struct lto_simple_header * header
= (const struct lto_simple_header *) data;
- struct lto_input_block* ib_main;
int main_offset = sizeof (struct lto_simple_header);
if (!data)
return NULL;
- ib_main = XNEW (struct lto_input_block);
-
*datar = data;
! LTO_INIT_INPUT_BLOCK_PTR (ib_main, data + main_offset,
! 0, header->main_size);
!
! return ib_main;
}
--- 227,239 ----
const struct lto_simple_header * header
= (const struct lto_simple_header *) data;
int main_offset = sizeof (struct lto_simple_header);
if (!data)
return NULL;
*datar = data;
! return new lto_input_block (data + main_offset, header->main_size);
}
*************** lto_free_function_in_decl_state_for_node
*** 454,468 ****
}
- /* Report read pass end of the section. */
-
- void
- lto_section_overrun (struct lto_input_block *ib)
- {
- fatal_error ("bytecode stream: trying to read %d bytes "
- "after the end of the input buffer", ib->p - ib->len);
- }
-
/* Report out of range value. */
void
--- 448,453 ----
Index: gcc/lto-cgraph.c
===================================================================
*** gcc/lto-cgraph.c.orig 2014-07-29 13:04:48.255073822 +0200
--- gcc/lto-cgraph.c 2014-07-29 13:09:05.040056143 +0200
*************** lto_output_node (struct lto_simple_outpu
*** 488,494 ****
comdat = IDENTIFIER_POINTER (group);
else
comdat = "";
! lto_output_data_stream (ob->main_stream, comdat, strlen (comdat) + 1);
if (group)
{
--- 488,495 ----
comdat = IDENTIFIER_POINTER (group);
else
comdat = "";
! streamer_write_uhwi_stream (ob->main_stream, strlen (comdat));
! streamer_write_data_stream (ob->main_stream, comdat, strlen (comdat));
if (group)
{
*************** lto_output_node (struct lto_simple_outpu
*** 546,552 ****
bp_pack_enum (&bp, ld_plugin_symbol_resolution,
LDPR_NUM_KNOWN, node->resolution);
streamer_write_bitpack (&bp);
! lto_output_data_stream (ob->main_stream, section, strlen (section) + 1);
if (node->thunk.thunk_p && !boundary_p)
{
--- 547,554 ----
bp_pack_enum (&bp, ld_plugin_symbol_resolution,
LDPR_NUM_KNOWN, node->resolution);
streamer_write_bitpack (&bp);
! streamer_write_uhwi_stream (ob->main_stream, strlen (section));
! streamer_write_data_stream (ob->main_stream, section, strlen (section));
if (node->thunk.thunk_p && !boundary_p)
{
*************** lto_output_varpool_node (struct lto_simp
*** 622,628 ****
comdat = IDENTIFIER_POINTER (group);
else
comdat = "";
! lto_output_data_stream (ob->main_stream, comdat, strlen (comdat) + 1);
if (group)
{
--- 624,631 ----
comdat = IDENTIFIER_POINTER (group);
else
comdat = "";
! streamer_write_uhwi_stream (ob->main_stream, strlen (comdat));
! streamer_write_data_stream (ob->main_stream, comdat, strlen (comdat));
if (group)
{
*************** lto_output_varpool_node (struct lto_simp
*** 640,646 ****
section = node->get_section ();
if (!section)
section = "";
! lto_output_data_stream (ob->main_stream, section, strlen (section) + 1);
streamer_write_enum (ob->main_stream, ld_plugin_symbol_resolution,
LDPR_NUM_KNOWN, node->resolution);
--- 643,650 ----
section = node->get_section ();
if (!section)
section = "";
! streamer_write_uhwi_stream (ob->main_stream, strlen (section));
! streamer_write_data_stream (ob->main_stream, section, strlen (section));
streamer_write_enum (ob->main_stream, ld_plugin_symbol_resolution,
LDPR_NUM_KNOWN, node->resolution);
*************** output_symtab (void)
*** 994,1012 ****
static tree
read_identifier (struct lto_input_block *ib)
{
! unsigned int len = strnlen (ib->data + ib->p, ib->len - ib->p - 1);
! tree id;
!
! if (ib->data[ib->p + len])
! lto_section_overrun (ib);
if (!len)
! {
! ib->p++;
! return NULL;
! }
! id = get_identifier (ib->data + ib->p);
! ib->p += len + 1;
! return id;
}
/* Return string encoded in IB, NULL if string is empty. */
--- 998,1011 ----
static tree
read_identifier (struct lto_input_block *ib)
{
! unsigned int len = streamer_read_uhwi (ib);
if (!len)
! return NULL;
! char *str = XALLOCAVEC (char, len + 1);
! for (unsigned i = 0; i < len; ++i)
! str[i] = streamer_read_uchar (ib);
! str[len] = '\0';
! return get_identifier (str);
}
/* Return string encoded in IB, NULL if string is empty. */
*************** read_identifier (struct lto_input_block
*** 1014,1031 ****
static const char *
read_string (struct lto_input_block *ib)
{
! unsigned int len = strnlen (ib->data + ib->p, ib->len - ib->p - 1);
! const char *str;
!
! if (ib->data[ib->p + len])
! lto_section_overrun (ib);
if (!len)
! {
! ib->p++;
! return NULL;
! }
! str = ib->data + ib->p;
! ib->p += len + 1;
return str;
}
--- 1013,1025 ----
static const char *
read_string (struct lto_input_block *ib)
{
! unsigned int len = streamer_read_uhwi (ib);
if (!len)
! return NULL;
! char *str = (char *)xmalloc (len + 1);
! for (unsigned i = 0; i < len; ++i)
! str[i] = streamer_read_uchar (ib);
! str[len] = '\0';
return str;
}
*************** input_cgraph_opt_section (struct lto_fil
*** 1902,1913 ****
const int main_offset = cfg_offset + header->cfg_size;
const int string_offset = main_offset + header->main_size;
struct data_in *data_in;
- struct lto_input_block ib_main;
unsigned int i;
unsigned int count;
! LTO_INIT_INPUT_BLOCK (ib_main, (const char *) data + main_offset, 0,
! header->main_size);
data_in =
lto_data_in_create (file_data, (const char *) data + string_offset,
--- 1896,1906 ----
const int main_offset = cfg_offset + header->cfg_size;
const int string_offset = main_offset + header->main_size;
struct data_in *data_in;
unsigned int i;
unsigned int count;
! lto_input_block ib_main ((const char *) data + main_offset,
! header->main_size);
data_in =
lto_data_in_create (file_data, (const char *) data + string_offset,
Index: gcc/data-streamer-in.c
===================================================================
*** gcc/data-streamer-in.c.orig 2014-07-29 13:04:48.255073822 +0200
--- gcc/data-streamer-in.c 2014-07-29 13:58:27.738852164 +0200
*************** along with GCC; see the file COPYING3.
*** 22,27 ****
--- 22,32 ----
#include "config.h"
#include "system.h"
+ /* zlib.h includes other system headers. Those headers may test feature
+ test macros. config.h may define feature test macros. For this reason,
+ zlib.h needs to be included after, rather than before, config.h and
+ system.h. */
+ #include <zlib.h>
#include "coretypes.h"
#include "diagnostic.h"
#include "tree.h"
*************** along with GCC; see the file COPYING3.
*** 33,45 ****
#include "gimple.h"
#include "data-streamer.h"
/* Read a string from the string table in DATA_IN using input block
IB. Write the length to RLEN. */
const char *
string_for_index (struct data_in *data_in, unsigned int loc, unsigned int *rlen)
{
- struct lto_input_block str_tab;
unsigned int len;
const char *result;
--- 38,107 ----
#include "gimple.h"
#include "data-streamer.h"
+
+ void
+ lto_input_block::append_block ()
+ {
+ gcc_assert (left_in_block == 0 && data);
+ if (!compress)
+ {
+ current_pointer = data + p;
+ left_in_block = MIN (4096, len - p);
+ p += left_in_block;
+ }
+ else
+ {
+ int status;
+
+ if (!zlib_stream)
+ {
+ zlib_stream = XCNEW (z_stream);
+ zlib_stream->zalloc = NULL;
+ zlib_stream->zfree = NULL;
+ zlib_stream->opaque = NULL;
+ zlib_stream->avail_in = len;
+ zlib_stream->next_in = (Bytef*)const_cast<char *>(data + p);
+ status = inflateInit (zlib_stream);
+ if (status != Z_OK)
+ internal_error ("compressed stream: %s", zError (status));
+ zbuf = XNEWVEC (char, 2 * 1024 * 1024);
+ }
+
+ zlib_stream->avail_out = 2 * 1024 * 1024;
+ zlib_stream->next_out = (Bytef*)zbuf;
+ status = inflate (zlib_stream, Z_NO_FLUSH);
+ if (status != Z_OK && status != Z_STREAM_END)
+ internal_error ("compressed stream: %s", zError (status));
+
+ current_pointer = zbuf;
+ left_in_block = 2 * 1024 * 1024 - zlib_stream->avail_out;
+ p = len - zlib_stream->avail_in;
+ }
+ if (left_in_block == 0)
+ fatal_error ("bytecode stream: trying to read bytes "
+ "after the end of the input buffer");
+ }
+
+ lto_input_block::~lto_input_block ()
+ {
+ if (compress)
+ {
+ if (zlib_stream)
+ {
+ inflateEnd (zlib_stream);
+ free (zlib_stream);
+ }
+ if (zbuf)
+ free (zbuf);
+ }
+ }
+
/* Read a string from the string table in DATA_IN using input block
IB. Write the length to RLEN. */
const char *
string_for_index (struct data_in *data_in, unsigned int loc, unsigned int *rlen)
{
unsigned int len;
const char *result;
*************** string_for_index (struct data_in *data_i
*** 50,64 ****
}
/* Get the string stored at location LOC in DATA_IN->STRINGS. */
! LTO_INIT_INPUT_BLOCK (str_tab, data_in->strings, loc - 1,
! data_in->strings_len);
len = streamer_read_uhwi (&str_tab);
*rlen = len;
! if (str_tab.p + len > data_in->strings_len)
internal_error ("bytecode stream: string too long for the string table");
! result = (const char *)(data_in->strings + str_tab.p);
return result;
}
--- 112,126 ----
}
/* Get the string stored at location LOC in DATA_IN->STRINGS. */
! lto_input_block str_tab (data_in->strings, loc - 1,
! data_in->strings_len - (loc - 1));
len = streamer_read_uhwi (&str_tab);
*rlen = len;
! if (str_tab.left_in_block < len)
internal_error ("bytecode stream: string too long for the string table");
! result = str_tab.current_pointer;
return result;
}
*************** bp_unpack_string (struct data_in *data_i
*** 127,158 ****
unsigned HOST_WIDE_INT
streamer_read_uhwi (struct lto_input_block *ib)
{
! unsigned HOST_WIDE_INT result;
! int shift;
! unsigned HOST_WIDE_INT byte;
! unsigned int p = ib->p;
! unsigned int len = ib->len;
!
! const char *data = ib->data;
! result = data[p++];
if ((result & 0x80) != 0)
{
result &= 0x7f;
shift = 7;
do
{
! byte = data[p++];
result |= (byte & 0x7f) << shift;
shift += 7;
}
while ((byte & 0x80) != 0);
}
- /* We check for section overrun after the fact for performance reason. */
- if (p > len)
- lto_section_overrun (ib);
-
- ib->p = p;
return result;
}
--- 189,210 ----
unsigned HOST_WIDE_INT
streamer_read_uhwi (struct lto_input_block *ib)
{
! unsigned HOST_WIDE_INT result = streamer_read_uchar (ib);
if ((result & 0x80) != 0)
{
+ unsigned HOST_WIDE_INT byte;
+ int shift;
result &= 0x7f;
shift = 7;
do
{
! byte = streamer_read_uchar (ib);
result |= (byte & 0x7f) << shift;
shift += 7;
}
while ((byte & 0x80) != 0);
}
return result;
}
Index: gcc/ipa-inline-analysis.c
===================================================================
*** gcc/ipa-inline-analysis.c.orig 2014-07-29 13:04:48.255073822 +0200
--- gcc/ipa-inline-analysis.c 2014-07-29 13:09:05.041056143 +0200
*************** inline_read_section (struct lto_file_dec
*** 4086,4097 ****
const int main_offset = cfg_offset + header->cfg_size;
const int string_offset = main_offset + header->main_size;
struct data_in *data_in;
- struct lto_input_block ib;
unsigned int i, count2, j;
unsigned int f_count;
! LTO_INIT_INPUT_BLOCK (ib, (const char *) data + main_offset, 0,
! header->main_size);
data_in =
lto_data_in_create (file_data, (const char *) data + string_offset,
--- 4086,4095 ----
const int main_offset = cfg_offset + header->cfg_size;
const int string_offset = main_offset + header->main_size;
struct data_in *data_in;
unsigned int i, count2, j;
unsigned int f_count;
! lto_input_block ib ((const char *) data + main_offset, header->main_size);
data_in =
lto_data_in_create (file_data, (const char *) data + string_offset,
Index: gcc/ipa-prop.c
===================================================================
*** gcc/ipa-prop.c.orig 2014-07-29 13:05:27.958071088 +0200
--- gcc/ipa-prop.c 2014-07-29 13:09:05.042056142 +0200
*************** ipa_prop_read_section (struct lto_file_d
*** 4895,4906 ****
const int main_offset = cfg_offset + header->cfg_size;
const int string_offset = main_offset + header->main_size;
struct data_in *data_in;
- struct lto_input_block ib_main;
unsigned int i;
unsigned int count;
! LTO_INIT_INPUT_BLOCK (ib_main, (const char *) data + main_offset, 0,
! header->main_size);
data_in =
lto_data_in_create (file_data, (const char *) data + string_offset,
--- 4895,4905 ----
const int main_offset = cfg_offset + header->cfg_size;
const int string_offset = main_offset + header->main_size;
struct data_in *data_in;
unsigned int i;
unsigned int count;
! lto_input_block ib_main ((const char *) data + main_offset,
! header->main_size);
data_in =
lto_data_in_create (file_data, (const char *) data + string_offset,
*************** read_replacements_section (struct lto_fi
*** 5073,5084 ****
const int main_offset = cfg_offset + header->cfg_size;
const int string_offset = main_offset + header->main_size;
struct data_in *data_in;
- struct lto_input_block ib_main;
unsigned int i;
unsigned int count;
! LTO_INIT_INPUT_BLOCK (ib_main, (const char *) data + main_offset, 0,
! header->main_size);
data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
header->string_size, vNULL);
--- 5072,5082 ----
const int main_offset = cfg_offset + header->cfg_size;
const int string_offset = main_offset + header->main_size;
struct data_in *data_in;
unsigned int i;
unsigned int count;
! lto_input_block ib_main ((const char *) data + main_offset,
! header->main_size);
data_in = lto_data_in_create (file_data, (const char *) data + string_offset,
header->string_size, vNULL);
Index: gcc/lto-streamer-in.c
===================================================================
*** gcc/lto-streamer-in.c.orig 2014-07-29 13:04:48.255073822 +0200
--- gcc/lto-streamer-in.c 2014-07-29 13:09:05.043056142 +0200
*************** lto_read_body_or_constructor (struct lto
*** 1054,1061 ****
int cfg_offset;
int main_offset;
int string_offset;
- struct lto_input_block ib_cfg;
- struct lto_input_block ib_main;
tree fn_decl = node->decl;
header = (const struct lto_function_header *) data;
--- 1054,1059 ----
*************** lto_read_body_or_constructor (struct lto
*** 1064,1089 ****
cfg_offset = sizeof (struct lto_function_header);
main_offset = cfg_offset + header->cfg_size;
string_offset = main_offset + header->main_size;
-
- LTO_INIT_INPUT_BLOCK (ib_cfg,
- data + cfg_offset,
- 0,
- header->cfg_size);
-
- LTO_INIT_INPUT_BLOCK (ib_main,
- data + main_offset,
- 0,
- header->main_size);
}
else
{
main_offset = sizeof (struct lto_function_header);
string_offset = main_offset + header->main_size;
-
- LTO_INIT_INPUT_BLOCK (ib_main,
- data + main_offset,
- 0,
- header->main_size);
}
data_in = lto_data_in_create (file_data, data + string_offset,
--- 1062,1072 ----
*************** lto_read_body_or_constructor (struct lto
*** 1104,1111 ****
/* Set up the struct function. */
from = data_in->reader_cache->nodes.length ();
if (TREE_CODE (node->decl) == FUNCTION_DECL)
! input_function (fn_decl, data_in, &ib_main, &ib_cfg);
else
input_constructor (fn_decl, data_in, &ib_main);
/* And fixup types we streamed locally. */
--- 1087,1098 ----
/* Set up the struct function. */
from = data_in->reader_cache->nodes.length ();
+ lto_input_block ib_main (data + main_offset, header->main_size);
if (TREE_CODE (node->decl) == FUNCTION_DECL)
! {
! lto_input_block ib_cfg (data + cfg_offset, header->cfg_size);
! input_function (fn_decl, data_in, &ib_main, &ib_cfg);
! }
else
input_constructor (fn_decl, data_in, &ib_main);
/* And fixup types we streamed locally. */
*************** lto_input_toplevel_asms (struct lto_file
*** 1360,1366 ****
const struct lto_asm_header *header = (const struct lto_asm_header *) data;
int string_offset;
struct data_in *data_in;
- struct lto_input_block ib;
tree str;
if (! data)
--- 1347,1352 ----
*************** lto_input_toplevel_asms (struct lto_file
*** 1368,1377 ****
string_offset = sizeof (*header) + header->main_size;
! LTO_INIT_INPUT_BLOCK (ib,
! data + sizeof (*header),
! 0,
! header->main_size);
data_in = lto_data_in_create (file_data, data + string_offset,
header->string_size, vNULL);
--- 1354,1360 ----
string_offset = sizeof (*header) + header->main_size;
! lto_input_block ib (data + sizeof (*header), header->main_size);
data_in = lto_data_in_create (file_data, data + string_offset,
header->string_size, vNULL);
Index: gcc/lto/lto.c
===================================================================
*** gcc/lto/lto.c.orig 2014-07-29 13:04:48.255073822 +0200
--- gcc/lto/lto.c 2014-07-29 13:09:05.044056142 +0200
*************** lto_read_decls (struct lto_file_decl_dat
*** 1843,1856 ****
const int decl_offset = sizeof (struct lto_decl_header);
const int main_offset = decl_offset + header->decl_state_size;
const int string_offset = main_offset + header->main_size;
- struct lto_input_block ib_main;
struct data_in *data_in;
unsigned int i;
const uint32_t *data_ptr, *data_end;
uint32_t num_decl_states;
! LTO_INIT_INPUT_BLOCK (ib_main, (const char *) data + main_offset, 0,
! header->main_size);
data_in = lto_data_in_create (decl_data, (const char *) data + string_offset,
header->string_size, resolutions);
--- 1843,1855 ----
const int decl_offset = sizeof (struct lto_decl_header);
const int main_offset = decl_offset + header->decl_state_size;
const int string_offset = main_offset + header->main_size;
struct data_in *data_in;
unsigned int i;
const uint32_t *data_ptr, *data_end;
uint32_t num_decl_states;
! lto_input_block ib_main ((const char *) data + main_offset,
! header->main_size);
data_in = lto_data_in_create (decl_data, (const char *) data + string_offset,
header->string_size, resolutions);
*************** lto_read_decls (struct lto_file_decl_dat
*** 1859,1865 ****
internal types that should not be merged. */
/* Read the global declarations and types. */
! while (ib_main.p < ib_main.len)
{
tree t;
unsigned from = data_in->reader_cache->nodes.length ();
--- 1858,1864 ----
internal types that should not be merged. */
/* Read the global declarations and types. */
! while (!ib_main.eof ())
{
tree t;
unsigned from = data_in->reader_cache->nodes.length ();
Index: gcc/common.opt
===================================================================
*** gcc/common.opt.orig 2014-07-29 13:04:48.255073822 +0200
--- gcc/common.opt 2014-07-29 13:09:05.044056142 +0200
*************** Specify the algorithm to partition symbo
*** 1545,1551 ****
; The initial value of -1 comes from Z_DEFAULT_COMPRESSION in zlib.h.
flto-compression-level=
! Common Joined RejectNegative UInteger Var(flag_lto_compression_level) Init(-1)
-flto-compression-level=<number> Use zlib compression level <number> for IL
flto-report
--- 1545,1551 ----
; The initial value of -1 comes from Z_DEFAULT_COMPRESSION in zlib.h.
flto-compression-level=
! Common Joined RejectNegative UInteger Var(flag_lto_compression_level) Init(0)
-flto-compression-level=<number> Use zlib compression level <number> for IL
flto-report
More information about the Gcc-patches
mailing list