/* Unreachable nodes should have been eliminated before ipcp. */
gcc_assert (node->needed || node->reachable);
+ node->local.versionable = tree_versionable_function_p (node->decl);
ipa_initialize_node_params (node);
ipa_detect_param_modifications (node);
}
static bool
ipcp_versionable_function_p (struct cgraph_node *node)
{
- tree decl = node->decl;
- basic_block bb;
+ struct cgraph_edge *edge;
/* There are a number of generic reasons functions cannot be versioned. */
- if (!tree_versionable_function_p (decl))
+ if (!node->local.versionable)
return false;
- /* Removing arguments doesn't work if the function takes varargs. */
- if (DECL_STRUCT_FUNCTION (decl)->stdarg)
- return false;
-
- /* Removing arguments doesn't work if we use __builtin_apply_args. */
- FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (decl))
+ /* Removing arguments doesn't work if the function takes varargs
+ or use __builtin_apply_args. */
+ for (edge = node->callees; edge; edge = edge->next_callee)
{
- gimple_stmt_iterator gsi;
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- const_gimple stmt = gsi_stmt (gsi);
- tree t;
-
- if (!is_gimple_call (stmt))
- continue;
- t = gimple_call_fndecl (stmt);
- if (t == NULL_TREE)
- continue;
- if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
- && DECL_FUNCTION_CODE (t) == BUILT_IN_APPLY_ARGS)
- return false;
- }
+ tree t = edge->callee->decl;
+ if (DECL_BUILT_IN_CLASS (t) == BUILT_IN_NORMAL
+ && (DECL_FUNCTION_CODE (t) == BUILT_IN_APPLY_ARGS
+ || DECL_FUNCTION_CODE (t) == BUILT_IN_VA_START))
+ return false;
}
return true;
for (i = 0; i < count; i++)
{
struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
- tree parm_tree = ipa_get_param (info, i);
/* We can proactively remove obviously unused arguments. */
- if (is_gimple_reg (parm_tree)
- && !gimple_default_def (DECL_STRUCT_FUNCTION (orig_node->decl),
- parm_tree))
+ if (!ipa_is_param_used (info, i))
{
bitmap_set_bit (args_to_skip, i);
continue;
for (i = 0; i < count; i++)
{
struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
- tree parm_tree = ipa_get_param (info, i);
/* We can proactively remove obviously unused arguments. */
- if (is_gimple_reg (parm_tree)
- && !gimple_default_def (DECL_STRUCT_FUNCTION (node->decl),
- parm_tree))
+ if (!ipa_is_param_used (info, i))
removable_args++;
if (lat->type == IPA_CONST_VALUE)
for (i = 0; i < count; i++)
{
struct ipcp_lattice *lat = ipcp_get_lattice (info, i);
- tree parm_tree = ipa_get_param (info, i);
if (ipcp_lat_is_insertable (lat)
/* Do not count obviously unused arguments. */
- && (!is_gimple_reg (parm_tree)
- || gimple_default_def (DECL_STRUCT_FUNCTION (node->decl),
- parm_tree)))
+ && ipa_is_param_used (info, i))
const_param++;
}
return const_param;
parm_tree = ipa_get_param (info, i);
/* We can proactively remove obviously unused arguments. */
- if (is_gimple_reg (parm_tree)
- && !gimple_default_def (DECL_STRUCT_FUNCTION (node->decl),
- parm_tree))
+ if (!ipa_is_param_used (info, i))
{
bitmap_set_bit (args_to_skip, i);
continue;
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_cgraph | TODO_dump_func |
- TODO_remove_functions /* todo_flags_finish */
+ TODO_remove_functions | TODO_ggc_collect /* todo_flags_finish */
},
ipcp_generate_summary, /* generate_summary */
ipcp_write_summary, /* write_summary */