This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[LTO]: patch committed to properly handle VAR_DECLs and FIELD_DECLs
- From: Kenneth Zadeck <zadeck at naturalbridge dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>, William Maddox <maddox at google dot com>, Jim Blandy <jimb at codesourcery dot com>, "Park, Seongbae" <seongbae dot park at gmail dot com>, "Hubicha, Jan" <jh at suse dot cz>, Mark Mitchell <mark at codesourcery dot com>
- Date: Tue, 28 Aug 2007 11:00:46 -0400
- Subject: [LTO]: patch committed to properly handle VAR_DECLs and FIELD_DECLs
This code gets the reading of local VAR_DECLs and FIELD_DECLs into shape.
The FIELD_DECL code just integrates Jim Brandy's last commit.
The VAR_DECLS required a lot of work:
1) A new section had to be added so that the VAR_DECLs could be read in
randomly. This is necessary because the tree for a VAR_DECL may contain
other VAR_DECLs so it is important to be able to reconstruct this bottom
up.
2) I had to initialize the unexpanded_var_list as i read in the
VAR_DECLs. Thanks Honza for pointing this out to me. The failure that
happens when this is not done is not obvious at all.
Kenny
2007-08-28 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto-function-out.c (output_block): Added
local_decl_index_stream, debug_decl_index_stream,
local_decls_index and local_decls_index_d.
(output_local_vars): Add code to write a seperate stream
containing the index of each local var.
(output_local_vars_index): New function.
(produce_asm, output_function): Write new streams.
(lto_static_init): Do not write flags or types for FIELD_DECLS.
* lto-tags.h (lto_debug_context): Added decl_index_data.
2007-08-28 Kenneth Zadeck <zadeck@naturalbridge.com>
*lto-read.c (fun_in): Added local_decls_index and
local_decls_index_d.
(input_expr_operand): Changed inputting of PARM_DECLs and VAR_DECLs.
(input_globals): Enabled code to handle FIELD_DECLs.
(input_local_vars_index, input_local_vars): New function.
(input_local_var): Changed to allow locals to be input randomly.
(lto_read_function_body): Added code to input the
local_decls_index and to free various structures.
committed as revision 127862.
Index: lto-function-out.c
===================================================================
--- lto-function-out.c (revision 127857)
+++ lto-function-out.c (working copy)
@@ -210,6 +210,8 @@ struct output_block
{
/* The stream that the main tree codes are written to. */
struct output_stream *main_stream;
+ /* The stream that contains the indexes for the local name table. */
+ struct output_stream *local_decl_index_stream;
/* The stream that contains the local name table. */
struct output_stream *local_decl_stream;
/* The stream that contains the names for the named_labels. */
@@ -222,6 +224,8 @@ struct output_block
struct output_stream *cfg_stream;
#ifdef LTO_STREAM_DEBUGGING
+ /* The stream that contains the local decls index debugging information. */
+ struct output_stream *debug_decl_index_stream;
/* The stream that contains the local decls debugging information. */
struct output_stream *debug_decl_stream;
/* The stream that contains the labels debugging information. */
@@ -245,6 +249,10 @@ struct output_block
we have seen so far and the indexes assigned to them. */
htab_t local_decl_hash_table;
unsigned int next_local_decl_index;
+ VEC(int,heap) *local_decls_index;
+#ifdef LTO_STREAM_DEBUGGING
+ VEC(int,heap) *local_decls_index_d;
+#endif
VEC(tree,heap) *local_decls;
/* The hash table that contains the set of field_decls we have
@@ -723,8 +731,13 @@ output_local_decl_ref (struct output_blo
/* Push the new local var or param onto a vector for later
processing. */
if (new)
- VEC_safe_push (tree, heap, ob->local_decls, name);
-
+ {
+ VEC_safe_push (tree, heap, ob->local_decls, name);
+ VEC_safe_push (int, heap, ob->local_decls_index, 0);
+#ifdef LTO_STREAM_DEBUGGING
+ VEC_safe_push (int, heap, ob->local_decls_index_d, 0);
+#endif
+ }
}
/* Look up LABEL in the type table and write the uleb128 index for it. */
@@ -1426,9 +1439,9 @@ output_local_vars (struct output_block *
unsigned int index = 0;
/* We have found MOST of the local vars by scanning the function.
- There is always the possibility that there may be some lurking on
- the fields (such as the two size fields) of the local vars that
- we must put out.
+ However, many local vars have other local vars inside them. So
+ this function uses the same mechanism that the function is output
+ in order to put out these local_vars.
The easiest way to get all of this stuff generated is to play
pointer games with the streams and reuse the code for putting out
@@ -1442,7 +1455,7 @@ output_local_vars (struct output_block *
while (index < VEC_length (tree, ob->local_decls))
{
- tree decl = VEC_index (tree, ob->local_decls, index++);
+ tree decl = VEC_index (tree, ob->local_decls, index);
unsigned int variant = 0;
bool is_var = (TREE_CODE (decl) == VAR_DECL);
bool needs_backing_var
@@ -1462,6 +1475,11 @@ output_local_vars (struct output_block *
: LTO_parm_decl_body0)
+ variant;
+ VEC_replace (int, ob->local_decls_index, index, ob->main_stream->total_size);
+#ifdef LTO_STREAM_DEBUGGING
+ VEC_replace (int, ob->local_decls_index_d, index, ob->debug_decl_stream->total_size);
+#endif
+ index++;
output_record_start (ob, NULL, NULL, tag);
/* Put out the name if there is one. */
@@ -1507,6 +1525,29 @@ output_local_vars (struct output_block *
}
+/* Output the local var_decls index and parm_decls index to OB. */
+
+static void
+output_local_vars_index (struct output_block *ob)
+{
+ unsigned int index = 0;
+ unsigned int stop;
+
+ struct output_stream *tmp_stream = ob->main_stream;
+ ob->main_stream = ob->local_decl_index_stream;
+
+ stop = VEC_length (int, ob->local_decls_index);
+ for (index = 0; index < stop; index++)
+ {
+ output_uleb128 (ob, VEC_index (int, ob->local_decls_index, index));
+#ifdef LTO_STREAM_DEBUGGING
+ output_uleb128 (ob, VEC_index (int, ob->local_decls_index_d, index));
+#endif
+ }
+ ob->main_stream = tmp_stream;
+}
+
+
/* Output the names in the named labels to the named_label stream. */
static void
@@ -1718,16 +1759,19 @@ produce_asm (struct output_block *ob, tr
function_header.named_label_size = ob->named_label_stream->total_size;
function_header.ssa_names_size = ob->ssa_names_stream->total_size;
function_header.cfg_size = ob->cfg_stream->total_size;
+ function_header.local_decls_index_size = ob->local_decl_index_stream->total_size;
function_header.local_decls_size = ob->local_decl_stream->total_size;
function_header.main_size = ob->main_stream->total_size;
function_header.string_size = ob->string_stream->total_size;
#ifdef LTO_STREAM_DEBUGGING
+ function_header.debug_decl_index_size = ob->debug_decl_index_stream->total_size;
function_header.debug_decl_size = ob->debug_decl_stream->total_size;
function_header.debug_label_size = ob->debug_label_stream->total_size;
function_header.debug_ssa_names_size = ob->debug_ssa_names_stream->total_size;
function_header.debug_cfg_size = ob->debug_cfg_stream->total_size;
function_header.debug_main_size = ob->debug_main_stream->total_size;
#else
+ function_header.debug_decl_index_size = -1;
function_header.debug_decl_size = -1;
function_header.debug_label_size = -1;
function_header.debug_ssa_names_size = -1;
@@ -1738,21 +1782,16 @@ produce_asm (struct output_block *ob, tr
assemble_string ((const char *)&function_header,
sizeof (struct lto_function_header));
- /* Write the global type references. */
+ /* Write the global function references. */
for (index = 0; VEC_iterate(tree, ob->field_decls, index, decl); index++)
{
-#ifdef GIMPLE_SYMBOL_TABLE_WORKS
- lto_field_ref (decl, out_ref);
-#else
- out_ref.section = 0;
- out_ref.base_label = "0";
- out_ref.label = "0";
-#endif
+ lto_field_ref (decl, &out_ref);
dw2_asm_output_data (8, out_ref.section, " ");
- dw2_asm_output_delta (8, out_ref.label, out_ref.base_label, " ");
+ dw2_asm_output_delta (8, out_ref.label,
+ out_ref.base_label, " ");
}
- /* Write the global type references. */
+ /* Write the global function references. */
for (index = 0; VEC_iterate(tree, ob->fn_decls, index, decl); index++)
{
lto_fn_ref (decl, &out_ref);
@@ -1761,7 +1800,7 @@ produce_asm (struct output_block *ob, tr
out_ref.base_label, " ");
}
- /* Write the global type references. */
+ /* Write the global var references. */
for (index = 0; VEC_iterate(tree, ob->var_decls, index, decl); index++)
{
lto_var_ref (decl, &out_ref);
@@ -1784,10 +1823,12 @@ produce_asm (struct output_block *ob, tr
write_stream (ob->named_label_stream);
write_stream (ob->ssa_names_stream);
write_stream (ob->cfg_stream);
+ write_stream (ob->local_decl_index_stream);
write_stream (ob->local_decl_stream);
write_stream (ob->main_stream);
write_stream (ob->string_stream);
#ifdef LTO_STREAM_DEBUGGING
+ write_stream (ob->debug_decl_index_stream);
write_stream (ob->debug_decl_stream);
write_stream (ob->debug_label_stream);
write_stream (ob->debug_ssa_names_stream);
@@ -1815,7 +1856,6 @@ lto_static_init (void)
lto_flags_needed_for = sbitmap_alloc (NUM_TREE_CODES);
sbitmap_ones (lto_flags_needed_for);
RESET_BIT (lto_flags_needed_for, FIELD_DECL);
- RESET_BIT (lto_flags_needed_for, FIELD_DECL);
RESET_BIT (lto_flags_needed_for, FUNCTION_DECL);
RESET_BIT (lto_flags_needed_for, PARM_DECL);
RESET_BIT (lto_flags_needed_for, SSA_NAME);
@@ -1828,6 +1868,7 @@ lto_static_init (void)
sbitmap_ones (lto_types_needed_for);
RESET_BIT (lto_types_needed_for, ASM_EXPR);
RESET_BIT (lto_types_needed_for, CASE_LABEL_EXPR);
+ RESET_BIT (lto_types_needed_for, FIELD_DECL);
RESET_BIT (lto_types_needed_for, GIMPLE_MODIFY_STMT);
RESET_BIT (lto_types_needed_for, LABEL_DECL);
RESET_BIT (lto_types_needed_for, LABEL_EXPR);
@@ -1913,6 +1954,7 @@ output_function (tree function)
ob->main_stream = xcalloc (1, sizeof (struct output_stream));
ob->string_stream = xcalloc (1, sizeof (struct output_stream));
+ ob->local_decl_index_stream = xcalloc (1, sizeof (struct output_stream));
ob->local_decl_stream = xcalloc (1, sizeof (struct output_stream));
ob->named_label_stream = xcalloc (1, sizeof (struct output_stream));
ob->ssa_names_stream = xcalloc (1, sizeof (struct output_stream));
@@ -1986,6 +2028,9 @@ output_function (tree function)
LTO_SET_DEBUGGING_STREAM (debug_decl_stream, decl_data)
output_local_vars (ob);
+ LTO_SET_DEBUGGING_STREAM (debug_decl_index_stream, decl_index_data)
+ output_local_vars_index (ob);
+
/* Create a file to hold the pickled output of this function. This
is a temp standin until we start writing sections. */
produce_asm (ob, function);
@@ -1997,6 +2042,8 @@ output_function (tree function)
htab_delete (ob->var_decl_hash_table);
htab_delete (ob->string_hash_table);
htab_delete (ob->type_hash_table);
+ VEC_free (int, heap, ob->local_decls_index);
+ VEC_free (int, heap, ob->local_decls_index_d);
VEC_free (tree, heap, ob->local_decls);
VEC_free (tree, heap, ob->field_decls);
VEC_free (tree, heap, ob->fn_decls);
Index: lto-tags.h
===================================================================
--- lto-tags.h (revision 127857)
+++ lto-tags.h (working copy)
@@ -39,20 +39,20 @@
The encoding for a function consists of 8 (9 in debugging mode),
sections of information.
- 1) The header.
- 2) FIELD_DECLS.
- 3) FUNCTION_DECLS.
- 4) global VAR_DECLS.
- 5) types.
- 6) Names for the labels that have names
- 7) The ssa names.
- 8) The control flow graph.
- 9) Gimple for local decls.
- 10)Gimple for the function.
- 11)Strings.
- 12-14)Redundant information to aid in debugging the stream.
- This is only present if the compiler is built with
- LTO_STREAM_DEBUGGING defined.
+ 1) The header.
+ 2) FIELD_DECLS.
+ 3) FUNCTION_DECLS.
+ 4) global VAR_DECLS.
+ 5) types.
+ 6) Names for the labels that have names
+ 7) The ssa names.
+ 8) The control flow graph.
+ 9-10) Gimple for local decls.
+ 11) Gimple for the function.
+ 12) Strings.
+ 13) Redundant information to aid in debugging the stream.
+ This is only present if the compiler is built with
+ LTO_STREAM_DEBUGGING defined.
Sections 1-5 are in plain text that can easily be read in the
assembly file. Sections 6-8 will be zlib encoded in the future.
@@ -76,9 +76,11 @@ struct lto_function_header
int32_t named_label_size; /* Size of names for named labels. */
int32_t ssa_names_size; /* Size of the SSA_NAMES table. */
int32_t cfg_size; /* Size of the cfg. */
+ int32_t local_decls_index_size; /* Size of local par and var decl index region. */
int32_t local_decls_size; /* Size of local par and var decl region. */
int32_t main_size; /* Size of main gimple body of function. */
int32_t string_size; /* Size of the string table. */
+ int32_t debug_decl_index_size; /* Size of local decl index debugging information. */
int32_t debug_decl_size; /* Size of local decl debugging information. */
int32_t debug_label_size; /* Size of label stream debugging information. */
int32_t debug_ssa_names_size; /* Size of ssa_names stream debugging information. */
@@ -113,7 +115,11 @@ struct lto_function_header
8) THE CFG.
- 9-10) GIMPLE FOR THE LOCAL DECLS AND THE FUNCTION BODY.
+ 9) Index into the local decls. Since local decls can have local
+ decls inside them, they must be read in randomly in order to
+ properly restore them.
+
+ 10-11) GIMPLE FOR THE LOCAL DECLS AND THE FUNCTION BODY.
The gimple consists of a set of records.
@@ -224,12 +230,12 @@ struct lto_function_header
to terminate the statements and exception
regions within this block.
- 11) STRINGS
+ 12) STRINGS
String are represented in the table as pairs, a length in ULEB128
form followed by the data for the string.
- 12) STREAM DEBUGGING
+ 13) STREAM DEBUGGING
If the preprocessor symbol LTO_STREAM_DEBUGGING is defined, the
gimple is encoded into .o file as two streams. The first stream
@@ -502,6 +508,7 @@ struct lto_debug_context
lto_debug_out out;
int indent;
void * current_data;
+ void * decl_index_data;
void * decl_data;
void * label_data;
void * ssa_names_data;
Index: lto/lto-read.c
===================================================================
--- lto/lto-read.c (revision 127857)
+++ lto/lto-read.c (working copy)
@@ -64,6 +64,10 @@ struct fun_in
tree *fn_decls; /* The function decls. */
tree *var_decls; /* The global or static var_decls. */
tree *types; /* All of the types. */
+ int *local_decls_index; /* The offsets to decode the local_decls. */
+#ifdef LTO_STREAM_DEBUGGING
+ int *local_decls_index_d; /* The offsets to decode the local_decls debug info. */
+#endif
tree *local_decls; /* The local var_decls and the parm_decls. */
tree *labels; /* All of the labels. */
const char * strings; /* The string table. */
@@ -91,6 +95,8 @@ static void dump_debug_stream (struct in
static tree
input_expr_operand (struct input_block *, struct fun_in *, struct function *,
enum LTO_tags);
+static tree
+input_local_var (struct fun_in *, struct input_block *, struct function *, unsigned int i);
/* Return the next character of input from IB. Abort if you
@@ -586,6 +592,7 @@ input_expr_operand (struct input_block *
break;
case VAR_DECL:
+ case PARM_DECL:
if (tag == LTO_var_decl1)
/* Static or externs are here. */
result = fun_in->var_decls [input_uleb128 (ib)];
@@ -594,23 +601,39 @@ input_expr_operand (struct input_block *
/* Locals are here. */
int lv_index = input_uleb128 (ib);
result = fun_in->local_decls [lv_index];
- /* There is a rare case where the local var decl in the
- table will be NULL. This is caused if the subtrees of
- var_decls reference other local var decls. Create an
- empty one now and the local decl reading code will fill
- in the fields later rather than creating its own. */
if (result == NULL)
{
- result = build_decl (VAR_DECL, NULL_TREE, NULL_TREE);
+ struct input_block lib;
+
+#ifdef LTO_STREAM_DEBUGGING
+ struct input_block *current = lto_debug_context.current_data;
+ struct input_block debug;
+ int current_indent = lto_debug_context.indent;
+
+ debug.data = current->data;
+ debug.len = current->len;
+ debug.p = fun_in->local_decls_index_d[lv_index];
+
+ lto_debug_context.indent = 0;
+ lto_debug_context.current_data = &debug;
+#endif
+
+ lib.data = ib->data;
+ lib.len = ib->len;
+ lib.p = fun_in->local_decls_index[lv_index];
+
+ result = input_local_var (fun_in, &lib, fn, lv_index);
fun_in->local_decls [lv_index] = result;
+
+#ifdef LTO_STREAM_DEBUGGING
+ lto_debug_context.indent = current_indent;
+ lto_debug_context.current_data = current;
+#endif
+
}
}
break;
- case PARM_DECL:
- result = fun_in->local_decls [input_uleb128 (ib)];
- break;
-
case LABEL_DECL:
result = get_label_decl (fun_in, ib);
break;
@@ -892,7 +915,7 @@ input_globals (struct lto_function_heade
lto_info_fd *fd,
lto_context *context,
struct fun_in *fun_in,
- lto_ref in_field_decls[] ATTRIBUTE_UNUSED,
+ lto_ref in_field_decls[],
lto_ref in_fn_decls[],
lto_ref in_var_decls[],
lto_ref in_types[])
@@ -903,14 +926,10 @@ input_globals (struct lto_function_heade
fun_in->var_decls = xcalloc (header->num_var_decls, sizeof (tree*));
fun_in->types = xcalloc (header->num_types, sizeof (tree*));
- /* FIXME: The test for zero section can go away when everything gets
- working. */
- /*
for (i=0; i<header->num_field_decls; i++)
if (in_field_decls[i].section)
fun_in->field_decls[i]
- = lto_resolve_field_ref (fd, context, in_field_decls[i]);
- */
+ = lto_resolve_field_ref (fd, context, &in_field_decls[i]);
for (i=0; i<header->num_fn_decls; i++)
if (in_fn_decls[i].section)
@@ -955,100 +974,147 @@ input_labels (struct fun_in *fun_in, str
= build_decl (LABEL_DECL, NULL_TREE, void_type_node);
}
-/* Load COUNT local var_decls and parm_decls from a DATA segment SIZE
- bytes long using FUN_IN. */
-static void
-input_local_vars (struct fun_in *fun_in, struct input_block *ib,
- struct function *fn, unsigned int count)
+/* Input the local var index table. */
+
+
+static void
+input_local_vars_index (struct fun_in *fun_in, struct input_block *ib,
+ unsigned int count)
{
unsigned int i;
+ fun_in->local_decls_index = xcalloc (count, sizeof (unsigned int));
+#ifdef LTO_STREAM_DEBUGGING
+ fun_in->local_decls_index_d = xcalloc (count, sizeof (unsigned int));
+#endif
- fun_in->local_decls = xcalloc (count, sizeof (tree*));
for (i = 0; i < count; i++)
{
- enum LTO_tags tag = input_record_start (ib);
- unsigned int variant = tag & 0xF;
- bool is_var = ((tag & 0xFFF0) == LTO_local_var_decl_body0);
+ fun_in->local_decls_index[i] = input_uleb128 (ib);
+#ifdef LTO_STREAM_DEBUGGING
+ fun_in->local_decls_index_d[i] = input_uleb128 (ib);
+#endif
+ }
+}
- unsigned int name_index;
- tree name;
- tree type;
- unsigned HOST_WIDE_INT flags;
- const char *new_file = NULL;
- int new_line = -1;
- tree result = fun_in->local_decls[i];
- name_index = input_uleb128 (ib);
- if (name_index)
- {
- unsigned int len;
- const char *s = input_string_internal (fun_in, name_index, &len);
- name = get_identifier_with_length (s, len);
- }
- else
- name = NULL_TREE;
+/* Input local var I from IB. */
- type = get_type_ref (fun_in, ib);
+static tree
+input_local_var (struct fun_in *fun_in, struct input_block *ib,
+ struct function *fn, unsigned int i)
+{
+ enum LTO_tags tag;
+ unsigned int variant;
+ bool is_var;
+ unsigned int name_index;
+ tree name;
+ tree type;
+ unsigned HOST_WIDE_INT flags;
+ const char *new_file = NULL;
+ int new_line = -1;
+ tree result;
- /* The result may not be NULL here because if any of the
- subtrees of some prior local var_decl referenced this local
- decl, a blank var decl would have been created and inserted
- here. However, the normal case is that it will be NULL. */
- if (result == NULL)
- {
- if (is_var)
- result = build_decl (VAR_DECL, name, type);
- else
- result = build_decl (PARM_DECL, name, type);
- }
- fun_in->local_decls[i] = result;
+ tag = input_record_start (ib);
+ variant = tag & 0xF;
+ is_var = ((tag & 0xFFF0) == LTO_local_var_decl_body0);
+
+ name_index = input_uleb128 (ib);
+ if (name_index)
+ {
+ unsigned int len;
+ const char *s = input_string_internal (fun_in, name_index, &len);
+ name = get_identifier_with_length (s, len);
+ }
+ else
+ name = NULL_TREE;
+
+ type = get_type_ref (fun_in, ib);
+ gcc_assert (type);
+
+ if (is_var)
+ result = build_decl (VAR_DECL, name, type);
+ else
+ result = build_decl (PARM_DECL, name, type);
- if (!is_var)
- DECL_ARG_TYPE (result) = get_type_ref (fun_in, ib);
+ fun_in->local_decls[i] = result;
+
+ if (!is_var)
+ DECL_ARG_TYPE (result) = get_type_ref (fun_in, ib);
+
+ LTO_DEBUG_TOKEN ("flags");
+ flags = input_uleb128 (ib);
+
+ /* FIXME: Need to figure out how to set the line number. */
+ if (flags & 0x2)
+ {
+ unsigned int len;
+ LTO_DEBUG_TOKEN ("file");
+ new_file = input_string_internal (fun_in, input_uleb128 (ib), &len);
+ }
+ if (flags & 0x1)
+ {
+ LTO_DEBUG_TOKEN ("line");
+ new_line = input_uleb128 (ib);
+ }
+
+ LTO_DEBUG_TOKEN ("align");
+ DECL_ALIGN (result) = input_uleb128 (ib);
+ LTO_DEBUG_TOKEN ("size");
+ DECL_SIZE (result)
+ = input_expr_operand (ib, fun_in, fn, input_record_start (ib));
+
+ if (variant & 0x1)
+ {
+ LTO_DEBUG_TOKEN ("attributes");
+ DECL_ATTRIBUTES (result)
+ = input_expr_operand (ib, fun_in, fn, input_record_start (ib));
+ }
+ if (variant & 0x2)
+ DECL_SIZE_UNIT (result)
+ = input_expr_operand (ib, fun_in, fn, input_record_start (ib));
+ if (variant & 0x4)
+ SET_DECL_DEBUG_EXPR (result,
+ input_expr_operand (ib, fun_in, fn,
+ input_record_start (ib)));
+ if (variant & 0x8)
+ DECL_ABSTRACT_ORIGIN (result)
+ = input_expr_operand (ib, fun_in, fn, input_record_start (ib));
+
+ process_flags (result, flags);
+ LTO_DEBUG_UNDENT();
- LTO_DEBUG_TOKEN ("flags");
- flags = input_uleb128 (ib);
+ /* Record the variable. */
+ if (is_var)
+ fn->unexpanded_var_list = tree_cons (NULL_TREE, result,
+ fn->unexpanded_var_list);
- /* FIXME: Need to figure out how to set the line number. */
- if (flags & 0x2)
- {
- unsigned int len;
- LTO_DEBUG_TOKEN ("file");
- new_file = input_string_internal (fun_in, input_uleb128 (ib), &len);
- }
- if (flags & 0x1)
- {
- LTO_DEBUG_TOKEN ("line");
- new_line = input_uleb128 (ib);
- }
+ return result;
+}
- LTO_DEBUG_TOKEN ("align");
- DECL_ALIGN (result) = input_uleb128 (ib);
- LTO_DEBUG_TOKEN ("size");
- DECL_SIZE (result)
- = input_expr_operand (ib, fun_in, fn, input_record_start (ib));
- if (variant & 0x1)
- {
- LTO_DEBUG_TOKEN ("attributes");
- DECL_ATTRIBUTES (result)
- = input_expr_operand (ib, fun_in, fn, input_record_start (ib));
- }
- if (variant & 0x2)
- DECL_SIZE_UNIT (result)
- = input_expr_operand (ib, fun_in, fn, input_record_start (ib));
- if (variant & 0x4)
- SET_DECL_DEBUG_EXPR (result,
- input_expr_operand (ib, fun_in, fn,
- input_record_start (ib)));
- if (variant & 0x8)
- DECL_ABSTRACT_ORIGIN (result)
- = input_expr_operand (ib, fun_in, fn, input_record_start (ib));
+/* Load COUNT local var_decls and parm_decls from a DATA segment SIZE
+ bytes long using FUN_IN. */
- process_flags (result, flags);
- LTO_DEBUG_UNDENT();
- }
+static void
+input_local_vars (struct fun_in *fun_in, struct input_block *ib,
+ struct function *fn, unsigned int count)
+{
+ unsigned int i;
+
+ fun_in->local_decls = xcalloc (count, sizeof (tree*));
+ for (i = 0; i < count; i++)
+ /* Some local decls may have already been read in if they are used
+ as part of a previous local_decl. */
+ if (!fun_in->local_decls[i])
+ {
+#ifdef LTO_STREAM_DEBUGGING
+ ((struct input_block *)lto_debug_context.current_data)->p
+ = fun_in->local_decls_index_d[i];
+#endif
+ ib->p = fun_in->local_decls_index[i];
+ input_local_var (fun_in, ib, fn, i);
+ }
}
@@ -1452,17 +1518,21 @@ lto_read_function_body (lto_info_fd *fd,
= named_label_offset + header->named_label_size;
int32_t cfg_offset
= ssa_names_offset + header->ssa_names_size;
- int32_t local_decls_offset = cfg_offset + header->cfg_size;
+ int32_t local_decls_index_offset = cfg_offset + header->cfg_size;
+ int32_t local_decls_offset = local_decls_index_offset + header->local_decls_index_size;
int32_t main_offset = local_decls_offset + header->local_decls_size;
int32_t string_offset = main_offset + header->main_size;
#ifdef LTO_STREAM_DEBUGGING
- int32_t debug_decl_offset = string_offset + header->string_size;
+ int32_t debug_decl_index_offset = string_offset + header->string_size;
+ int32_t debug_decl_offset = debug_decl_index_offset + header->debug_decl_index_size;
int32_t debug_label_offset = debug_decl_offset + header->debug_decl_size;
int32_t debug_ssa_names_offset = debug_label_offset + header->debug_label_size;
int32_t debug_cfg_offset = debug_ssa_names_offset + header->debug_ssa_names_size;
int32_t debug_main_offset = debug_cfg_offset + header->debug_cfg_size;
+ struct input_block debug_decl_index
+ = {data + debug_decl_index_offset, 0, header->debug_decl_index_size};
struct input_block debug_decl
= {data + debug_decl_offset, 0, header->debug_decl_size};
struct input_block debug_label
@@ -1489,6 +1559,8 @@ lto_read_function_body (lto_info_fd *fd,
= {data + ssa_names_offset, 0, header->ssa_names_size};
struct input_block ib_cfg
= {data + cfg_offset, 0, header->cfg_size};
+ struct input_block ib_local_decls_index
+ = {data + local_decls_index_offset, 0, header->local_decls_index_size};
struct input_block ib_local_decls
= {data + local_decls_offset, 0, header->local_decls_size};
struct input_block ib_main
@@ -1516,6 +1588,11 @@ lto_read_function_body (lto_info_fd *fd,
header->num_named_labels, header->num_unnamed_labels);
#ifdef LTO_STREAM_DEBUGGING
+ lto_debug_context.current_data = &debug_decl_index;
+#endif
+ input_local_vars_index (&fun_in, &ib_local_decls_index, header->num_local_decls);
+
+#ifdef LTO_STREAM_DEBUGGING
lto_debug_context.current_data = &debug_decl;
#endif
input_local_vars (&fun_in, &ib_local_decls, fn, header->num_local_decls);
@@ -1538,6 +1615,14 @@ lto_read_function_body (lto_info_fd *fd,
#endif
/* Set up the struct function. */
input_function (fn_decl, &fun_in, &ib_main);
+
+ free (fun_in.field_decls);
+ free (fun_in.fn_decls);
+ free (fun_in.var_decls);
+ free (fun_in.types);
+ free (fun_in.labels);
+ free (fun_in.local_decls_index);
+ free (fun_in.local_decls_index_d);
}
void