Mercurial > hg > CbC > GCC_original
diff gcc/lto-section-out.c @ 16:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
line wrap: on
line diff
--- a/gcc/lto-section-out.c Sun Aug 21 07:07:55 2011 +0900 +++ b/gcc/lto-section-out.c Fri Oct 27 22:46:09 2017 +0900 @@ -1,6 +1,6 @@ /* Functions for writing LTO sections. - Copyright (C) 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2009-2017 Free Software Foundation, Inc. Contributed by Kenneth Zadeck <zadeck@naturalbridge.com> This file is part of GCC. @@ -22,85 +22,22 @@ #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 "tree-pass.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 "data-streamer.h" #include "langhooks.h" -#include "lto-streamer.h" #include "lto-compress.h" -static VEC(lto_out_decl_state_ptr, heap) *decl_state_stack; +static vec<lto_out_decl_state_ptr> decl_state_stack; /* List of out decl states used by functions. We use this to generate the decl directory later. */ -VEC(lto_out_decl_state_ptr, heap) *lto_function_decl_states; -/* Returns a hash code for P. */ - -hashval_t -lto_hash_decl_slot_node (const void *p) -{ - const struct lto_decl_slot *ds = (const struct lto_decl_slot *) p; - - /* - return (hashval_t) DECL_UID (ds->t); - */ - return (hashval_t) TREE_HASH (ds->t); -} - - -/* Returns nonzero if P1 and P2 are equal. */ - -int -lto_eq_decl_slot_node (const void *p1, const void *p2) -{ - const struct lto_decl_slot *ds1 = - (const struct lto_decl_slot *) p1; - const struct lto_decl_slot *ds2 = - (const struct lto_decl_slot *) p2; +vec<lto_out_decl_state_ptr> lto_function_decl_states; - /* - return DECL_UID (ds1->t) == DECL_UID (ds2->t); - */ - return ds1->t == ds2->t; -} - - -/* Returns a hash code for P. */ - -hashval_t -lto_hash_type_slot_node (const void *p) -{ - const struct lto_decl_slot *ds = (const struct lto_decl_slot *) p; - return (hashval_t) TYPE_UID (ds->t); -} - - -/* Returns nonzero if P1 and P2 are equal. */ - -int -lto_eq_type_slot_node (const void *p1, const void *p2) -{ - const struct lto_decl_slot *ds1 = - (const struct lto_decl_slot *) p1; - const struct lto_decl_slot *ds2 = - (const struct lto_decl_slot *) p2; - - return TYPE_UID (ds1->t) == TYPE_UID (ds2->t); -} /***************************************************************************** Output routines shared by all of the serialization passes. @@ -129,9 +66,6 @@ { 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. */ gcc_assert (compression_stream == NULL); if (compress) compression_stream = lto_start_compression (lto_append_data, NULL); @@ -151,6 +85,24 @@ 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. */ @@ -176,177 +128,16 @@ 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. */ - -static void -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 a character to the output block. */ - -void -lto_output_1_stream (struct lto_output_stream *obs, char c) -{ - /* No space left. */ - if (obs->left_in_block == 0) - append_block (obs); - - /* Write the actual character. */ - *obs->current_pointer = c; - obs->current_pointer++; - obs->total_size++; - obs->left_in_block--; -} - - -/* 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) - 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; - } -} - - -/* Output an unsigned LEB128 quantity to OBS. */ - -void -lto_output_uleb128_stream (struct lto_output_stream *obs, - unsigned HOST_WIDE_INT work) -{ - do - { - unsigned int byte = (work & 0x7f); - work >>= 7; - if (work != 0) - /* More bytes to follow. */ - byte |= 0x80; - - lto_output_1_stream (obs, byte); - } - while (work != 0); -} - -/* Identical to output_uleb128_stream above except using unsigned - HOST_WIDEST_INT type. For efficiency on host where unsigned HOST_WIDEST_INT - is not native, we only use this if we know that HOST_WIDE_INT is not wide - enough. */ - -void -lto_output_widest_uint_uleb128_stream (struct lto_output_stream *obs, - unsigned HOST_WIDEST_INT work) -{ - do - { - unsigned int byte = (work & 0x7f); - work >>= 7; - if (work != 0) - /* More bytes to follow. */ - byte |= 0x80; - - lto_output_1_stream (obs, byte); - } - while (work != 0); -} - - -/* Output a signed LEB128 quantity. */ - -void -lto_output_sleb128_stream (struct lto_output_stream *obs, HOST_WIDE_INT work) -{ - int more, byte; - - do - { - byte = (work & 0x7f); - /* arithmetic shift */ - work >>= 7; - more = !((work == 0 && (byte & 0x40) == 0) - || (work == -1 && (byte & 0x40) != 0)); - if (more) - byte |= 0x80; - - lto_output_1_stream (obs, byte); - } - 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 @@ -359,33 +150,20 @@ struct lto_tree_ref_encoder *encoder, tree name, unsigned int *this_index) { - void **slot; - struct lto_decl_slot d_slot; - int index; bool new_entry_p = FALSE; + bool existed_p; - d_slot.t = name; - slot = htab_find_slot (encoder->tree_hash_table, &d_slot, INSERT); - if (*slot == NULL) + unsigned int &index + = encoder->tree_hash_table->get_or_insert (name, &existed_p); + if (!existed_p) { - struct lto_decl_slot *new_slot - = (struct lto_decl_slot *) xmalloc (sizeof (struct lto_decl_slot)); - index = encoder->next_index++; - - new_slot->t = name; - new_slot->slot_num = index; - *slot = new_slot; - VEC_safe_push (tree, heap, encoder->trees, name); + index = encoder->trees.length (); + encoder->trees.safe_push (name); new_entry_p = TRUE; } - else - { - struct lto_decl_slot *old_slot = (struct lto_decl_slot *)*slot; - index = old_slot->slot_num; - } if (obs) - lto_output_uleb128_stream (obs, index); + streamer_write_uhwi_stream (obs, index); *this_index = index; return new_entry_p; } @@ -483,7 +261,6 @@ { 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); lto_begin_section (section_name, !flag_wpa); @@ -492,18 +269,10 @@ /* 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.lto_header.section_type = LTO_section_cgraph; - - header.compressed_size = 0; - + header.major_version = LTO_major_version; + header.minor_version = LTO_minor_version; 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); @@ -523,23 +292,12 @@ { struct lto_out_decl_state *state = XCNEW (struct lto_out_decl_state); int i; - htab_hash hash_fn; - htab_eq eq_fn; for (i = 0; i < LTO_N_DECL_STREAMS; i++) - { - if (i == LTO_DECL_STREAM_TYPE) - { - hash_fn = lto_hash_type_slot_node; - eq_fn = lto_eq_type_slot_node; - } - else - { - hash_fn = lto_hash_decl_slot_node; - eq_fn = lto_eq_decl_slot_node; - } - lto_init_tree_ref_encoder (&state->streams[i], hash_fn, eq_fn); - } + lto_init_tree_ref_encoder (&state->streams[i]); + + /* At WPA time we do not compress sections by default. */ + state->compressed = !flag_wpa; return state; } @@ -564,7 +322,7 @@ struct lto_out_decl_state * lto_get_out_decl_state (void) { - return VEC_last (lto_out_decl_state_ptr, decl_state_stack); + return decl_state_stack.last (); } /* Push STATE to top of out decl stack. */ @@ -572,7 +330,7 @@ void lto_push_out_decl_state (struct lto_out_decl_state *state) { - VEC_safe_push (lto_out_decl_state_ptr, heap, decl_state_stack, state); + decl_state_stack.safe_push (state); } /* Pop the currently used out-decl state from top of stack. */ @@ -580,7 +338,7 @@ struct lto_out_decl_state * lto_pop_out_decl_state (void) { - return VEC_pop (lto_out_decl_state_ptr, decl_state_stack); + return decl_state_stack.pop (); } /* Record STATE after it has been used in serializing the body of @@ -597,10 +355,9 @@ for (i = 0; i < LTO_N_DECL_STREAMS; i++) if (state->streams[i].tree_hash_table) { - htab_delete (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; - VEC_safe_push (lto_out_decl_state_ptr, heap, lto_function_decl_states, - state); + lto_function_decl_states.safe_push (state); }