Sorry, forgot to attach the patch... Dehao
On Wed, Dec 14, 2011 at 9:13 AM, Dehao Chen <de...@google.com> wrote: > I've updated the patch to fix a bug in dump_inline_decision. > > Thanks, > Dehao > > On Thu, Dec 1, 2011 at 9:59 AM, Dehao Chen <de...@google.com> wrote: >> >> This patch is for google-{main|gcc_4.6} only. >> >> Tested with bootstrap and regression tests. >> >> Dump inline decisions, also output the inline chain. >> >> Dehao >> >> 2011-12-01 Dehao Chen <de...@google.com> >> >> * ipa-inline.c (dump_inline_decision): New function. >> (inline_small_functions): Use it to dump the inline decisions to >> stderr. >> >> Index: gcc/ipa-inline.c >> =================================================================== >> --- gcc/ipa-inline.c (revision 181835) >> +++ gcc/ipa-inline.c (working copy) >> @@ -1377,6 +1377,45 @@ >> } >> >> >> +/* Dump the inline decision of EDGE to stderr. */ >> + >> +static void >> +dump_inline_decision (struct cgraph_edge *edge) >> +{ >> + location_t locus; >> + size_t buf_size = 4096; >> + size_t current_string_len = 0; >> + char *buf = (char *) xmalloc (buf_size); >> + struct cgraph_node *inlined_to; >> + gcov_type callee_count = edge->callee->count; >> + buf[0] = 0; >> + if (edge->inline_failed == CIF_OK && edge->callee->clone_of) >> + callee_count += edge->callee->clone_of->count; >> + for (inlined_to = edge->caller->global.inlined_to; >> + inlined_to; inlined_to = inlined_to->global.inlined_to) >> + { >> + const char *name = cgraph_node_name (inlined_to); >> + if (!name) >> + name = "unknown"; >> + current_string_len += (strlen (name) + 4); >> + while (current_string_len >= buf_size) >> + { >> + buf_size *= 2; >> + buf = (char *) xrealloc (buf, buf_size); >> + } >> + strcat (buf, "-->"); >> + strcat (buf, name); >> + } >> + locus = gimple_location (edge->call_stmt); >> + inform (locus, "%s ("HOST_WIDEST_INT_PRINT_DEC") --" >> + HOST_WIDEST_INT_PRINT_DEC"--> %s (" >> + HOST_WIDEST_INT_PRINT_DEC") %s : %s", >> + cgraph_node_name (edge->callee), callee_count, edge->count, >> + cgraph_node_name (edge->caller), edge->caller->count, buf, >> + edge->inline_failed == CIF_OK ? "INLINED": "IGNORED"); >> +} >> + >> + >> /* We use greedy algorithm for inlining of small functions: >> All inline candidates are put into prioritized heap ordered in >> increasing badness. >> @@ -1428,6 +1467,7 @@ >> overall_size = initial_size; >> max_size = compute_max_insns (overall_size); >> min_size = overall_size; >> + edge = NULL; >> >> /* Populate the heeap with all edges we might inline. */ >> >> @@ -1462,6 +1502,9 @@ >> int current_badness; >> int growth; >> >> + if (edge && flag_opt_info >= OPT_INFO_MIN) >> + dump_inline_decision (edge); >> + >> edge = (struct cgraph_edge *) fibheap_extract_min (heap); >> gcc_assert (edge->aux); >> edge->aux = NULL; >> @@ -1482,6 +1525,7 @@ >> if (current_badness != badness) >> { >> edge->aux = fibheap_insert (heap, current_badness, edge); >> + edge = NULL; >> continue; >> } >> >> @@ -1636,6 +1680,8 @@ >> fprintf (dump_file, "New minimal size reached: %i\n", min_size); >> } >> } >> + if (edge && flag_opt_info >= OPT_INFO_MIN) >> + dump_inline_decision (edge); >> >> free_growth_caches (); >> if (new_indirect_edges)
Index: ipa-inline.c =================================================================== --- ipa-inline.c (revision 181835) +++ ipa-inline.c (working copy) @@ -1073,6 +1073,44 @@ return false; } +/* Dump the inline decision of EDGE to stderr. */ + +static void +dump_inline_decision (struct cgraph_edge *edge) +{ + location_t locus; + size_t buf_size = 4096; + size_t current_string_len = 0; + char *buf = (char *) xmalloc (buf_size); + struct cgraph_node *inlined_to; + gcov_type callee_count = edge->callee->count; + buf[0] = 0; + if (edge->inline_failed == CIF_OK && edge->callee->clone_of) + callee_count += edge->callee->clone_of->count; + for (inlined_to = edge->caller->global.inlined_to; + inlined_to; inlined_to = inlined_to->global.inlined_to) + { + const char *name = cgraph_node_name (inlined_to); + if (!name) + name = "unknown"; + current_string_len += (strlen (name) + 4); + while (current_string_len >= buf_size) + { + buf_size *= 2; + buf = (char *) xrealloc (buf, buf_size); + } + strcat (buf, "-->"); + strcat (buf, name); + } + locus = gimple_location (edge->call_stmt); + inform (locus, "%s ("HOST_WIDEST_INT_PRINT_DEC") --" + HOST_WIDEST_INT_PRINT_DEC"--> %s (" + HOST_WIDEST_INT_PRINT_DEC") %s : %s", + xstrdup (cgraph_node_name (edge->callee)), callee_count, edge->count, + xstrdup (cgraph_node_name (edge->caller)), edge->caller->count, buf, + edge->inline_failed == CIF_OK ? "INLINED": "IGNORED"); +} + /* We use greedy algorithm for inlining of small functions: All inline candidates are put into prioritized heap based on estimated @@ -1125,6 +1163,7 @@ max_size = compute_max_insns (overall_size); min_size = overall_size; + edge = NULL; while (overall_size <= max_size && !fibheap_empty (heap)) @@ -1136,6 +1175,9 @@ int growth; cgraph_inline_failed_t not_good = CIF_OK; + if (edge && flag_opt_info >= OPT_INFO_MIN) + dump_inline_decision (edge); + edge = (struct cgraph_edge *) fibheap_extract_min (heap); gcc_assert (edge->aux); edge->aux = NULL; @@ -1150,6 +1192,7 @@ if (current_badness != badness) { edge->aux = fibheap_insert (heap, current_badness, edge); + edge = NULL; continue; } @@ -1337,6 +1380,9 @@ fprintf (dump_file, "New minimal size reached: %i\n", min_size); } } + if (edge && flag_opt_info >= OPT_INFO_MIN) + dump_inline_decision (edge); + while (!fibheap_empty (heap)) { int badness = fibheap_min_key (heap);