* Make ipcp IPA_PASS
@ 2008-08-20 17:03 Jan Hubicka
0 siblings, 0 replies; only message in thread
From: Jan Hubicka @ 2008-08-20 17:03 UTC (permalink / raw)
To: gcc-patches, matz, zadeck
Hi,
this patch makes IPCP IPA_PASS (instead of SIMPLE_IPA_PASS).
The patch updates inliner and ipcp to compute one set of summaries and
I've also fixed some problems in ipcp so one can get clean regtesting
run and bootstrap on i686. I still get failure on x86_64 with ipcp
enabled, but same failure appears on unpatched ipcp with my fixes
backported (otherwise compilation dies earlier). I am looking into it.
I didn't updated the transformation to happen later, since this needs
some extra infrastructure. We need to reorganize ipcp to not use
iteration (I don't think it helps anyway) and the callgraph's clonning
code needs to be updated to be able to deal with versioning. This is
quite involved, so I would like to deal with this later after debugging
remaining issues with ipcp and trying to enable it by default.
For LTO/whopr it is not completely critical: we can do the job of saving
summaries and experimenting with the idea of bringing functions to
memory early for nontrivial transformations. We will need that for other
passes later anyway.
I will commit it tomorrow if there will be no complains.
Bootstrapped/regtested x86_64-linux and i686-linux (without ipcp enabled by default)
Honza
* tree-pass.h (pass_ipa_cp): Make ipa_opt_pass.
* ipa-cp.c (ipcp_update_cloned_node): New function.
(build_const_val): Handle functions correctly; bring type logic
into sync with tree-inline.c
(ipcp_init_stage): Take care of computing stuff needed by
indirect inlining; update clones.
(ipcp_generate_summary): Break out of ipcp_driver.
(ipcp_driver): Do only execution and transformation.
(pass_ipa_cp): Make IPA_PASS.
* tree-ssa-ccp.c (fold_stmt_r): Check type before trying to fold
offset to address.
* ipa-inline.c (inline_indirect_intraprocedural_analysis): When doing
ipcp, some info is already available.
* ipa-prop.c (ipa_count_arguments): Grow edge lists as needed.
* tree-inline.c (remap_ssa_name): Unshare expression.
Index: tree-pass.h
===================================================================
*** tree-pass.h (revision 139234)
--- tree-pass.h (working copy)
*************** extern struct gimple_opt_pass pass_reset
*** 390,399 ****
/* IPA Passes */
extern struct ipa_opt_pass pass_ipa_inline;
extern struct simple_ipa_opt_pass pass_ipa_reference;
extern struct simple_ipa_opt_pass pass_ipa_matrix_reorg;
- extern struct simple_ipa_opt_pass pass_ipa_cp;
extern struct simple_ipa_opt_pass pass_ipa_early_inline;
extern struct simple_ipa_opt_pass pass_ipa_pure_const;
extern struct simple_ipa_opt_pass pass_ipa_type_escape;
--- 390,399 ----
/* IPA Passes */
extern struct ipa_opt_pass pass_ipa_inline;
+ extern struct ipa_opt_pass pass_ipa_cp;
extern struct simple_ipa_opt_pass pass_ipa_reference;
extern struct simple_ipa_opt_pass pass_ipa_matrix_reorg;
extern struct simple_ipa_opt_pass pass_ipa_early_inline;
extern struct simple_ipa_opt_pass pass_ipa_pure_const;
extern struct simple_ipa_opt_pass pass_ipa_type_escape;
Index: ipa-cp.c
===================================================================
*** ipa-cp.c (revision 139234)
--- ipa-cp.c (working copy)
*************** ipcp_init_cloned_node (struct cgraph_nod
*** 159,164 ****
--- 159,194 ----
ipa_create_param_decls_array (new_node);
}
+ /* Recompute all local information since node might've got new
+ direct calls after clonning. */
+ static void
+ ipcp_update_cloned_node (struct cgraph_node *new_node)
+ {
+ /* We might've introduced new direct calls. */
+ push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
+ current_function_decl = new_node->decl;
+ rebuild_cgraph_edges ();
+
+ if (flag_indirect_inlining)
+ {
+ struct cgraph_edge *cs;
+
+ ipa_check_create_node_params ();
+ ipa_count_formal_params (new_node);
+ ipa_create_param_decls_array (new_node);
+ ipa_detect_param_modifications (new_node);
+ ipa_analyze_params_uses (new_node);
+
+ for (cs = new_node->callees; cs; cs = cs->next_callee)
+ {
+ ipa_count_arguments (cs);
+ ipa_compute_jump_functions (cs);
+ }
+ }
+ pop_cfun ();
+ current_function_decl = NULL;
+ }
+
/* Return scale for NODE. */
static inline gcov_type
ipcp_get_node_scale (struct cgraph_node *node)
*************** constant_val_insert (tree parm1 ATTRIBUT
*** 377,387 ****
static tree
build_const_val (struct ipcp_lattice *lat, tree tree_type)
{
! tree const_val = NULL;
gcc_assert (ipcp_lat_is_const (lat));
! const_val = fold_convert (tree_type, lat->constant);
! return const_val;
}
/* Build the tree representing the constant and call constant_val_insert(). */
--- 407,433 ----
static tree
build_const_val (struct ipcp_lattice *lat, tree tree_type)
{
! tree val;
gcc_assert (ipcp_lat_is_const (lat));
! val = lat->constant;
!
! /* compute_jump_functions inserts FUNCTION_DECL as value of parameter
! when address of function is taken. It would make more sense to pass
! whole ADDR_EXPR, but for now compensate here. */
! if ((lat->type == IPA_CONST_VALUE
! && TREE_CODE (val) == FUNCTION_DECL)
! || lat->type == IPA_CONST_VALUE_REF)
! return build_fold_addr_expr_with_type (val, tree_type);
!
! if (!useless_type_conversion_p (tree_type, TREE_TYPE (val)))
! {
! if (fold_convertible_p (tree_type, val))
! return fold_build1 (NOP_EXPR, tree_type, val);
! else
! return fold_build1 (VIEW_CONVERT_EXPR, tree_type, val);
! }
! return val;
}
/* Build the tree representing the constant and call constant_val_insert(). */
*************** ipcp_init_stage (void)
*** 456,461 ****
--- 502,509 ----
/* Handle cases of functions with
a variable number of parameters. */
ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee));
+ if (flag_indirect_inlining)
+ ipa_compute_jump_functions (cs);
}
else
ipa_compute_jump_functions (cs);
*************** ipcp_insert_stage (void)
*** 966,972 ****
--- 1014,1023 ----
free_dominance_info (CDI_POST_DOMINATORS);
pop_cfun ();
current_function_decl = NULL;
+ /* We've possibly introduced direct calls. */
+ ipcp_update_cloned_node (node1);
}
+
if (dump_file)
dump_function_to_file (node1->decl, dump_file, dump_flags);
}
*************** ipcp_insert_stage (void)
*** 978,996 ****
static unsigned int
ipcp_driver (void)
{
- if (dump_file)
- fprintf (dump_file, "\nIPA constant propagation start:\n");
- ipa_check_create_node_params ();
- ipa_check_create_edge_args ();
- ipa_register_cgraph_hooks ();
- /* 1. Call the init stage to initialize
- the ipa_node_params and ipa_edge_args structures. */
- ipcp_init_stage ();
- if (dump_file)
- {
- fprintf (dump_file, "\nIPA structures before propagation:\n");
- ipcp_print_all_structures (dump_file);
- }
/* 2. Do the interprocedural propagation. */
ipcp_iterate_stage ();
if (dump_file)
--- 1029,1034 ----
*************** ipcp_driver (void)
*** 1015,1020 ****
--- 1053,1077 ----
return 0;
}
+ /* Note function body size. */
+ static void
+ ipcp_generate_summary (void)
+ {
+ if (dump_file)
+ fprintf (dump_file, "\nIPA constant propagation start:\n");
+ ipa_check_create_node_params ();
+ ipa_check_create_edge_args ();
+ ipa_register_cgraph_hooks ();
+ /* 1. Call the init stage to initialize
+ the ipa_node_params and ipa_edge_args structures. */
+ ipcp_init_stage ();
+ if (dump_file)
+ {
+ fprintf (dump_file, "\nIPA structures before propagation:\n");
+ ipcp_print_all_structures (dump_file);
+ }
+ }
+
/* Gate for IPCP optimization. */
static bool
cgraph_gate_cp (void)
*************** cgraph_gate_cp (void)
*** 1022,1031 ****
return flag_ipa_cp;
}
! struct simple_ipa_opt_pass pass_ipa_cp =
{
{
! SIMPLE_IPA_PASS,
"cp", /* name */
cgraph_gate_cp, /* gate */
ipcp_driver, /* execute */
--- 1079,1088 ----
return flag_ipa_cp;
}
! struct ipa_opt_pass pass_ipa_cp =
{
{
! IPA_PASS,
"cp", /* name */
cgraph_gate_cp, /* gate */
ipcp_driver, /* execute */
*************** struct simple_ipa_opt_pass pass_ipa_cp =
*** 1038,1042 ****
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_cgraph | TODO_dump_func /* todo_flags_finish */
! }
};
--- 1095,1106 ----
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_cgraph | TODO_dump_func /* todo_flags_finish */
! },
! ipcp_generate_summary, /* generate_summary */
! NULL, /* write_summary */
! NULL, /* read_summary */
! NULL, /* function_read_summary */
! 0, /* TODOs */
! NULL, /* function_transform */
! NULL, /* variable_transform */
};
Index: tree-ssa-ccp.c
===================================================================
*** tree-ssa-ccp.c (revision 139234)
--- tree-ssa-ccp.c (working copy)
*************** fold_stmt_r (tree *expr_p, int *walk_sub
*** 2300,2305 ****
--- 2300,2306 ----
*walk_subtrees = 0;
if (POINTER_TYPE_P (TREE_TYPE (expr))
+ && POINTER_TYPE_P (TREE_TYPE (TREE_TYPE (expr)))
&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0)))
&& (t = maybe_fold_offset_to_address (TREE_OPERAND (expr, 0),
integer_zero_node,
Index: ipa-inline.c
===================================================================
*** ipa-inline.c (revision 139234)
--- ipa-inline.c (working copy)
*************** inline_indirect_intraprocedural_analysis
*** 1633,1651 ****
{
struct cgraph_edge *cs;
! ipa_count_formal_params (node);
! ipa_create_param_decls_array (node);
! ipa_detect_param_modifications (node);
ipa_analyze_params_uses (node);
if (dump_file)
ipa_print_node_param_flags (dump_file, node);
! for (cs = node->callees; cs; cs = cs->next_callee)
! {
! ipa_count_arguments (cs);
! ipa_compute_jump_functions (cs);
! }
if (dump_file)
ipa_print_node_jump_functions (dump_file, node);
--- 1633,1655 ----
{
struct cgraph_edge *cs;
! if (!flag_ipa_cp)
! {
! ipa_count_formal_params (node);
! ipa_create_param_decls_array (node);
! ipa_detect_param_modifications (node);
! }
ipa_analyze_params_uses (node);
if (dump_file)
ipa_print_node_param_flags (dump_file, node);
! if (!flag_ipa_cp)
! for (cs = node->callees; cs; cs = cs->next_callee)
! {
! ipa_count_arguments (cs);
! ipa_compute_jump_functions (cs);
! }
if (dump_file)
ipa_print_node_jump_functions (dump_file, node);
*************** inline_generate_summary (void)
*** 1660,1666 ****
int nnodes = cgraph_postorder (order);
int i;
! if (flag_indirect_inlining)
{
ipa_register_cgraph_hooks ();
ipa_check_create_node_params ();
--- 1664,1670 ----
int nnodes = cgraph_postorder (order);
int i;
! if (flag_indirect_inlining && !flag_ipa_cp)
{
ipa_register_cgraph_hooks ();
ipa_check_create_node_params ();
Index: ipa-prop.c
===================================================================
*** ipa-prop.c (revision 139234)
--- ipa-prop.c (working copy)
*************** ipa_count_arguments (struct cgraph_edge
*** 238,243 ****
--- 238,247 ----
stmt = cs->call_stmt;
gcc_assert (is_gimple_call (stmt));
arg_num = gimple_call_num_args (stmt);
+ 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, cgraph_edge_max_uid + 1);
ipa_set_cs_argument_count (IPA_EDGE_REF (cs), arg_num);
}
Index: tree-inline.c
===================================================================
*** tree-inline.c (revision 139234)
--- tree-inline.c (working copy)
*************** remap_ssa_name (tree name, copy_body_dat
*** 161,167 ****
n = (tree *) pointer_map_contains (id->decl_map, name);
if (n)
! return *n;
/* Do not set DEF_STMT yet as statement is not copied yet. We do that
in copy_bb. */
--- 161,167 ----
n = (tree *) pointer_map_contains (id->decl_map, name);
if (n)
! return unshare_expr (*n);
/* Do not set DEF_STMT yet as statement is not copied yet. We do that
in copy_bb. */
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2008-08-20 16:04 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-08-20 17:03 Make ipcp IPA_PASS Jan Hubicka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).