Commit fb3f88cc by Jan Hubicka Committed by Jan Hubicka

ipa-cp.c (ipcp_write_summary, [...]): New functions.


	* ipa-cp.c (ipcp_write_summary, ipcp_read_summary): New functions.
	(pass_ipa_cp): Register them.
	(ipcp_init_stage): Analyze all functions for whopr/lto.
	(ipcp_propagate_stage): Skip external calls.
	(ipcp_iterate_stage): Call ipa_update_after_lto_read if needed.
	* ipa-reference.c (write_node_summary_p): Fix thinko about availability.
	* cgraphunit.c (ipa_passes): When in lto, ne er produce new summaries;
	when in ltrans, skip executing of ipa passes since everything should've
	been done.
	* ipa-inline.c (cgraph_decide_inlining): Remove FIXMEs.
	(inline_generate_summary): Likewise.
	(inline_read_summary): New function.
	(inline_write_summary): New function.
	(pass_ipa_inline): Register new hooks.
	* ipa-prop.c: Inlcude lto-streamer.h
	(ipa_edge_args_vector): Update declaration.
	(ipa_count_arguments, ipa_compute_jump_functions,
	ipa_free_edge_args_substructures): Move ipa_edge_args_vector into ggc.
	(ipa_write_jump_function, ipa_read_jump_function, ipa_write_node_info,
	ipa_read_node_info): New static functions.
	(ipa_prop_write_jump_functions, ipa_prop_read_jump_functions): Update.
	(duplicate_array): Use xmalloc.
	(duplicate_ggc_array): New.
	(ipa_edge_duplication_hook): Use it.
	(ipa_update_after_lto_read): New function.
	* ipa-prop.h (ipa_prop_write_jump_functions,
	ipa_prop_read_jump_functions): Declare.
	(ipa_pass_through_data, ipa_ancestor_jf_data, ipa_member_ptr_cst,
	jump_func_value, ipa_member_ptr_cst, ipa_edge_args): Add GTY markers.
	(ipa_edge_args_vector): Move into GGC.
	(ipa_check_create_edge_args): Update.
	(ipa_update_after_lto_read): New.
	* passes.c (ipa_write_summaries_1): When in wpa, do not write summaries.
	(ipa_read_summaries): When in ltrans, so not read summaries.
	* lto-streamer.c (lto_get_section_name): Add LTO_section_jump_functions.
	* lto-streamer.h (LTO_section_jump_functions): New section.
	(produce_asm): Declare.
	* lto-cgraph.c (output_cgraph): Output edges in reverse order.
	* lto-streamer-out.c (produce_asm): Export.
	* lto-streamer-in.c: Include tree-pass.h
	(input_function): Free dominance info when done.
	(lto_read_body): Push ipa_inline in ltrans stage.
	* gengtype.c (open_base_files): Add ipa-prop.h into includes.
	* Makefile.in (GTFILES): Add ipa-prop.h

	* lto.c (lto_fixup_jump_functions): New function.
	(lto_fixup_decls): Use it.

