diff options
author | Bill Maddox <maddox@google.com> | 2008-06-04 01:50:23 +0000 |
---|---|---|
committer | Bill Maddox <maddox@google.com> | 2008-06-04 01:50:23 +0000 |
commit | 7b295708c1d8cd216c15aba31f4d1a38b16aa873 (patch) | |
tree | dc69b7d49da4214ccfcc05a676845b56293d83f3 | |
parent | 55b5aefe0dcf7759b73f9dd8a2c31fc8aa19700d (diff) |
* lto-tree-flags.def: Add flags for LABEL_DECL.
* lto-function-out.c (output_label_decl): New function.
(output_tree): Make sure that we do not stream out
well-known nodes, even for node types for which we
would not necessarily force sharing. Reinstate handlers
for SWITCH_EXPR and CASE_LABEL. Add case for LABEL_DECL.
* lto-function-in.c (input_label_decl): New function.
(input_tree_operand): Reinstate handlers for
SWITCH_EXPR and CASE_LABEL. Add case for LABEL_DECL.
* lto-section-out.c (preload_common_nodes): Verify
that main_identifier_name is as expected by the reader.
* lto.c (preload_common_nodes): Initialize
main_identifier_node.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/lto-streamer@136350 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog.lto | 16 | ||||
-rw-r--r-- | gcc/lto-function-in.c | 89 | ||||
-rw-r--r-- | gcc/lto-function-out.c | 92 | ||||
-rw-r--r-- | gcc/lto-section-out.c | 10 | ||||
-rw-r--r-- | gcc/lto-tree-flags.def | 6 | ||||
-rw-r--r-- | gcc/lto/lto.c | 26 |
6 files changed, 225 insertions, 14 deletions
diff --git a/gcc/ChangeLog.lto b/gcc/ChangeLog.lto index 3472991695e..3e5ccaa7a3d 100644 --- a/gcc/ChangeLog.lto +++ b/gcc/ChangeLog.lto @@ -1,3 +1,19 @@ +2008-06-03 Bill Maddox <maddox@google.com> + + * lto-tree-flags.def: Add flags for LABEL_DECL. + * lto-function-out.c (output_label_decl): New function. + (output_tree): Make sure that we do not stream out + well-known nodes, even for node types for which we + would not necessarily force sharing. Reinstate handlers + for SWITCH_EXPR and CASE_LABEL. Add case for LABEL_DECL. + * lto-function-in.c (input_label_decl): New function. + (input_tree_operand): Reinstate handlers for + SWITCH_EXPR and CASE_LABEL. Add case for LABEL_DECL. + * lto-section-out.c (preload_common_nodes): Verify + that main_identifier_name is as expected by the reader. + * lto.c (preload_common_nodes): Initialize + main_identifier_node. + 2008-06-03 Diego Novillo <dnovillo@google.com> * lto-header.h: Tidy formatting. diff --git a/gcc/lto-function-in.c b/gcc/lto-function-in.c index 56e9e7cd74c..91bc41ea3e3 100644 --- a/gcc/lto-function-in.c +++ b/gcc/lto-function-in.c @@ -1702,7 +1702,7 @@ lto_static_init_local (void) } -/* Read the body form DATA for tree T and fill it in. File_data are +/* Read the body from DATA for tree T and fill it in. File_data are the global decls and types. SECTION_TYPE is either LTO_section_function_body or LTO_section_static_initializer. IF section type is LTO_section_function_body, FN must be the decl for @@ -2256,6 +2256,43 @@ input_type_decl (struct lto_input_block *ib, struct data_in *data_in) } static tree +input_label_decl (struct lto_input_block *ib, struct data_in *data_in) +{ + tree decl = make_node (LABEL_DECL); + + lto_flags_type flags = input_tree_flags (ib, LABEL_DECL, true); + if (input_line_info (ib, data_in, flags)) + set_line_info (data_in, decl); + process_tree_flags (decl, flags); + + global_vector_enter (data_in, decl); + + /* omit locus, uid */ + decl->decl_minimal.name = input_tree (ib, data_in); + decl->decl_minimal.context = input_tree (ib, data_in); + + decl->common.type = input_tree (ib, data_in); + + decl->decl_common.attributes = input_tree (ib, data_in); + decl->decl_common.abstract_origin = input_tree (ib, data_in); + + decl->decl_common.mode = lto_input_uleb128 (ib); + decl->decl_common.align = lto_input_uleb128 (ib); + /* omit off_align */ + + /*decl->decl_common.size = input_tree (ib, data_in);*/ + /*decl->decl_common.size_unit = input_tree (ib, data_in);*/ + + decl->decl_common.initial = input_tree (ib, data_in); + + /* lang_specific */ + /* omit rtl, incoming_rtl */ + /* omit chain */ + + return decl; +} + +static tree input_namespace_decl (struct lto_input_block *ib, struct data_in *data_in) { tree decl = make_node (NAMESPACE_DECL); @@ -2571,7 +2608,24 @@ input_tree_operand (struct lto_input_block *ib, struct data_in *data_in, case CASE_LABEL_EXPR: /* ### We shouldn't see these here. */ - gcc_unreachable (); + { + int variant = tag - LTO_case_label_expr0; + tree op0 = NULL_TREE; + tree op1 = NULL_TREE; + tree label; + + if (variant & 0x1) + op0 = input_tree_operand (ib, data_in, fn, input_record_start (ib)); + + if (variant & 0x2) + op1 = input_tree_operand (ib, data_in, fn, input_record_start (ib)); + + label = input_tree_operand (ib, data_in, fn, input_record_start (ib)); + gcc_assert (label && TREE_CODE (label) == LABEL_DECL); + + result = build3 (code, void_type_node, op0, op1, label); + } + break; case CONSTRUCTOR: { @@ -2660,8 +2714,22 @@ input_tree_operand (struct lto_input_block *ib, struct data_in *data_in, break; case LABEL_DECL: + result = input_label_decl (ib, data_in); + break; + case LABEL_EXPR: - gcc_unreachable (); + { + tree label; + label = input_tree_operand (ib, data_in, fn, + input_record_start (ib)); + gcc_assert (label && TREE_CODE (label) == LABEL_DECL); + result = build1 (code, void_type_node, label); + /* ### + if (!DECL_CONTEXT (LABEL_EXPR_LABEL (result))) + DECL_CONTEXT (LABEL_EXPR_LABEL (result)) = fn->decl; + */ + gcc_assert (DECL_CONTEXT (LABEL_EXPR_LABEL (result))); + } break; case COND_EXPR: @@ -2823,7 +2891,20 @@ input_tree_operand (struct lto_input_block *ib, struct data_in *data_in, case SWITCH_EXPR: /* ### We shouldn't see these here. */ - gcc_unreachable (); + { + unsigned int len = lto_input_uleb128 (ib); + unsigned int i; + tree op0 = input_tree_operand (ib, data_in, fn, + input_record_start (ib)); + tree op2 = make_tree_vec (len); + + for (i = 0; i < len; ++i) + TREE_VEC_ELT (op2, i) + = input_tree_operand (ib, data_in, fn, + input_record_start (ib)); + result = build3 (code, type, op0, NULL_TREE, op2); + } + break; case TREE_LIST: { diff --git a/gcc/lto-function-out.c b/gcc/lto-function-out.c index b66daa207f0..043c71ddc2e 100644 --- a/gcc/lto-function-out.c +++ b/gcc/lto-function-out.c @@ -2456,6 +2456,36 @@ output_type_decl (struct output_block *ob, tree decl) } static void +output_label_decl (struct output_block *ob, tree decl) +{ + /* tag and flags */ + output_global_record_start (ob, NULL, NULL, LTO_label_decl); + output_tree_flags (ob, 0, decl, true); + + /* uid and locus are handled specially */ + output_tree (ob, decl->decl_minimal.name); + output_tree (ob, decl->decl_minimal.context); + + output_tree (ob, decl->common.type); + + output_tree (ob, decl->decl_common.attributes); /* ??? */ + output_tree (ob, decl->decl_common.abstract_origin); /* ??? */ + + output_uleb128 (ob, decl->decl_common.mode); /* ??? */ + output_uleb128 (ob, decl->decl_common.align); /* ??? */ + gcc_assert (decl->decl_common.off_align == 0); + + gcc_assert (decl->decl_common.size == NULL_TREE); + gcc_assert (decl->decl_common.size_unit == NULL_TREE); + + output_tree (ob, decl->decl_common.initial); + + /* lang_specific */ + /* omit rtl, incoming_rtl */ + /* omit chain */ +} + +static void output_namespace_decl (struct output_block *ob, tree decl) { /* tag and flags */ @@ -2665,6 +2695,8 @@ output_tree (struct output_block *ob, tree expr) enum tree_code code; enum tree_code_class class; unsigned int tag; + void **slot; + struct lto_decl_slot d_slot; if (expr == NULL_TREE) { @@ -2680,8 +2712,6 @@ output_tree (struct output_block *ob, tree expr) if (TYPE_P (expr) || DECL_P (expr) || TREE_CODE (expr) == TREE_BINFO) { - void **slot; - struct lto_decl_slot d_slot; unsigned int global_index; struct lto_decl_slot *new_slot; @@ -2712,6 +2742,25 @@ output_tree (struct output_block *ob, tree expr) fprintf (stderr, "%p -> NEW %d\n", expr, new_slot->slot_num); #endif } + else + { + /* We don't share new instances of other classes of tree nodes, + but we always want to share the preloaded "well-known" nodes. */ + + d_slot.t = expr; + slot = htab_find_slot (ob->main_hash_table, &d_slot, NO_INSERT); + if (slot != NULL) + { + struct lto_decl_slot *old_slot = (struct lto_decl_slot *)*slot; +#ifdef GLOBAL_STREAMER_TRACE + fprintf (stderr, "%p -> OLD %d\n", expr, old_slot->slot_num); +#endif + output_global_record_start (ob, NULL, NULL, LTO_tree_pickle_reference); + output_uleb128 (ob, old_slot->slot_num); + LTO_DEBUG_UNDENT (); + return; + } + } code = TREE_CODE (expr); class = TREE_CODE_CLASS (code); @@ -2802,7 +2851,22 @@ output_tree (struct output_block *ob, tree expr) case CASE_LABEL_EXPR: /* ### We should not be seeing case labels here. */ - gcc_unreachable (); + { + int variant = 0; + if (CASE_LOW (expr) != NULL_TREE) + variant |= 0x1; + if (CASE_HIGH (expr) != NULL_TREE) + variant |= 0x2; + output_global_record_start (ob, expr, NULL, + LTO_case_label_expr0 + variant); + + if (CASE_LOW (expr) != NULL_TREE) + output_tree (ob, CASE_LOW (expr)); + if (CASE_HIGH (expr) != NULL_TREE) + output_tree (ob, CASE_HIGH (expr)); + output_tree (ob, CASE_LABEL (expr)); + } + break; case CONSTRUCTOR: output_global_constructor (ob, expr); @@ -2859,9 +2923,13 @@ output_tree (struct output_block *ob, tree expr) case LABEL_DECL: + output_label_decl (ob, expr); + break; + case LABEL_EXPR: - /* ### These should occur only within a function body. */ - gcc_unreachable (); + output_global_record_start (ob, expr, NULL, tag); + output_tree (ob, TREE_OPERAND (expr, 0)); + break; case COND_EXPR: if (TREE_OPERAND (expr, 1)) @@ -3026,7 +3094,19 @@ output_tree (struct output_block *ob, tree expr) case SWITCH_EXPR: /* ### We shouldn't see these here. */ - gcc_unreachable (); + { + tree label_vec = TREE_OPERAND (expr, 2); + size_t len = TREE_VEC_LENGTH (label_vec); + size_t i; + output_global_record_start (ob, expr, expr, tag); + output_uleb128 (ob, len); + output_tree (ob, TREE_OPERAND (expr, 0)); + gcc_assert (TREE_OPERAND (expr, 1) == NULL); + + for (i = 0; i < len; ++i) + output_tree (ob, TREE_VEC_ELT (label_vec, i)); + } + break; case TREE_LIST: { diff --git a/gcc/lto-section-out.c b/gcc/lto-section-out.c index 97a32a33d24..ba8a221ae0a 100644 --- a/gcc/lto-section-out.c +++ b/gcc/lto-section-out.c @@ -51,6 +51,7 @@ along with GCC; see the file COPYING3. If not see #include "lto-section-out.h" #include "lto-tree-out.h" #include <ctype.h> +#include <strings.h> /* Returns a hash code for P. */ @@ -493,6 +494,15 @@ static void preload_common_nodes (struct output_block *ob) { unsigned i; + + /* The MAIN_IDENTIFIER_NODE is normally set up by the front-end, but the + LTO back-end must agree. Currently, the only languages that set this + use the name "main". */ + if (main_identifier_node) + { + const char *main_name = IDENTIFIER_POINTER (main_identifier_node); + gcc_assert (strcmp (main_name, "main") == 0); + } for (i = 0; i < TI_MAX; i++) preload_common_node (ob, global_trees[i]); diff --git a/gcc/lto-tree-flags.def b/gcc/lto-tree-flags.def index 437cbe7995f..16bca62c696 100644 --- a/gcc/lto-tree-flags.def +++ b/gcc/lto-tree-flags.def @@ -428,8 +428,10 @@ END_EXPR_CASE (INTEGER_TYPE) START_EXPR_CASE (LABEL_DECL) - ADD_EXPR_FLAG (addressable_flag) - ADD_EXPR_FLAG (side_effects_flag) + ADD_EXPR_FLAG (addressable_flag) /* TREE_ADDRESSABLE */ + ADD_EXPR_FLAG (side_effects_flag) /* FORCED_LABEL */ + ADD_DECL_FLAG (nonlocal_flag) /* DECL_NONLOCAL */ + ADD_DECL_FLAG (decl_flag_0) /* DECL_ERROR_ISSUED */ END_EXPR_CASE (LABEL_DECL) START_EXPR_CASE (LABEL_EXPR) diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index fe6ebe56f3b..75c49abb6d0 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -118,10 +118,32 @@ preload_common_nodes (struct data_in *data_in) { unsigned i; + /* The global tree for the main identifier is filled in by language-specific + front-end initialization that is not run in the LTO back-end. It appears + that all languages that perform such initialization currently do so in the + same way, so we do it here. */ + if (!main_identifier_node) + main_identifier_node = get_identifier ("main"); + for (i = 0; i < TI_MAX; i++) - VEC_safe_push (tree, heap, data_in->globals_index, global_trees[i]); + { +#ifdef GLOBAL_STREAMER_TRACE + fprintf (stderr, "preloaded 0x%x: ", i); + print_generic_expr (stderr, global_trees[i], 0); + fprintf (stderr, "\n"); +#endif + VEC_safe_push (tree, heap, data_in->globals_index, global_trees[i]); + } + for (i = 0; i < itk_none; i++) - VEC_safe_push (tree, heap, data_in->globals_index, integer_types[i]); + { +#ifdef GLOBAL_STREAMER_TRACE + fprintf (stderr, "preloaded 0x%x: ", i); + print_generic_expr (stderr, integer_types[i], 0); + fprintf (stderr, "\n"); +#endif + VEC_safe_push (tree, heap, data_in->globals_index, integer_types[i]); + } } /* ### */ |