summaryrefslogtreecommitdiff
path: root/gcc/ipa-inline.c
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2014-04-18 20:30:45 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2014-04-18 18:30:45 +0000
commite86a910ff5b8ecfeeeb1e57bffcb85887b771f9a (patch)
treef13c9287e9f4b5d2d24d112f7c85d5f4ecf6d4ce /gcc/ipa-inline.c
parentfc45aeeeeccfe9e81f7e9619188c5450b1550634 (diff)
downloadgcc-e86a910ff5b8ecfeeeb1e57bffcb85887b771f9a.tar.gz
ipa-inline.c (spec_rem): New static variable.
* ipa-inline.c (spec_rem): New static variable. (dump_overall_stats): New function. (dump_inline_stats): New function. From-SVN: r209522
Diffstat (limited to 'gcc/ipa-inline.c')
-rw-r--r--gcc/ipa-inline.c138
1 files changed, 135 insertions, 3 deletions
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index e8f03be397b..1b7a74e0745 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -127,6 +127,7 @@ along with GCC; see the file COPYING3. If not see
static int overall_size;
static gcov_type max_count;
static sreal max_count_real, max_relbenefit_real, half_int_min_real;
+static gcov_type spec_rem;
/* Return false when inlining edge E would lead to violating
limits on function unit growth or stack usage growth.
@@ -1533,6 +1534,7 @@ resolve_noninline_speculation (fibheap_t edge_heap, struct cgraph_edge *edge)
? node->global.inlined_to : node;
bitmap updated_nodes = BITMAP_ALLOC (NULL);
+ spec_rem += edge->count;
cgraph_resolve_speculation (edge, NULL);
reset_edge_caches (where);
inline_update_overall_summary (where);
@@ -1996,6 +1998,130 @@ inline_to_all_callers (struct cgraph_node *node, void *data)
return false;
}
+/* Output overall time estimate. */
+static void
+dump_overall_stats (void)
+{
+ HOST_WIDEST_INT sum_weighted = 0, sum = 0;
+ struct cgraph_node *node;
+
+ FOR_EACH_DEFINED_FUNCTION (node)
+ if (!node->global.inlined_to
+ && !node->alias)
+ {
+ int time = inline_summary (node)->time;
+ sum += time;
+ sum_weighted += time * node->count;
+ }
+ fprintf (dump_file, "Overall time estimate: "
+ HOST_WIDEST_INT_PRINT_DEC" weighted by profile: "
+ HOST_WIDEST_INT_PRINT_DEC"\n", sum, sum_weighted);
+}
+
+/* Output some useful stats about inlining. */
+
+static void
+dump_inline_stats (void)
+{
+ HOST_WIDEST_INT inlined_cnt = 0, inlined_indir_cnt = 0;
+ HOST_WIDEST_INT inlined_virt_cnt = 0, inlined_virt_indir_cnt = 0;
+ HOST_WIDEST_INT noninlined_cnt = 0, noninlined_indir_cnt = 0;
+ HOST_WIDEST_INT noninlined_virt_cnt = 0, noninlined_virt_indir_cnt = 0;
+ HOST_WIDEST_INT inlined_speculative = 0, inlined_speculative_ply = 0;
+ HOST_WIDEST_INT indirect_poly_cnt = 0, indirect_cnt = 0;
+ HOST_WIDEST_INT reason[CIF_N_REASONS][3];
+ int i;
+ struct cgraph_node *node;
+
+ memset (reason, 0, sizeof (reason));
+ FOR_EACH_DEFINED_FUNCTION (node)
+ {
+ struct cgraph_edge *e;
+ for (e = node->callees; e; e = e->next_callee)
+ {
+ if (e->inline_failed)
+ {
+ reason[(int) e->inline_failed][0] += e->count;
+ reason[(int) e->inline_failed][1] += e->frequency;
+ reason[(int) e->inline_failed][2] ++;
+ if (DECL_VIRTUAL_P (e->callee->decl))
+ {
+ if (e->indirect_inlining_edge)
+ noninlined_virt_indir_cnt += e->count;
+ else
+ noninlined_virt_cnt += e->count;
+ }
+ else
+ {
+ if (e->indirect_inlining_edge)
+ noninlined_indir_cnt += e->count;
+ else
+ noninlined_cnt += e->count;
+ }
+ }
+ else
+ {
+ if (e->speculative)
+ {
+ if (DECL_VIRTUAL_P (e->callee->decl))
+ inlined_speculative_ply += e->count;
+ else
+ inlined_speculative += e->count;
+ }
+ else if (DECL_VIRTUAL_P (e->callee->decl))
+ {
+ if (e->indirect_inlining_edge)
+ inlined_virt_indir_cnt += e->count;
+ else
+ inlined_virt_cnt += e->count;
+ }
+ else
+ {
+ if (e->indirect_inlining_edge)
+ inlined_indir_cnt += e->count;
+ else
+ inlined_cnt += e->count;
+ }
+ }
+ }
+ for (e = node->indirect_calls; e; e = e->next_callee)
+ if (e->indirect_info->polymorphic)
+ indirect_poly_cnt += e->count;
+ else
+ indirect_cnt += e->count;
+ }
+ if (max_count)
+ {
+ fprintf (dump_file,
+ "Inlined " HOST_WIDEST_INT_PRINT_DEC " + speculative "
+ HOST_WIDEST_INT_PRINT_DEC " + speculative polymorphic "
+ HOST_WIDEST_INT_PRINT_DEC " + previously indirect "
+ HOST_WIDEST_INT_PRINT_DEC " + virtual "
+ HOST_WIDEST_INT_PRINT_DEC " + virtual and previously indirect "
+ HOST_WIDEST_INT_PRINT_DEC "\n" "Not inlined "
+ HOST_WIDEST_INT_PRINT_DEC " + previously indirect "
+ HOST_WIDEST_INT_PRINT_DEC " + virtual "
+ HOST_WIDEST_INT_PRINT_DEC " + virtual and previously indirect "
+ HOST_WIDEST_INT_PRINT_DEC " + stil indirect "
+ HOST_WIDEST_INT_PRINT_DEC " + still indirect polymorphic "
+ HOST_WIDEST_INT_PRINT_DEC "\n", inlined_cnt,
+ inlined_speculative, inlined_speculative_ply,
+ inlined_indir_cnt, inlined_virt_cnt, inlined_virt_indir_cnt,
+ noninlined_cnt, noninlined_indir_cnt, noninlined_virt_cnt,
+ noninlined_virt_indir_cnt, indirect_cnt, indirect_poly_cnt);
+ fprintf (dump_file,
+ "Removed speculations " HOST_WIDEST_INT_PRINT_DEC "\n",
+ spec_rem);
+ }
+ dump_overall_stats ();
+ fprintf (dump_file, "\nWhy inlining failed?\n");
+ for (i = 0; i < CIF_N_REASONS; i++)
+ if (reason[i][2])
+ fprintf (dump_file, "%-50s: %8i calls, %8i freq, "HOST_WIDEST_INT_PRINT_DEC" count\n",
+ cgraph_inline_failed_string ((cgraph_inline_failed_t) i),
+ (int) reason[i][2], (int) reason[i][1], reason[i][0]);
+}
+
/* Decide on the inlining. We do so in the topological order to avoid
expenses on updating data structures. */
@@ -2048,6 +2174,8 @@ ipa_inline (void)
flatten_function (node, false);
}
}
+ if (dump_file)
+ dump_overall_stats ();
inline_small_functions ();
@@ -2092,6 +2220,7 @@ ipa_inline (void)
if (edge->speculative && !speculation_useful_p (edge, false))
{
cgraph_resolve_speculation (edge, NULL);
+ spec_rem += edge->count;
update = true;
remove_functions = true;
}
@@ -2122,9 +2251,12 @@ ipa_inline (void)
ipa_free_all_structures_after_iinln ();
if (dump_file)
- fprintf (dump_file,
- "\nInlined %i calls, eliminated %i functions\n\n",
- ncalls_inlined, nfunctions_inlined);
+ {
+ fprintf (dump_file,
+ "\nInlined %i calls, eliminated %i functions\n\n",
+ ncalls_inlined, nfunctions_inlined);
+ dump_inline_stats ();
+ }
if (dump_file)
dump_inline_summaries (dump_file);