summaryrefslogtreecommitdiff
path: root/gcc/lto-streamer-in.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/lto-streamer-in.c')
-rw-r--r--gcc/lto-streamer-in.c138
1 files changed, 109 insertions, 29 deletions
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 1330d606dc6..16947c7338b 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -195,7 +195,7 @@ lto_input_location (struct lto_input_block *ib, struct data_in *data_in)
TAG is the expected node that should be found in IB, if TAG belongs
to one of the indexable trees, expect to read a reference index to
be looked up in one of the symbol tables, otherwise read the pysical
- representation of the tree using lto_input_tree. FN is the
+ representation of the tree using stream_read_tree. FN is the
function scope for the read tree. */
tree
@@ -280,9 +280,9 @@ lto_input_eh_catch_list (struct lto_input_block *ib, struct data_in *data_in,
/* Read the catch node. */
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);
+ n->type_list = stream_read_tree (ib, data_in);
+ n->filter_list = stream_read_tree (ib, data_in);
+ n->label = stream_read_tree (ib, data_in);
/* Register all the types in N->FILTER_LIST. */
for (list = n->filter_list; list; list = TREE_CHAIN (list))
@@ -351,8 +351,8 @@ input_eh_region (struct lto_input_block *ib, struct data_in *data_in, int ix)
tree l;
r->type = ERT_ALLOWED_EXCEPTIONS;
- r->u.allowed.type_list = lto_input_tree (ib, data_in);
- r->u.allowed.label = lto_input_tree (ib, data_in);
+ r->u.allowed.type_list = stream_read_tree (ib, data_in);
+ r->u.allowed.label = stream_read_tree (ib, data_in);
r->u.allowed.filter = lto_input_uleb128 (ib);
for (l = r->u.allowed.type_list; l ; l = TREE_CHAIN (l))
@@ -362,7 +362,7 @@ input_eh_region (struct lto_input_block *ib, struct data_in *data_in, int ix)
case LTO_ert_must_not_throw:
r->type = ERT_MUST_NOT_THROW;
- r->u.must_not_throw.failure_decl = lto_input_tree (ib, data_in);
+ r->u.must_not_throw.failure_decl = stream_read_tree (ib, data_in);
r->u.must_not_throw.failure_loc = lto_input_location (ib, data_in);
break;
@@ -397,7 +397,7 @@ input_eh_lp (struct lto_input_block *ib, struct data_in *data_in, int ix)
gcc_assert (lp->index == ix);
lp->next_lp = (eh_landing_pad) (intptr_t) lto_input_sleb128 (ib);
lp->region = (eh_region) (intptr_t) lto_input_sleb128 (ib);
- lp->post_landing_pad = lto_input_tree (ib, data_in);
+ lp->post_landing_pad = stream_read_tree (ib, data_in);
return lp;
}
@@ -542,7 +542,7 @@ input_eh_regions (struct lto_input_block *ib, struct data_in *data_in,
VEC_safe_grow (tree, gc, fn->eh->ttype_data, len);
for (i = 0; i < len; i++)
{
- tree ttype = lto_input_tree (ib, data_in);
+ tree ttype = stream_read_tree (ib, data_in);
VEC_replace (tree, fn->eh->ttype_data, i, ttype);
}
}
@@ -557,7 +557,7 @@ input_eh_regions (struct lto_input_block *ib, struct data_in *data_in,
VEC_safe_grow (tree, gc, fn->eh->ehspec_data.arm_eabi, len);
for (i = 0; i < len; i++)
{
- tree t = lto_input_tree (ib, data_in);
+ tree t = stream_read_tree (ib, data_in);
VEC_replace (tree, fn->eh->ehspec_data.arm_eabi, i, t);
}
}
@@ -700,7 +700,7 @@ input_ssa_names (struct lto_input_block *ib, struct data_in *data_in,
VEC_quick_push (tree, SSANAMES (fn), NULL_TREE);
is_default_def = (lto_input_1_unsigned (ib) != 0);
- name = lto_input_tree (ib, data_in);
+ name = stream_read_tree (ib, data_in);
ssa_name = make_ssa_name_fn (fn, name, gimple_build_nop ());
if (is_default_def)
@@ -800,8 +800,8 @@ input_function (tree fn_decl, struct data_in *data_in,
fn->curr_properties = lto_input_uleb128 (ib);
/* Read the static chain and non-local goto save area. */
- fn->static_chain_decl = lto_input_tree (ib, data_in);
- fn->nonlocal_goto_save_area = lto_input_tree (ib, data_in);
+ fn->static_chain_decl = stream_read_tree (ib, data_in);
+ fn->nonlocal_goto_save_area = stream_read_tree (ib, data_in);
/* Read all the local symbols. */
len = lto_input_sleb128 (ib);
@@ -811,14 +811,14 @@ input_function (tree fn_decl, struct data_in *data_in,
VEC_safe_grow (tree, gc, fn->local_decls, len);
for (i = 0; i < len; i++)
{
- tree t = lto_input_tree (ib, data_in);
+ tree t = stream_read_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. */
- args = lto_input_tree (ib, data_in);
+ args = stream_read_tree (ib, data_in);
for (oarg = args, narg = DECL_ARGUMENTS (fn_decl);
oarg && narg;
oarg = TREE_CHAIN (oarg), narg = TREE_CHAIN (narg))
@@ -839,7 +839,7 @@ input_function (tree fn_decl, struct data_in *data_in,
input_eh_regions (ib, data_in, fn);
/* Read the tree of lexical scopes for the function. */
- DECL_INITIAL (fn_decl) = lto_input_tree (ib, data_in);
+ DECL_INITIAL (fn_decl) = stream_read_tree (ib, data_in);
gcc_assert (DECL_INITIAL (fn_decl));
DECL_SAVED_TREE (fn_decl) = NULL_TREE;
node = cgraph_get_create_node (fn_decl);
@@ -920,7 +920,7 @@ input_alias_pairs (struct lto_input_block *ib, struct data_in *data_in)
clear_line_info (data_in);
- var = lto_input_tree (ib, data_in);
+ var = stream_read_tree (ib, data_in);
while (var)
{
const char *orig_name, *new_name;
@@ -928,7 +928,7 @@ input_alias_pairs (struct lto_input_block *ib, struct data_in *data_in)
p = VEC_safe_push (alias_pair, gc, alias_pairs, NULL);
p->decl = var;
- p->target = lto_input_tree (ib, data_in);
+ p->target = stream_read_tree (ib, data_in);
/* If the target is a static object, we may have registered a
new name for it to avoid clashes between statics coming from
@@ -938,7 +938,7 @@ input_alias_pairs (struct lto_input_block *ib, struct data_in *data_in)
if (strcmp (orig_name, new_name) != 0)
p->target = get_identifier (new_name);
- var = lto_input_tree (ib, data_in);
+ var = stream_read_tree (ib, data_in);
}
}
@@ -1044,18 +1044,98 @@ lto_input_constructors_and_inits (struct lto_file_decl_data *file_data,
}
-/* LTO streamer hook for reading GIMPLE trees. IB and DATA_IN are as in
- lto_read_tree. EXPR is the tree was materialized by lto_read_tree and
- needs GIMPLE specific data to be filled in. */
+/* Read the physical representation of a tree node with tag TAG from
+ input block IB using the per-file context in DATA_IN. */
-void
-lto_streamer_read_tree (struct lto_input_block *ib, struct data_in *data_in,
- tree expr)
+static tree
+lto_read_tree (struct lto_input_block *ib, struct data_in *data_in,
+ enum LTO_tags tag)
{
- if (DECL_P (expr)
- && TREE_CODE (expr) != FUNCTION_DECL
- && TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
- DECL_INITIAL (expr) = lto_input_tree (ib, data_in);
+ /* Instantiate a new tree node. */
+ tree result = lto_materialize_tree (ib, data_in, tag);
+
+ /* Enter RESULT in the reader cache. This will make RESULT
+ available so that circular references in the rest of the tree
+ structure can be resolved in subsequent calls to stream_read_tree. */
+ lto_streamer_cache_append (data_in->reader_cache, result);
+
+ /* Read all the bitfield values in RESULT. Note that for LTO, we
+ only write language-independent bitfields, so no more unpacking is
+ needed. */
+ tree_read_bitfields (ib, result);
+
+ /* Read all the pointer fields in RESULT. */
+ lto_input_tree_pointers (ib, data_in, result);
+
+ /* Read any LTO-specific data not read by the tree streamer. */
+ if (DECL_P (result)
+ && TREE_CODE (result) != FUNCTION_DECL
+ && TREE_CODE (result) != TRANSLATION_UNIT_DECL)
+ DECL_INITIAL (result) = stream_read_tree (ib, data_in);
+
+ /* We should never try to instantiate an MD or NORMAL builtin here. */
+ if (TREE_CODE (result) == FUNCTION_DECL)
+ gcc_assert (!lto_stream_as_builtin_p (result));
+
+ /* end_marker = */ lto_input_1_unsigned (ib);
+
+#ifdef LTO_STREAMER_DEBUG
+ /* Remove the mapping to RESULT's original address set by
+ lto_materialize_tree. */
+ lto_orig_address_remove (result);
+#endif
+
+ return result;
+}
+
+
+/* Read a tree from input block IB using the per-file context in
+ DATA_IN. This context is used, for example, to resolve references
+ to previously read nodes. */
+
+tree
+lto_input_tree (struct lto_input_block *ib, struct data_in *data_in)
+{
+ enum LTO_tags tag;
+ tree result;
+
+ tag = input_record_start (ib);
+ gcc_assert ((unsigned) tag < (unsigned) LTO_NUM_TAGS);
+
+ if (tag == LTO_null)
+ result = NULL_TREE;
+ else if (tag >= LTO_field_decl_ref && tag <= LTO_global_decl_ref)
+ {
+ /* If TAG is a reference to an indexable tree, the next value
+ in IB is the index into the table where we expect to find
+ that tree. */
+ result = lto_input_tree_ref (ib, data_in, cfun, tag);
+ }
+ else if (tag == LTO_tree_pickle_reference)
+ {
+ /* If TAG is a reference to a previously read tree, look it up in
+ the reader cache. */
+ result = lto_get_pickled_tree (ib, data_in);
+ }
+ else if (tag == LTO_builtin_decl)
+ {
+ /* If we are going to read a built-in function, all we need is
+ the code and class. */
+ result = lto_get_builtin_tree (ib, data_in);
+ }
+ else if (tag == lto_tree_code_to_tag (INTEGER_CST))
+ {
+ /* For integer constants we only need the type and its hi/low
+ words. */
+ result = lto_input_integer_cst (ib, data_in);
+ }
+ else
+ {
+ /* Otherwise, materialize a new node from IB. */
+ result = lto_read_tree (ib, data_in, tag);
+ }
+
+ return result;
}