cgraph.c (cgraph_remove_node): Do not remove nested nodes.

* cgraph.c (cgraph_remove_node): Do not remove nested nodes.

	* cgraph.h (cgraph_maybe_hot_edge_p): Declare.
	* ipa-cp.c (n_cloning_candidates): New static variable.
	(ipcp_print_profile_data, ipcp_function_scale_print): Forward declare.
	(ipcp_print_all_lattices): Improve debug output.
	(ipcp_cloning_candidate_p): New function.
	(ipcp_initialize_node_lattices): Use it.
	(ipcp_init_stage): Do only analyzis here; prettier debug output.
	(ipcp_propagate_stage): Prettier debug output.
	(ipcp_iterate_stage): Initialize latices here; prettier debug output.
	(ipcp_print_all_structures): Remove.
	(ipcp_need_redirect_p): Test !n_cloning_candidates.
	(ipcp_insert_stage): Prettier debug output; call
	cgraph_remove_unreachable_nodes before propagating.
	(pass_ipa_cp): Schedule function removal pass.
	* ipa-inline.c (inline_indirect_intraprocedural_analysis): Better
	debug output.
	(cgraph_maybe_hot_edge_p): Move to ...
	* predict.c (cgraph_maybe_hot_edge_p) ... here.
	* opts.c (flag_ipa_cp_set, flag_ipa_cp_clone_set): New.
	(common_handle_option): Set them; enable ipa-cp when profiling.
	* ipa-prop.c (ipa_print_node_jump_functions): Prettier output.
	(ipa_print_all_jump_functions): Likewise.
	(ipa_print_all_tree_maps, ipa_print_node_param_flags): Remove.
	(ipa_print_node_params, ipa_print_all_params): New.
	* ipa-prop.h (ipa_print_all_tree_maps, ipa_print_node_param_flags,
	ipa_print_all_param_flags): Remove.
	(ipa_print_node_params, ipa_print_all_params): New.

From-SVN: r139772
This commit is contained in:
Jan Hubicka 2008-08-29 18:41:35 +02:00 committed by Jan Hubicka
parent a1f626ad3b
commit ca30a5396a
11 changed files with 279 additions and 126 deletions

View File

@ -1,3 +1,35 @@
2008-08-29 Jan Hubicka <jh@suse.cz>
* cgraph.c (cgraph_remove_node): Do not remove nested nodes.
* cgraph.h (cgraph_maybe_hot_edge_p): Declare.
* ipa-cp.c (n_cloning_candidates): New static variable.
(ipcp_print_profile_data, ipcp_function_scale_print): Forward declare.
(ipcp_print_all_lattices): Improve debug output.
(ipcp_cloning_candidate_p): New function.
(ipcp_initialize_node_lattices): Use it.
(ipcp_init_stage): Do only analyzis here; prettier debug output.
(ipcp_propagate_stage): Prettier debug output.
(ipcp_iterate_stage): Initialize latices here; prettier debug output.
(ipcp_print_all_structures): Remove.
(ipcp_need_redirect_p): Test !n_cloning_candidates.
(ipcp_insert_stage): Prettier debug output; call
cgraph_remove_unreachable_nodes before propagating.
(pass_ipa_cp): Schedule function removal pass.
* ipa-inline.c (inline_indirect_intraprocedural_analysis): Better
debug output.
(cgraph_maybe_hot_edge_p): Move to ...
* predict.c (cgraph_maybe_hot_edge_p) ... here.
* opts.c (flag_ipa_cp_set, flag_ipa_cp_clone_set): New.
(common_handle_option): Set them; enable ipa-cp when profiling.
* ipa-prop.c (ipa_print_node_jump_functions): Prettier output.
(ipa_print_all_jump_functions): Likewise.
(ipa_print_all_tree_maps, ipa_print_node_param_flags): Remove.
(ipa_print_node_params, ipa_print_all_params): New.
* ipa-prop.h (ipa_print_all_tree_maps, ipa_print_node_param_flags,
ipa_print_all_param_flags): Remove.
(ipa_print_node_params, ipa_print_all_params): New.
2008-08-29 Bob Wilson <bob.wilson@acm.org>
* config/xtensa/xtensa.c (xtensa_secondary_reload_class): Revert

