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.
? 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);
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. */
flatten_function (node, false);
}
}
+ if (dump_file)
+ dump_overall_stats ();
inline_small_functions ();
if (edge->speculative && !speculation_useful_p (edge, false))
{
cgraph_resolve_speculation (edge, NULL);
+ spec_rem += edge->count;
update = true;
remove_functions = true;
}
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);