/* Write the GIMPLE representation to a file stream.
- Copyright 2009 Free Software Foundation, Inc.
+ Copyright 2009, 2010 Free Software Foundation, Inc.
Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>
Re-implemented by Diego Novillo <dnovillo@google.com>
/* Free the string slot pointed-to by P. */
-static void
+static void
string_slot_free (void *p)
{
struct string_slot *slot = (struct string_slot *) p;
bp_pack_value (bp, DECL_UNSIGNED (expr), 1);
else if (TYPE_P (expr))
bp_pack_value (bp, TYPE_UNSIGNED (expr), 1);
- bp_pack_value (bp, TREE_ASM_WRITTEN (expr), 1);
+ /* We write debug info two times, do not confuse the second one. */
+ bp_pack_value (bp, TYPE_P (expr) ? 0 : TREE_ASM_WRITTEN (expr), 1);
bp_pack_value (bp, TREE_NO_WARNING (expr), 1);
bp_pack_value (bp, TREE_USED (expr), 1);
bp_pack_value (bp, TREE_NOTHROW (expr), 1);
{
unsigned i;
REAL_VALUE_TYPE r;
-
+
r = TREE_REAL_CST (expr);
bp_pack_value (bp, r.cl, 2);
bp_pack_value (bp, r.decimal, 1);
if (TREE_CODE (expr) == VAR_DECL
|| TREE_CODE (expr) == PARM_DECL)
bp_pack_value (bp, DECL_HAS_VALUE_EXPR_P (expr), 1);
+ bp_pack_value (bp, DECL_RESTRICTED_P (expr), 1);
}
}
bp_pack_value (bp, TYPE_STRING_FLAG (expr), 1);
bp_pack_value (bp, TYPE_NO_FORCE_BLK (expr), 1);
bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING(expr), 1);
- if (TREE_CODE (expr) == UNION_TYPE)
- bp_pack_value (bp, TYPE_TRANSPARENT_UNION (expr), 1);
+ if (TREE_CODE (expr) == UNION_TYPE || TREE_CODE (expr) == RECORD_TYPE)
+ bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
bp_pack_value (bp, TYPE_PACKED (expr), 1);
bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
bp_pack_value (bp, TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr), 2);
output_string (ob, ob->main_stream, xloc.file);
output_sleb128 (ob, xloc.line);
output_sleb128 (ob, xloc.column);
+ output_sleb128 (ob, xloc.sysp);
ob->current_file = xloc.file;
ob->current_line = xloc.line;
{
if (TREE_CODE (t) == PARM_DECL)
return false;
- else if (TREE_CODE (t) == VAR_DECL && decl_function_context (t))
+ else if (TREE_CODE (t) == VAR_DECL && decl_function_context (t)
+ && !TREE_STATIC (t))
return false;
else
return (TYPE_P (t) || DECL_P (t) || TREE_CODE (t) == SSA_NAME);
break;
case VAR_DECL:
- gcc_assert (decl_function_context (expr) == NULL);
+ case DEBUG_EXPR_DECL:
+ gcc_assert (decl_function_context (expr) == NULL
+ || TREE_STATIC (expr));
output_record_start (ob, LTO_global_decl_ref);
lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
break;
lto_output_chain (struct output_block *ob, tree t, bool ref_p)
{
int i, count;
-
+
count = list_length (t);
output_sleb128 (ob, count);
for (i = 0; i < count; i++)
if (TREE_CODE (expr) == PARM_DECL)
lto_output_chain (ob, TREE_CHAIN (expr), ref_p);
+
+ if ((TREE_CODE (expr) == VAR_DECL
+ || TREE_CODE (expr) == PARM_DECL)
+ && DECL_HAS_VALUE_EXPR_P (expr))
+ lto_output_tree_or_ref (ob, DECL_VALUE_EXPR (expr), ref_p);
}
lto_output_tree_or_ref (ob, TYPE_BINFO (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_CONTEXT (expr), ref_p);
lto_output_tree_or_ref (ob, TYPE_CANONICAL (expr), ref_p);
+ lto_output_tree_or_ref (ob, TYPE_STUB_DECL (expr), ref_p);
}
}
if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
- {
- /* FIXME lto. Not handled yet. */
- gcc_unreachable ();
- }
+ sorry ("gimple bytecode streams do not support the optimization attribute");
if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
- {
- /* FIXME lto. Not handled yet. */
- gcc_unreachable ();
- }
+ sorry ("gimple bytecode streams do not support the target attribute");
}
{
gcc_assert (lto_stream_as_builtin_p (expr));
+ if (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_MD
+ && !targetm.builtin_decl)
+ sorry ("gimple bytecode streams do not support machine specific builtin "
+ "functions on this target");
+
output_record_start (ob, LTO_builtin_decl);
output_uleb128 (ob, DECL_BUILT_IN_CLASS (expr));
output_uleb128 (ob, DECL_FUNCTION_CODE (expr));
output_phi (struct output_block *ob, gimple phi)
{
unsigned i, len = gimple_phi_num_args (phi);
-
+
output_record_start (ob, lto_gimple_code_to_tag (GIMPLE_PHI));
output_uleb128 (ob, SSA_NAME_VERSION (PHI_RESULT (phi)));
gimple stmt = gsi_stmt (bsi);
output_gimple_stmt (ob, stmt);
-
+
/* Emit the EH region holding STMT. */
region = lookup_stmt_eh_lp_fn (fn, stmt);
if (region != 0)
/* Create the header in the file using OB. If the section type is for
a function, set FN to the decl for that function. */
-static void
+void
produce_asm (struct output_block *ob, tree fn)
{
enum lto_section_type section_type = ob->section_type;
/* The entire header is stream computed here. */
memset (&header, 0, sizeof (struct lto_function_header));
-
+
/* Write the header. */
header.lto_header.major_version = LTO_major_version;
header.lto_header.minor_version = LTO_minor_version;
header.lto_header.section_type = section_type;
-
+
header.compressed_size = 0;
-
+
if (section_type == LTO_section_function_body)
header.cfg_size = ob->cfg_stream->total_size;
header.main_size = ob->main_stream->total_size;
lto_output_bitpack (ob->main_stream, bp);
bitpack_delete (bp);
+ /* Output current IL state of the function. */
+ output_uleb128 (ob, fn->curr_properties);
+
/* Output the static chain and non-local goto save area. */
lto_output_tree_ref (ob, fn->static_chain_decl);
lto_output_tree_ref (ob, fn->nonlocal_goto_save_area);
/* Output all the local variables in the function. */
lto_output_tree_ref (ob, fn->local_decls);
+ /* Output the head of the arguments list. */
+ lto_output_tree_ref (ob, DECL_ARGUMENTS (function));
+
/* Output all the SSA names used in the function. */
output_ssa_names (ob, fn);
lexical scopes. */
lto_output_tree (ob, DECL_INITIAL (function), true);
- /* Output the head of the arguments list. */
- lto_output_tree_ref (ob, DECL_ARGUMENTS (function));
-
/* We will renumber the statements. The code that does this uses
the same ordering that we use for serializing them so we can use
the same code on the other end and not have to write out the
{
tree var = vnode->decl;
- if (TREE_CODE (var) == VAR_DECL && TREE_PUBLIC (var))
- lto_output_tree_ref (ob, var);
+ if (TREE_CODE (var) == VAR_DECL)
+ {
+ struct varpool_node *alias;
+
+ /* Output the object in order to output references used in the
+ initialization. */
+ lto_output_tree (ob, var, true);
+
+ /* If it is public we also need a reference to the object itself. */
+ if (TREE_PUBLIC (var))
+ lto_output_tree_ref (ob, var);
+
+ /* Also output any extra_name aliases for this variable. */
+ for (alias = vnode->extra_name; alias; alias = alias->next)
+ {
+ lto_output_tree (ob, alias->decl, true);
+ output_record_start (ob, LTO_var_decl_alias);
+ lto_output_var_decl_index (ob->decl_state, ob->main_stream,
+ alias->decl);
+ lto_output_var_decl_index (ob->decl_state, ob->main_stream,
+ var);
+ }
+ }
}
output_zero (ob);
VEC_safe_push (tree, heap, encoder->trees, trees[j]);
encoder->next_index = n;
}
-
+
lto_free_section_data (file_data, LTO_section_function_body, name,
data, len);
free (output_stream);
lto_output, /* write_summary */
NULL, /* read_summary */
NULL, /* function_read_summary */
+ NULL, /* stmt_fixup */
0, /* TODOs */
NULL, /* function_transform */
NULL /* variable_transform */
};
-/* Write each node in encoded by ENCODER to OB, as well as those reachable
+/* Write each node in encoded by ENCODER to OB, as well as those reachable
from it and required for correct representation of its semantics.
Each node in ENCODER must be a global declaration or a type. A node
is written only once, even if it appears multiple times in the
{
t = lto_tree_ref_encoder_get_tree (encoder, index);
if (!lto_streamer_cache_lookup (ob->writer_cache, t, NULL))
- {
- if (flag_wpa)
- {
- /* In WPA we should not emit multiple definitions of the
- same symbol to all the files in the link set. If
- T had already been emitted as the pervailing definition
- in one file, emit it as an external reference in the
- others. */
- /* FIXME lto. We should check if T belongs to the
- file we are writing to. */
- if (TREE_CODE (t) == VAR_DECL
- && TREE_PUBLIC (t)
- && !DECL_EXTERNAL (t))
- {
- /* FIXME lto. Make DECLS_ALREADY_EMITTED an argument
- to this function so it can be freed up afterwards.
- Alternately, assign global symbols to cgraph
- node sets. */
- static struct pointer_set_t *decls_already_emitted = NULL;
-
- if (decls_already_emitted == NULL)
- decls_already_emitted = pointer_set_create ();
-
- if (pointer_set_insert (decls_already_emitted, t))
- make_decl_one_only (t, DECL_ASSEMBLER_NAME (t));
- }
- }
+ lto_output_tree (ob, t, false);
- lto_output_tree (ob, t, false);
+ if (flag_wpa)
+ {
+ /* In WPA we should not emit multiple definitions of the
+ same symbol to all the files in the link set. If
+ T had already been emitted as the pervailing definition
+ in one file, do not emit it in the others. */
+ /* FIXME lto. We should check if T belongs to the
+ file we are writing to. */
+ if (TREE_CODE (t) == VAR_DECL
+ && TREE_PUBLIC (t)
+ && !DECL_EXTERNAL (t))
+ TREE_ASM_WRITTEN (t) = 1;
}
}
}
unsigned i;
int32_t ref;
tree decl;
-
+
/* Write reference to FUNCTION_DECL. If there is not function,
write reference to void_type_node. */
decl = (state->fn_decl) ? state->fn_decl : void_type_node;
break;
}
- if (kind == GCCPK_COMMON && DECL_SIZE (t))
+ if (kind == GCCPK_COMMON
+ && DECL_SIZE (t)
+ && TREE_CODE (DECL_SIZE (t)) == INTEGER_CST)
size = (((uint64_t) TREE_INT_CST_HIGH (DECL_SIZE (t))) << 32)
| TREE_INT_CST_LOW (DECL_SIZE (t));
else
needed. */
output_unreferenced_globals (set);
- memset (&header, 0, sizeof (struct lto_decl_header));
+ memset (&header, 0, sizeof (struct lto_decl_header));
section_name = lto_get_section_name (LTO_section_decls, NULL);
lto_begin_section (section_name, !flag_wpa);
lto_output_data_stream (header_stream, &header, sizeof header);
lto_write_stream (header_stream);
free (header_stream);
-
+
/* Write the main out-decl state, followed by out-decl states of
functions. */
decl_state_stream = ((struct lto_output_stream *)
lto_output_decl_state_refs (ob, decl_state_stream, fn_out_state);
}
lto_write_stream (decl_state_stream);
- free(decl_state_stream);
+ free(decl_state_stream);
lto_write_stream (ob->main_stream);
lto_write_stream (ob->string_stream);
produce_asm_for_decls, /* write_summary */
NULL, /* read_summary */
NULL, /* function_read_summary */
+ NULL, /* stmt_fixup */
0, /* TODOs */
NULL, /* function_transform */
NULL /* variable_transform */