View File

@ -857,6 +857,7 @@ cgraph_remove_node (struct cgraph_node *node)
{
void **slot;
bool kill_body = false;
struct cgraph_node *n;
cgraph_call_node_removal_hooks (node);
cgraph_node_remove_callers (node);
@ -865,8 +866,9 @@ cgraph_remove_node (struct cgraph_node *node)
/* Incremental inlining access removed nodes stored in the postorder list.
*/
node->needed = node->reachable = false;
while (node->nested)
cgraph_remove_node (node->nested);
for (n = node->nested; n; n = n->next_nested)
n->origin = NULL;
node->nested = NULL;
if (node->origin)
{
struct cgraph_node **node2 = &node->origin->nested;

View File

@ -390,6 +390,8 @@ int compute_call_stmt_bb_frequency (basic_block bb);
bool cgraph_remove_unreachable_nodes (bool, FILE *);
int cgraph_postorder (struct cgraph_node **);
bool cgraph_maybe_hot_edge_p (struct cgraph_edge *e);
/* In varpool.c */
extern GTY(()) struct varpool_node *varpool_nodes_queue;

View File

@ -135,6 +135,21 @@ along with GCC; see the file COPYING3. If not see
#include "fibheap.h"
#include "params.h"
/* Number of functions identified as candidates for cloning. When not cloning
we can simplify iterate stage not forcing it to go through the decision
on what is profitable and what not. */
static int n_cloning_candidates;
/* Maximal count found in program. */
static gcov_type max_count;
/* Cgraph nodes that has been completely replaced by cloning during iterate
* stage and will be removed after ipcp is finished. */
static bitmap dead_nodes;
static void ipcp_print_profile_data (FILE *);
static void ipcp_function_scale_print (FILE *);
/* Get the original node field of ipa_node_params associated with node NODE. */
static inline struct cgraph_node *
ipcp_get_orig_node (struct cgraph_node *node)
@ -174,7 +189,7 @@ ipcp_analyze_node (struct cgraph_node *node)
}
/* Recompute all local information since node might've got new
direct calls after clonning. */
direct calls after cloning. */
static void
ipcp_update_cloned_node (struct cgraph_node *new_node)
{
@ -337,7 +352,7 @@ ipcp_print_all_lattices (FILE * f)
struct cgraph_node *node;
int i, count;
fprintf (f, "\nLATTICE PRINT\n");
fprintf (f, "\nLattice:\n");
for (node = cgraph_nodes; node; node = node->next)
{
struct ipa_node_params *info;
@ -345,13 +360,13 @@ ipcp_print_all_lattices (FILE * f)
if (!node->analyzed)
continue;
info = IPA_NODE_REF (node);
fprintf (f, "Printing lattices %s:\n", cgraph_node_name (node));
fprintf (f, " Node: %s:\n", cgraph_node_name (node));
count = ipa_get_param_count (info);
for (i = 0; i < count; i++)
{
struct ipcp_lattice *lat = ipcp_get_ith_lattice (info, i);
fprintf (f, " param [%d]: ", i);
fprintf (f, " param [%d]: ", i);
if (lat->type == IPA_CONST_VALUE)
{
fprintf (f, "type is CONST ");
@ -366,6 +381,100 @@ ipcp_print_all_lattices (FILE * f)
}
}
/* Return true if this NODE is viable candidate for cloning. */
static bool
ipcp_cloning_candidate_p (struct cgraph_node *node)
{
int n_calls = 0;
int n_hot_calls = 0;
gcov_type direct_call_sum = 0;
struct cgraph_edge *e;
/* We never clone functions that are not visible from outside.
FIXME: in future we should clone such functions when they are called with
different constants, but current ipcp implementation is not good on this.
*/
if (!node->needed || !node->analyzed)
return false;
if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
{
if (dump_file)
fprintf (dump_file, "Not considering %s for cloning; body is overwrittable.\n",
cgraph_node_name (node));
return false;
}
if (!tree_versionable_function_p (node->decl))
{
if (dump_file)
fprintf (dump_file, "Not considering %s for cloning; body is not versionable.\n",
cgraph_node_name (node));
return false;
}
for (e = node->callers; e; e = e->next_caller)
{
direct_call_sum += e->count;
n_calls ++;
if (cgraph_maybe_hot_edge_p (e))
n_hot_calls ++;
}
if (!n_calls)
{
if (dump_file)
fprintf (dump_file, "Not considering %s for cloning; no direct calls.\n",
cgraph_node_name (node));
return false;
}
if (node->local.inline_summary.self_insns < n_calls)
{
if (dump_file)
fprintf (dump_file, "Considering %s for cloning; code would shrink.\n",
cgraph_node_name (node));
return true;
}
if (!flag_ipa_cp_clone)
{
if (dump_file)
fprintf (dump_file, "Not considering %s for cloning; -fipa-cp-clone disabled.\n",
cgraph_node_name (node));
return false;
}
if (!optimize_function_for_speed_p (DECL_STRUCT_FUNCTION (node->decl)))
{
if (dump_file)
fprintf (dump_file, "Not considering %s for cloning; optimizing it for size.\n",
cgraph_node_name (node));
return false;
}
/* When profile is available and function is hot, propagate into it even if
calls seems cold; constant propagation can improve function's speed
significandly. */
if (max_count)
{
if (direct_call_sum > node->count * 90 / 100)
{
if (dump_file)
fprintf (dump_file, "Considering %s for cloning; usually called directly.\n",
cgraph_node_name (node));
return true;
}
}
if (!n_hot_calls)
{
if (dump_file)
fprintf (dump_file, "Not considering %s for cloning; no hot calls.\n",
cgraph_node_name (node));
}
if (dump_file)
fprintf (dump_file, "Considering %s for cloning.\n",
cgraph_node_name (node));
return true;
}
/* Initialize ipcp_lattices array. The lattices corresponding to supported
types (integers, real types and Fortran constants defined as const_decls)
are initialized to IPA_TOP, the rest of them to IPA_BOTTOM. */
@ -374,18 +483,24 @@ ipcp_initialize_node_lattices (struct cgraph_node *node)
{
int i;
struct ipa_node_params *info = IPA_NODE_REF (node);
enum ipa_lattice_type type;
info->ipcp_lattices = XCNEWVEC (struct ipcp_lattice,
ipa_get_param_count (info));
if (ipa_is_called_with_var_arguments (info))
type = IPA_BOTTOM;
else if (!node->needed)
type = IPA_TOP;
/* When cloning is allowed, we can assume that externally visible functions
are not called. We will compensate this by cloning later. */
if (flag_ipa_cp_clone || !node->needed)
for (i = 0; i < ipa_get_param_count (info) ; i++)
ipcp_get_ith_lattice (info, i)->type = IPA_TOP;
else if (ipcp_cloning_candidate_p (node))
type = IPA_TOP, n_cloning_candidates ++;
else
for (i = 0; i < ipa_get_param_count (info) ; i++)
ipcp_get_ith_lattice (info, i)->type = IPA_BOTTOM;
type = IPA_BOTTOM;
for (i = 0; i < ipa_get_param_count (info) ; i++)
ipcp_get_ith_lattice (info, i)->type = type;
}
/* build INTEGER_CST tree with type TREE_TYPE and value according to LAT.
@ -438,11 +553,7 @@ ipcp_init_stage (void)
for (node = cgraph_nodes; node; node = node->next)
if (node->analyzed)
{
ipcp_analyze_node (node);
ipcp_initialize_node_lattices (node);
ipcp_compute_node_scale (node);
}
ipcp_analyze_node (node);
for (node = cgraph_nodes; node; node = node->next)
{
if (!node->analyzed)
@ -489,6 +600,13 @@ ipcp_change_tops_to_bottom (void)
if (lat->type == IPA_TOP)
{
prop_again = true;
if (dump_file)
{
fprintf (dump_file, "Forcing param ");
print_generic_expr (dump_file, ipa_get_ith_param (info, i), 0);
fprintf (dump_file, " of node %s to bottom.\n",
cgraph_node_name (node));
}
lat->type = IPA_BOTTOM;
}
}
@ -512,6 +630,7 @@ ipcp_propagate_stage (void)
ipa_check_create_node_params ();
ipa_check_create_edge_args ();
/* Initialize worklist to contain all functions. */
wl = ipa_init_func_list ();
while (wl)
@ -550,11 +669,37 @@ ipcp_propagate_stage (void)
static void
ipcp_iterate_stage (void)
{
struct cgraph_node *node;
n_cloning_candidates = 0;
if (dump_file)
fprintf (dump_file, "\nIPA iterate stage:\n\n");
for (node = cgraph_nodes; node; node = node->next)
{
ipcp_initialize_node_lattices (node);
ipcp_compute_node_scale (node);
}
if (dump_file && (dump_flags & TDF_DETAILS))
{
ipcp_print_all_lattices (dump_file);
ipcp_function_scale_print (dump_file);
}
ipcp_propagate_stage ();
if (ipcp_change_tops_to_bottom ())
/* Some lattices have changed from IPA_TOP to IPA_BOTTOM.
This change should be propagated. */
ipcp_propagate_stage ();
{
gcc_assert (n_cloning_candidates);
ipcp_propagate_stage ();
}
if (dump_file)
{
fprintf (dump_file, "\nIPA lattices after propagation:\n");
ipcp_print_all_lattices (dump_file);
if (dump_flags & TDF_DETAILS)
ipcp_print_profile_data (dump_file);
}
}
/* Check conditions to forbid constant insertion to function described by
@ -708,17 +853,6 @@ ipcp_print_bb_profiles (FILE * f)
}
}
/* Print all IPCP data structures to F. */
static void
ipcp_print_all_structures (FILE * f)
{
ipcp_print_all_lattices (f);
ipcp_function_scale_print (f);
ipa_print_all_tree_maps (f);
ipa_print_all_param_flags (f);
ipa_print_all_jump_functions (f);
}
/* Print profile info for all functions. */
static void
ipcp_print_profile_data (FILE * f)
@ -771,7 +905,7 @@ ipcp_need_redirect_p (struct cgraph_edge *cs)
struct ipa_jump_func *jump_func;
struct cgraph_node *node = cs->callee, *orig;
if (!flag_ipa_cp_clone)
if (!n_cloning_candidates)
return false;
if ((orig = ipcp_get_orig_node (node)) != NULL)
@ -908,10 +1042,6 @@ ipcp_update_profiling (void)
}
}
/* Maximal count found in program. */
static gcov_type max_count;
bitmap dead_nodes;
/* Return true if original clone needs to be preserved. */
static bool
ipcp_need_original_clone_p (struct cgraph_node *node)
@ -1008,6 +1138,8 @@ ipcp_insert_stage (void)
ipa_check_create_node_params ();
ipa_check_create_edge_args ();
if (dump_file)
fprintf (dump_file, "\nIPA insert stage:\n\n");
dead_nodes = BITMAP_ALLOC (NULL);
@ -1156,18 +1288,19 @@ ipcp_insert_stage (void)
static unsigned int
ipcp_driver (void)
{
/* 2. Do the interprocedural propagation. */
ipcp_iterate_stage ();
cgraph_remove_unreachable_nodes (true,dump_file);
if (dump_file)
{
fprintf (dump_file, "\nIPA structures after propagation:\n");
ipcp_print_all_structures (dump_file);
fprintf (dump_file, "\nProfiling info before insert stage:\n");
ipcp_print_profile_data (dump_file);
fprintf (dump_file, "\nIPA structures before propagation:\n");
if (dump_flags & TDF_DETAILS)
ipa_print_all_params (dump_file);
ipa_print_all_jump_functions (dump_file);
}
/* 2. Do the interprocedural propagation. */
ipcp_iterate_stage ();
/* 3. Insert the constants found to the functions. */
ipcp_insert_stage ();
if (dump_file)
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "\nProfiling info after insert stage:\n");
ipcp_print_profile_data (dump_file);
@ -1176,7 +1309,6 @@ ipcp_driver (void)
free_all_ipa_structures_after_ipa_cp ();
if (dump_file)
fprintf (dump_file, "\nIPA constant propagation end\n");
cgraph_remove_unreachable_nodes (true, NULL);
return 0;
}
@ -1192,11 +1324,6 @@ ipcp_generate_summary (void)
/* 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. */
@ -1221,7 +1348,8 @@ struct ipa_opt_pass pass_ipa_cp =
PROP_trees, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_cgraph | TODO_dump_func /* todo_flags_finish */
TODO_dump_cgraph | TODO_dump_func |
TODO_remove_functions /* todo_flags_finish */
},
ipcp_generate_summary, /* generate_summary */
NULL, /* write_summary */

