cgraph.c (dump_cgraph_node): Dump same_comdat_group, only_called_at_startup and only_called_at_exit.
* cgraph.c (dump_cgraph_node): Dump same_comdat_group, only_called_at_startup and only_called_at_exit. (cgraph_propagate_frequency): Compute only_called_at_startup and only_called_at_exit. * cgraph.h (struct cgraph_node): New fileds only_called_at_startup and only_called_at_exit. * lto-cgraph.c (lto_output_node, input_overwrite_node): Stream the new flags. * predict.c (compute_function_frequency): Initialize the new flags. From-SVN: r165560
This commit is contained in:
parent
6eb6875d7e
commit
844db5d09e
|
@ -1,3 +1,15 @@
|
|||
2010-10-16 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* cgraph.c (dump_cgraph_node): Dump same_comdat_group,
|
||||
only_called_at_startup and only_called_at_exit.
|
||||
(cgraph_propagate_frequency): Compute only_called_at_startup and
|
||||
only_called_at_exit.
|
||||
* cgraph.h (struct cgraph_node): New fileds only_called_at_startup and
|
||||
only_called_at_exit.
|
||||
* lto-cgraph.c (lto_output_node, input_overwrite_node): Stream the new
|
||||
flags.
|
||||
* predict.c (compute_function_frequency): Initialize the new flags.
|
||||
|
||||
2010-10-16 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gimplify.c (gimplify_type_sizes) <ARRAY_TYPE>: If the type is to be
|
||||
|
|
86
gcc/cgraph.c
86
gcc/cgraph.c
|
@ -1816,6 +1816,10 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
|
|||
fprintf (f, " (inline copy in %s/%i)",
|
||||
cgraph_node_name (node->global.inlined_to),
|
||||
node->global.inlined_to->uid);
|
||||
if (node->same_comdat_group)
|
||||
fprintf (f, " (same comdat group as %s/%i)",
|
||||
cgraph_node_name (node->same_comdat_group),
|
||||
node->same_comdat_group->uid);
|
||||
if (node->clone_of)
|
||||
fprintf (f, " (clone of %s/%i)",
|
||||
cgraph_node_name (node->clone_of),
|
||||
|
@ -1876,6 +1880,10 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
|
|||
fprintf (f, " redefined_extern_inline");
|
||||
if (TREE_ASM_WRITTEN (node->decl))
|
||||
fprintf (f, " asm_written");
|
||||
if (node->only_called_at_startup)
|
||||
fprintf (f, " only_called_at_startup");
|
||||
if (node->only_called_at_exit)
|
||||
fprintf (f, " only_called_at_exit");
|
||||
|
||||
fprintf (f, "\n called by: ");
|
||||
for (edge = node->callers; edge; edge = edge->next_caller)
|
||||
|
@ -2627,20 +2635,32 @@ bool
|
|||
cgraph_propagate_frequency (struct cgraph_node *node)
|
||||
{
|
||||
bool maybe_unlikely_executed = true, maybe_executed_once = true;
|
||||
bool only_called_at_startup = true;
|
||||
bool only_called_at_exit = true;
|
||||
bool changed = false;
|
||||
struct cgraph_edge *edge;
|
||||
|
||||
if (!node->local.local)
|
||||
return false;
|
||||
gcc_assert (node->analyzed);
|
||||
if (node->frequency == NODE_FREQUENCY_HOT)
|
||||
return false;
|
||||
if (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
|
||||
return false;
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, "Processing frequency %s\n", cgraph_node_name (node));
|
||||
|
||||
for (edge = node->callers;
|
||||
edge && (maybe_unlikely_executed || maybe_executed_once);
|
||||
edge && (maybe_unlikely_executed || maybe_executed_once
|
||||
|| only_called_at_startup || only_called_at_exit);
|
||||
edge = edge->next_caller)
|
||||
{
|
||||
if (edge->caller != node)
|
||||
{
|
||||
only_called_at_startup &= edge->caller->only_called_at_startup;
|
||||
/* It makes snese to put main() together with the static constructors.
|
||||
It will be executed for sure, but rest of functions called from
|
||||
main are definitly not at startup only. */
|
||||
if (MAIN_NAME_P (DECL_NAME (edge->caller->decl)))
|
||||
only_called_at_startup = 0;
|
||||
only_called_at_exit &= edge->caller->only_called_at_exit;
|
||||
}
|
||||
if (!edge->frequency)
|
||||
continue;
|
||||
switch (edge->caller->frequency)
|
||||
|
@ -2649,7 +2669,8 @@ cgraph_propagate_frequency (struct cgraph_node *node)
|
|||
break;
|
||||
case NODE_FREQUENCY_EXECUTED_ONCE:
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, " Called by %s that is executed once\n", cgraph_node_name (node));
|
||||
fprintf (dump_file, " Called by %s that is executed once\n",
|
||||
cgraph_node_name (node));
|
||||
maybe_unlikely_executed = false;
|
||||
if (edge->loop_nest)
|
||||
{
|
||||
|
@ -2661,27 +2682,52 @@ cgraph_propagate_frequency (struct cgraph_node *node)
|
|||
case NODE_FREQUENCY_HOT:
|
||||
case NODE_FREQUENCY_NORMAL:
|
||||
if (dump_file && (dump_flags & TDF_DETAILS))
|
||||
fprintf (dump_file, " Called by %s that is normal or hot\n", cgraph_node_name (node));
|
||||
fprintf (dump_file, " Called by %s that is normal or hot\n",
|
||||
cgraph_node_name (node));
|
||||
maybe_unlikely_executed = false;
|
||||
maybe_executed_once = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (maybe_unlikely_executed)
|
||||
{
|
||||
node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED;
|
||||
if ((only_called_at_startup && !only_called_at_exit)
|
||||
&& !node->only_called_at_startup)
|
||||
{
|
||||
node->only_called_at_startup = true;
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "Node %s promoted to unlikely executed.\n", cgraph_node_name (node));
|
||||
return true;
|
||||
}
|
||||
if (maybe_executed_once && node->frequency != NODE_FREQUENCY_EXECUTED_ONCE)
|
||||
{
|
||||
node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
|
||||
fprintf (dump_file, "Node %s promoted to only called at startup.\n",
|
||||
cgraph_node_name (node));
|
||||
changed = true;
|
||||
}
|
||||
if ((only_called_at_exit && !only_called_at_startup)
|
||||
&& !node->only_called_at_exit)
|
||||
{
|
||||
node->only_called_at_exit = true;
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "Node %s promoted to executed once.\n", cgraph_node_name (node));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
fprintf (dump_file, "Node %s promoted to only called at exit.\n",
|
||||
cgraph_node_name (node));
|
||||
changed = true;
|
||||
}
|
||||
/* These come either from profile or user hints; never update them. */
|
||||
if (node->frequency == NODE_FREQUENCY_HOT
|
||||
|| node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
|
||||
return changed;
|
||||
if (maybe_unlikely_executed)
|
||||
{
|
||||
node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED;
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "Node %s promoted to unlikely executed.\n",
|
||||
cgraph_node_name (node));
|
||||
changed = true;
|
||||
}
|
||||
if (maybe_executed_once && node->frequency != NODE_FREQUENCY_EXECUTED_ONCE)
|
||||
{
|
||||
node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "Node %s promoted to executed once.\n",
|
||||
cgraph_node_name (node));
|
||||
changed = true;
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
|
||||
/* Return true when NODE can not return or throw and thus
|
||||
|
|
|
@ -298,6 +298,10 @@ struct GTY((chain_next ("%h.next"), chain_prev ("%h.previous"))) cgraph_node {
|
|||
/* How commonly executed the node is. Initialized during branch
|
||||
probabilities pass. */
|
||||
ENUM_BITFIELD (node_frequency) frequency : 2;
|
||||
/* True when function can only be called at startup (from static ctor). */
|
||||
unsigned only_called_at_startup : 1;
|
||||
/* True when function can only be called at startup (from static dtor). */
|
||||
unsigned only_called_at_exit : 1;
|
||||
};
|
||||
|
||||
typedef struct cgraph_node *cgraph_node_ptr;
|
||||
|
|
|
@ -518,6 +518,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
|
|||
bp_pack_value (&bp, node->alias, 1);
|
||||
bp_pack_value (&bp, node->finalized_by_frontend, 1);
|
||||
bp_pack_value (&bp, node->frequency, 2);
|
||||
bp_pack_value (&bp, node->only_called_at_startup, 1);
|
||||
bp_pack_value (&bp, node->only_called_at_exit, 1);
|
||||
lto_output_bitpack (&bp);
|
||||
lto_output_uleb128_stream (ob->main_stream, node->resolution);
|
||||
|
||||
|
@ -978,6 +980,8 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
|
|||
node->alias = bp_unpack_value (bp, 1);
|
||||
node->finalized_by_frontend = bp_unpack_value (bp, 1);
|
||||
node->frequency = (enum node_frequency)bp_unpack_value (bp, 2);
|
||||
node->only_called_at_startup = bp_unpack_value (bp, 1);
|
||||
node->only_called_at_exit = bp_unpack_value (bp, 1);
|
||||
node->resolution = resolution;
|
||||
}
|
||||
|
||||
|
|
|
@ -2187,6 +2187,11 @@ compute_function_frequency (void)
|
|||
{
|
||||
basic_block bb;
|
||||
struct cgraph_node *node = cgraph_node (current_function_decl);
|
||||
if (DECL_STATIC_CONSTRUCTOR (current_function_decl)
|
||||
|| MAIN_NAME_P (DECL_NAME (current_function_decl)))
|
||||
node->only_called_at_startup = true;
|
||||
if (DECL_STATIC_DESTRUCTOR (current_function_decl))
|
||||
node->only_called_at_exit = true;
|
||||
|
||||
if (!profile_info || !flag_branch_probabilities)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue