This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[lto]: PATCH committed to process ssa gimple.
- From: Kenneth Zadeck <zadeck at naturalbridge dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>, Mark Mitchell <mark at codesourcery dot com>, "Hubicha, Jan" <jh at suse dot cz>, "Novillo, Diego" <dnovillo at redhat dot com>
- Date: Fri, 13 Jul 2007 15:25:57 -0400
- Subject: [lto]: PATCH committed to process ssa gimple.
With this patch it is now possible to process this function:
extern int foo (int);
int foo (int a)
{
return a * 6;
}
By this i mean that the function can be compiled using the command:
./xgcc -c -O2 -flto ../../gccLTO/gcc/test2.c -o test2.o
and the output can be later processed by
./lto1 -O2 test2.o -o test2o.o
and we construct test2o.o without core dumping.
Note the lack of an assertion that the code in test2o.o is correct.
This patch creates a new variable in_lto_p which is true if called from
the lto front end. This is used to gate the passes that would normally
be run before the point where the lto code is written in the first step.
This patch is large because the point where we are both reading and
writing the lto code is after ssa form has been created. This not only
required that ssa form be supported, but required that the cfg be
processed first in order to build the phi function data structures.
Note that while the above program seems to work, the following program
does not.
extern int foo (void);
int foo (void)
{
int a = 2;
return a * 6;
}
the lto pass seems to blow up in mark's code with the message
test.o:0: fatal error: ELF symbol table does not contain ‘a’
compilation terminated.
This is most likely a nit and there are most certainly nits of
equivalent complexity in my code.
At this point, we should be reading and writing enough gimple to compile
c as long as there are no exception regions. As pointed out, while the
code is there, it is grossly undertested. What i do not know is if
enough of the types are being processed to try non trivial examples.
2007-07-13 Kenneth Zadeck <zadeck@naturalbridge.com>
* flags.h (in_lto_p): New flag.
* lto-tree_flags.def (CHANGE_DYNAMIC_TYPE_EXPR, POINTER_PLUS_EXPR):
New tree codes from merge.
* tree.h (init_ssanames): Added cfun parameter.
* lto-function-out.c: (ssa_names_stream, cfg_stream): New streams.
(output_eh_regions): Renamed parameter cfun to fn.
(output_expr_operand): Implemented SSA_NAME and GIMPLE_MODIFY_STMT
cases.
(output_local_vars): Set the local_vars stream locally.
(output_ssa_names, output_cfg, output_phi): New function.
(output_bb): Changed the cfun parameter to fn. Do not put out cfg
locally. Output the phi_functions.
(produce_asm): Add code to support ssa_names and cfg streams.
(lto_static_init): Added GIMPLE_MODIFY_STMT.
(LTO_SET_DEBUGGING_STREAM): New macro.
(output_function): Add code to support ssa_names and cfg streams.
* toplev.c (in_lto_p): Initialize.
* ipa-inline.c (cgraph_gate_ipa_early_inlining): Added test for
in_lto_p.
* lto-tree-tags.def (GIMPLE_MODIFY_STMT, PHI_NODE): New tags.
(LTO_change_dynamic_type_expr, LTO_gimple_modify_stmt,
LTO_phi_node, LTO_pointer_plus_expr): New names.
lto-tags.h (ssa_names_size, cfg_size, debug_ssa_names_size,
debug_cfg_size): New fields in lto_function_header.
(LTO_change_dynamic_type_expr, LTO_gimple_modify_stmt,
LTO_phi_node, LTO_pointer_plus_expr): New fields and renumbered
the rest.
(ssa_names_data, cfg_data): New fields of lto_debug_context.
* ipa.c (flags.h): New include.
(gate_ipa_fun_and_var_visibility): New function for
pass_ipa_function_and_variable_visibility.
* tree-ssa.c (init_tree_ssa): Add fn parameter and replaced refs
to cfun.
* tree-inline.c (initialize_cfun): Ditto.
* tree-optimize.c (gate_all_early_local_passes): Added ref to
in_ltp_p.
(execute_init_datastructures): Added cfun parameter to
init_tree_ssa.
* tree-flow.h (init_tree_ssa): Added struct function parameter.
* Makefile.in (ipa.o): Added FLAGS_H dependency.
* tree-ssanames.c (init_ssanames): Added two parameters. Now
takes struct function and default size.
2007-07-13 Kenneth Zadeck <zadeck@naturalbridge.com>
* lto-read.c (input_list, input_expr_operand): Added struct
function parameter.
(init_cfg, finalize_cfg): Removed function.
(input_expr_operand): Added SSA_NAME and GIMPLE_MODIFY_STMT cases.
(input_labels, input_local_vars): Now takes input_block parameter rather
than
synthsyzing it.
(input_cfg, input_phi, input_ssa_names): New functions.
(input_bb): Now passes in input_blocks. Does not construct cfg
and processes the list of phi functions.
(input_function): Now builds both the cfg and ssa_names table.
(lto_read_function_body): Processes new header fields to construct
streams for the ssa_names and cfg and their debugging.
* lto/lto-lang.c (lto_init): Set in_lto_p.
This has been committed to the lto branch as revision 126627.
Kenny
Index: flags.h
===================================================================
--- flags.h (revision 126565)
+++ flags.h (working copy)
@@ -111,6 +111,13 @@ extern int optimize;
extern int optimize_size;
+/* True if this is the lto front end. This is used to disable
+ gimple generation and lowering passes that are normally run on the
+ output of a front end. These passes must be bypassed for lto since
+ they have already been done before the gimple was written. */
+
+extern bool in_lto_p;
+
/* Do print extra warnings (such as for uninitialized variables).
-W/-Wextra. */
Index: lto-tree-flags.def
===================================================================
--- lto-tree-flags.def (revision 126565)
+++ lto-tree-flags.def (working copy)
@@ -218,6 +218,9 @@
START_EXPR_CASE (CEIL_MOD_EXPR)
END_EXPR_CASE (CEIL_MOD_EXPR)
+ START_EXPR_CASE (CHANGE_DYNAMIC_TYPE_EXPR)
+ END_EXPR_CASE (CHANGE_DYNAMIC_TYPE_EXPR)
+
START_EXPR_CASE (CLEANUP_POINT_EXPR)
END_EXPR_CASE (CLEANUP_POINT_EXPR)
@@ -508,6 +511,9 @@
START_EXPR_CASE (PLUS_EXPR)
END_EXPR_CASE (PLUS_EXPR)
+
+ START_EXPR_CASE (POINTER_PLUS_EXPR)
+ END_EXPR_CASE (POINTER_PLUS_EXPR)
START_EXPR_CASE (POINTER_TYPE)
ADD_EXPR_FLAG (static_flag)
Index: tree.h
===================================================================
--- tree.h (revision 126565)
+++ tree.h (working copy)
@@ -3695,7 +3695,7 @@ extern void release_phi_node (tree);
extern void phinodes_print_statistics (void);
#endif
-extern void init_ssanames (void);
+extern void init_ssanames (struct function *, int);
extern void fini_ssanames (void);
extern tree make_ssa_name (tree, tree);
extern tree duplicate_ssa_name (tree, tree);
Index: lto-function-out.c
===================================================================
--- lto-function-out.c (revision 126565)
+++ lto-function-out.c (working copy)
@@ -216,12 +216,21 @@ struct output_block
struct output_stream *named_label_stream;
/* The stream that contains the string table. */
struct output_stream *string_stream;
+ /* The stream that contains the ssa_names table. */
+ struct output_stream *ssa_names_stream;
+ /* The stream that contains the cfg. */
+ struct output_stream *cfg_stream;
+
#ifdef LTO_STREAM_DEBUGGING
- /* The stream that contains the stream debugging information. */
+ /* The stream that contains the local decls debugging information. */
struct output_stream *debug_decl_stream;
- /* The stream that contains the stream debugging information. */
+ /* The stream that contains the labels debugging information. */
struct output_stream *debug_label_stream;
- /* The stream that contains the stream debugging information. */
+ /* The stream that contains the ssa_names debugging information. */
+ struct output_stream *debug_ssa_names_stream;
+ /* The stream that contains the cfg debugging information. */
+ struct output_stream *debug_cfg_stream;
+ /* The stream that contains the gimple debugging information. */
struct output_stream *debug_main_stream;
#endif
@@ -934,12 +943,12 @@ output_eh_must_not_throw (void *obv,
/* Output the existing eh_table to OB. */
static void
-output_eh_regions (struct output_block *ob, struct function *cfun)
+output_eh_regions (struct output_block *ob, struct function *fn)
{
- if (0 && cfun->eh)
+ if (0 && fn->eh)
{
output_record_start (ob, NULL, NULL, LTO_eh_table);
- output_eh_records (ob, cfun,
+ output_eh_records (ob, fn,
output_eh_cleanup,
output_eh_try,
output_eh_catch,
@@ -1104,15 +1113,8 @@ output_expr_operand (struct output_block
break;
case SSA_NAME:
- /* FIXME: I am dead sure that this code is wrong for SSA
- names. But lto output is currently being done before SSA form
- is built so we can just fix it later. */
output_record_start (ob, expr, expr, LTO_ssa_name);
- output_local_decl_ref (ob, SSA_NAME_VAR (expr));
output_uleb128 (ob, SSA_NAME_VERSION (expr));
-
- /* Just to make sure that the comment above is headed. */
- gcc_unreachable ();
break;
case CONST_DECL:
@@ -1319,6 +1321,12 @@ output_expr_operand (struct output_block
}
break;
+ case GIMPLE_MODIFY_STMT:
+ output_record_start (ob, expr, NULL, tag);
+ output_expr_operand (ob, GIMPLE_STMT_OPERAND (expr, 0));
+ output_expr_operand (ob, GIMPLE_STMT_OPERAND (expr, 1));
+ break;
+
case SWITCH_EXPR:
{
tree label_vec = TREE_OPERAND (expr, 2);
@@ -1391,9 +1399,20 @@ output_local_vars (struct output_block *
{
unsigned int index = 0;
-#ifdef LTO_STREAM_DEBUGGING
- lto_debug_context.current_data = ob->debug_decl_stream;
-#endif
+ /* 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.
+
+ 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
+ the function bodies for putting out the local decls. It needs to
+ go into a separate stream because the LTO reader will want to
+ process the local variables first, rather than have to back patch
+ them.
+ */
+ struct output_stream *tmp_stream = ob->main_stream;
+ ob->main_stream = ob->local_decl_stream;
while (index < VEC_length (tree, ob->local_decls))
{
@@ -1457,6 +1476,8 @@ output_local_vars (struct output_block *
LTO_DEBUG_UNDENT()
}
+
+ ob->main_stream = tmp_stream;
}
@@ -1467,10 +1488,6 @@ output_named_labels (struct output_block
{
unsigned int index = 0;
-#ifdef LTO_STREAM_DEBUGGING
- lto_debug_context.current_data = ob->debug_label_stream;
-#endif
-
while (index < VEC_length (tree, ob->named_labels))
{
tree decl = VEC_index (tree, ob->named_labels, index++);
@@ -1482,37 +1499,116 @@ output_named_labels (struct output_block
}
-/* Output a basic block BB to the main stream in OB for this CFUN. */
+/* Output all of the active ssa names to the ssa_names stream. */
+
+static void
+output_ssa_names (struct output_block *ob, struct function *fn)
+{
+ /* Switch streams so we can use output_expr_operand to write the
+ SSA_NAME_VAR. */
+ struct output_stream *tmp_stream = ob->main_stream;
+ unsigned int i;
+ unsigned int len = VEC_length (tree, SSANAMES (fn));
+
+ ob->main_stream = ob->ssa_names_stream;
+
+ output_uleb128 (ob, len);
+
+ for (i = 1; i < len; i++)
+ {
+ tree ptr = VEC_index (tree, SSANAMES (fn), i);
+
+ if (ptr == NULL_TREE || SSA_NAME_IN_FREE_LIST (ptr))
+ continue;
+
+ output_uleb128 (ob, i);
+ output_expr_operand (ob, SSA_NAME_VAR (ptr));
+ }
+
+ output_uleb128 (ob, 0);
+ ob->main_stream = tmp_stream;
+}
+
+
+/* Output the cfg. */
+
+static void
+output_cfg (struct output_block *ob, struct function *fn)
+{
+ struct output_stream *tmp_stream = ob->main_stream;
+ basic_block bb;
+
+ ob->main_stream = ob->cfg_stream;
+
+ /* Output the number of the highest basic block. */
+ LTO_DEBUG_TOKEN ("lastbb")
+ output_uleb128 (ob, last_basic_block_for_function(fn));
+
+ FOR_ALL_BB_FN (bb, fn)
+ {
+ edge_iterator ei;
+ edge e;
+
+ LTO_DEBUG_TOKEN ("bbindex")
+ output_sleb128 (ob, bb->index);
+
+ /* Output the successors and the edge flags. */
+ LTO_DEBUG_TOKEN ("edgecount")
+ output_uleb128 (ob, EDGE_COUNT (bb->succs));
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ LTO_DEBUG_TOKEN ("dest")
+ output_uleb128 (ob, e->dest->index);
+ LTO_DEBUG_TOKEN ("eflags")
+ output_uleb128 (ob, e->flags);
+ }
+ }
+
+ LTO_DEBUG_TOKEN ("bbindex")
+ output_sleb128 (ob, -1);
+ ob->main_stream = tmp_stream;
+}
+
+
+/* Output a phi function to the main stream in OB. */
+
+static void
+output_phi (struct output_block *ob, tree expr)
+{
+ int len = PHI_NUM_ARGS (expr);
+ int i;
+
+ output_record_start (ob, expr, NULL, LTO_phi_node);
+ output_uleb128 (ob, SSA_NAME_VERSION (PHI_RESULT (expr)));
+
+ for (i = 0; i < len; i++)
+ {
+ output_uleb128 (ob, SSA_NAME_VERSION (PHI_ARG_DEF (expr, i)));
+ output_uleb128 (ob, PHI_ARG_EDGE (expr, i)->src->index);
+ }
+}
+
+
+/* Output a basic block BB to the main stream in OB for this FN. */
static void
-output_bb (struct output_block *ob, basic_block bb, struct function *cfun)
+output_bb (struct output_block *ob, basic_block bb, struct function *fn)
{
- edge e;
- edge_iterator ei;
block_stmt_iterator bsi = bsi_start (bb);
output_record_start (ob, NULL, NULL,
- bsi_end_p (bsi) ? LTO_bb0 : LTO_bb1);
+ (!bsi_end_p (bsi)) || phi_nodes (bb) ? LTO_bb1 : LTO_bb0);
/* The index of the basic block. */
LTO_DEBUG_TOKEN ("bbindex")
output_uleb128 (ob, bb->index);
- /* Output the successors and the edge flags. */
- LTO_DEBUG_TOKEN ("edgecount")
- output_uleb128 (ob, EDGE_COUNT (bb->succs));
- FOR_EACH_EDGE (e, ei, bb->succs)
- {
- LTO_DEBUG_TOKEN ("dest")
- output_uleb128 (ob, e->dest->index);
- LTO_DEBUG_TOKEN ("eflags")
- output_uleb128 (ob, e->flags);
- }
-
- if (!bsi_end_p (bsi))
+ if ((!bsi_end_p (bsi)) || phi_nodes (bb))
{
/* Output the statements. The list of statements is terminated
with a zero. */
+ tree phi;
+
for (bsi = bsi_start (bb);
!bsi_end_p (bsi); bsi_next (&bsi))
{
@@ -1526,7 +1622,7 @@ output_bb (struct output_block *ob, basi
last region number we set. */
if (0 && tree_could_throw_p (stmt))
{
- int region = lookup_stmt_eh_region_fn (cfun, stmt);
+ int region = lookup_stmt_eh_region_fn (fn, stmt);
if (region != last_eh_region_seen)
{
output_record_start (ob, NULL, NULL,
@@ -1541,7 +1637,17 @@ output_bb (struct output_block *ob, basi
LTO_DEBUG_INDENT_TOKEN ("stmt")
output_zero (ob);
+
+ for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+ {
+ LTO_DEBUG_INDENT_TOKEN ("phi")
+ output_phi (ob, phi);
+ }
+
+ LTO_DEBUG_INDENT_TOKEN ("phi")
+ output_zero (ob);
}
+
LTO_DEBUG_UNDENT()
}
@@ -1577,16 +1683,22 @@ produce_asm (struct output_block *ob, tr
function_header.compressed_size = 0;
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_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_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_size = -1;
function_header.debug_label_size = -1;
+ function_header.debug_ssa_names_size = -1;
+ function_header.debug_cfg_size = -1;
function_header.debug_main_size = -1;
#endif
@@ -1604,8 +1716,7 @@ produce_asm (struct output_block *ob, tr
out_ref.label = "0";
#endif
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. */
@@ -1644,12 +1755,16 @@ produce_asm (struct output_block *ob, tr
/* Put all of the gimple and the string table out the asm file as a
block of text. */
write_stream (ob->named_label_stream);
+ write_stream (ob->ssa_names_stream);
+ write_stream (ob->cfg_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_stream);
write_stream (ob->debug_label_stream);
+ write_stream (ob->debug_ssa_names_stream);
+ write_stream (ob->debug_cfg_stream);
write_stream (ob->debug_main_stream);
#endif
}
@@ -1685,6 +1800,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, GIMPLE_MODIFY_STMT);
RESET_BIT (lto_types_needed_for, LABEL_DECL);
RESET_BIT (lto_types_needed_for, LABEL_EXPR);
RESET_BIT (lto_types_needed_for, MODIFY_EXPR);
@@ -1746,30 +1862,34 @@ lto_static_init_local (void)
static int function_num;
#endif
-/* Output CFUN. */
+#ifdef LTO_STREAM_DEBUGGING
+#define LTO_SET_DEBUGGING_STREAM(STREAM,CONTEXT) \
+{ \
+ ob-> STREAM = xcalloc (1, sizeof (struct output_stream)); \
+ lto_debug_context. CONTEXT = ob-> STREAM; \
+ lto_debug_context.current_data = ob-> STREAM; \
+}
+#else
+#define LTO_SET_DEBUGGING_STREAM(STREAM,CONTEXT)
+#endif
+
+/* Output FN. */
static void
output_function (tree function)
{
- struct function *this_cfun = DECL_STRUCT_FUNCTION (function);
+ struct function *fn = DECL_STRUCT_FUNCTION (function);
basic_block bb;
- struct output_stream *tmp_stream;
-
struct output_block *ob = xcalloc (1, sizeof (struct output_block));
+
ob->main_stream = xcalloc (1, sizeof (struct output_stream));
ob->string_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));
+ ob->cfg_stream = xcalloc (1, sizeof (struct output_stream));
#ifdef LTO_STREAM_DEBUGGING
- ob->debug_decl_stream = xcalloc (1, sizeof (struct output_stream));
- ob->debug_label_stream = xcalloc (1, sizeof (struct output_stream));
- ob->debug_main_stream = xcalloc (1, sizeof (struct output_stream));
-
- lto_debug_context.out = &debug_out_fun;
- lto_debug_context.decl_data = ob->debug_decl_stream;
- lto_debug_context.label_data = ob->debug_label_stream;
- lto_debug_context.main_data = ob->debug_main_stream;
- lto_debug_context.current_data = ob->debug_main_stream;
+ lto_debug_context.out = debug_out_fun;
lto_debug_context.indent = 0;
#endif
@@ -1797,6 +1917,9 @@ output_function (tree function)
/* The unnamed labels must all be negative. */
ob->next_unnamed_label_index = -1;
+
+ LTO_SET_DEBUGGING_STREAM (debug_main_stream, main_data)
+
/* Make string 0 be a NULL string. */
output_1_stream (ob->string_stream, 0);
@@ -1805,38 +1928,27 @@ output_function (tree function)
output_record_start (ob, NULL, NULL, LTO_function);
/* Output any exception-handling regions. */
- output_eh_regions (ob, this_cfun);
-
- /* Output the number of the highest basic block. */
- output_uleb128 (ob, last_basic_block_for_function(this_cfun));
+ output_eh_regions (ob, fn);
/* Output the code for the function. */
- FOR_ALL_BB_FN (bb, this_cfun)
- output_bb (ob, bb, this_cfun);
+ FOR_ALL_BB_FN (bb, fn)
+ output_bb (ob, bb, fn);
/* The terminator for this function. */
output_zero (ob);
LTO_DEBUG_UNDENT()
- /* 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.
+ LTO_SET_DEBUGGING_STREAM (debug_label_stream, label_data)
+ output_named_labels (ob);
- 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
- the function bodies for putting out the local decls. It needs to
- go into a separate stream because the LTO reader will want to
- process the local variables first, rather than have to back patch
- them.
- */
- tmp_stream = ob->main_stream;
- ob->main_stream = ob->local_decl_stream;
- output_local_vars (ob);
- ob->main_stream = tmp_stream;
+ LTO_SET_DEBUGGING_STREAM (debug_ssa_names_stream, ssa_names_data)
+ output_ssa_names (ob, fn);
- /* Output the names in the named labels. */
- output_named_labels (ob);
+ LTO_SET_DEBUGGING_STREAM (debug_cfg_stream, cfg_data)
+ output_cfg (ob, fn);
+
+ LTO_SET_DEBUGGING_STREAM (debug_decl_stream, decl_data)
+ output_local_vars (ob);
/* Create a file to hold the pickled output of this function. This
is a temp standin until we start writing sections. */
Index: toplev.c
===================================================================
--- toplev.c (revision 126565)
+++ toplev.c (working copy)
@@ -222,6 +222,13 @@ int optimize = 0;
int optimize_size = 0;
+/* True if this is the lto front end. This is used to disable
+ gimple generation and lowering passes that are normally run on the
+ output of a front end. These passes must be bypassed for lto since
+ they have already been done before the gimple was written. */
+
+bool in_lto_p = false;
+
/* The FUNCTION_DECL for the function currently being compiled,
or 0 if between functions. */
tree current_function_decl;
Index: ipa-inline.c
===================================================================
--- ipa-inline.c (revision 126565)
+++ ipa-inline.c (working copy)
@@ -1492,6 +1492,7 @@ static bool
cgraph_gate_ipa_early_inlining (void)
{
return (flag_inline_trees && flag_early_inlining
+ && !in_lto_p
&& (flag_branch_probabilities || flag_test_coverage
|| profile_arc_flag));
}
Index: lto-tree-tags.def
===================================================================
--- lto-tree-tags.def (revision 126565)
+++ lto-tree-tags.def (working copy)
@@ -70,10 +70,12 @@
MAP_EXPR_TAG(CONSTRUCTOR, LTO_constructor)
MAP_EXPR_TAG(FIELD_DECL, LTO_field_decl)
MAP_EXPR_TAG(FUNCTION_DECL, LTO_function_decl)
+ MAP_EXPR_TAG(GIMPLE_MODIFY_STMT, LTO_gimple_modify_stmt)
MAP_EXPR_TAG(INTEGER_CST, LTO_integer_cst)
MAP_EXPR_TAG(LABEL_DECL, LTO_label_decl)
MAP_EXPR_TAG(LABEL_EXPR, LTO_label_expr)
MAP_EXPR_TAG(PARM_DECL, LTO_parm_decl)
+ MAP_EXPR_TAG(PHI_NODE, LTO_phi_node)
MAP_EXPR_TAG(RANGE_EXPR, LTO_range_expr)
MAP_EXPR_TAG(REAL_CST, LTO_real_cst)
MAP_EXPR_TAG(RESULT_DECL, LTO_result_decl)
@@ -188,6 +190,7 @@
SET_NAME (LTO_case_label_expr3, "case_label_expr3")
SET_NAME (LTO_ceil_div_expr, "ceil_div_expr")
SET_NAME (LTO_ceil_mod_expr, "ceil_mod_expr")
+ SET_NAME (LTO_change_dynamic_type_expr, "change_dynamic_type_expr")
SET_NAME (LTO_complex_cst0, "complex_cst0")
SET_NAME (LTO_complex_cst1, "complex_cst1")
SET_NAME (LTO_complex_expr, "complex_expr")
@@ -211,6 +214,7 @@
SET_NAME (LTO_floor_mod_expr, "floor_mod_expr")
SET_NAME (LTO_function_decl, "function_decl")
SET_NAME (LTO_ge_expr, "ge_expr")
+ SET_NAME (LTO_gimple_modify_stmt, "gimple_modify_stmt")
SET_NAME (LTO_goto_expr, "goto_expr")
SET_NAME (LTO_gt_expr, "gt_expr")
SET_NAME (LTO_imagpart_expr, "imagpart_expr")
@@ -236,6 +240,8 @@
SET_NAME (LTO_obj_type_ref, "obj_type_ref")
SET_NAME (LTO_ordered_expr, "ordered_expr")
SET_NAME (LTO_parm_decl, "parm_decl")
+ SET_NAME (LTO_phi_node, "phi_node")
+ SET_NAME (LTO_pointer_plus_expr, "pointer_plus_expr")
SET_NAME (LTO_plus_expr, "plus_expr")
SET_NAME (LTO_range_expr, "range_expr")
SET_NAME (LTO_rdiv_expr, "rdiv_expr")
Index: lto-tags.h
===================================================================
--- lto-tags.h (revision 126565)
+++ lto-tags.h (working copy)
@@ -45,10 +45,12 @@
4) global VAR_DECLS.
5) types.
6) Names for the labels that have names
- 7) Gimple for local decls.
- 8) Gimple for the function.
- 9) Strings.
- 10-12)Redundant information to aid in debugging the stream.
+ 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.
@@ -61,35 +63,39 @@
/* The is the first part of the record for a function in the .o file. */
struct lto_function_header
{
- int16_t major_version; /* LTO_major_version. */
- int16_t minor_version; /* LTO_minor_version. */
- int32_t num_field_decls; /* Number of FIELD_DECLS. */
- int32_t num_fn_decls; /* Number of FUNCTION_DECLS. */
- int32_t num_var_decls; /* Number of non local VAR_DECLS. */
- int32_t num_types; /* Number of types. */
- int32_t num_local_decls; /* Number of local VAR_DECLS and PARM_DECLS. */
- int32_t num_named_labels; /* Number of labels with names. */
- int32_t num_unnamed_labels; /* Number of labels without names. */
- int32_t compressed_size; /* Size compressed or 0 if not compressed. */
- int32_t named_label_size; /* Size of names for named labels. */
- 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_size; /* Size of local decl debugging information. */
- int32_t debug_label_size; /* Size of label stream debugging information. */
- int32_t debug_main_size; /* Size of main stream debugging information. */
+ int16_t major_version; /* LTO_major_version. */
+ int16_t minor_version; /* LTO_minor_version. */
+ int32_t num_field_decls; /* Number of FIELD_DECLS. */
+ int32_t num_fn_decls; /* Number of FUNCTION_DECLS. */
+ int32_t num_var_decls; /* Number of non local VAR_DECLS. */
+ int32_t num_types; /* Number of types. */
+ int32_t num_local_decls; /* Number of local VAR_DECLS and PARM_DECLS. */
+ int32_t num_named_labels; /* Number of labels with names. */
+ int32_t num_unnamed_labels; /* Number of labels without names. */
+ int32_t compressed_size; /* Size compressed or 0 if not compressed. */
+ 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_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_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. */
+ int32_t debug_cfg_size; /* Size of cfg stream debugging information. */
+ int32_t debug_main_size; /* Size of main stream debugging information. */
};
/* 2-5) THE GLOBAL DECLS AND TYPES.
- The global decls and types are encoded in the same way. For each
- entry, there is a pair of words. The first is the debugging
- section number and the second is the offset within the section to
- the entry.
-
- FIXME: This encoding may change change so that the first word is
- a label for the debugging section. This will cause more work for
- the linker but will make ln -r work properly.
+ The global decls and types are encoded in the same way. For each
+ entry, there is a pair of words. The first is the debugging
+ section number and the second is the offset within the section to
+ the entry.
+
+ FIXME: This encoding may change change so that the first word is
+ a label for the debugging section. This will cause more work for
+ the linker but will make ln -r work properly.
6) THE LABEL NAMES.
@@ -100,7 +106,14 @@ struct lto_function_header
the negative ones do not. The positive index can be used to
find the name in this array.
- 7-8) GIMPLE FOR THE LOCAL DECLS AND THE FUNCTION BODY.
+ 7) THE ACTIVE SSA NAMES.
+
+ The SSA_NAME_VERSION in an SSA_NAME in used as an index into
+ this table.
+
+ 8) THE CFG.
+
+ 9-10) GIMPLE FOR THE LOCAL DECLS AND THE FUNCTION BODY.
The gimple consists of a set of records.
@@ -211,12 +224,12 @@ struct lto_function_header
to terminate the statements and exception
regions within this block.
- 9) STRINGS
+ 11) STRINGS
String are represented in the table as pairs, a length in ULEB128
form followed by the data for the string.
- 10) STREAM DEBUGGING
+ 12) STREAM DEBUGGING
If the preprocessor symbol LTO_STREAM_DEBUGGING is defined, the
gimple is encoded into .o file as two streams. The first stream
@@ -275,143 +288,147 @@ struct lto_function_header
#define LTO_case_label_expr3 0x017
#define LTO_ceil_div_expr 0x018
#define LTO_ceil_mod_expr 0x019
+#define LTO_change_dynamic_type_expr 0x01A
/* 1 if the elements are reals and 0 if the elements are ints. */
-#define LTO_complex_cst0 0x01A
-#define LTO_complex_cst1 0x01B
-#define LTO_complex_expr 0x01C
-#define LTO_component_ref 0x01D
-#define LTO_compound_expr 0x01E
-#define LTO_cond_expr 0x01F
-#define LTO_conj_expr 0x020
-#define LTO_const_decl 0x021
+#define LTO_complex_cst0 0x01B
+#define LTO_complex_cst1 0x01C
+#define LTO_complex_expr 0x01D
+#define LTO_component_ref 0x01E
+#define LTO_compound_expr 0x01F
+#define LTO_cond_expr 0x020
+#define LTO_conj_expr 0x021
+#define LTO_const_decl 0x022
/* This form is terminated by a zero. */
-#define LTO_constructor 0x022
-#define LTO_constructor_range 0x023
-#define LTO_convert_expr 0x024
-#define LTO_dot_prod_expr 0x025
-#define LTO_eq_expr 0x026
-#define LTO_exact_div_expr 0x027
-#define LTO_exc_ptr_expr 0x028
-#define LTO_field_decl 0x029
-#define LTO_filter_expr 0x02A
-#define LTO_fix_ceil_expr 0x02B
-#define LTO_fix_floor_expr 0x02C
-#define LTO_fix_round_expr 0x02D
-#define LTO_fix_trunc_expr 0x02E
-#define LTO_float_expr 0x02F
-#define LTO_floor_div_expr 0x030
-#define LTO_floor_mod_expr 0x031
-#define LTO_function_decl 0x032
-#define LTO_ge_expr 0x033
-#define LTO_goto_expr 0x034
-#define LTO_gt_expr 0x035
-#define LTO_imagpart_expr 0x036
-#define LTO_indirect_ref 0x037
-#define LTO_integer_cst 0x038
-#define LTO_label_decl 0x039
-#define LTO_label_expr 0x03A
-#define LTO_le_expr 0x03B
-#define LTO_lrotate_expr 0x03C
-#define LTO_lshift_expr 0x03D
-#define LTO_lt_expr 0x03E
-#define LTO_ltgt_expr 0x03F
-#define LTO_max_expr 0x040
-#define LTO_min_expr 0x041
-#define LTO_minus_expr 0x042
-#define LTO_misaligned_indirect_ref 0x043
-#define LTO_modify_expr 0x044
-#define LTO_mult_expr 0x045
-#define LTO_ne_expr 0x046
-#define LTO_negate_expr 0x047
-#define LTO_non_lvalue_expr 0x048
-#define LTO_nop_expr 0x049
-#define LTO_obj_type_ref 0x04A
-#define LTO_ordered_expr 0x04B
-#define LTO_parm_decl 0x04C
-#define LTO_plus_expr 0x04D
-#define LTO_range_expr 0x04E
-#define LTO_rdiv_expr 0x04F
-#define LTO_real_cst 0x050
-#define LTO_realign_load_expr 0x051
-#define LTO_realpart_expr 0x052
-#define LTO_reduc_max_expr 0x053
-#define LTO_reduc_min_expr 0x054
-#define LTO_reduc_plus_expr 0x055
-#define LTO_result_decl 0x056
+#define LTO_constructor 0x023
+#define LTO_constructor_range 0x024
+#define LTO_convert_expr 0x025
+#define LTO_dot_prod_expr 0x026
+#define LTO_eq_expr 0x027
+#define LTO_exact_div_expr 0x028
+#define LTO_exc_ptr_expr 0x029
+#define LTO_field_decl 0x02A
+#define LTO_filter_expr 0x02B
+#define LTO_fix_ceil_expr 0x02C
+#define LTO_fix_floor_expr 0x02D
+#define LTO_fix_round_expr 0x02E
+#define LTO_fix_trunc_expr 0x02F
+#define LTO_float_expr 0x030
+#define LTO_floor_div_expr 0x031
+#define LTO_floor_mod_expr 0x032
+#define LTO_function_decl 0x033
+#define LTO_ge_expr 0x034
+#define LTO_gimple_modify_stmt 0x035
+#define LTO_goto_expr 0x036
+#define LTO_gt_expr 0x037
+#define LTO_imagpart_expr 0x038
+#define LTO_indirect_ref 0x039
+#define LTO_integer_cst 0x03A
+#define LTO_label_decl 0x03B
+#define LTO_label_expr 0x03C
+#define LTO_le_expr 0x03D
+#define LTO_lrotate_expr 0x03E
+#define LTO_lshift_expr 0x03F
+#define LTO_lt_expr 0x040
+#define LTO_ltgt_expr 0x041
+#define LTO_max_expr 0x042
+#define LTO_min_expr 0x043
+#define LTO_minus_expr 0x044
+#define LTO_misaligned_indirect_ref 0x045
+#define LTO_modify_expr 0x046
+#define LTO_mult_expr 0x047
+#define LTO_ne_expr 0x048
+#define LTO_negate_expr 0x049
+#define LTO_non_lvalue_expr 0x04A
+#define LTO_nop_expr 0x04B
+#define LTO_obj_type_ref 0x04C
+#define LTO_ordered_expr 0x04D
+#define LTO_parm_decl 0x04E
+#define LTO_phi_node 0x04F
+#define LTO_pointer_plus_expr 0x050
+#define LTO_plus_expr 0x051
+#define LTO_range_expr 0x052
+#define LTO_rdiv_expr 0x053
+#define LTO_real_cst 0x054
+#define LTO_realign_load_expr 0x055
+#define LTO_realpart_expr 0x056
+#define LTO_reduc_max_expr 0x057
+#define LTO_reduc_min_expr 0x058
+#define LTO_reduc_plus_expr 0x059
+#define LTO_result_decl 0x05A
/* Form "return;" */
-#define LTO_return_expr0 0x057
+#define LTO_return_expr0 0x05B
/* Form "return x;" */
-#define LTO_return_expr1 0x058
+#define LTO_return_expr1 0x05C
/* Form "return x=y;" */
-#define LTO_return_expr2 0x059
-#define LTO_resx_expr 0x05A
-#define LTO_round_div_expr 0x05B
-#define LTO_round_mod_expr 0x05C
-#define LTO_rrotate_expr 0x05D
-#define LTO_rshift_expr 0x05E
-#define LTO_ssa_name 0x05F
-#define LTO_string_cst 0x060
+#define LTO_return_expr2 0x05D
+#define LTO_resx_expr 0x05E
+#define LTO_round_div_expr 0x05F
+#define LTO_round_mod_expr 0x060
+#define LTO_rrotate_expr 0x061
+#define LTO_rshift_expr 0x062
+#define LTO_ssa_name 0x063
+#define LTO_string_cst 0x064
/* Cases are terminated a zero. */
-#define LTO_switch_expr 0x061
-#define LTO_trunc_div_expr 0x062
-#define LTO_trunc_mod_expr 0x063
-#define LTO_truth_and_expr 0x064
-#define LTO_truth_not_expr 0x065
-#define LTO_truth_or_expr 0x066
-#define LTO_truth_xor_expr 0x067
-#define LTO_uneq_expr 0x068
-#define LTO_unge_expr 0x069
-#define LTO_ungt_expr 0x06A
-#define LTO_unle_expr 0x06B
-#define LTO_unlt_expr 0x06C
-#define LTO_unordered_expr 0x070
+#define LTO_switch_expr 0x065
+#define LTO_trunc_div_expr 0x066
+#define LTO_trunc_mod_expr 0x067
+#define LTO_truth_and_expr 0x068
+#define LTO_truth_not_expr 0x069
+#define LTO_truth_or_expr 0x06A
+#define LTO_truth_xor_expr 0x06B
+#define LTO_uneq_expr 0x06C
+#define LTO_unge_expr 0x070
+#define LTO_ungt_expr 0x071
+#define LTO_unle_expr 0x072
+#define LTO_unlt_expr 0x073
+#define LTO_unordered_expr 0x074
/* 1 for static or extern and 0 for local. */
-#define LTO_var_decl0 0x071
-#define LTO_var_decl1 0x072
-#define LTO_vec_cond_expr 0x073
-#define LTO_vec_lshift_expr 0x074
-#define LTO_vec_rshift_expr 0x075
+#define LTO_var_decl0 0x075
+#define LTO_var_decl1 0x076
+#define LTO_vec_cond_expr 0x077
+#define LTO_vec_lshift_expr 0x078
+#define LTO_vec_rshift_expr 0x079
/* 1 if the elements are reals and 0 if the elements are ints. */
-#define LTO_vector_cst0 0x076
-#define LTO_vector_cst1 0x077
-#define LTO_view_convert_expr 0x078
-#define LTO_widen_mult_expr 0x079
-#define LTO_widen_sum_expr 0x07A
-#define LTO_with_size_expr 0x07B
+#define LTO_vector_cst0 0x07A
+#define LTO_vector_cst1 0x07B
+#define LTO_view_convert_expr 0x07C
+#define LTO_widen_mult_expr 0x07D
+#define LTO_widen_sum_expr 0x07E
+#define LTO_with_size_expr 0x080
/* All of the statement types that do not also appear as
expressions. */
-#define LTO_asm_inputs 0x080
-#define LTO_asm_outputs 0x081
-#define LTO_asm_clobbers 0x082
-
-#define LTO_function 0x083
-#define LTO_attribute_list 0x084
-#define LTO_eh_table 0x085
+#define LTO_asm_inputs 0x090
+#define LTO_asm_outputs 0x091
+#define LTO_asm_clobbers 0x092
+
+#define LTO_function 0x093
+#define LTO_attribute_list 0x094
+#define LTO_eh_table 0x095
/* Each of these requires 4 variants. 1 and 3 are have_inner and 2
and 3 are may_contain_throw. */
-#define LTO_eh_table_cleanup0 0x090
-#define LTO_eh_table_cleanup1 0x091
-#define LTO_eh_table_cleanup2 0x092
-#define LTO_eh_table_cleanup3 0x093
-#define LTO_eh_table_try0 0x094
-#define LTO_eh_table_try1 0x095
-#define LTO_eh_table_try2 0x096
-#define LTO_eh_table_try3 0x097
-#define LTO_eh_table_catch0 0x098
-#define LTO_eh_table_catch1 0x099
-#define LTO_eh_table_catch2 0x09A
-#define LTO_eh_table_catch3 0x09B
-#define LTO_eh_table_allowed0 0x09C
-#define LTO_eh_table_allowed1 0x09D
-#define LTO_eh_table_allowed2 0x09E
-#define LTO_eh_table_allowed3 0x09F
-#define LTO_eh_table_must_not_throw0 0x0A0
-#define LTO_eh_table_must_not_throw1 0x0A1
-#define LTO_eh_table_must_not_throw2 0x0A2
-#define LTO_eh_table_must_not_throw3 0x0A3
+#define LTO_eh_table_cleanup0 0x0A0
+#define LTO_eh_table_cleanup1 0x0A1
+#define LTO_eh_table_cleanup2 0x0A2
+#define LTO_eh_table_cleanup3 0x0A3
+#define LTO_eh_table_try0 0x0A4
+#define LTO_eh_table_try1 0x0A5
+#define LTO_eh_table_try2 0x0A6
+#define LTO_eh_table_try3 0x0A7
+#define LTO_eh_table_catch0 0x0A8
+#define LTO_eh_table_catch1 0x0A9
+#define LTO_eh_table_catch2 0x0AA
+#define LTO_eh_table_catch3 0x0AB
+#define LTO_eh_table_allowed0 0x0AC
+#define LTO_eh_table_allowed1 0x0AD
+#define LTO_eh_table_allowed2 0x0AE
+#define LTO_eh_table_allowed3 0x0AF
+#define LTO_eh_table_must_not_throw0 0x0B0
+#define LTO_eh_table_must_not_throw1 0x0B1
+#define LTO_eh_table_must_not_throw2 0x0B2
+#define LTO_eh_table_must_not_throw3 0x0B3
/* There are 16 variants of the following decl bodies depending on the
subtrees that may or may not be there in the decl_common part of
@@ -424,9 +441,9 @@ struct lto_function_header
These next two tags must have their last hex digit be 0.
*/
-#define LTO_local_var_decl_body0 0x0B0
-#define LTO_parm_decl_body0 0x0C0
-#define LTO_last_tag 0x0D0
+#define LTO_local_var_decl_body0 0x0C0
+#define LTO_parm_decl_body0 0x0D0
+#define LTO_last_tag 0x0E0
/* The string that is prepended on the DECL_ASSEMBLER_NAME to make the
section name for the function. */
#define LTO_SECTION_NAME_PREFIX ".gnu.lto_"
@@ -470,6 +487,8 @@ struct lto_debug_context
void * current_data;
void * decl_data;
void * label_data;
+ void * ssa_names_data;
+ void * cfg_data;
void * main_data;
};
Index: ipa.c
===================================================================
--- ipa.c (revision 126565)
+++ ipa.c (working copy)
@@ -25,6 +25,7 @@ Software Foundation, 51 Franklin Street,
#include "cgraph.h"
#include "tree-pass.h"
#include "timevar.h"
+#include "flags.h"
/* Fill array order with all nodes with output flag set in the reverse
topological order. */
@@ -278,10 +279,17 @@ function_and_variable_visibility (void)
return 0;
}
+static bool
+gate_ipa_fun_and_var_visibility (void)
+{
+ return !in_lto_p;
+}
+
+
struct tree_opt_pass pass_ipa_function_and_variable_visibility =
{
"visibility", /* name */
- NULL, /* gate */
+ gate_ipa_fun_and_var_visibility, /* gate */
function_and_variable_visibility, /* execute */
NULL, /* sub */
NULL, /* next */
Index: tree-ssa.c
===================================================================
--- tree-ssa.c (revision 126565)
+++ tree-ssa.c (working copy)
@@ -797,18 +797,18 @@ var_ann_hash (const void *item)
/* Initialize global DFA and SSA structures. */
void
-init_tree_ssa (void)
+init_tree_ssa (struct function *fn)
{
- cfun->gimple_df = GGC_CNEW (struct gimple_df);
- cfun->gimple_df->referenced_vars = htab_create_ggc (20, int_tree_map_hash,
+ fn->gimple_df = GGC_CNEW (struct gimple_df);
+ fn->gimple_df->referenced_vars = htab_create_ggc (20, int_tree_map_hash,
int_tree_map_eq, NULL);
- cfun->gimple_df->default_defs = htab_create_ggc (20, int_tree_map_hash,
+ fn->gimple_df->default_defs = htab_create_ggc (20, int_tree_map_hash,
int_tree_map_eq, NULL);
- cfun->gimple_df->var_anns = htab_create_ggc (20, var_ann_hash,
+ fn->gimple_df->var_anns = htab_create_ggc (20, var_ann_hash,
var_ann_eq, NULL);
- cfun->gimple_df->call_clobbered_vars = BITMAP_GGC_ALLOC ();
- cfun->gimple_df->addressable_vars = BITMAP_GGC_ALLOC ();
- init_ssanames ();
+ fn->gimple_df->call_clobbered_vars = BITMAP_GGC_ALLOC ();
+ fn->gimple_df->addressable_vars = BITMAP_GGC_ALLOC ();
+ init_ssanames (fn, 0);
init_phinodes ();
}
Index: tree-inline.c
===================================================================
--- tree-inline.c (revision 126565)
+++ tree-inline.c (working copy)
@@ -1138,7 +1138,7 @@ initialize_cfun (tree new_fndecl, tree c
if (src_cfun->gimple_df)
{
- init_tree_ssa ();
+ init_tree_ssa (cfun);
cfun->gimple_df->in_ssa_p = true;
init_ssa_operands ();
}
Index: tree-optimize.c
===================================================================
--- tree-optimize.c (revision 126565)
+++ tree-optimize.c (working copy)
@@ -85,7 +85,7 @@ static bool
gate_all_early_local_passes (void)
{
/* Don't bother doing anything if the program has errors. */
- return (!errorcount && !sorrycount);
+ return (!errorcount && !sorrycount && !in_lto_p);
}
struct tree_opt_pass pass_early_local_passes =
@@ -319,7 +319,7 @@ static unsigned int
execute_init_datastructures (void)
{
/* Allocate hash tables, arrays and other structures. */
- init_tree_ssa ();
+ init_tree_ssa (cfun);
return 0;
}
Index: tree-flow.h
===================================================================
--- tree-flow.h (revision 126565)
+++ tree-flow.h (working copy)
@@ -864,7 +864,7 @@ typedef bool (*walk_use_def_chains_fn) (
extern void strict_aliasing_warning_backend (void);
/* In tree-ssa.c */
-extern void init_tree_ssa (void);
+extern void init_tree_ssa (struct function *);
extern edge ssa_redirect_edge (edge, basic_block);
extern void flush_pending_stmts (edge);
extern bool tree_ssa_useless_type_conversion (tree);
Index: Makefile.in
===================================================================
--- Makefile.in (revision 126565)
+++ Makefile.in (working copy)
@@ -2459,7 +2459,7 @@ varpool.o : varpool.c $(CONFIG_H) $(SYST
$(TREE_FLOW_H) tree-pass.h $(C_COMMON_H) debug.h $(DIAGNOSTIC_H) \
$(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) ipa-prop.h \
gt-varpool.h
-ipa.o : ipa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H)
+ipa.o : ipa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) $(FLAGS_H)
ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) ipa-prop.h \
$(TREE_FLOW_H) $(TM_H) tree-pass.h $(FLAGS_H) $(TREE_H)
Index: tree-ssanames.c
===================================================================
--- tree-ssanames.c (revision 126565)
+++ tree-ssanames.c (working copy)
@@ -68,12 +68,15 @@ unsigned int ssa_name_nodes_reused;
unsigned int ssa_name_nodes_created;
#endif
-/* Initialize management of SSA_NAMEs. */
+/* Initialize management of SSA_NAMEs to default SIZE. If SIZE is
+ zero use default. */
void
-init_ssanames (void)
+init_ssanames (struct function *the_fun, int size)
{
- SSANAMES (cfun) = VEC_alloc (tree, gc, 50);
+ if (size < 50)
+ size = 50;
+ SSANAMES (the_fun) = VEC_alloc (tree, gc, size);
/* Version 0 is special, so reserve the first slot in the table. Though
currently unused, we may use version 0 in alias analysis as part of
@@ -82,8 +85,8 @@ init_ssanames (void)
We use VEC_quick_push here because we know that SSA_NAMES has at
least 50 elements reserved in it. */
- VEC_quick_push (tree, SSANAMES (cfun), NULL_TREE);
- FREE_SSANAMES (cfun) = NULL;
+ VEC_quick_push (tree, SSANAMES (the_fun), NULL_TREE);
+ FREE_SSANAMES (the_fun) = NULL;
}
/* Finalize management of SSA_NAMEs. */
Index: lto/lto-read.c
===================================================================
--- lto/lto-read.c (revision 126565)
+++ lto/lto-read.c (working copy)
@@ -89,7 +89,7 @@ static void dump_debug_stream (struct in
#endif
static tree
-input_expr_operand (struct input_block *, struct fun_in *, unsigned int);
+input_expr_operand (struct input_block *, struct fun_in *, struct function *, unsigned int);
/* Return the next character of input from IB. Abort if you
@@ -274,19 +274,19 @@ input_record_start (struct input_block *
/* Build a tree list stopping when the tag is 0. */
static tree
-input_list (struct input_block *ib, struct fun_in *fun_in)
+input_list (struct input_block *ib, struct fun_in *fun_in, struct function *fn)
{
unsigned int tag = input_record_start (ib);
tree first = NULL_TREE;
if (tag)
{
- first = build_tree_list (NULL_TREE, input_expr_operand (ib, fun_in, tag));
+ first = build_tree_list (NULL_TREE, input_expr_operand (ib, fun_in, fn, tag));
tree next = first;
tag = input_record_start (ib);
while (tag)
{
TREE_CHAIN (next)
- = build_tree_list (NULL_TREE, input_expr_operand (ib, fun_in, tag));
+ = build_tree_list (NULL_TREE, input_expr_operand (ib, fun_in, fn, tag));
next = TREE_CHAIN (next);
tag = input_record_start (ib);
}
@@ -296,61 +296,6 @@ input_list (struct input_block *ib, stru
return first;
}
-/* Set up an empty cfg for THIS_FUN with BB_COUNT slots available. */
-
-static void
-init_cfg (struct function *this_fun, unsigned int bb_count)
-{
- init_flow (this_fun);
- profile_status_for_function (this_fun) = PROFILE_ABSENT;
- n_basic_blocks_for_function (this_fun) = NUM_FIXED_BLOCKS;
- last_basic_block_for_function (this_fun) = bb_count;
- basic_block_info_for_function (this_fun)
- = VEC_alloc (basic_block, gc, bb_count);
- VEC_safe_grow (basic_block, gc, basic_block_info, bb_count);
- memset (VEC_address (basic_block,
- basic_block_info_for_function (this_fun)),
- 0, sizeof (basic_block) * bb_count);
-
- /* Build a mapping of labels to their associated blocks. */
- label_to_block_map_for_function (this_fun)
- = VEC_alloc (basic_block, gc, bb_count);
- VEC_safe_grow (basic_block, gc,
- label_to_block_map_for_function (this_fun), bb_count);
- memset (VEC_address (basic_block,
- label_to_block_map_for_function (this_fun)),
- 0, sizeof (basic_block) * bb_count);
-
- SET_BASIC_BLOCK_FOR_FUNCTION (this_fun, ENTRY_BLOCK,
- ENTRY_BLOCK_PTR_FOR_FUNCTION (this_fun));
- SET_BASIC_BLOCK_FOR_FUNCTION (this_fun, EXIT_BLOCK,
- EXIT_BLOCK_PTR_FOR_FUNCTION (this_fun));
-}
-
-
-/* Link up the prev_bb and next_bb fields in the cfg. */
-
-static void
-finalize_cfg (struct function *this_fun, unsigned int bb_count)
-{
- unsigned int i;
- basic_block p_bb = ENTRY_BLOCK_PTR_FOR_FUNCTION(this_fun);
-
- for (i=NUM_FIXED_BLOCKS; i<bb_count; i++)
- {
- basic_block bb = BASIC_BLOCK_FOR_FUNCTION (this_fun, i);
- if (bb)
- {
- bb->prev_bb = p_bb;
- p_bb->next_bb = bb;
- p_bb = bb;
- }
- }
-
- p_bb->next_bb = EXIT_BLOCK_PTR_FOR_FUNCTION(this_fun);
- EXIT_BLOCK_PTR_FOR_FUNCTION(this_fun)->prev_bb = p_bb;
-}
-
/* Get the label referenced by the next token in IB. */
@@ -444,7 +389,7 @@ process_flags (tree expr, unsigned HOST_
static tree
input_expr_operand (struct input_block *ib, struct fun_in *fun_in,
- unsigned int tag)
+ struct function *fn, unsigned int tag)
{
enum tree_code code = tag_to_expr[tag];
tree type = NULL_TREE;
@@ -560,11 +505,11 @@ input_expr_operand (struct input_block *
tree op1 = NULL_TREE;
if (variant & 0x1)
- op0 = input_expr_operand (ib, fun_in,
+ op0 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
if (variant & 0x2)
- op1 = input_expr_operand (ib, fun_in,
+ op1 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
result = build3 (code, void_type_node,
@@ -594,7 +539,7 @@ input_expr_operand (struct input_block *
else
{
tree value =
- input_expr_operand (ib, fun_in, ctag);
+ input_expr_operand (ib, fun_in, fn, ctag);
constructor_elt *elt
= VEC_quick_push (constructor_elt, vec, NULL);
elt->index = purpose;
@@ -611,6 +556,10 @@ input_expr_operand (struct input_block *
}
break;
+ case SSA_NAME:
+ result = VEC_index (tree, SSANAMES (fn), input_uleb128 (ib));
+ break;
+
case CONST_DECL:
/* Just ignore these, Mark will make them disappear. */
break;
@@ -665,9 +614,9 @@ input_expr_operand (struct input_block *
{
tree op0;
tree op1;
- op0 = input_expr_operand (ib, fun_in,
+ op0 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
- op1 = input_expr_operand (ib, fun_in,
+ op1 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
/* Ignore 3 because it can be recomputed. */
@@ -684,11 +633,11 @@ input_expr_operand (struct input_block *
/* The call chain. */
if (tag == LTO_call_expr1)
- op2 = input_expr_operand (ib, fun_in,
+ op2 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
/* The callee. */
- op1 = input_expr_operand (ib, fun_in,
+ op1 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
result = build_vl_exp (code, count);
@@ -696,7 +645,7 @@ input_expr_operand (struct input_block *
CALL_EXPR_STATIC_CHAIN (result) = op2;
for (i = 3; i < count; i++)
TREE_OPERAND (result, i)
- = input_expr_operand (ib, fun_in,
+ = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
}
break;
@@ -710,16 +659,16 @@ input_expr_operand (struct input_block *
{
op1 = input_integer (ib, SIZETYPE);
op2 = input_integer (ib, SIZETYPE);
- op0 = input_expr_operand (ib, fun_in,
+ op0 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
}
else
{
- op0 = input_expr_operand (ib, fun_in,
+ op0 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
- op1 = input_expr_operand (ib, fun_in,
+ op1 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
- op2 = input_expr_operand (ib, fun_in,
+ op2 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
}
result = build3 (code, type, op0, op1, op2);
@@ -731,9 +680,9 @@ input_expr_operand (struct input_block *
/* Ignore operands 2 and 3 for ARRAY_REF and ARRAY_RANGE REF
because they can be recomputed. */
{
- tree op0 = input_expr_operand (ib, fun_in,
+ tree op0 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
- tree op1 = input_expr_operand (ib, fun_in,
+ tree op1 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
result = build4 (code, type, op0, op1, NULL_TREE, NULL_TREE);
}
@@ -742,10 +691,15 @@ input_expr_operand (struct input_block *
case ASM_EXPR:
{
tree str = input_string (fun_in, input_uleb128 (ib));
- tree ins = input_list (ib, fun_in);
- tree outs = input_list (ib, fun_in);
- tree clobbers = input_list (ib, fun_in);
+ tree ins = input_list (ib, fun_in, fn);
+ tree outs = input_list (ib, fun_in, fn);
+ tree clobbers = input_list (ib, fun_in, fn);
+ tree tl;
result = build4 (code, void_type_node, str, outs, ins, clobbers);
+
+ for (tl = ASM_OUTPUTS (result); tl; tl = TREE_CHAIN (tl))
+ if (TREE_CODE (TREE_VALUE (tl)) == SSA_NAME)
+ SSA_NAME_DEF_STMT (TREE_VALUE (tl)) = result;
}
break;
@@ -762,15 +716,15 @@ input_expr_operand (struct input_block *
case LTO_return_expr1:
result = build1 (code, NULL_TREE,
- input_expr_operand (ib, fun_in,
+ input_expr_operand (ib, fun_in, fn,
input_record_start (ib)));
break;
case LTO_return_expr2:
{
- tree op0 = input_expr_operand (ib, fun_in,
+ tree op0 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
- tree op1 = input_expr_operand (ib, fun_in,
+ tree op1 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
result = build1 (code, NULL_TREE,
build2 (MODIFY_EXPR, NULL_TREE, op0, op1));
@@ -779,17 +733,30 @@ input_expr_operand (struct input_block *
}
break;
+ case GIMPLE_MODIFY_STMT:
+ {
+ tree op0 = input_expr_operand (ib, fun_in, fn,
+ input_record_start (ib));
+ tree op1 = input_expr_operand (ib, fun_in, fn,
+ input_record_start (ib));
+
+ result = build_gimple_modify_stmt (op0, op1);
+ if (TREE_CODE (op0) == SSA_NAME)
+ SSA_NAME_DEF_STMT (op0) = result;
+ }
+ break;
+
case SWITCH_EXPR:
{
unsigned int len = input_uleb128 (ib);
unsigned int i;
- tree op0 = input_expr_operand (ib, fun_in,
+ tree op0 = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
tree op2 = make_tree_vec (len);
for (i = 0; i < len; ++i)
TREE_VEC_ELT (op2, i)
- = input_expr_operand (ib, fun_in,
+ = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
result = build3 (code, NULL_TREE, op0, NULL_TREE, op2);
}
@@ -809,7 +776,7 @@ input_expr_operand (struct input_block *
int len = TREE_CODE_LENGTH (code);
int i;
for (i = 0; i<len; i++)
- ops[i] = input_expr_operand (ib, fun_in,
+ ops[i] = input_expr_operand (ib, fun_in, fn,
input_record_start (ib));
switch (len)
{
@@ -858,7 +825,6 @@ input_expr_operand (struct input_block *
case OMP_RETURN:
case OMP_SECTIONS:
case OMP_SINGLE:
- case SSA_NAME:
case STRUCT_FIELD_TAG:
case SYMBOL_MEMORY_TAG:
case TARGET_MEM_REF:
@@ -933,11 +899,9 @@ input_globals (struct lto_function_heade
labels from DATA segment SIZE bytes long using FUN_IN. */
static void
-input_labels (struct fun_in *fun_in, const char *data,
- unsigned int size, unsigned int named_count,
- unsigned int unnamed_count)
+input_labels (struct fun_in *fun_in, struct input_block *ib,
+ unsigned int named_count, unsigned int unnamed_count)
{
- struct input_block ib = {data, 0, size};
unsigned int i;
/* The named and unnamed labels share the same array. In the lto
@@ -947,7 +911,7 @@ input_labels (struct fun_in *fun_in, con
fun_in->labels = xcalloc (named_count + unnamed_count, sizeof (tree*));
for (i = 0; i < named_count; i++)
{
- unsigned int name_index = input_uleb128 (&ib);
+ unsigned int name_index = input_uleb128 (ib);
unsigned int len;
const char *s = input_string_internal (fun_in, name_index, &len);
tree name = get_identifier_with_length (s, len);
@@ -963,16 +927,15 @@ input_labels (struct fun_in *fun_in, con
bytes long using FUN_IN. */
static void
-input_local_vars (struct fun_in *fun_in, const char *data,
- unsigned int size, unsigned int count)
+input_local_vars (struct fun_in *fun_in, struct input_block *ib,
+ struct function *fn, unsigned int count)
{
- struct input_block ib = {data, 0, size};
unsigned int i;
fun_in->local_decls = xcalloc (count, sizeof (tree*));
for (i = 0; i < count; i++)
{
- unsigned int tag = input_record_start (&ib);
+ unsigned int tag = input_record_start (ib);
unsigned int variant = tag & 0xF;
bool is_var = ((tag & 0xFFF0) == LTO_local_var_decl_body0);
@@ -984,7 +947,7 @@ input_local_vars (struct fun_in *fun_in,
int new_line = -1;
tree result = fun_in->local_decls[i];
- name_index = input_uleb128 (&ib);
+ name_index = input_uleb128 (ib);
if (name_index)
{
unsigned int len;
@@ -994,7 +957,7 @@ input_local_vars (struct fun_in *fun_in,
else
name = NULL_TREE;
- type = get_type_ref (fun_in, &ib);
+ type = get_type_ref (fun_in, ib);
/* The result may not be NULL here because if any of the
subtrees of some prior local var_decl referenced this local
@@ -1010,46 +973,46 @@ input_local_vars (struct fun_in *fun_in,
fun_in->local_decls[i] = result;
if (!is_var)
- DECL_ARG_TYPE (result) = get_type_ref (fun_in, &ib);
+ DECL_ARG_TYPE (result) = get_type_ref (fun_in, ib);
LTO_DEBUG_TOKEN ("flags")
- flags = input_uleb128 (&ib);
+ 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);
+ new_file = input_string_internal (fun_in, input_uleb128 (ib), &len);
}
if (flags & 0x1)
{
LTO_DEBUG_TOKEN ("line")
- new_line = input_uleb128 (&ib);
+ new_line = input_uleb128 (ib);
}
LTO_DEBUG_TOKEN ("align")
- DECL_ALIGN (result) = input_uleb128 (&ib);
+ DECL_ALIGN (result) = input_uleb128 (ib);
LTO_DEBUG_TOKEN ("size")
DECL_SIZE (result)
- = input_expr_operand (&ib, fun_in, input_record_start (&ib));
+ = 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, input_record_start (&ib));
+ = input_expr_operand (ib, fun_in, fn, input_record_start (ib));
}
if (variant & 0x2)
DECL_SIZE_UNIT (result)
- = input_expr_operand (&ib, fun_in, input_record_start (&ib));
+ = 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,
- input_record_start (&ib)));
+ input_expr_operand (ib, fun_in, fn,
+ input_record_start (ib)));
if (variant & 0x8)
DECL_ABSTRACT_ORIGIN (result)
- = input_expr_operand (&ib, fun_in, input_record_start (&ib));
+ = input_expr_operand (ib, fun_in, fn, input_record_start (ib));
process_flags (result, flags);
LTO_DEBUG_UNDENT()
@@ -1084,6 +1047,151 @@ make_new_block (struct function *fn, uns
}
+/* Set up the cfg for THIS_FUN. */
+
+static void
+input_cfg (struct input_block *ib, struct function *fn)
+{
+ unsigned int bb_count;
+ basic_block p_bb;
+ unsigned int i;
+ int index;
+
+ init_flow (fn);
+
+ LTO_DEBUG_TOKEN ("lastbb")
+ bb_count = input_uleb128 (ib);
+
+ profile_status_for_function (fn) = PROFILE_ABSENT;
+ n_basic_blocks_for_function (fn) = bb_count;
+ last_basic_block_for_function (fn) = bb_count;
+ basic_block_info_for_function (fn)
+ = VEC_alloc (basic_block, gc, bb_count);
+ VEC_safe_grow (basic_block, gc, basic_block_info, bb_count);
+ memset (VEC_address (basic_block,
+ basic_block_info_for_function (fn)),
+ 0, sizeof (basic_block) * bb_count);
+
+ /* Build a mapping of labels to their associated blocks. */
+ label_to_block_map_for_function (fn)
+ = VEC_alloc (basic_block, gc, bb_count);
+ VEC_safe_grow (basic_block, gc,
+ label_to_block_map_for_function (fn), bb_count);
+ memset (VEC_address (basic_block,
+ label_to_block_map_for_function (fn)),
+ 0, sizeof (basic_block) * bb_count);
+
+ SET_BASIC_BLOCK_FOR_FUNCTION (fn, ENTRY_BLOCK,
+ ENTRY_BLOCK_PTR_FOR_FUNCTION (fn));
+ SET_BASIC_BLOCK_FOR_FUNCTION (fn, EXIT_BLOCK,
+ EXIT_BLOCK_PTR_FOR_FUNCTION (fn));
+
+ LTO_DEBUG_TOKEN ("bbindex")
+ index = input_sleb128 (ib);
+ while (index != -1)
+ {
+ basic_block bb = BASIC_BLOCK_FOR_FUNCTION (fn, index);
+ unsigned int edge_count;
+
+ if (bb == NULL)
+ bb = make_new_block (fn, index);
+
+ LTO_DEBUG_TOKEN ("edgecount")
+ edge_count = input_uleb128 (ib);
+
+ /* Connect up the cfg. */
+ for (i = 0; i < edge_count; i++)
+ {
+ LTO_DEBUG_TOKEN ("dest")
+ unsigned int dest_index = input_uleb128 (ib);
+ LTO_DEBUG_TOKEN ("eflags")
+ unsigned int edge_flags = input_uleb128 (ib);
+ basic_block dest = BASIC_BLOCK_FOR_FUNCTION (fn, dest_index);
+ if (dest == NULL)
+ dest = make_new_block (fn, dest_index);
+ make_edge (bb, dest, edge_flags);
+ }
+
+ LTO_DEBUG_TOKEN ("bbindex")
+ index = input_sleb128 (ib);
+ }
+
+ p_bb = ENTRY_BLOCK_PTR_FOR_FUNCTION(fn);
+ for (i = NUM_FIXED_BLOCKS; i < bb_count; i++)
+ {
+ basic_block bb = BASIC_BLOCK_FOR_FUNCTION (fn, i);
+ if (bb)
+ {
+ bb->prev_bb = p_bb;
+ p_bb->next_bb = bb;
+ p_bb = bb;
+ }
+ }
+
+ p_bb->next_bb = EXIT_BLOCK_PTR_FOR_FUNCTION(fn);
+ EXIT_BLOCK_PTR_FOR_FUNCTION(fn)->prev_bb = p_bb;
+}
+
+
+/* Input the next phi function for BB. */
+
+static tree
+input_phi (struct input_block *ib, basic_block bb, struct function *fn)
+{
+ tree phi_result = VEC_index (tree, SSANAMES (fn), input_uleb128 (ib));
+ int len = EDGE_COUNT (bb->preds);
+ int i;
+ tree result = create_phi_node (phi_result, bb);
+
+ SSA_NAME_DEF_STMT (phi_result) = result;
+
+ for (i = 0; i < len; i++)
+ {
+ tree def = VEC_index (tree, SSANAMES (fn), input_uleb128 (ib));
+ int src_index = input_uleb128 (ib);
+ basic_block sbb = BASIC_BLOCK_FOR_FUNCTION (fn, src_index);
+
+ edge e = NULL;
+ int j;
+
+ for (j = 0; j < len; j++)
+ if (EDGE_PRED (bb, j)->src == sbb)
+ {
+ e = EDGE_PRED (bb, j);
+ break;
+ }
+
+ add_phi_arg (result, def, e);
+ }
+ return result;
+}
+
+
+/* Read in the ssa_names array from IB. */
+
+static void
+input_ssa_names (struct fun_in *fun_in, struct input_block *ib, struct function *fn)
+{
+ unsigned int i;
+ int size = input_uleb128 (ib);
+
+ init_tree_ssa (fn);
+ init_ssanames (fn, size);
+ i = input_uleb128 (ib);
+
+ while (i)
+ {
+ /* Skip over the elements that had been freed. */
+ while (VEC_length (tree, SSANAMES (fn)) < i)
+ VEC_quick_push (tree, SSANAMES (fn), NULL_TREE);
+
+ make_ssa_name (input_expr_operand (ib, fun_in, fn, input_record_start (ib)), NULL);
+
+ i = input_uleb128 (ib);
+ }
+}
+
+
/* Read in the next basic block. */
static void
@@ -1091,34 +1199,12 @@ input_bb (struct input_block *ib, unsign
struct function *fn, struct fun_in *fun_in)
{
unsigned int index;
- unsigned int edge_count;
basic_block bb;
- unsigned int i;
block_stmt_iterator bsi;
LTO_DEBUG_TOKEN ("bbindex")
index = input_uleb128 (ib);
- LTO_DEBUG_TOKEN ("edgecount")
- edge_count = input_uleb128 (ib);
bb = BASIC_BLOCK_FOR_FUNCTION (fn, index);
- /* There are several reasons why the slot may already have a block.
- Either it is the entry or exit block or else it was the
- destination of a block that was created earlier. */
- if (bb == NULL)
- make_new_block (fn, index);
-
- /* Connect up the cfg. */
- for (i=0; i<edge_count; i++)
- {
- LTO_DEBUG_TOKEN ("dest")
- unsigned int dest_index = input_uleb128 (ib);
- LTO_DEBUG_TOKEN ("eflags")
- unsigned int edge_flags = input_uleb128 (ib);
- basic_block dest = BASIC_BLOCK_FOR_FUNCTION (fn, dest_index);
- if (dest == NULL)
- dest = make_new_block (fn, dest_index);
- make_edge (bb, dest, edge_flags);
- }
/* LTO_bb1 has stmts, LTO_bb0 does not. */
if (tag == LTO_bb0)
@@ -1132,12 +1218,22 @@ input_bb (struct input_block *ib, unsign
tag = input_record_start (ib);
while (tag)
{
- tree stmt = input_expr_operand (ib, fun_in, tag);
+ tree stmt = input_expr_operand (ib, fun_in, fn, tag);
bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
LTO_DEBUG_INDENT_TOKEN ("stmt")
tag = input_record_start (ib);
/* FIXME, add code to handle the exception. */
}
+
+ LTO_DEBUG_INDENT_TOKEN ("phi")
+ tag = input_record_start (ib);
+ while (tag)
+ {
+ input_phi (ib, bb, fn);
+ LTO_DEBUG_INDENT_TOKEN ("phi")
+ tag = input_record_start (ib);
+ }
+
LTO_DEBUG_UNDENT()
}
@@ -1146,28 +1242,23 @@ input_bb (struct input_block *ib, unsign
static void
input_function (tree fn_decl, struct fun_in *fun_in,
- const char *data, unsigned int size)
+ struct input_block *ib)
{
struct function *fn = DECL_STRUCT_FUNCTION (fn_decl);
- struct input_block ib = {data, 0, size};
- unsigned int tag = input_record_start (&ib);
- unsigned int last_bb_index;
+ unsigned int tag = input_record_start (ib);
tree_register_cfg_hooks ();
gcc_assert (tag == LTO_function);
- input_eh_regions (&ib, fn, fun_in);
+ input_eh_regions (ib, fn, fun_in);
- last_bb_index = input_uleb128 (&ib);
- init_cfg (fn, last_bb_index);
- tag = input_record_start (&ib);
+ tag = input_record_start (ib);
while (tag)
{
- input_bb (&ib, tag, fn, fun_in);
- tag = input_record_start (&ib);
+ input_bb (ib, tag, fn, fun_in);
+ tag = input_record_start (ib);
}
- finalize_cfg (fn, last_bb_index);
LTO_DEBUG_UNDENT()
}
@@ -1267,6 +1358,7 @@ lto_static_init_local (void)
#undef END_EXPR_SWITCH
lto_static_init ();
+ tree_register_cfg_hooks ();
}
@@ -1285,32 +1377,43 @@ lto_read_function_body (lto_info_fd *fd,
struct fun_in fun_in;
int32_t fields_offset = sizeof (struct lto_function_header);
int32_t fns_offset
- = fields_offset +
- (header->num_field_decls * sizeof (lto_ref));
+ = fields_offset + (header->num_field_decls * sizeof (lto_ref));
int32_t vars_offset
- = fns_offset +
- (header->num_fn_decls * sizeof (lto_ref));
+ = fns_offset + (header->num_fn_decls * sizeof (lto_ref));
int32_t types_offset
- = vars_offset +
- (header->num_var_decls * sizeof (lto_ref));
- int32_t named_labels_offset
- = types_offset +
- (header->num_types * sizeof (lto_ref));
- int32_t locals_offset = named_labels_offset + header->named_label_size;
- int32_t main_offset = locals_offset + header->local_decls_size;
+ = vars_offset + (header->num_var_decls * sizeof (lto_ref));
+ int32_t named_label_offset
+ = types_offset + (header->num_types * sizeof (lto_ref));
+ int32_t ssa_names_offset
+ = 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 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_label_offset = debug_decl_offset + header->debug_decl_size;
- int32_t debug_main_offset = debug_label_offset + header->debug_label_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
= {data + debug_decl_offset, 0, header->debug_decl_size};
struct input_block debug_label
= {data + debug_label_offset, 0, header->debug_label_size};
+ struct input_block debug_ssa_names
+ = {data + debug_ssa_names_offset, 0, header->debug_ssa_names_size};
+ struct input_block debug_cfg
+ = {data + debug_cfg_offset, 0, header->debug_cfg_size};
struct input_block debug_main
= {data + debug_main_offset, 0, header->debug_main_size};
+
+ struct function *fn = DECL_STRUCT_FUNCTION (fn_decl);
+
+ lto_debug_context.out = debug_out_fun;
+ lto_debug_context.indent = 0;
#endif
lto_ref *in_field_decls = (lto_ref*)(data + fields_offset);
@@ -1318,13 +1421,18 @@ lto_read_function_body (lto_info_fd *fd,
lto_ref *in_var_decls = (lto_ref*)(data + vars_offset);
lto_ref *in_types = (lto_ref*)(data + types_offset);
- const char * named_labels = data + named_labels_offset;
- const char * local_decls = data + locals_offset;
- const char * main_gimple = data + main_offset;
+ struct input_block ib_named_labels
+ = {data + named_label_offset, 0, header->named_label_size};
+ struct input_block ib_ssa_names
+ = {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
+ = {data + local_decls_offset, 0, header->local_decls_size};
+ struct input_block ib_main
+ = {data + main_offset, 0, header->main_size};
#ifdef LTO_STREAM_DEBUGGING
- lto_debug_context.out = debug_out_fun;
- lto_debug_context.indent = 0;
lto_debug_context.current_data = &debug_label;
#endif
@@ -1342,26 +1450,29 @@ lto_read_function_body (lto_info_fd *fd,
in_var_decls, in_types);
fun_in.num_named_labels = header->num_named_labels;
- input_labels (&fun_in, named_labels,
- header->named_label_size,
+ input_labels (&fun_in, &ib_named_labels,
header->num_named_labels, header->num_unnamed_labels);
#ifdef LTO_STREAM_DEBUGGING
lto_debug_context.current_data = &debug_decl;
#endif
- input_local_vars (&fun_in, local_decls,
- header->local_decls_size, header->num_local_decls);
+ input_local_vars (&fun_in, &ib_local_decls, fn, header->num_local_decls);
#ifdef LTO_STREAM_DEBUGGING
- lto_debug_context.current_data = &debug_main;
-#if 0
- dump_debug_stream ((struct input_block *)lto_debug_context.current_data,
- ' ', ' ');
+ lto_debug_context.current_data = &debug_ssa_names;
#endif
+ input_ssa_names (&fun_in, &ib_ssa_names, fn);
+
+#ifdef LTO_STREAM_DEBUGGING
+ lto_debug_context.current_data = &debug_cfg;
#endif
+ input_cfg (&ib_cfg, fn);
+#ifdef LTO_STREAM_DEBUGGING
+ lto_debug_context.current_data = &debug_main;
+#endif
/* Set up the struct function. */
- input_function (fn_decl, &fun_in, main_gimple, header->main_size);
+ input_function (fn_decl, &fun_in, &ib_main);
}
@@ -1375,7 +1486,7 @@ dump_debug_stream (struct input_block *s
int chars = 0;
int hit_pos = -1;
fprintf (stderr,
- "stream failure: looking for '%c' found '%c' at stream->%d\n\n",
+ "stream failure: looking for a '%c' in the debug stream.\nHowever the data translated into a '%c' at position%d\n\n",
c, b, stream->p);
while (i < stream->len)
Index: lto/lto-lang.c
===================================================================
--- lto/lto-lang.c (revision 126565)
+++ lto/lto-lang.c (working copy)
@@ -151,6 +151,7 @@ lto_init (void)
/* Always operate in unit-at-time mode so that we can defer
decisions about what to output. */
flag_unit_at_a_time = 1;
+ in_lto_p = false;
/* Create the basic integer types. */
build_common_tree_nodes (flag_signed_char,