View File

@ -468,26 +468,6 @@ cgraph_recursive_inlining_p (struct cgraph_node *to,
return recursive;
}
/* Return true if the call can be hot. */
static bool
cgraph_maybe_hot_edge_p (struct cgraph_edge *edge)
{
if (profile_info && flag_branch_probabilities
&& (edge->count
<= profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION)))
return false;
if (lookup_attribute ("cold", DECL_ATTRIBUTES (edge->callee->decl))
|| lookup_attribute ("cold", DECL_ATTRIBUTES (edge->caller->decl)))
return false;
if (lookup_attribute ("hot", DECL_ATTRIBUTES (edge->caller->decl)))
return true;
if (flag_guess_branch_prob
&& edge->frequency < (CGRAPH_FREQ_MAX
/ PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION)))
return false;
return true;
}
/* A cost model driving the inlining heuristics in a way so the edges with
smallest badness are inlined first. After each inlining is performed
the costs of all caller edges of nodes affected are recomputed so the
@ -1646,9 +1626,6 @@ inline_indirect_intraprocedural_analysis (struct cgraph_node *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)
{
@ -1657,7 +1634,10 @@ inline_indirect_intraprocedural_analysis (struct cgraph_node *node)
}
if (dump_file)
ipa_print_node_jump_functions (dump_file, node);
{
ipa_print_node_params (dump_file, node);
ipa_print_node_jump_functions (dump_file, node);
}
}
/* Note function body size. */

