Mercurial > hg > CbC > CbC_gcc
diff gcc/lto-streamer-in.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
line wrap: on
line diff
--- a/gcc/lto-streamer-in.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/lto-streamer-in.c Tue Mar 22 17:18:12 2011 +0900 @@ -355,6 +355,7 @@ case LTO_const_decl_ref: case LTO_imported_decl_ref: case LTO_label_decl_ref: + case LTO_translation_unit_decl_ref: ix_u = lto_input_uleb128 (ib); result = lto_file_decl_data_get_var_decl (data_in->file_data, ix_u); break; @@ -389,7 +390,7 @@ lto_tag_check_range (tag, LTO_eh_catch, LTO_eh_catch); /* Read the catch node. */ - n = GGC_CNEW (struct eh_catch_d); + n = ggc_alloc_cleared_eh_catch_d (); n->type_list = lto_input_tree (ib, data_in); n->filter_list = lto_input_tree (ib, data_in); n->label = lto_input_tree (ib, data_in); @@ -429,7 +430,7 @@ if (tag == LTO_null) return NULL; - r = GGC_CNEW (struct eh_region_d); + r = ggc_alloc_cleared_eh_region_d (); r->index = lto_input_sleb128 (ib); gcc_assert (r->index == ix); @@ -502,7 +503,7 @@ lto_tag_check_range (tag, LTO_eh_landing_pad, LTO_eh_landing_pad); - lp = GGC_CNEW (struct eh_landing_pad_d); + lp = ggc_alloc_cleared_eh_landing_pad_d (); lp->index = lto_input_sleb128 (ib); gcc_assert (lp->index == ix); lp->next_lp = (eh_landing_pad) (intptr_t) lto_input_sleb128 (ib); @@ -539,7 +540,7 @@ /* Convert all the index numbers stored in pointer fields into pointers to the corresponding slots in the EH region array. */ - for (i = 0; VEC_iterate (eh_region, eh_array, i, r); i++) + FOR_EACH_VEC_ELT (eh_region, eh_array, i, r) { /* The array may contain NULL regions. */ if (r == NULL) @@ -554,7 +555,7 @@ /* Convert all the index numbers stored in pointer fields into pointers to the corresponding slots in the EH landing pad array. */ - for (i = 0; VEC_iterate (eh_landing_pad, lp_array, i, lp); i++) + FOR_EACH_VEC_ELT (eh_landing_pad, lp_array, i, lp) { /* The array may contain NULL landing pads. */ if (lp == NULL) @@ -707,7 +708,7 @@ basic_block bb = alloc_block (); bb->index = index; SET_BASIC_BLOCK_FOR_FUNCTION (fn, index, bb); - bb->il.gimple = GGC_CNEW (struct gimple_bb_info); + bb->il.gimple = ggc_alloc_cleared_gimple_bb_info (); n_basic_blocks_for_function (fn)++; bb->flags = 0; set_bb_seq (bb, gimple_seq_alloc ()); @@ -718,7 +719,8 @@ /* Read the CFG for function FN from input block IB. */ static void -input_cfg (struct lto_input_block *ib, struct function *fn) +input_cfg (struct lto_input_block *ib, struct function *fn, + int count_materialization_scale) { unsigned int bb_count; basic_block p_bb; @@ -765,7 +767,8 @@ dest_index = lto_input_uleb128 (ib); probability = (int) lto_input_sleb128 (ib); - count = (gcov_type) lto_input_sleb128 (ib); + count = ((gcov_type) lto_input_sleb128 (ib) * count_materialization_scale + + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE; edge_flags = lto_input_uleb128 (ib); dest = BASIC_BLOCK_FOR_FUNCTION (fn, dest_index); @@ -872,124 +875,6 @@ } } - -/* Fixup the reference tree OP for replaced VAR_DECLs with mismatched - types. */ - -static void -maybe_fixup_handled_component (tree op) -{ - tree decl_type; - tree wanted_type; - - while (handled_component_p (TREE_OPERAND (op, 0))) - op = TREE_OPERAND (op, 0); - if (TREE_CODE (TREE_OPERAND (op, 0)) != VAR_DECL) - return; - - decl_type = TREE_TYPE (TREE_OPERAND (op, 0)); - - switch (TREE_CODE (op)) - { - case COMPONENT_REF: - /* The DECL_CONTEXT of the field-decl is the record type we look for. */ - wanted_type = DECL_CONTEXT (TREE_OPERAND (op, 1)); - break; - - case ARRAY_REF: - if (TREE_CODE (decl_type) == ARRAY_TYPE - && (TREE_TYPE (decl_type) == TREE_TYPE (op) - || useless_type_conversion_p (TREE_TYPE (op), - TREE_TYPE (decl_type)))) - return; - /* An unknown size array type should be ok. But we do not - lower the lower bound in all cases - ugh. */ - wanted_type = build_array_type (TREE_TYPE (op), NULL_TREE); - break; - - case ARRAY_RANGE_REF: - if (TREE_CODE (decl_type) == ARRAY_TYPE - && (TREE_TYPE (decl_type) == TREE_TYPE (TREE_TYPE (op)) - || useless_type_conversion_p (TREE_TYPE (TREE_TYPE (op)), - TREE_TYPE (decl_type)))) - return; - /* An unknown size array type should be ok. But we do not - lower the lower bound in all cases - ugh. */ - wanted_type = build_array_type (TREE_TYPE (TREE_TYPE (op)), NULL_TREE); - break; - - case BIT_FIELD_REF: - case VIEW_CONVERT_EXPR: - /* Very nice - nothing to do. */ - return; - - case REALPART_EXPR: - case IMAGPART_EXPR: - if (TREE_CODE (decl_type) == COMPLEX_TYPE - && (TREE_TYPE (decl_type) == TREE_TYPE (op) - || useless_type_conversion_p (TREE_TYPE (op), - TREE_TYPE (decl_type)))) - return; - wanted_type = build_complex_type (TREE_TYPE (op)); - break; - - default: - gcc_unreachable (); - } - - if (!useless_type_conversion_p (wanted_type, decl_type)) - TREE_OPERAND (op, 0) = build1 (VIEW_CONVERT_EXPR, wanted_type, - TREE_OPERAND (op, 0)); -} - -/* Fixup reference tree operands for substituted prevailing decls - with mismatched types in STMT. This handles plain DECLs where - we need the stmt for context to lookup the required type. */ - -static void -maybe_fixup_decls (gimple stmt) -{ - /* We have to fixup replaced decls here in case there were - inter-TU type mismatches. Catch the most common cases - for now - this way we'll get testcases for the rest as - the type verifier will complain. */ - if (gimple_assign_single_p (stmt)) - { - tree lhs = gimple_assign_lhs (stmt); - tree rhs = gimple_assign_rhs1 (stmt); - - /* First catch loads and aggregate copies by adjusting the rhs. */ - if (TREE_CODE (rhs) == VAR_DECL) - { - if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs))) - gimple_assign_set_rhs1 (stmt, build1 (VIEW_CONVERT_EXPR, - TREE_TYPE (lhs), rhs)); - } - /* Then catch scalar stores. */ - else if (TREE_CODE (lhs) == VAR_DECL) - { - if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs))) - gimple_assign_set_lhs (stmt, build1 (VIEW_CONVERT_EXPR, - TREE_TYPE (rhs), lhs)); - } - } - else if (is_gimple_call (stmt)) - { - tree lhs = gimple_call_lhs (stmt); - - if (lhs && TREE_CODE (lhs) == VAR_DECL) - { - if (!useless_type_conversion_p (TREE_TYPE (lhs), - gimple_call_return_type (stmt))) - gimple_call_set_lhs (stmt, build1 (VIEW_CONVERT_EXPR, - gimple_call_return_type (stmt), - lhs)); - } - - /* Arguments, especially for varargs functions will be funny... */ - } -} - /* Read a statement with tag TAG in function FN from block IB using descriptors in DATA_IN. */ @@ -1001,20 +886,19 @@ enum gimple_code code; unsigned HOST_WIDE_INT num_ops; size_t i; - struct bitpack_d *bp; + struct bitpack_d bp; code = lto_tag_to_gimple_code (tag); /* Read the tuple header. */ bp = lto_input_bitpack (ib); - num_ops = bp_unpack_value (bp, sizeof (unsigned) * 8); + num_ops = bp_unpack_value (&bp, sizeof (unsigned) * 8); stmt = gimple_alloc (code, num_ops); - stmt->gsbase.no_warning = bp_unpack_value (bp, 1); + stmt->gsbase.no_warning = bp_unpack_value (&bp, 1); if (is_gimple_assign (stmt)) - stmt->gsbase.nontemporal_move = bp_unpack_value (bp, 1); - stmt->gsbase.has_volatile_ops = bp_unpack_value (bp, 1); - stmt->gsbase.subcode = bp_unpack_value (bp, 16); - bitpack_delete (bp); + stmt->gsbase.nontemporal_move = bp_unpack_value (&bp, 1); + stmt->gsbase.has_volatile_ops = bp_unpack_value (&bp, 1); + stmt->gsbase.subcode = bp_unpack_value (&bp, 16); /* Read location information. */ gimple_set_location (stmt, lto_input_location (ib, data_in)); @@ -1065,21 +949,6 @@ if (!op) continue; - /* Fixup reference tree operands for substituted prevailing decls - with mismatched types. For plain VAR_DECLs we need to look - at context to determine the wanted type - we do that below - after the stmt is completed. */ - if (TREE_CODE (op) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (op, 0)) == VAR_DECL - && !useless_type_conversion_p (TREE_TYPE (TREE_TYPE (op)), - TREE_TYPE (op))) - { - TREE_OPERAND (op, 0) - = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (TREE_TYPE (op)), - TREE_OPERAND (op, 0)); - continue; - } - /* Fixup FIELD_DECLs in COMPONENT_REFs, they are not handled by decl merging. */ if (TREE_CODE (op) == ADDR_EXPR) @@ -1089,39 +958,65 @@ if (TREE_CODE (op) == COMPONENT_REF) { tree field, type, tem; + tree closest_match = NULL_TREE; field = TREE_OPERAND (op, 1); type = DECL_CONTEXT (field); for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) { - if (tem == field - || (TREE_TYPE (tem) == TREE_TYPE (field) - && DECL_NONADDRESSABLE_P (tem) - == DECL_NONADDRESSABLE_P (field) - && gimple_compare_field_offset (tem, field))) + if (tem == field) break; + if (DECL_NONADDRESSABLE_P (tem) + == DECL_NONADDRESSABLE_P (field) + && gimple_compare_field_offset (tem, field)) + { + if (types_compatible_p (TREE_TYPE (tem), + TREE_TYPE (field))) + break; + else + closest_match = tem; + } } /* In case of type mismatches across units we can fail to unify some types and thus not find a proper - field-decl here. So only assert here if checking - is enabled. */ -#ifdef ENABLE_CHECKING - gcc_assert (tem != NULL_TREE); -#endif - if (tem != NULL_TREE) + field-decl here. */ + if (tem == NULL_TREE) + { + /* Thus, emit a ODR violation warning. */ + if (warning_at (gimple_location (stmt), 0, + "use of type %<%E%> with two mismatching " + "declarations at field %<%E%>", + type, TREE_OPERAND (op, 1))) + { + if (TYPE_FIELDS (type)) + inform (DECL_SOURCE_LOCATION (TYPE_FIELDS (type)), + "original type declared here"); + inform (DECL_SOURCE_LOCATION (TREE_OPERAND (op, 1)), + "field in mismatching type declared here"); + if (TYPE_NAME (TREE_TYPE (field)) + && (TREE_CODE (TYPE_NAME (TREE_TYPE (field))) + == TYPE_DECL)) + inform (DECL_SOURCE_LOCATION + (TYPE_NAME (TREE_TYPE (field))), + "type of field declared here"); + if (closest_match + && TYPE_NAME (TREE_TYPE (closest_match)) + && (TREE_CODE (TYPE_NAME + (TREE_TYPE (closest_match))) == TYPE_DECL)) + inform (DECL_SOURCE_LOCATION + (TYPE_NAME (TREE_TYPE (closest_match))), + "type of mismatching field declared here"); + } + /* And finally fixup the types. */ + TREE_OPERAND (op, 0) + = build1 (VIEW_CONVERT_EXPR, type, + TREE_OPERAND (op, 0)); + } + else TREE_OPERAND (op, 1) = tem; } - /* Preserve the last handled component for the fixup of - its operand below. */ - if (!handled_component_p (TREE_OPERAND (op, 0))) - break; op = TREE_OPERAND (op, 0); } - - /* Fixup reference tree operands for substituted prevailing decls - with mismatched types. */ - if (handled_component_p (op)) - maybe_fixup_handled_component (op); } break; @@ -1161,10 +1056,6 @@ if (code == GIMPLE_CALL) gimple_call_reset_alias_info (stmt); - /* Fixup reference tree operands for substituted prevailing decls - with mismatched types. */ - maybe_fixup_decls (stmt); - /* Mark the statement modified so its operand vectors can be filled in. */ gimple_set_modified (stmt, true); @@ -1177,7 +1068,8 @@ static void input_bb (struct lto_input_block *ib, enum LTO_tags tag, - struct data_in *data_in, struct function *fn) + struct data_in *data_in, struct function *fn, + int count_materialization_scale) { unsigned int index; basic_block bb; @@ -1190,7 +1082,8 @@ index = lto_input_uleb128 (ib); bb = BASIC_BLOCK_FOR_FUNCTION (fn, index); - bb->count = lto_input_sleb128 (ib); + bb->count = (lto_input_sleb128 (ib) * count_materialization_scale + + REG_BR_PROB_BASE / 2) / REG_BR_PROB_BASE; bb->loop_depth = lto_input_sleb128 (ib); bb->frequency = lto_input_sleb128 (ib); bb->flags = lto_input_sleb128 (ib); @@ -1204,15 +1097,8 @@ while (tag) { gimple stmt = input_gimple_stmt (ib, data_in, fn, tag); - - /* Change debug stmts to nops on-the-fly if we do not have VTA enabled. - This allows us to build for example static libs with debugging - enabled and do the final link without. */ - if (!MAY_HAVE_DEBUG_STMTS - && is_gimple_debug (stmt)) - stmt = gimple_build_nop (); - - find_referenced_vars_in (stmt); + if (!is_gimple_debug (stmt)) + find_referenced_vars_in (stmt); gsi_insert_after (&bsi, stmt, GSI_NEW_STMT); /* After the statement, expect a 0 delimiter or the EH region @@ -1291,9 +1177,10 @@ enum LTO_tags tag; gimple *stmts; basic_block bb; - struct bitpack_d *bp; + struct bitpack_d bp; struct cgraph_node *node; tree args, narg, oarg; + int len; fn = DECL_STRUCT_FUNCTION (fn_decl); tag = input_record_start (ib); @@ -1304,21 +1191,25 @@ /* Read all the attributes for FN. */ bp = lto_input_bitpack (ib); - fn->is_thunk = bp_unpack_value (bp, 1); - fn->has_local_explicit_reg_vars = bp_unpack_value (bp, 1); - fn->after_tree_profile = bp_unpack_value (bp, 1); - fn->returns_pcc_struct = bp_unpack_value (bp, 1); - fn->returns_struct = bp_unpack_value (bp, 1); - fn->always_inline_functions_inlined = bp_unpack_value (bp, 1); - fn->after_inlining = bp_unpack_value (bp, 1); - fn->dont_save_pending_sizes_p = bp_unpack_value (bp, 1); - fn->stdarg = bp_unpack_value (bp, 1); - fn->has_nonlocal_label = bp_unpack_value (bp, 1); - fn->calls_alloca = bp_unpack_value (bp, 1); - fn->calls_setjmp = bp_unpack_value (bp, 1); - fn->va_list_fpr_size = bp_unpack_value (bp, 8); - fn->va_list_gpr_size = bp_unpack_value (bp, 8); - bitpack_delete (bp); + fn->is_thunk = bp_unpack_value (&bp, 1); + fn->has_local_explicit_reg_vars = bp_unpack_value (&bp, 1); + fn->after_tree_profile = bp_unpack_value (&bp, 1); + fn->returns_pcc_struct = bp_unpack_value (&bp, 1); + fn->returns_struct = bp_unpack_value (&bp, 1); + fn->can_throw_non_call_exceptions = bp_unpack_value (&bp, 1); + fn->always_inline_functions_inlined = bp_unpack_value (&bp, 1); + fn->after_inlining = bp_unpack_value (&bp, 1); + fn->dont_save_pending_sizes_p = bp_unpack_value (&bp, 1); + fn->stdarg = bp_unpack_value (&bp, 1); + fn->has_nonlocal_label = bp_unpack_value (&bp, 1); + fn->calls_alloca = bp_unpack_value (&bp, 1); + fn->calls_setjmp = bp_unpack_value (&bp, 1); + fn->va_list_fpr_size = bp_unpack_value (&bp, 8); + fn->va_list_gpr_size = bp_unpack_value (&bp, 8); + + /* Input the function start and end loci. */ + fn->function_start_locus = lto_input_location (ib, data_in); + fn->function_end_locus = lto_input_location (ib, data_in); /* Input the current IL state of the function. */ fn->curr_properties = lto_input_uleb128 (ib); @@ -1328,7 +1219,17 @@ fn->nonlocal_goto_save_area = lto_input_tree (ib, data_in); /* Read all the local symbols. */ - fn->local_decls = lto_input_tree (ib, data_in); + len = lto_input_sleb128 (ib); + if (len > 0) + { + int i; + VEC_safe_grow (tree, gc, fn->local_decls, len); + for (i = 0; i < len; i++) + { + tree t = lto_input_tree (ib, data_in); + VEC_replace (tree, fn->local_decls, i, t); + } + } /* Read all function arguments. We need to re-map them here to the arguments of the merged function declaration. */ @@ -1356,12 +1257,14 @@ DECL_INITIAL (fn_decl) = lto_input_tree (ib, data_in); gcc_assert (DECL_INITIAL (fn_decl)); DECL_SAVED_TREE (fn_decl) = NULL_TREE; + node = cgraph_node (fn_decl); /* Read all the basic blocks. */ tag = input_record_start (ib); while (tag) { - input_bb (ib, tag, data_in, fn); + input_bb (ib, tag, data_in, fn, + node->count_materialization_scale); tag = input_record_start (ib); } @@ -1371,11 +1274,26 @@ stmts = (gimple *) xcalloc (gimple_stmt_max_uid (fn), sizeof (gimple)); FOR_ALL_BB (bb) { - gimple_stmt_iterator bsi; - for (bsi = gsi_start_bb (bb); !gsi_end_p (bsi); gsi_next (&bsi)) + gimple_stmt_iterator bsi = gsi_start_bb (bb); + while (!gsi_end_p (bsi)) { gimple stmt = gsi_stmt (bsi); - stmts[gimple_uid (stmt)] = stmt; + /* If we're recompiling LTO objects with debug stmts but + we're not supposed to have debug stmts, remove them now. + We can't remove them earlier because this would cause uid + mismatches in fixups, but we can do it at this point, as + long as debug stmts don't require fixups. */ + if (!MAY_HAVE_DEBUG_STMTS && is_gimple_debug (stmt)) + { + gimple_stmt_iterator gsi = bsi; + gsi_next (&bsi); + gsi_remove (&gsi, true); + } + else + { + gsi_next (&bsi); + stmts[gimple_uid (stmt)] = stmt; + } } } @@ -1388,7 +1306,6 @@ gimple_set_body (fn_decl, bb_seq (ei_edge (ei)->dest)); } - node = cgraph_node (fn_decl); fixup_call_stmt_edges (node, stmts); execute_all_ipa_stmt_fixups (node, stmts); @@ -1481,6 +1398,7 @@ { struct function *fn = DECL_STRUCT_FUNCTION (fn_decl); struct lto_in_decl_state *decl_state; + struct cgraph_node *node = cgraph_node (fn_decl); push_cfun (fn); init_tree_ssa (fn); @@ -1490,7 +1408,7 @@ gcc_assert (decl_state); file_data->current_decl_state = decl_state; - input_cfg (&ib_cfg, fn); + input_cfg (&ib_cfg, fn, node->count_materialization_scale); /* Set up the struct function. */ input_function (fn_decl, data_in, &ib_main); @@ -1580,12 +1498,16 @@ so we skip it here. */ TREE_PUBLIC (expr) = (unsigned) bp_unpack_value (bp, 1); } + else + bp_unpack_value (bp, 4); TREE_ADDRESSABLE (expr) = (unsigned) bp_unpack_value (bp, 1); TREE_THIS_VOLATILE (expr) = (unsigned) bp_unpack_value (bp, 1); if (DECL_P (expr)) DECL_UNSIGNED (expr) = (unsigned) bp_unpack_value (bp, 1); else if (TYPE_P (expr)) TYPE_UNSIGNED (expr) = (unsigned) bp_unpack_value (bp, 1); + else + bp_unpack_value (bp, 1); TREE_ASM_WRITTEN (expr) = (unsigned) bp_unpack_value (bp, 1); TREE_NO_WARNING (expr) = (unsigned) bp_unpack_value (bp, 1); TREE_USED (expr) = (unsigned) bp_unpack_value (bp, 1); @@ -1596,8 +1518,10 @@ TREE_DEPRECATED (expr) = (unsigned) bp_unpack_value (bp, 1); if (TYPE_P (expr)) TYPE_SATURATING (expr) = (unsigned) bp_unpack_value (bp, 1); - if (TREE_CODE (expr) == SSA_NAME) + else if (TREE_CODE (expr) == SSA_NAME) SSA_NAME_IS_DEFAULT_DEF (expr) = (unsigned) bp_unpack_value (bp, 1); + else + bp_unpack_value (bp, 1); } @@ -1620,7 +1544,7 @@ for (i = 0; i < SIGSZ; i++) r.sig[i] = (unsigned long) bp_unpack_value (bp, HOST_BITS_PER_LONG); - rp = GGC_NEW (REAL_VALUE_TYPE); + rp = ggc_alloc_real_value (); memcpy (rp, &r, sizeof (REAL_VALUE_TYPE)); TREE_REAL_CST_PTR (expr) = rp; } @@ -1636,6 +1560,7 @@ fv.data.low = (HOST_WIDE_INT) bp_unpack_value (bp, HOST_BITS_PER_WIDE_INT); fv.data.high = (HOST_WIDE_INT) bp_unpack_value (bp, HOST_BITS_PER_WIDE_INT); + fv.mode = (enum machine_mode) bp_unpack_value (bp, HOST_BITS_PER_INT); TREE_FIXED_CST (expr) = fv; } @@ -1758,6 +1683,11 @@ DECL_DISREGARD_INLINE_LIMITS (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_PURE_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_LOOPING_CONST_OR_PURE_P (expr) = (unsigned) bp_unpack_value (bp, 1); + if (DECL_STATIC_DESTRUCTOR (expr)) + { + priority_type p = (priority_type) bp_unpack_value (bp, HOST_BITS_PER_SHORT); + SET_DECL_FINI_PRIORITY (expr, p); + } } @@ -1769,8 +1699,8 @@ { enum machine_mode mode; - TYPE_PRECISION (expr) = (unsigned) bp_unpack_value (bp, 9); - mode = (enum machine_mode) bp_unpack_value (bp, 7); + TYPE_PRECISION (expr) = (unsigned) bp_unpack_value (bp, 10); + mode = (enum machine_mode) bp_unpack_value (bp, 8); SET_TYPE_MODE (expr, mode); TYPE_STRING_FLAG (expr) = (unsigned) bp_unpack_value (bp, 1); TYPE_NO_FORCE_BLK (expr) = (unsigned) bp_unpack_value (bp, 1); @@ -1798,6 +1728,13 @@ BLOCK_NUMBER (expr) = (unsigned) bp_unpack_value (bp, 31); } +/* Unpack all the non-pointer fields of the TS_TRANSLATION_UNIT_DECL + structure of expression EXPR from bitpack BP. */ + +static void +unpack_ts_translation_unit_decl_value_fields (struct bitpack_d *bp ATTRIBUTE_UNUSED, tree expr ATTRIBUTE_UNUSED) +{ +} /* Unpack all the non-pointer fields in EXPR into a bit pack. */ @@ -1853,32 +1790,9 @@ /* This is only used by High GIMPLE. */ gcc_unreachable (); } -} - - -/* Read a bitpack from input block IB. */ - -struct bitpack_d * -lto_input_bitpack (struct lto_input_block *ib) -{ - unsigned i, num_words; - struct bitpack_d *bp; - - bp = bitpack_create (); - - /* If we are about to read more than a handful of words, something - is wrong. This check is overly strict, but it acts as an early - warning. No streamed object has hundreds of bits in its fields. */ - num_words = lto_input_uleb128 (ib); - gcc_assert (num_words < 20); - - for (i = 0; i < num_words; i++) - { - bitpack_word_t w = lto_input_uleb128 (ib); - VEC_safe_push (bitpack_word_t, heap, bp->values, w); - } - - return bp; + + if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL)) + unpack_ts_translation_unit_decl_value_fields (bp, expr); } @@ -1890,7 +1804,7 @@ lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in, enum LTO_tags tag, int *ix_p) { - struct bitpack_d *bp; + struct bitpack_d bp; enum tree_code code; tree result; #ifdef LTO_STREAMER_DEBUG @@ -1955,12 +1869,11 @@ /* The first word in BP contains the code of the tree that we are about to read. */ - code = (enum tree_code) bp_unpack_value (bp, 16); + code = (enum tree_code) bp_unpack_value (&bp, 16); lto_tag_check (lto_tree_code_to_tag (code), tag); /* Unpack all the value fields from BP. */ - unpack_value_fields (bp, result); - bitpack_delete (bp); + unpack_value_fields (&bp, result); /* Enter RESULT in the reader cache. This will make RESULT available so that circular references in the rest of the tree @@ -2007,7 +1920,8 @@ lto_input_ts_common_tree_pointers (struct lto_input_block *ib, struct data_in *data_in, tree expr) { - TREE_TYPE (expr) = lto_input_tree (ib, data_in); + if (TREE_CODE (expr) != IDENTIFIER_NODE) + TREE_TYPE (expr) = lto_input_tree (ib, data_in); } @@ -2061,11 +1975,14 @@ DECL_SIZE (expr) = lto_input_tree (ib, data_in); DECL_SIZE_UNIT (expr) = lto_input_tree (ib, data_in); - if (TREE_CODE (expr) != FUNCTION_DECL) + if (TREE_CODE (expr) != FUNCTION_DECL + && TREE_CODE (expr) != TRANSLATION_UNIT_DECL) DECL_INITIAL (expr) = lto_input_tree (ib, data_in); DECL_ATTRIBUTES (expr) = lto_input_tree (ib, data_in); - DECL_ABSTRACT_ORIGIN (expr) = lto_input_tree (ib, data_in); + /* Do not stream DECL_ABSTRACT_ORIGIN. We cannot handle debug information + for early inlining so drop it on the floor instead of ICEing in + dwarf2out.c. */ if (TREE_CODE (expr) == PARM_DECL) TREE_CHAIN (expr) = lto_input_chain (ib, data_in); @@ -2074,6 +1991,13 @@ || TREE_CODE (expr) == PARM_DECL) && DECL_HAS_VALUE_EXPR_P (expr)) SET_DECL_VALUE_EXPR (expr, lto_input_tree (ib, data_in)); + + if (TREE_CODE (expr) == VAR_DECL) + { + tree dexpr = lto_input_tree (ib, data_in); + if (dexpr) + SET_DECL_DEBUG_EXPR (expr, dexpr); + } } @@ -2172,8 +2096,6 @@ else if (TREE_CODE (expr) == FUNCTION_TYPE || TREE_CODE (expr) == METHOD_TYPE) TYPE_ARG_TYPES (expr) = lto_input_tree (ib, data_in); - else if (TREE_CODE (expr) == VECTOR_TYPE) - TYPE_DEBUG_REPRESENTATION_TYPE (expr) = lto_input_tree (ib, data_in); TYPE_SIZE (expr) = lto_input_tree (ib, data_in); TYPE_SIZE_UNIT (expr) = lto_input_tree (ib, data_in); @@ -2190,7 +2112,8 @@ if (RECORD_OR_UNION_TYPE_P (expr)) TYPE_BINFO (expr) = lto_input_tree (ib, data_in); TYPE_CONTEXT (expr) = lto_input_tree (ib, data_in); - TYPE_CANONICAL (expr) = lto_input_tree (ib, data_in); + /* TYPE_CANONICAL gets re-computed during type merging. */ + TYPE_CANONICAL (expr) = NULL_TREE; TYPE_STUB_DECL (expr) = lto_input_tree (ib, data_in); } @@ -2258,23 +2181,37 @@ lto_input_ts_block_tree_pointers (struct lto_input_block *ib, struct data_in *data_in, tree expr) { - unsigned i, len; - - BLOCK_SOURCE_LOCATION (expr) = lto_input_location (ib, data_in); + /* Do not stream BLOCK_SOURCE_LOCATION. We cannot handle debug information + for early inlining so drop it on the floor instead of ICEing in + dwarf2out.c. */ BLOCK_VARS (expr) = lto_input_chain (ib, data_in); - len = lto_input_uleb128 (ib); - for (i = 0; i < len; i++) - { - tree t = lto_input_tree (ib, data_in); - VEC_safe_push (tree, gc, BLOCK_NONLOCALIZED_VARS (expr), t); - } + /* Do not stream BLOCK_NONLOCALIZED_VARS. We cannot handle debug information + for early inlining so drop it on the floor instead of ICEing in + dwarf2out.c. */ BLOCK_SUPERCONTEXT (expr) = lto_input_tree (ib, data_in); - BLOCK_ABSTRACT_ORIGIN (expr) = lto_input_tree (ib, data_in); + /* Do not stream BLOCK_ABSTRACT_ORIGIN. We cannot handle debug information + for early inlining so drop it on the floor instead of ICEing in + dwarf2out.c. */ BLOCK_FRAGMENT_ORIGIN (expr) = lto_input_tree (ib, data_in); BLOCK_FRAGMENT_CHAIN (expr) = lto_input_tree (ib, data_in); - BLOCK_SUBBLOCKS (expr) = lto_input_chain (ib, data_in); + /* We re-compute BLOCK_SUBBLOCKS of our parent here instead + of streaming it. For non-BLOCK BLOCK_SUPERCONTEXTs we still + stream the child relationship explicitly. */ + if (BLOCK_SUPERCONTEXT (expr) + && TREE_CODE (BLOCK_SUPERCONTEXT (expr)) == BLOCK) + { + BLOCK_CHAIN (expr) = BLOCK_SUBBLOCKS (BLOCK_SUPERCONTEXT (expr)); + BLOCK_SUBBLOCKS (BLOCK_SUPERCONTEXT (expr)) = expr; + } + /* The global block is rooted at the TU decl. Hook it here to + avoid the need to stream in this block during WPA time. */ + else if (BLOCK_SUPERCONTEXT (expr) + && TREE_CODE (BLOCK_SUPERCONTEXT (expr)) == TRANSLATION_UNIT_DECL) + DECL_INITIAL (BLOCK_SUPERCONTEXT (expr)) = expr; + /* The function-level block is connected at the time we read in + function bodies for the same reason. */ } @@ -2308,10 +2245,14 @@ BINFO_VPTR_FIELD (expr) = lto_input_tree (ib, data_in); len = lto_input_uleb128 (ib); - for (i = 0; i < len; i++) + if (len > 0) { - tree a = lto_input_tree (ib, data_in); - VEC_safe_push (tree, gc, BINFO_BASE_ACCESSES (expr), a); + VEC_reserve_exact (tree, gc, BINFO_BASE_ACCESSES (expr), len); + for (i = 0; i < len; i++) + { + tree a = lto_input_tree (ib, data_in); + VEC_quick_push (tree, BINFO_BASE_ACCESSES (expr), a); + } } BINFO_INHERITANCE_CHAIN (expr) = lto_input_tree (ib, data_in); @@ -2342,6 +2283,34 @@ } +/* Input a TS_TARGET_OPTION tree from IB into EXPR. */ + +static void +lto_input_ts_target_option (struct lto_input_block *ib, tree expr) +{ + unsigned i, len; + struct bitpack_d bp; + struct cl_target_option *t = TREE_TARGET_OPTION (expr); + + bp = lto_input_bitpack (ib); + len = sizeof (struct cl_target_option); + for (i = 0; i < len; i++) + ((unsigned char *)t)[i] = bp_unpack_value (&bp, 8); + if (bp_unpack_value (&bp, 32) != 0x12345678) + fatal_error ("cl_target_option size mismatch in LTO reader and writer"); +} + +/* Input a TS_TRANSLATION_UNIT_DECL tree from IB and DATA_IN into EXPR. */ + +static void +lto_input_ts_translation_unit_decl_tree_pointers (struct lto_input_block *ib, + struct data_in *data_in, + tree expr) +{ + TRANSLATION_UNIT_LANGUAGE (expr) = xstrdup (input_string (data_in, ib)); + VEC_safe_push (tree, gc, all_translation_units, expr); +} + /* Helper for lto_input_tree. Read all pointer fields in EXPR from input block IB. DATA_IN contains tables and descriptors for the file being read. */ @@ -2426,9 +2395,10 @@ } if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)) - { - sorry ("target optimization options not supported yet"); - } + lto_input_ts_target_option (ib, expr); + + if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL)) + lto_input_ts_translation_unit_decl_tree_pointers (ib, data_in, expr); } @@ -2439,27 +2409,28 @@ static void lto_register_var_decl_in_symtab (struct data_in *data_in, tree decl) { - /* Register symbols with file or global scope to mark what input - file has their definition. */ - if (decl_function_context (decl) == NULL_TREE) + tree context; + + /* Variable has file scope, not local. Need to ensure static variables + between different files don't clash unexpectedly. */ + if (!TREE_PUBLIC (decl) + && !((context = decl_function_context (decl)) + && auto_var_in_fn_p (decl, context))) { - /* Variable has file scope, not local. Need to ensure static variables - between different files don't clash unexpectedly. */ - if (!TREE_PUBLIC (decl)) - { - /* ??? We normally pre-mangle names before we serialize them - out. Here, in lto1, we do not know the language, and - thus cannot do the mangling again. Instead, we just - append a suffix to the mangled name. The resulting name, - however, is not a properly-formed mangled name, and will - confuse any attempt to unmangle it. */ - const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - char *label; - - ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl)); - SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label)); - rest_of_decl_compilation (decl, 1, 0); - } + /* ??? We normally pre-mangle names before we serialize them + out. Here, in lto1, we do not know the language, and + thus cannot do the mangling again. Instead, we just + append a suffix to the mangled name. The resulting name, + however, is not a properly-formed mangled name, and will + confuse any attempt to unmangle it. */ + const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + char *label; + + ASM_FORMAT_PRIVATE_NAME (label, name, DECL_UID (decl)); + SET_DECL_ASSEMBLER_NAME (decl, get_identifier (label)); + rest_of_decl_compilation (decl, 1, 0); + + VEC_safe_push (tree, gc, lto_global_var_decls, decl); } /* If this variable has already been declared, queue the