/* Functions for writing LTO sections.
- Copyright (C) 2009-2013 Free Software Foundation, Inc.
+ Copyright (C) 2009-2020 Free Software Foundation, Inc.
Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
This file is part of GCC.
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
+#include "backend.h"
+#include "rtl.h"
#include "tree.h"
-#include "expr.h"
-#include "params.h"
-#include "input.h"
-#include "hashtab.h"
-#include "basic-block.h"
-#include "tree-flow.h"
+#include "gimple.h"
#include "cgraph.h"
-#include "function.h"
-#include "ggc.h"
-#include "except.h"
-#include "vec.h"
-#include "pointer-set.h"
-#include "bitmap.h"
-#include "langhooks.h"
#include "data-streamer.h"
-#include "lto-streamer.h"
+#include "langhooks.h"
#include "lto-compress.h"
+#include "print-tree.h"
static vec<lto_out_decl_state_ptr> decl_state_stack;
{
lang_hooks.lto.begin_section (name);
- /* FIXME lto: for now, suppress compression if the lang_hook that appends
- data is anything other than assembler output. The effect here is that
- we get compression of IL only in non-ltrans object files. */
+ if (streamer_dump_file)
+ {
+ if (flag_dump_unnumbered || flag_dump_noaddr)
+ fprintf (streamer_dump_file, "Creating %ssection\n",
+ compress ? "compressed " : "");
+ else
+ fprintf (streamer_dump_file, "Creating %ssection %s\n",
+ compress ? "compressed " : "", name);
+ }
gcc_assert (compression_stream == NULL);
if (compress)
compression_stream = lto_start_compression (lto_append_data, NULL);
lang_hooks.lto.end_section ();
}
+/* Write SIZE bytes starting at DATA to the assembler. */
+
+void
+lto_write_data (const void *data, unsigned int size)
+{
+ if (compression_stream)
+ lto_compress_block (compression_stream, (const char *)data, size);
+ else
+ lang_hooks.lto.append_data ((const char *)data, size, NULL);
+}
+
+/* Write SIZE bytes starting at DATA to the assembler. */
+
+void
+lto_write_raw_data (const void *data, unsigned int size)
+{
+ lang_hooks.lto.append_data ((const char *)data, size, NULL);
+}
/* Write all of the chars in OBS to the assembler. Recycle the blocks
in obs as this is being done. */
if (!next_block)
num_chars -= obs->left_in_block;
- /* FIXME lto: WPA mode uses an ELF function as a lang_hook to append
- output data. This hook is not happy with the way that compression
- blocks up output differently to the way it's blocked here. So for
- now, we don't compress WPA output. */
if (compression_stream)
- {
- lto_compress_block (compression_stream, base, num_chars);
- lang_hooks.lto.append_data (NULL, 0, block);
- }
+ lto_compress_block (compression_stream, base, num_chars);
else
lang_hooks.lto.append_data (base, num_chars, block);
+ free (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;
- }
-}
-
-
/* 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
struct lto_tree_ref_encoder *encoder,
tree name, unsigned int *this_index)
{
- void **slot;
- int index;
bool new_entry_p = FALSE;
+ bool existed_p;
- slot = pointer_map_insert (encoder->tree_hash_table, name);
- if (*slot == NULL)
+ unsigned int &index
+ = encoder->tree_hash_table->get_or_insert (name, &existed_p);
+ if (!existed_p)
{
index = encoder->trees.length ();
- *slot = (void *)(uintptr_t) index;
+ if (streamer_dump_file)
+ {
+ print_node_brief (streamer_dump_file, " Encoding indexable ",
+ name, 4);
+ fprintf (streamer_dump_file, " as %i \n", index);
+ }
encoder->trees.safe_push (name);
new_entry_p = TRUE;
}
- else
- index = (uintptr_t) *slot;
if (obs)
streamer_write_uhwi_stream (obs, index);
{
char *section_name;
struct lto_simple_header header;
- struct lto_output_stream *header_stream;
- section_name = lto_get_section_name (ob->section_type, NULL, NULL);
+ section_name = lto_get_section_name (ob->section_type, NULL, 0, NULL);
lto_begin_section (section_name, !flag_wpa);
free (section_name);
/* Write the header which says how to decode the pieces of the
t. */
memset (&header, 0, sizeof (struct lto_simple_header));
- header.lto_header.major_version = LTO_major_version;
- header.lto_header.minor_version = LTO_minor_version;
-
- 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_data (&header, sizeof header);
lto_write_stream (ob->main_stream);
for (i = 0; i < LTO_N_DECL_STREAMS; i++)
lto_init_tree_ref_encoder (&state->streams[i]);
+ /* At WPA time we do not compress sections by default. */
+ state->compressed = !flag_wpa;
+
return state;
}
for (i = 0; i < LTO_N_DECL_STREAMS; i++)
if (state->streams[i].tree_hash_table)
{
- pointer_map_destroy (state->streams[i].tree_hash_table);
+ delete state->streams[i].tree_hash_table;
state->streams[i].tree_hash_table = NULL;
}
state->fn_decl = fn_decl;