Looks good in general. 1) The profile information should be omitted when profile information is not available 2) have a test case showing the call chain.
Ok for google branches with the above changes. thanks, David On Thu, Dec 15, 2011 at 12:30 AM, Dehao Chen <de...@google.com> wrote: > I change to use the bfd_name, which is much shorter for C++ symbols. > > Thanks, > Dehao > > On Thu, Dec 15, 2011 at 2:07 AM, Xinliang David Li <davi...@google.com> wrote: >> Another usability related issue for C++. The long demangled function >> names will make the info messages very hard to swallow. Since there >> will be source lines to show the source context, it might be better to >> just use the short decl names. The downside is it can be ambiguous for >> template functions. >> >> David >> >> On Tue, Dec 13, 2011 at 11:18 PM, Xinliang David Li <davi...@google.com> >> wrote: >>> 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)