From-SVN: r153449
parent 34677bae
2009-10-22 Jan Hubicka <jh@suse.cz>
* ipa-cp.c (ipcp_write_summary, ipcp_read_summary): New functions.
(pass_ipa_cp): Register them.
(ipcp_init_stage): Analyze all functions for whopr/lto.
(ipcp_propagate_stage): Skip external calls.
(ipcp_iterate_stage): Call ipa_update_after_lto_read if needed.
* ipa-reference.c (write_node_summary_p): Fix thinko about availability.
* cgraphunit.c (ipa_passes): When in lto, ne er produce new summaries;
when in ltrans, skip executing of ipa passes since everything should've
been done.
* ipa-inline.c (cgraph_decide_inlining): Remove FIXMEs.
(inline_generate_summary): Likewise.
(inline_read_summary): New function.
(inline_write_summary): New function.
(pass_ipa_inline): Register new hooks.
* ipa-prop.c: Inlcude lto-streamer.h
(ipa_edge_args_vector): Update declaration.
(ipa_count_arguments, ipa_compute_jump_functions,
ipa_free_edge_args_substructures): Move ipa_edge_args_vector into ggc.
(ipa_write_jump_function, ipa_read_jump_function, ipa_write_node_info,
ipa_read_node_info): New static functions.
(ipa_prop_write_jump_functions, ipa_prop_read_jump_functions): Update.
(duplicate_array): Use xmalloc.
(duplicate_ggc_array): New.
(ipa_edge_duplication_hook): Use it.
(ipa_update_after_lto_read): New function.
* ipa-prop.h (ipa_prop_write_jump_functions,
ipa_prop_read_jump_functions): Declare.
(ipa_pass_through_data, ipa_ancestor_jf_data, ipa_member_ptr_cst,
jump_func_value, ipa_member_ptr_cst, ipa_edge_args): Add GTY markers.
(ipa_edge_args_vector): Move into GGC.
(ipa_check_create_edge_args): Update.
(ipa_update_after_lto_read): New.
* passes.c (ipa_write_summaries_1): When in wpa, do not write summaries.
(ipa_read_summaries): When in ltrans, so not read summaries.
* lto-streamer.c (lto_get_section_name): Add LTO_section_jump_functions.
* lto-streamer.h (LTO_section_jump_functions): New section.
(produce_asm): Declare.
* lto-cgraph.c (output_cgraph): Output edges in reverse order.
* lto-streamer-out.c (produce_asm): Export.
* lto-streamer-in.c: Include tree-pass.h
(input_function): Free dominance info when done.
(lto_read_body): Push ipa_inline in ltrans stage.
* gengtype.c (open_base_files): Add ipa-prop.h into includes.
* Makefile.in (GTFILES): Add ipa-prop.h
2009-10-22 Matthias Klose <doko@ubuntu.com>
* doc/install.texi: Document --enable-browser-plugin.
......@@ -3585,6 +3585,7 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
$(srcdir)/tree-ssa-structalias.c \
$(srcdir)/lto-symtab.c \
$(srcdir)/tree-ssa-alias.h \
$(srcdir)/ipa-prop.h \
@all_gtfiles@
# Compute the list of GT header files from the corresponding C sources,
......
......@@ -1375,15 +1375,16 @@ ipa_passes (void)
set_cfun (NULL);
current_function_decl = NULL;
cgraph_process_new_functions ();
}
execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
}
execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
if (!in_lto_p)
ipa_write_summaries ();
execute_ipa_pass_list (all_regular_ipa_passes);
if (!flag_ltrans)
execute_ipa_pass_list (all_regular_ipa_passes);
bitmap_obstack_release (NULL);
}
......
......@@ -1571,7 +1571,7 @@ open_base_files (void)
"optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
"tree-flow.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
"cfglayout.h", "except.h", "output.h", "gimple.h", "cfgloop.h",
"target.h", NULL
"target.h", "ipa-prop.h", NULL
};
const char *const *ifp;
outf_p gtype_desc_c;
......
......@@ -614,7 +614,9 @@ ipcp_init_stage (void)
/* building jump functions */
for (cs = node->callees; cs; cs = cs->next_callee)
{
if (!cs->callee->analyzed)
/* We do not need to bother analyzing calls to unknown
functions unless they may become known during lto/whopr. */
if (!cs->callee->analyzed && !flag_lto && !flag_whopr)
continue;
ipa_count_arguments (cs);
if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
......@@ -696,7 +698,9 @@ ipcp_propagate_stage (void)
struct ipa_node_params *callee_info = IPA_NODE_REF (cs->callee);
struct ipa_edge_args *args = IPA_EDGE_REF (cs);
if (ipa_is_called_with_var_arguments (callee_info))
if (ipa_is_called_with_var_arguments (callee_info)
|| !cs->callee->analyzed
|| ipa_is_called_with_var_arguments (callee_info))
continue;
count = ipa_get_cs_argument_count (args);
......@@ -727,6 +731,10 @@ ipcp_iterate_stage (void)
if (dump_file)
fprintf (dump_file, "\nIPA iterate stage:\n\n");
if (in_lto_p)
ipa_update_after_lto_read ();
for (node = cgraph_nodes; node; node = node->next)
{
ipcp_initialize_node_lattices (node);
......@@ -1276,6 +1284,20 @@ ipcp_generate_summary (void)
ipcp_init_stage ();
}
/* Write ipcp summary for nodes in SET. */
static void
ipcp_write_summary (cgraph_node_set set)
{
ipa_prop_write_jump_functions (set);
}
/* Read ipcp summary. */
static void
ipcp_read_summary (void)
{
ipa_prop_read_jump_functions ();
}
/* Gate for IPCP optimization. */
static bool
cgraph_gate_cp (void)
......@@ -1308,8 +1330,8 @@ struct ipa_opt_pass_d pass_ipa_cp =
TODO_remove_functions /* todo_flags_finish */
},
ipcp_generate_summary, /* generate_summary */
NULL, /* write_summary */
NULL, /* read_summary */
ipcp_write_summary, /* write_summary */
ipcp_read_summary, /* read_summary */
NULL, /* function_read_summary */
0, /* TODOs */
NULL, /* function_transform */
......
......@@ -1113,13 +1113,9 @@ cgraph_decide_inlining (void)
bool redo_always_inline = true;
int initial_size = 0;
/* FIXME lto. We need to rethink how to coordinate different passes. */
if (flag_ltrans)
return 0;
/* FIXME lto. We need to re-think about how the passes get invoked. */
if (!flag_wpa)
cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
cgraph_remove_function_insertion_hook (function_insertion_hook_holder);
if (in_lto_p && flag_indirect_inlining)
ipa_update_after_lto_read ();
max_count = 0;
max_benefit = 0;
......@@ -1928,10 +1924,6 @@ inline_generate_summary (void)
{
struct cgraph_node *node;
/* FIXME lto. We should not run any IPA-summary pass in LTRANS mode. */
if (flag_ltrans)
return;
function_insertion_hook_holder =
cgraph_add_function_insertion_hook (&add_new_function, NULL);
......@@ -1976,6 +1968,34 @@ inline_transform (struct cgraph_node *node)
return todo | execute_fixup_cfg ();
}
/* Read inline summary. Jump functions are shared among ipa-cp
and inliner, so when ipa-cp is active, we don't need to write them
twice. */
static void
inline_read_summary (void)
{
if (flag_indirect_inlining)
{
ipa_register_cgraph_hooks ();
if (!flag_ipa_cp)
ipa_prop_read_jump_functions ();
}
function_insertion_hook_holder =
cgraph_add_function_insertion_hook (&add_new_function, NULL);
}
/* Write inline summary for node in SET.
Jump functions are shared among ipa-cp and inliner, so when ipa-cp is
active, we don't need to write them twice. */
static void
inline_write_summary (cgraph_node_set set)
{
if (flag_indirect_inlining && !flag_ipa_cp)
ipa_prop_write_jump_functions (set);
}
struct ipa_opt_pass_d pass_ipa_inline =
{
{
......@@ -1995,8 +2015,8 @@ struct ipa_opt_pass_d pass_ipa_inline =
| TODO_remove_functions /* todo_flags_finish */
},
inline_generate_summary, /* generate_summary */
NULL, /* write_summary */
NULL, /* read_summary */
inline_write_summary, /* write_summary */
inline_read_summary, /* read_summary */
NULL, /* function_read_summary */
0, /* TODOs */
inline_transform, /* function_transform */
......
......@@ -72,7 +72,7 @@ enum ipa_lattice_type
/* Structure holding data required to describe a pass-through jump function. */
struct ipa_pass_through_data
struct GTY(()) ipa_pass_through_data
{
/* If an operation is to be performed on the original parameter, this is the
second (constant) operand. */
......@@ -89,7 +89,7 @@ struct ipa_pass_through_data
/* Structure holding data required to describe and ancestor pass throu
funkci. */
struct ipa_ancestor_jf_data
struct GTY(()) ipa_ancestor_jf_data
{
/* Offset of the field representing the ancestor. */
HOST_WIDE_INT offset;
......@@ -101,30 +101,28 @@ struct ipa_ancestor_jf_data
/* Structure holding a C++ member pointer constant. Holds a pointer to the
method and delta offset. */
struct ipa_member_ptr_cst
struct GTY(()) ipa_member_ptr_cst
{
tree pfn;
tree delta;
};
/* Represents a value of a jump function. pass_through is used only in jump
function context. constant represents the actual constant in constant jump
functions and member_cst holds constant c++ member functions. */
union jump_func_value
{
tree constant;
struct ipa_pass_through_data pass_through;
struct ipa_ancestor_jf_data ancestor;
struct ipa_member_ptr_cst member_cst;
};
/* A jump function for a callsite represents the values passed as actual
arguments of the callsite. See enum jump_func_type for the various
types of jump functions supported. */
struct ipa_jump_func
struct GTY (()) ipa_jump_func
{
enum jump_func_type type;
union jump_func_value value;
/* Represents a value of a jump function. pass_through is used only in jump
function context. constant represents the actual constant in constant jump
functions and member_cst holds constant c++ member functions. */
union jump_func_value
{
tree GTY ((tag ("IPA_JF_CONST"))) constant;
struct ipa_pass_through_data GTY ((tag ("IPA_JF_PASS_THROUGH"))) pass_through;
struct ipa_ancestor_jf_data GTY ((tag ("IPA_JF_ANCESTOR"))) ancestor;
struct ipa_member_ptr_cst GTY ((tag ("IPA_JF_CONST_MEMBER_PTR"))) member_cst;
} GTY ((desc ("%1.type"))) value;
};
/* All formal parameters in the program have a cval computed by
......@@ -280,15 +278,15 @@ ipa_is_called_with_var_arguments (struct ipa_node_params *info)
/* ipa_edge_args stores information related to a callsite and particularly
its arguments. It is pointed to by a field in the
callsite's corresponding cgraph_edge. */
struct ipa_edge_args
typedef struct GTY(()) ipa_edge_args
{
/* Number of actual arguments in this callsite. When set to 0,
this callsite's parameters would not be analyzed by the different
stages of IPA CP. */
int argument_count;
/* Array of the callsite's jump function of each parameter. */
struct ipa_jump_func *jump_functions;
};
struct ipa_jump_func GTY ((length ("%h.argument_count"))) *jump_functions;
} ipa_edge_args_t;
/* ipa_edge_args access functions. Please use these to access fields that
are or will be shared among various passes. */
......@@ -321,18 +319,17 @@ ipa_get_ith_jump_func (struct ipa_edge_args *args, int i)
/* Vectors need to have typedefs of structures. */
typedef struct ipa_node_params ipa_node_params_t;
typedef struct ipa_edge_args ipa_edge_args_t;
/* Types of vectors holding the infos. */
DEF_VEC_O (ipa_node_params_t);
DEF_VEC_ALLOC_O (ipa_node_params_t, heap);
DEF_VEC_O (ipa_edge_args_t);
DEF_VEC_ALLOC_O (ipa_edge_args_t, heap);
DEF_VEC_ALLOC_O (ipa_edge_args_t, gc);
/* Vector where the parameter infos are actually stored. */
extern VEC (ipa_node_params_t, heap) *ipa_node_params_vector;
/* Vector where the parameter infos are actually stored. */
extern VEC (ipa_edge_args_t, heap) *ipa_edge_args_vector;
extern GTY(()) VEC (ipa_edge_args_t, gc) *ipa_edge_args_vector;
/* Return the associated parameter/argument info corresponding to the given
node/edge. */
......@@ -378,12 +375,12 @@ static inline void
ipa_check_create_edge_args (void)
{
if (!ipa_edge_args_vector)
ipa_edge_args_vector = VEC_alloc (ipa_edge_args_t, heap,
ipa_edge_args_vector = VEC_alloc (ipa_edge_args_t, gc,
cgraph_edge_max_uid);
if (VEC_length (ipa_edge_args_t, ipa_edge_args_vector)
<= (unsigned) cgraph_edge_max_uid)
VEC_safe_grow_cleared (ipa_edge_args_t, heap, ipa_edge_args_vector,
VEC_safe_grow_cleared (ipa_edge_args_t, gc, ipa_edge_args_vector,
cgraph_edge_max_uid + 1);
}
......@@ -508,6 +505,10 @@ ipa_parm_adjustment_vec ipa_combine_adjustments (ipa_parm_adjustment_vec,
ipa_parm_adjustment_vec);
void ipa_dump_param_adjustments (FILE *, ipa_parm_adjustment_vec, tree);
void ipa_prop_write_jump_functions (cgraph_node_set set);
void ipa_prop_read_jump_functions (void);
void ipa_update_after_lto_read (void);
/* From tree-sra.c: */
bool build_ref_for_offset (tree *, tree, HOST_WIDE_INT, tree, bool);
......
......@@ -1014,7 +1014,7 @@ write_node_summary_p (struct cgraph_node *node)
{
return (node->analyzed
&& node->global.inlined_to == NULL
&& cgraph_function_body_availability (node) == AVAIL_OVERWRITABLE
&& cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE
&& get_reference_vars_info (node) != NULL);
}
......
......@@ -372,8 +372,16 @@ output_cgraph (cgraph_node_set set)
for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
{
node = csi_node (csi);
for (edge = node->callees; edge; edge = edge->next_callee)
lto_output_edge (ob, edge, encoder);
if (node->callees)
{
/* Output edges in backward direction, so the reconstructed callgraph
match and it is easy to associate call sites in the IPA pass summaries. */
edge = node->callees;
while (edge->next_callee)
edge = edge->next_callee;
for (; edge; edge = edge->prev_callee)
lto_output_edge (ob, edge, encoder);
}
}
lto_output_uleb128_stream (ob->main_stream, 0);
......
......@@ -47,6 +47,7 @@ along with GCC; see the file COPYING3. If not see
#include "output.h"
#include "ipa-utils.h"
#include "lto-streamer.h"
#include "tree-pass.h"
/* Data structure used to hash file names in the source_location field. */
struct string_slot
......@@ -1341,6 +1342,8 @@ input_function (tree fn_decl, struct data_in *data_in,
fixup_call_stmt_edges (cgraph_node (fn_decl), stmts);
update_ssa (TODO_update_ssa_only_virtuals);
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
free (stmts);
}
......@@ -1455,6 +1458,15 @@ lto_read_body (struct lto_file_decl_data *file_data, tree fn_decl,
/* Restore decl state */
file_data->current_decl_state = file_data->global_decl_state;
/* FIXME: ipa_transforms_to_apply holds list of passes that have optimization
summaries computed and needs to apply changes. At the moment WHOPR only
supports inlining, so we can push it here by hand. In future we need to stream
this field into ltrans compilation. This will also need to move the field
from struct function into cgraph node where it belongs. */
if (flag_ltrans && !cgraph_node (fn_decl)->global.inlined_to)
VEC_safe_push (ipa_opt_pass, heap,
cfun->ipa_transforms_to_apply,
(ipa_opt_pass)&pass_ipa_inline);
pop_cfun ();
}
else
......
......@@ -1762,7 +1762,7 @@ output_bb (struct output_block *ob, basic_block bb, struct function *fn)
/* 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;
......
......@@ -157,6 +157,9 @@ lto_get_section_name (int section_type, const char *name)
case LTO_section_cgraph:
return concat (LTO_SECTION_NAME_PREFIX, ".cgraph", NULL);
case LTO_section_jump_functions:
return concat (LTO_SECTION_NAME_PREFIX, ".jmpfuncs", NULL);
case LTO_section_ipa_pure_const:
return concat (LTO_SECTION_NAME_PREFIX, ".pureconst", NULL);
......
......@@ -256,6 +256,7 @@ enum lto_section_type
LTO_section_function_body,
LTO_section_static_initializer,
LTO_section_cgraph,
LTO_section_jump_functions,
LTO_section_ipa_pure_const,
LTO_section_ipa_reference,
LTO_section_symtab,
......@@ -827,6 +828,7 @@ extern struct output_block *create_output_block (enum lto_section_type);
extern void destroy_output_block (struct output_block *);
extern void lto_output_tree (struct output_block *, tree, bool);
extern void lto_output_bitpack (struct lto_output_stream *, struct bitpack_d *);
extern void produce_asm (struct output_block *ob, tree fn);
/* In lto-cgraph.c */
......
2009-10-22 Jan Hubicka <jh@suse.cz>
* lto.c (lto_fixup_jump_functions): New function.
(lto_fixup_decls): Use it.
2009-10-16 Richard Guenther <rguenther@suse.de>
PR lto/41715
......
......@@ -1652,6 +1652,53 @@ free_decl (const void *p, void *data ATTRIBUTE_UNUSED)
return true;
}
/* Fixup pointers in jump functions.
TODO: We need some generic solution that will allow tree pointers in
function summaries. */
static void
lto_fixup_jump_functions (lto_fixup_data_t * data)
{
struct cgraph_node *node;
struct cgraph_edge *cs;
for (node = cgraph_nodes; node; node = node->next)
{
if (!node->analyzed)
continue;
for (cs = node->callees; cs; cs = cs->next_callee)
{
int i;
struct ipa_edge_args *args = IPA_EDGE_REF (cs);
for (i = 0; i < ipa_get_cs_argument_count (args); i++)
{
struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
switch (jf->type)
{
case IPA_JF_UNKNOWN:
break;
case IPA_JF_CONST:
walk_tree (&jf->value.constant, lto_fixup_tree, data, NULL);
break;
case IPA_JF_PASS_THROUGH:
walk_tree (&jf->value.pass_through.operand, lto_fixup_tree,
data, NULL);
break;
case IPA_JF_ANCESTOR:
walk_tree (&jf->value.ancestor.type, lto_fixup_tree, data,
NULL);
break;
case IPA_JF_CONST_MEMBER_PTR:
walk_tree (&jf->value.member_cst.pfn, lto_fixup_tree, data,
NULL);
walk_tree (&jf->value.member_cst.delta, lto_fixup_tree,
data, NULL);
break;
}
}
}
}
}
/* Fix the decls from all FILES. Replaces each decl with the corresponding
prevailing one. */
......@@ -1682,6 +1729,8 @@ lto_fixup_decls (struct lto_file_decl_data **files)
if (decl != saved_decl)
VEC_replace (tree, lto_global_var_decls, i, decl);
}
if (ipa_edge_args_vector)
lto_fixup_jump_functions (&data);
pointer_set_traverse (free_list, free_decl, NULL);
pointer_set_destroy (free_list);
......
......@@ -1618,7 +1618,8 @@ ipa_write_summaries_1 (cgraph_node_set set)
struct lto_out_decl_state *state = lto_new_out_decl_state ();
lto_push_out_decl_state (state);
ipa_write_summaries_2 (all_regular_ipa_passes, set, state);
if (!flag_wpa)
ipa_write_summaries_2 (all_regular_ipa_passes, set, state);
ipa_write_summaries_2 (all_lto_gen_passes, set, state);
gcc_assert (lto_get_out_decl_state () == state);
......@@ -1712,7 +1713,8 @@ ipa_read_summaries_1 (struct opt_pass *pass)
void
ipa_read_summaries (void)
{
ipa_read_summaries_1 (all_regular_ipa_passes);
if (!flag_ltrans)
ipa_read_summaries_1 (all_regular_ipa_passes);
ipa_read_summaries_1 (all_lto_gen_passes);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment