diff options
author | Jan Hubicka <jh@suse.cz> | 2010-10-16 18:59:07 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2010-10-16 16:59:07 +0000 |
commit | 844db5d09eb972e4f9188b77854d76ce345ca9ee (patch) | |
tree | 729e8daec41bc5163de53301f1aa679b1c2fadf7 /gcc/cgraph.c | |
parent | 6eb6875d7ec398935d3ae76f805e33db0c3773dd (diff) | |
download | gcc-844db5d09eb972e4f9188b77854d76ce345ca9ee.zip gcc-844db5d09eb972e4f9188b77854d76ce345ca9ee.tar.gz gcc-844db5d09eb972e4f9188b77854d76ce345ca9ee.tar.bz2 |
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
Diffstat (limited to 'gcc/cgraph.c')
-rw-r--r-- | gcc/cgraph.c | 86 |
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 |