aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBill Maddox <maddox@google.com>2008-06-04 01:50:23 +0000
committerBill Maddox <maddox@google.com>2008-06-04 01:50:23 +0000
commit7b295708c1d8cd216c15aba31f4d1a38b16aa873 (patch)
treedc69b7d49da4214ccfcc05a676845b56293d83f3
parent55b5aefe0dcf7759b73f9dd8a2c31fc8aa19700d (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.lto16
-rw-r--r--gcc/lto-function-in.c89
-rw-r--r--gcc/lto-function-out.c92
-rw-r--r--gcc/lto-section-out.c10
-rw-r--r--gcc/lto-tree-flags.def6
-rw-r--r--gcc/lto/lto.c26
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]);
+ }
}
/* ### */