View File

@ -255,13 +255,13 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
struct ipa_jump_func *jump_func;
enum jump_func_type type;
fprintf (f, "JUMP FUNCTIONS OF CALLER %s:\n", cgraph_node_name (node));
fprintf (f, " Jump functions of caller %s:\n", cgraph_node_name (node));
for (cs = node->callees; cs; cs = cs->next_callee)
{
if (!ipa_edge_args_info_available_for_edge_p (cs))
continue;
fprintf (f, "callsite %s ", cgraph_node_name (node));
fprintf (f, " callsite %s ", cgraph_node_name (node));
fprintf (f, "-> %s :: \n", cgraph_node_name (cs->callee));
count = ipa_get_cs_argument_count (IPA_EDGE_REF (cs));
@ -270,7 +270,7 @@ ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node)
jump_func = ipa_get_ith_jump_func (IPA_EDGE_REF (cs), i);
type = jump_func->type;
fprintf (f, " param %d: ", i);
fprintf (f, " param %d: ", i);
if (type == IPA_UNKNOWN)
fprintf (f, "UNKNOWN\n");
else if (type == IPA_CONST)
@ -303,7 +303,7 @@ ipa_print_all_jump_functions (FILE *f)
{
struct cgraph_node *node;
fprintf (f, "\nCALLSITE PARAM PRINT\n");
fprintf (f, "\nJump functions:\n");
for (node = cgraph_nodes; node; node = node->next)
{
ipa_print_node_jump_functions (f, node);
@ -1207,48 +1207,23 @@ free_all_ipa_structures_after_iinln (void)
/* Print ipa_tree_map data structures of all functions in the
callgraph to F. */
void
ipa_print_all_tree_maps (FILE * f)
ipa_print_node_params (FILE * f, struct cgraph_node *node)
{
int i, count;
tree temp;
struct cgraph_node *node;
fprintf (f, "\nPARAM TREE MAP PRINT\n");
for (node = cgraph_nodes; node; node = node->next)
{
struct ipa_node_params *info;
if (!node->analyzed)
continue;
info = IPA_NODE_REF (node);
fprintf (f, "function %s Trees :: \n", cgraph_node_name (node));
count = ipa_get_param_count (info);
for (i = 0; i < count; i++)
{
temp = ipa_get_ith_param (info, i);
if (TREE_CODE (temp) == PARM_DECL)
fprintf (f, " param [%d] : %s\n", i,
(*lang_hooks.decl_printable_name) (temp, 2));
}
}
}
/* Print param_flags data structures of the NODE to F. */
void
ipa_print_node_param_flags (FILE * f, struct cgraph_node *node)
{
int i, count;
struct ipa_node_params *info;
if (!node->analyzed)
return;
info = IPA_NODE_REF (node);
fprintf (f, "PARAM FLAGS of function %s: \n", cgraph_node_name (node));
fprintf (f, " function %s Trees :: \n", cgraph_node_name (node));
count = ipa_get_param_count (info);
for (i = 0; i < count; i++)
{
fprintf (f, " param %d flags:", i);
temp = ipa_get_ith_param (info, i);
if (TREE_CODE (temp) == PARM_DECL)
fprintf (f, " param %d : %s", i,
(*lang_hooks.decl_printable_name) (temp, 2));
if (ipa_is_ith_param_modified (info, i))
fprintf (f, " modified");
if (ipa_is_ith_param_called (info, i))
@ -1257,14 +1232,14 @@ ipa_print_node_param_flags (FILE * f, struct cgraph_node *node)
}
}
/* Print param_flags data structures of all functions in the
/* Print ipa_tree_map data structures of all functions in the
callgraph to F. */
void
ipa_print_all_param_flags (FILE * f)
ipa_print_all_params (FILE * f)
{
struct cgraph_node *node;
fprintf (f, "\nIPA PARAM FLAGS DUMP\n");
fprintf (f, "\nFunction parameters:\n");
for (node = cgraph_nodes; node; node = node->next)
ipa_print_node_param_flags (f, node);
ipa_print_node_params (f, node);
}

View File

@ -381,9 +381,8 @@ void ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
VEC (cgraph_edge_p, heap) *new_edges);
/* Debugging interface. */
void ipa_print_all_tree_maps (FILE *);
void ipa_print_node_param_flags (FILE * f, struct cgraph_node *node);
void ipa_print_all_param_flags (FILE *);
void ipa_print_node_params (FILE *, struct cgraph_node *node);
void ipa_print_all_params (FILE *);
void ipa_print_node_jump_functions (FILE *f, struct cgraph_node *node);
void ipa_print_all_jump_functions (FILE * f);

View File

@ -347,7 +347,7 @@ static bool profile_arc_flag_set, flag_profile_values_set;
static bool flag_unroll_loops_set, flag_tracer_set;
static bool flag_value_profile_transformations_set;
static bool flag_peel_loops_set, flag_branch_probabilities_set;
static bool flag_inline_functions_set;
static bool flag_inline_functions_set, flag_ipa_cp_set, flag_ipa_cp_clone_set;
/* Functions excluded from profiling. */
@ -1031,9 +1031,6 @@ decode_options (unsigned int argc, const char **argv)
/* We want to crossjump as much as possible. */
set_param_value ("min-crossjump-insns", 1);
/* Do not perform clonning in ipcp. */
flag_ipa_cp_clone = 0;
}
else
set_param_value ("min-crossjump-insns", initial_min_crossjump_insns);
@ -1837,6 +1834,11 @@ common_handle_option (size_t scode, const char *arg, int value,
flag_value_profile_transformations = value;
if (!flag_inline_functions_set)
flag_inline_functions = value;
if (!flag_ipa_cp_set)
flag_ipa_cp = value;
if (!flag_ipa_cp_clone_set
&& value && flag_ipa_cp)
flag_ipa_cp_clone = value;
break;
case OPT_fprofile_generate_:
@ -1994,6 +1996,14 @@ common_handle_option (size_t scode, const char *arg, int value,
flag_tracer_set = true;
break;
case OPT_fipa_cp:
flag_ipa_cp_set = true;
break;
case OPT_fipa_cp_clone:
flag_ipa_cp_clone_set = true;
break;
case OPT_funroll_loops:
flag_unroll_loops_set = true;
break;

View File

@ -138,6 +138,27 @@ maybe_hot_bb_p (const_basic_block bb)
return maybe_hot_frequency_p (bb->frequency);
}
/* Return true if the call can be hot. */
bool
cgraph_maybe_hot_edge_p (struct cgraph_edge *edge)
{
if (profile_info && flag_branch_probabilities
&& (edge->count
<= profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION)))
return false;
if (lookup_attribute ("cold", DECL_ATTRIBUTES (edge->callee->decl))
|| lookup_attribute ("cold", DECL_ATTRIBUTES (edge->caller->decl)))
return false;
if (lookup_attribute ("hot", DECL_ATTRIBUTES (edge->caller->decl)))
return true;
if (flag_guess_branch_prob
&& edge->frequency < (CGRAPH_FREQ_MAX
/ PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION)))
return false;
return true;
}
/* Return true in case BB can be CPU intensive and should be optimized
for maximal performance. */

