There are a couple of problems with the patch (the patch is only compatible with 4_6 branch)
1) the dump_inline_decision should be called inside cgraph_mark_inline_edge when the edge is finally picked (and when the callee node is cloned) 2) The source location is not printed which makes the dumping less useful 3) the information line should clearly print out the final caller where the inlining happens, and the intermediate inline instance information should be clearly printed as additional information showing the inline context. For instance, foo1->foo2->foo3->foo4 If all callsites are inlined in top down order, the messages I expect to see are: a.c:5: note: 'foo2' is inlined into 'foo1' with call count xxxx a.c:10: note: 'foo3' is inlined into 'foo1' with call count yyyy (via inline instance 'foo2') a.c:20: note: 'foo4' is inlined into foo1' with call count zzzz (via inline instances 'foo3', 'foo2') If the decision is bottom up, the messages should look like: a.c:20: note: 'foo4' is inlined into 'foo3' with call count zzzz a.c:10: note: 'foo3' is inlined into 'foo2' with call count yyyy a.c:5: note: 'foo2' is inlined into 'foo1' with call count xxxx Ideally, the caller and callee should also be marked with 'entry count and max bb count' information -- but that probably should be controlled by opt-info level. 4) Also notice that for inline node clones, the right way to walk up the call context chain is via 'edge->caller->callers'. 5) there should be a test case. Thanks, David On Tue, Dec 13, 2011 at 5:13 PM, 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)