Sorry, forgot to attach the patch...
Dehao
On Wed, Dec 14, 2011 at 9:13 AM, Dehao Chen <[email protected]> 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 <[email protected]> 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 <[email protected]>
>>
>> * 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);