View File

@ -1,3 +1,7 @@
2008-08-29 Jan Hubicka <jh@suse.cz>
* gcc.dg/ipa/modif-1.c: Update template.
2008-08-29 Jan Hubicka <jh@suse.cz>
* gcc.dg/ipa/ipa-1.c: Fix template for better debug output.

View File

@ -1,6 +1,6 @@
/* Verify that modification analysis detects modfications. */
/* { dg-do compile } */
/* { dg-options "-O3 -c -fdump-ipa-inline -fno-early-inlining" } */
/* { dg-options "-O3 -c -fdump-ipa-inline-details -fno-early-inlining" } */
struct whatever
{
@ -33,12 +33,12 @@ void the_test (struct whatever u, struct whatever v,
func4 (&l);
}
/* { dg-final { scan-ipa-dump-not "param 0 flags:\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump "param 1 flags:\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump "param 2 flags:\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump "param 3 flags:\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump-not "param 4 flags:\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump "param 5 flags:\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump "param 6 flags:\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump "param 7 flags:\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump-not "param 0\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump "param 1\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump "param 2\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump "param 3\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump-not "param 4\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump "param 5\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump "param 6\[^\\n\]*modified" "inline" } } */
/* { dg-final { scan-ipa-dump "param 7\[^\\n\]*modified" "inline" } } */
/* { dg-final { cleanup-ipa-dump "inline" } } */