aboutsummaryrefslogtreecommitdiff
path: root/gcc/cgraph.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/cgraph.c')
-rw-r--r--gcc/cgraph.c86
1 files changed, 66 insertions, 20 deletions
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 465e9af..342ad63 100644
--- a/gcc/cgraph.c
+++ b/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