X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Flto-streamer-out.c;h=054bb85be0b4dfb11786897568f39cc123d1ab4f;hb=2c4ea188e808313c2ece0b5b1825324791c22fbe;hp=4d88f62d0913df93a1866f948d28da636cf38d4a;hpb=c59bc102442d6b5d31c35d6c38ebcde244d3b380;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c index 4d88f62d091..054bb85be0b 100644 --- a/gcc/lto-streamer-out.c +++ b/gcc/lto-streamer-out.c @@ -129,6 +129,16 @@ tree_is_indexable (tree t) else if (TREE_CODE (t) == VAR_DECL && decl_function_context (t) && !TREE_STATIC (t)) return false; + /* Variably modified types need to be streamed alongside function + bodies because they can refer to local entities. Together with + them we have to localize their members as well. + ??? In theory that includes non-FIELD_DECLs as well. */ + else if (TYPE_P (t) + && variably_modified_type_p (t, NULL_TREE)) + return false; + else if (TREE_CODE (t) == FIELD_DECL + && variably_modified_type_p (DECL_CONTEXT (t), NULL_TREE)) + return false; else return (TYPE_P (t) || DECL_P (t) || TREE_CODE (t) == SSA_NAME); } @@ -294,7 +304,6 @@ lto_is_streamable (tree expr) && code != WITH_CLEANUP_EXPR && code != STATEMENT_LIST && code != OMP_CLAUSE - && code != OPTIMIZATION_NODE && (code == CASE_LABEL_EXPR || code == DECL_EXPR || TREE_CODE_CLASS (code) != tcc_statement); @@ -360,11 +369,12 @@ lto_write_tree (struct output_block *ob, tree expr, bool ref_p) /* Emit the physical representation of tree node EXPR to output block - OB. If REF_P is true, the leaves of EXPR are emitted as references - via lto_output_tree_ref. */ + OB. If THIS_REF_P is true, the leaves of EXPR are emitted as references + via lto_output_tree_ref. REF_P is used for streaming siblings of EXPR. */ void -lto_output_tree (struct output_block *ob, tree expr, bool ref_p) +lto_output_tree (struct output_block *ob, tree expr, + bool ref_p, bool this_ref_p) { unsigned ix; bool existed_p; @@ -375,7 +385,7 @@ lto_output_tree (struct output_block *ob, tree expr, bool ref_p) return; } - if (ref_p && tree_is_indexable (expr)) + if (this_ref_p && tree_is_indexable (expr)) { lto_output_tree_ref (ob, expr); return; @@ -719,36 +729,30 @@ produce_asm (struct output_block *ob, tree fn) } -/* Output the body of function NODE->DECL. */ +/* Output the base body of struct function FN using output block OB. */ static void -output_function (struct cgraph_node *node) +output_struct_function_base (struct output_block *ob, struct function *fn) { struct bitpack_d bp; - tree function; - struct function *fn; - basic_block bb; - struct output_block *ob; unsigned i; tree t; - function = node->decl; - fn = DECL_STRUCT_FUNCTION (function); - ob = create_output_block (LTO_section_function_body); - - clear_line_info (ob); - ob->cgraph_node = node; - - gcc_assert (current_function_decl == NULL_TREE && cfun == NULL); + /* Output the static chain and non-local goto save area. */ + stream_write_tree (ob, fn->static_chain_decl, true); + stream_write_tree (ob, fn->nonlocal_goto_save_area, true); - /* Set current_function_decl and cfun. */ - current_function_decl = function; - push_cfun (fn); + /* Output all the local variables in the function. */ + streamer_write_hwi (ob, VEC_length (tree, fn->local_decls)); + FOR_EACH_VEC_ELT (tree, fn->local_decls, i, t) + stream_write_tree (ob, t, true); - /* Make string 0 be a NULL string. */ - streamer_write_char_stream (ob->string_stream, 0); + /* Output the function start and end loci. */ + lto_output_location (ob, fn->function_start_locus); + lto_output_location (ob, fn->function_end_locus); - streamer_write_record_start (ob, LTO_function); + /* Output current IL state of the function. */ + streamer_write_uhwi (ob, fn->curr_properties); /* Write all the attributes for FN. */ bp = bitpack_create (ob->main_stream); @@ -767,22 +771,38 @@ output_function (struct cgraph_node *node) bp_pack_value (&bp, fn->va_list_fpr_size, 8); bp_pack_value (&bp, fn->va_list_gpr_size, 8); streamer_write_bitpack (&bp); +} - /* Output the function start and end loci. */ - lto_output_location (ob, fn->function_start_locus); - lto_output_location (ob, fn->function_end_locus); - /* Output current IL state of the function. */ - streamer_write_uhwi (ob, fn->curr_properties); +/* Output the body of function NODE->DECL. */ - /* Output the static chain and non-local goto save area. */ - stream_write_tree (ob, fn->static_chain_decl, true); - stream_write_tree (ob, fn->nonlocal_goto_save_area, true); +static void +output_function (struct cgraph_node *node) +{ + tree function; + struct function *fn; + basic_block bb; + struct output_block *ob; - /* Output all the local variables in the function. */ - streamer_write_hwi (ob, VEC_length (tree, fn->local_decls)); - FOR_EACH_VEC_ELT (tree, fn->local_decls, i, t) - stream_write_tree (ob, t, true); + function = node->decl; + fn = DECL_STRUCT_FUNCTION (function); + ob = create_output_block (LTO_section_function_body); + + clear_line_info (ob); + ob->cgraph_node = node; + + gcc_assert (current_function_decl == NULL_TREE && cfun == NULL); + + /* Set current_function_decl and cfun. */ + current_function_decl = function; + push_cfun (fn); + + /* Make string 0 be a NULL string. */ + streamer_write_char_stream (ob->string_stream, 0); + + streamer_write_record_start (ob, LTO_function); + + output_struct_function_base (ob, fn); /* Output the head of the arguments list. */ stream_write_tree (ob, DECL_ARGUMENTS (function), true); @@ -1260,7 +1280,7 @@ write_symbol (struct streamer_tree_cache_d *cache, enum gcc_plugin_symbol_kind kind; enum gcc_plugin_symbol_visibility visibility; unsigned slot_num; - uint64_t size; + unsigned HOST_WIDEST_INT size; const char *comdat; unsigned char c; @@ -1318,7 +1338,7 @@ write_symbol (struct streamer_tree_cache_d *cache, when symbol has attribute (visibility("hidden")) specified. targetm.binds_local_p check DECL_VISIBILITY_SPECIFIED and gets this right. */ - + if (DECL_EXTERNAL (t) && !targetm.binds_local_p (t)) visibility = GCCPV_DEFAULT; @@ -1340,14 +1360,9 @@ write_symbol (struct streamer_tree_cache_d *cache, } if (kind == GCCPK_COMMON - && DECL_SIZE (t) - && TREE_CODE (DECL_SIZE (t)) == INTEGER_CST) - { - size = (HOST_BITS_PER_WIDE_INT >= 64) - ? (uint64_t) int_size_in_bytes (TREE_TYPE (t)) - : (((uint64_t) TREE_INT_CST_HIGH (DECL_SIZE_UNIT (t))) << 32) - | TREE_INT_CST_LOW (DECL_SIZE_UNIT (t)); - } + && DECL_SIZE_UNIT (t) + && TREE_CODE (DECL_SIZE_UNIT (t)) == INTEGER_CST) + size = TREE_INT_CST_LOW (DECL_SIZE_UNIT (t)); else size = 0; @@ -1420,11 +1435,7 @@ produce_symtab (struct output_block *ob, them indirectly or via vtables. Do not output them to symbol table: they end up being undefined and just consume space. */ if (!node->address_taken && !node->callers) - { - gcc_assert (node->analyzed); - gcc_assert (DECL_DECLARED_INLINE_P (node->decl)); - continue; - } + continue; if (DECL_COMDAT (node->decl) && cgraph_comdat_can_be_unshared_p (node)) continue;