[PATCH] Convert more passes to new dump framework
Teresa Johnson
tejohnson@google.com
Mon Aug 19 18:34:00 GMT 2013
Ping.
Thanks,
Teresa
On Mon, Aug 12, 2013 at 6:54 AM, Teresa Johnson <tejohnson@google.com> wrote:
> On Tue, Aug 6, 2013 at 10:23 PM, Teresa Johnson <tejohnson@google.com> wrote:
>> On Tue, Aug 6, 2013 at 9:29 AM, Teresa Johnson <tejohnson@google.com> wrote:
>>> On Tue, Aug 6, 2013 at 9:01 AM, Martin Jambor <mjambor@suse.cz> wrote:
>>>> Hi,
>>>>
>>>> On Tue, Aug 06, 2013 at 07:14:42AM -0700, Teresa Johnson wrote:
>>>>> On Tue, Aug 6, 2013 at 5:37 AM, Martin Jambor <mjambor@suse.cz> wrote:
>>>>> > On Mon, Aug 05, 2013 at 10:37:00PM -0700, Teresa Johnson wrote:
>>>>> >> This patch ports messages to the new dump framework,
>>>>> >
>>>>> > It would be great this new framework was documented somewhere. I lost
>>>>> > track of what was agreed it would be and from the uses in the
>>>>> > vectorizer I was never quite sure how to utilize it in other passes.
>>>>>
>>>>> Cc'ing Sharad who implemented this - Sharad, is this documented on a
>>>>> wiki or elsewhere?
>>>>
>>>> Thanks
>>>>
>>>>>
>>>>> >
>>>>> > I'd also like to point out two other minor things inline:
>>>>> >
>>>>> > [...]
>>>>> >
>>>>> >> 2013-08-06 Teresa Johnson <tejohnson@google.com>
>>>>> >> Dehao Chen <dehao@google.com>
>>>>> >>
>>>>> >> * dumpfile.c (dump_loc): Add column number to output, make newlines
>>>>> >> consistent.
>>>>> >> * dumpfile.h (OPTGROUP_OTHER): Add and enable under OPTGROUP_ALL.
>>>>> >> * ipa-inline-transform.c (clone_inlined_nodes):
>>>>> >> (cgraph_node_opt_info): New function.
>>>>> >> (cgraph_node_call_chain): Ditto.
>>>>> >> (dump_inline_decision): Ditto.
>>>>> >> (inline_call): Invoke dump_inline_decision.
>>>>> >> * doc/invoke.texi: Document optall -fopt-info flag.
>>>>> >> * profile.c (read_profile_edge_counts): Use new dump framework.
>>>>> >> (compute_branch_probabilities): Ditto.
>>>>> >> * passes.c (pass_manager::register_one_dump_file): Use OPTGROUP_OTHER
>>>>> >> when pass not in any opt group.
>>>>> >> * value-prof.c (check_counter): Use new dump framework.
>>>>> >> (find_func_by_funcdef_no): Ditto.
>>>>> >> (check_ic_target): Ditto.
>>>>> >> * coverage.c (get_coverage_counts): Ditto.
>>>>> >> (coverage_init): Setup new dump framework.
>>>>> >> * ipa-inline.c (inline_small_functions): Set is_in_ipa_inline.
>>>>> >> * ipa-inline.h (is_in_ipa_inline): Declare.
>>>>> >>
>>>>> >> * testsuite/gcc.dg/pr40209.c: Use -fopt-info.
>>>>> >> * testsuite/gcc.dg/pr26570.c: Ditto.
>>>>> >> * testsuite/gcc.dg/pr32773.c: Ditto.
>>>>> >> * testsuite/g++.dg/tree-ssa/dom-invalid.C (struct C): Ditto.
>>>>> >>
>>>>> >
>>>>> > [...]
>>>>> >
>>>>> >> Index: ipa-inline-transform.c
>>>>> >> ===================================================================
>>>>> >> --- ipa-inline-transform.c (revision 201461)
>>>>> >> +++ ipa-inline-transform.c (working copy)
>>>>> >> @@ -192,6 +192,108 @@ clone_inlined_nodes (struct cgraph_edge *e, bool d
>>>>> >> }
>>>>> >>
>>>>> >>
>>>>> >> +#define MAX_INT_LENGTH 20
>>>>> >> +
>>>>> >> +/* Return NODE's name and profile count, if available. */
>>>>> >> +
>>>>> >> +static const char *
>>>>> >> +cgraph_node_opt_info (struct cgraph_node *node)
>>>>> >> +{
>>>>> >> + char *buf;
>>>>> >> + size_t buf_size;
>>>>> >> + const char *bfd_name = lang_hooks.dwarf_name (node->symbol.decl, 0);
>>>>> >> +
>>>>> >> + if (!bfd_name)
>>>>> >> + bfd_name = "unknown";
>>>>> >> +
>>>>> >> + buf_size = strlen (bfd_name) + 1;
>>>>> >> + if (profile_info)
>>>>> >> + buf_size += (MAX_INT_LENGTH + 3);
>>>>> >> +
>>>>> >> + buf = (char *) xmalloc (buf_size);
>>>>> >> +
>>>>> >> + strcpy (buf, bfd_name);
>>>>> >> +
>>>>> >> + if (profile_info)
>>>>> >> + sprintf (buf, "%s ("HOST_WIDEST_INT_PRINT_DEC")", buf, node->count);
>>>>> >> + return buf;
>>>>> >> +}
>>>>> >
>>>>> > I'm not sure if output of this function is aimed only at the user or
>>>>> > if it is supposed to be used by gcc developers as well. If the
>>>>> > latter, an incredibly useful thing is to also dump node->symbol.order
>>>>> > too. We usually dump it after "/" sign separating it from node name.
>>>>> > It is invaluable when examining decisions in C++ code where you can
>>>>> > have lots of clones of a node (and also because existing dumps print
>>>>> > it, it is easy to combine them).
>>>>>
>>>>> The output is useful for both power users doing performance tuning of
>>>>> their application, and by gcc developers. Adding the id is not so
>>>>> useful for the former, but I agree that it is very useful for compiler
>>>>> developers. In fact, in the google branch version we emit more verbose
>>>>> information (the lipo module id and the funcdef_no) to help uniquely
>>>>> identify the routines and to aid in post-processing by humans and
>>>>> tools. So it is probably useful to add something similar here too. Is
>>>>> the node->symbol.order more or less unique than the funcdef_no? I see
>>>>> that you added a patch a few months ago to print the
>>>>> node->symbol.order in the function header, and it also has the
>>>>> advantage as you note of matching up with existing ipa dumps.
>>>>
>>>> node->symbol.order is unique and if I remember correctly, it is not
>>>> even recycled. Clones, inline clones, thunks, every symbol table node
>>>> gets its own symbol order so it should be more unique than funcdef_no.
>>>> On the other hand it may be a bit cryptic for users but at the same
>>>> time it is only one number.
>>>
>>> Ok, I am going to go ahead and add this to the output.
>>>
>>>>
>>>>>
>>>>> >
>>>>> > [...]
>>>>> >
>>>>> >> Index: ipa-inline.c
>>>>> >> ===================================================================
>>>>> >> --- ipa-inline.c (revision 201461)
>>>>> >> +++ ipa-inline.c (working copy)
>>>>> >> @@ -118,6 +118,9 @@ along with GCC; see the file COPYING3. If not see
>>>>> >> static int overall_size;
>>>>> >> static gcov_type max_count;
>>>>> >>
>>>>> >> +/* Global variable to denote if it is in ipa-inline pass. */
>>>>> >> +bool is_in_ipa_inline = false;
>>>>> >> +
>>>>> >> /* Return false when inlining edge E would lead to violating
>>>>> >> limits on function unit growth or stack usage growth.
>>>>> >>
>>>>> >
>>>>> > In this age of removing global variables, are you sure you need this?
>>>>> > The only user of this seems to be a function that is only being called
>>>>> > from inline_call... can that ever happen when not inlining? If you
>>>>> > plan to use this function also elsewhere, perhaps the callers will
>>>>> > know whether we are inlining or not and can provide this in a
>>>>> > parameter?
>>>>>
>>>>> This is to distinguish early inlining from ipa inlining.
>>>>
>>>> Oh, right, I did not realize that the IPA part was the important bit
>>>> of the name.
>>>>
>>>>> The volume of
>>>>> early inlining messages is too high to be on for the default setting
>>>>> of -fopt-info, and are not as interesting usually for performance
>>>>> tuning. The dumper will only emit the early inline messages under a
>>>>> more verbose setting (MSG_NOTE):
>>>>> dump_printf_loc (is_in_ipa_inline ? MSG_OPTIMIZED_LOCATIONS : MSG_NOTE ...
>>>>> The other way I can see to distinguish this would be to check the
>>>>> always_inline_functions_inlined flag on the caller's function. It
>>>>> could also be possible to pass down a flag from the callers of
>>>>> inline_call, but at least one caller (flatten_functions) is shared
>>>>> between early and late inlining, so the flag needs to be passed
>>>>> through that as well. WDYT?
>>>>
>>>> Did you mean flatten_function? It already has a bool "early"
>>>> parameter. But I can see that being able to quickly figure out
>>>> whether we are in early inliner or ipa inliner without much hassle is
>>>> useful enough to justify a global variable a month ago, however I
>>>> suppose we should not be introducing them now and so you'd have to put
>>>> such stuff into... well, you'd probably have to put into the universe
>>>> object somewhere because it is basically shared between two passes.
>>>> Another option, even though somewhat hackish, would be to look at
>>>> current_pass and see which pass it is. I don't know, do what is
>>>> easier or what you like more, just be aware of the problem.
>>>
>>> After thinking about this some more, I think passing down an early
>>> flag from callers is the cleanest way to go.
>>>
>>> I'll fix these and post a new patch later today.
>>
>> New patch below that removes this global variable, and also outputs
>> the node->symbol.order (in square brackets after the function name so
>> as to not clutter it). Inline messages with profile data look look:
>>
>> test.c:8:3: note: foobar [0] (99999000) inlined into foo [2] (1000)
>> with call count 99999000 (via inline instance bar [3] (99999000))
>>
>> (without FDO the counts in parentheses and the call count would not be
>> included).
>>
>> Ok for trunk?
>
> Ping.
> Teresa
>
>> Thanks,
>> Teresa
>>
>> 013-08-06 Teresa Johnson <tejohnson@google.com>
>> Dehao Chen <dehao@google.com>
>>
>> * dumpfile.c (dump_loc): Output column number, make newlines consistent.
>> * dumpfile.h (OPTGROUP_OTHER): Add and enable under OPTGROUP_ALL.
>> * ipa-inline-transform.c (cgraph_node_opt_info): New function.
>> (cgraph_node_call_chain): Ditto.
>> (dump_inline_decision): Ditto.
>> (inline_call): Invoke dump_inline_decision, new parameter.
>> * doc/invoke.texi: Document optall -fopt-info flag.
>> * profile.c (read_profile_edge_counts): Use new dump framework.
>> (compute_branch_probabilities): Ditto.
>> * passes.c (pass_manager::register_one_dump_file): Use OPTGROUP_OTHER
>> when pass not in any opt group.
>> * value-prof.c (check_counter): Use new dump framework.
>> (find_func_by_funcdef_no): Ditto.
>> (check_ic_target): Ditto.
>> * coverage.c (get_coverage_counts): Ditto.
>> (coverage_init): Setup new dump framework.
>> * ipa-inline.c (recursive_inlining): New inline_call parameter.
>> (inline_small_functions): Ditto.
>> (flatten_function): Ditto.
>> (ipa_inline): Ditto.
>> (inline_always_inline_functions): Ditto.
>> (early_inline_small_functions): Ditto.
>> * ipa-inline.h: Ditto.
>>
>> * testsuite/gcc.dg/pr40209.c: Use -fopt-info.
>> * testsuite/gcc.dg/pr26570.c: Ditto.
>> * testsuite/gcc.dg/pr32773.c: Ditto.
>> * testsuite/g++.dg/tree-ssa/dom-invalid.C: Ditto.
>> * testsuite/gcc.dg/inline-dump.c: New test.
>>
>> Index: dumpfile.c
>> ===================================================================
>> --- dumpfile.c (revision 201461)
>> +++ dumpfile.c (working copy)
>> @@ -257,16 +257,18 @@ dump_open_alternate_stream (struct dump_file_info
>> void
>> dump_loc (int dump_kind, FILE *dfile, source_location loc)
>> {
>> - /* Currently vectorization passes print location information. */
>> if (dump_kind)
>> {
>> + /* Ensure dump message starts on a new line. */
>> + fprintf (dfile, "\n");
>> if (LOCATION_LOCUS (loc) > BUILTINS_LOCATION)
>> - fprintf (dfile, "\n%s:%d: note: ", LOCATION_FILE (loc),
>> - LOCATION_LINE (loc));
>> + fprintf (dfile, "%s:%d:%d: note: ", LOCATION_FILE (loc),
>> + LOCATION_LINE (loc), LOCATION_COLUMN (loc));
>> else if (current_function_decl)
>> - fprintf (dfile, "\n%s:%d: note: ",
>> + fprintf (dfile, "%s:%d:%d: note: ",
>> DECL_SOURCE_FILE (current_function_decl),
>> - DECL_SOURCE_LINE (current_function_decl));
>> + DECL_SOURCE_LINE (current_function_decl),
>> + DECL_SOURCE_COLUMN (current_function_decl));
>> }
>> }
>>
>> Index: dumpfile.h
>> ===================================================================
>> --- dumpfile.h (revision 201461)
>> +++ dumpfile.h (working copy)
>> @@ -97,8 +97,9 @@ enum tree_dump_index
>> #define OPTGROUP_LOOP (1 << 2) /* Loop optimization passes */
>> #define OPTGROUP_INLINE (1 << 3) /* Inlining passes */
>> #define OPTGROUP_VEC (1 << 4) /* Vectorization passes */
>> +#define OPTGROUP_OTHER (1 << 5) /* All other passes */
>> #define OPTGROUP_ALL (OPTGROUP_IPA | OPTGROUP_LOOP | OPTGROUP_INLINE \
>> - | OPTGROUP_VEC)
>> + | OPTGROUP_VEC | OPTGROUP_OTHER)
>>
>> /* Define a tree dump switch. */
>> struct dump_file_info
>> Index: ipa-inline-transform.c
>> ===================================================================
>> --- ipa-inline-transform.c (revision 201461)
>> +++ ipa-inline-transform.c (working copy)
>> @@ -192,6 +192,111 @@ clone_inlined_nodes (struct cgraph_edge *e, bool d
>> }
>>
>>
>> +#define MAX_INT_LENGTH 20
>> +
>> +/* Return NODE's name and profile count, if available. */
>> +
>> +static const char *
>> +cgraph_node_opt_info (struct cgraph_node *node)
>> +{
>> + char *buf;
>> + size_t buf_size;
>> + const char *bfd_name = lang_hooks.dwarf_name (node->symbol.decl, 0);
>> +
>> + if (!bfd_name)
>> + bfd_name = "unknown";
>> +
>> + buf_size = strlen (bfd_name) + 1;
>> + if (profile_info)
>> + buf_size += (MAX_INT_LENGTH + 3);
>> + buf_size += MAX_INT_LENGTH;
>> +
>> + buf = (char *) xmalloc (buf_size);
>> +
>> + strcpy (buf, bfd_name);
>> + //sprintf (buf, "%s/%i", buf, node->symbol.order);
>> + sprintf (buf, "%s [%i]", buf, node->symbol.order);
>> +
>> + if (profile_info)
>> + sprintf (buf, "%s ("HOST_WIDEST_INT_PRINT_DEC")", buf, node->count);
>> + return buf;
>> +}
>> +
>> +
>> +/* Return CALLER's inlined call chain. Save the cgraph_node of the ultimate
>> + function that the caller is inlined to in FINAL_CALLER. */
>> +
>> +static const char *
>> +cgraph_node_call_chain (struct cgraph_node *caller,
>> + struct cgraph_node **final_caller)
>> +{
>> + struct cgraph_node *node;
>> + const char *via_str = " (via inline instance";
>> + size_t current_string_len = strlen (via_str) + 1;
>> + size_t buf_size = current_string_len;
>> + char *buf = (char *) xmalloc (buf_size);
>> +
>> + buf[0] = 0;
>> + gcc_assert (caller->global.inlined_to != NULL);
>> + strcat (buf, via_str);
>> + for (node = caller; node->global.inlined_to != NULL;
>> + node = node->callers->caller)
>> + {
>> + const char *name = cgraph_node_opt_info (node);
>> + current_string_len += (strlen (name) + 1);
>> + if (current_string_len >= buf_size)
>> + {
>> + buf_size = current_string_len * 2;
>> + buf = (char *) xrealloc (buf, buf_size);
>> + }
>> + strcat (buf, " ");
>> + strcat (buf, name);
>> + }
>> + strcat (buf, ")");
>> + *final_caller = node;
>> + return buf;
>> +}
>> +
>> +
>> +/* Dump the inline decision of EDGE. */
>> +
>> +static void
>> +dump_inline_decision (struct cgraph_edge *edge, bool early)
>> +{
>> + location_t locus;
>> + const char *inline_chain_text;
>> + const char *call_count_text;
>> + struct cgraph_node *final_caller = edge->caller;
>> +
>> + if (final_caller->global.inlined_to != NULL)
>> + inline_chain_text = cgraph_node_call_chain (final_caller, &final_caller);
>> + else
>> + inline_chain_text = "";
>> +
>> + if (edge->count > 0)
>> + {
>> + const char *call_count_str = " with call count ";
>> + char *buf = (char *) xmalloc (strlen (call_count_str) + MAX_INT_LENGTH);
>> + sprintf (buf, "%s"HOST_WIDEST_INT_PRINT_DEC, call_count_str,
>> + edge->count);
>> + call_count_text = buf;
>> + }
>> + else
>> + {
>> + call_count_text = "";
>> + }
>> +
>> + locus = gimple_location (edge->call_stmt);
>> + dump_printf_loc (early ? MSG_NOTE : MSG_OPTIMIZED_LOCATIONS,
>> + locus,
>> + "%s inlined into %s%s%s\n",
>> + cgraph_node_opt_info (edge->callee),
>> + cgraph_node_opt_info (final_caller),
>> + call_count_text,
>> + inline_chain_text);
>> +}
>> +
>> +
>> /* Mark edge E as inlined and update callgraph accordingly. UPDATE_ORIGINAL
>> specify whether profile of original function should be updated. If any new
>> indirect edges are discovered in the process, add them to NEW_EDGES, unless
>> @@ -205,7 +310,8 @@ clone_inlined_nodes (struct cgraph_edge *e, bool d
>> bool
>> inline_call (struct cgraph_edge *e, bool update_original,
>> vec<cgraph_edge_p> *new_edges,
>> - int *overall_size, bool update_overall_summary)
>> + int *overall_size, bool update_overall_summary,
>> + bool early)
>> {
>> int old_size = 0, new_size = 0;
>> struct cgraph_node *to = NULL;
>> @@ -218,6 +324,9 @@ inline_call (struct cgraph_edge *e, bool update_or
>> bool predicated = inline_edge_summary (e)->predicate != NULL;
>> #endif
>>
>> + if (dump_enabled_p ())
>> + dump_inline_decision (e, early);
>> +
>> /* Don't inline inlined edges. */
>> gcc_assert (e->inline_failed);
>> /* Don't even think of inlining inline clone. */
>> Index: doc/invoke.texi
>> ===================================================================
>> --- doc/invoke.texi (revision 201461)
>> +++ doc/invoke.texi (working copy)
>> @@ -6234,6 +6234,9 @@ Enable dumps from all loop optimizations.
>> Enable dumps from all inlining optimizations.
>> @item vec
>> Enable dumps from all vectorization optimizations.
>> +@item optall
>> +Enable dumps from all optimizations. This is a superset of
>> +the optimization groups listed above.
>> @end table
>>
>> For example,
>> Index: profile.c
>> ===================================================================
>> --- profile.c (revision 201461)
>> +++ profile.c (working copy)
>> @@ -432,8 +432,8 @@ read_profile_edge_counts (gcov_type *exec_counts)
>> if (flag_profile_correction)
>> {
>> static bool informed = 0;
>> - if (!informed)
>> - inform (input_location,
>> + if (dump_enabled_p () && !informed)
>> + dump_printf_loc (MSG_NOTE, input_location,
>> "corrupted profile info: edge count
>> exceeds maximal count");
>> informed = 1;
>> }
>> @@ -692,10 +692,11 @@ compute_branch_probabilities (unsigned cfg_checksu
>> {
>> /* Inconsistency detected. Make it flow-consistent. */
>> static int informed = 0;
>> - if (informed == 0)
>> + if (dump_enabled_p () && informed == 0)
>> {
>> informed = 1;
>> - inform (input_location, "correcting inconsistent profile data");
>> + dump_printf_loc (MSG_NOTE, input_location,
>> + "correcting inconsistent profile data");
>> }
>> correct_negative_edge_counts ();
>> /* Set bb counts to the sum of the outgoing edge counts */
>> Index: passes.c
>> ===================================================================
>> --- passes.c (revision 201461)
>> +++ passes.c (working copy)
>> @@ -524,6 +524,11 @@ pass_manager::register_one_dump_file (struct opt_p
>> flag_name = concat (prefix, name, num, NULL);
>> glob_name = concat (prefix, name, NULL);
>> optgroup_flags |= pass->optinfo_flags;
>> + /* For any passes that do not have an optgroup set, and which are not
>> + IPA passes setup above, set the optgroup to OPTGROUP_OTHER so that
>> + any dump messages are emitted properly under -fopt-info(-optall). */
>> + if (optgroup_flags == OPTGROUP_NONE)
>> + optgroup_flags = OPTGROUP_OTHER;
>> id = dump_register (dot_name, flag_name, glob_name, flags, optgroup_flags);
>> set_pass_for_id (id, pass);
>> full_name = concat (prefix, pass->name, num, NULL);
>> Index: value-prof.c
>> ===================================================================
>> --- value-prof.c (revision 201461)
>> +++ value-prof.c (working copy)
>> @@ -585,9 +585,11 @@ check_counter (gimple stmt, const char * name,
>> : DECL_SOURCE_LOCATION (current_function_decl);
>> if (flag_profile_correction)
>> {
>> - inform (locus, "correcting inconsistent value profile: "
>> - "%s profiler overall count (%d) does not match BB count "
>> - "(%d)", name, (int)*all, (int)bb_count);
>> + if (dump_enabled_p ())
>> + dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus,
>> + "correcting inconsistent value profile: %s "
>> + "profiler overall count (%d) does not match BB "
>> + "count (%d)", name, (int)*all, (int)bb_count);
>> *all = bb_count;
>> if (*count > *all)
>> *count = *all;
>> @@ -1209,9 +1211,11 @@ find_func_by_funcdef_no (int func_id)
>> int max_id = get_last_funcdef_no ();
>> if (func_id >= max_id || cgraph_node_map[func_id] == NULL)
>> {
>> - if (flag_profile_correction)
>> - inform (DECL_SOURCE_LOCATION (current_function_decl),
>> - "Inconsistent profile: indirect call target (%d) does
>> not exist", func_id);
>> + if (flag_profile_correction && dump_enabled_p ())
>> + dump_printf_loc (MSG_MISSED_OPTIMIZATION,
>> + DECL_SOURCE_LOCATION (current_function_decl),
>> + "Inconsistent profile: indirect call target (%d) "
>> + "does not exist", func_id);
>> else
>> error ("Inconsistent profile: indirect call target (%d) does
>> not exist", func_id);
>>
>> @@ -1235,8 +1239,10 @@ check_ic_target (gimple call_stmt, struct cgraph_n
>> return true;
>>
>> locus = gimple_location (call_stmt);
>> - inform (locus, "Skipping target %s with mismatching types for icall ",
>> - cgraph_node_name (target));
>> + if (dump_enabled_p ())
>> + dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus,
>> + "Skipping target %s with mismatching types for icall ",
>> + cgraph_node_name (target));
>> return false;
>> }
>>
>> Index: coverage.c
>> ===================================================================
>> --- coverage.c (revision 201461)
>> +++ coverage.c (working copy)
>> @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see
>> #include "langhooks.h"
>> #include "hash-table.h"
>> #include "tree-iterator.h"
>> +#include "tree-pass.h"
>> #include "cgraph.h"
>> #include "dumpfile.h"
>> #include "diagnostic-core.h"
>> @@ -341,11 +342,13 @@ get_coverage_counts (unsigned counter, unsigned ex
>> {
>> static int warned = 0;
>>
>> - if (!warned++)
>> - inform (input_location, (flag_guess_branch_prob
>> - ? "file %s not found, execution counts estimated"
>> - : "file %s not found, execution counts assumed to be zero"),
>> - da_file_name);
>> + if (!warned++ && dump_enabled_p ())
>> + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
>> + (flag_guess_branch_prob
>> + ? "file %s not found, execution counts estimated"
>> + : "file %s not found, execution counts assumed to "
>> + "be zero"),
>> + da_file_name);
>> return NULL;
>> }
>>
>> @@ -369,21 +372,25 @@ get_coverage_counts (unsigned counter, unsigned ex
>> warning_at (input_location, OPT_Wcoverage_mismatch,
>> "the control flow of function %qE does not match "
>> "its profile data (counter %qs)", id, ctr_names[counter]);
>> - if (warning_printed)
>> + if (warning_printed && dump_enabled_p ())
>> {
>> - inform (input_location, "use -Wno-error=coverage-mismatch to tolerate "
>> - "the mismatch but performance may drop if the
>> function is hot");
>> + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
>> + "use -Wno-error=coverage-mismatch to tolerate "
>> + "the mismatch but performance may drop if the "
>> + "function is hot");
>>
>> if (!seen_error ()
>> && !warned++)
>> {
>> - inform (input_location, "coverage mismatch ignored");
>> - inform (input_location, flag_guess_branch_prob
>> - ? G_("execution counts estimated")
>> - : G_("execution counts assumed to be zero"));
>> + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
>> + "coverage mismatch ignored");
>> + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
>> + flag_guess_branch_prob
>> + ? G_("execution counts estimated")
>> + : G_("execution counts assumed to be zero"));
>> if (!flag_guess_branch_prob)
>> - inform (input_location,
>> - "this can result in poorly optimized code");
>> + dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
>> + "this can result in poorly optimized code");
>> }
>> }
>>
>> @@ -1103,6 +1110,11 @@ coverage_init (const char *filename)
>> int len = strlen (filename);
>> int prefix_len = 0;
>>
>> + /* Since coverage_init is invoked very early, before the pass
>> + manager, we need to set up the dumping explicitly. This is
>> + similar to the handling in finish_optimization_passes. */
>> + dump_start (pass_profile.pass.static_pass_number, NULL);
>> +
>> if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
>> profile_data_prefix = getpwd ();
>>
>> @@ -1145,6 +1157,8 @@ coverage_init (const char *filename)
>> gcov_write_unsigned (bbg_file_stamp);
>> }
>> }
>> +
>> + dump_finish (pass_profile.pass.static_pass_number);
>> }
>>
>> /* Performs file-level cleanup. Close notes file, generate coverage
>> Index: ipa-inline.c
>> ===================================================================
>> --- ipa-inline.c (revision 201461)
>> +++ ipa-inline.c (working copy)
>> @@ -1322,7 +1322,7 @@ recursive_inlining (struct cgraph_edge *edge,
>> reset_edge_growth_cache (curr);
>> }
>>
>> - inline_call (curr, false, new_edges, &overall_size, true);
>> + inline_call (curr, false, new_edges, &overall_size, true, false);
>> lookup_recursive_calls (node, curr->callee, heap);
>> n++;
>> }
>> @@ -1612,7 +1612,8 @@ inline_small_functions (void)
>> fprintf (dump_file, " Peeling recursion with depth %i\n", depth);
>>
>> gcc_checking_assert (!callee->global.inlined_to);
>> - inline_call (edge, true, &new_indirect_edges, &overall_size, true);
>> + inline_call (edge, true, &new_indirect_edges, &overall_size, true,
>> + false);
>> if (flag_indirect_inlining)
>> add_new_edges_to_heap (edge_heap, new_indirect_edges);
>>
>> @@ -1733,7 +1734,7 @@ flatten_function (struct cgraph_node *node, bool e
>> xstrdup (cgraph_node_name (callee)),
>> xstrdup (cgraph_node_name (e->caller)));
>> orig_callee = callee;
>> - inline_call (e, true, NULL, NULL, false);
>> + inline_call (e, true, NULL, NULL, false, early);
>> if (e->callee != orig_callee)
>> orig_callee->symbol.aux = (void *) node;
>> flatten_function (e->callee, early);
>> @@ -1852,7 +1853,8 @@ ipa_inline (void)
>> inline_summary
>> (node->callers->caller)->size);
>> }
>>
>> - inline_call (node->callers, true, NULL, NULL, true);
>> + inline_call (node->callers, true, NULL, NULL, true,
>> + false);
>> if (dump_file)
>> fprintf (dump_file,
>> " Inlined into %s which now has %i size\n",
>> @@ -1925,7 +1927,7 @@ inline_always_inline_functions (struct cgraph_node
>> fprintf (dump_file, " Inlining %s into %s (always_inline).\n",
>> xstrdup (cgraph_node_name (e->callee)),
>> xstrdup (cgraph_node_name (e->caller)));
>> - inline_call (e, true, NULL, NULL, false);
>> + inline_call (e, true, NULL, NULL, false, true);
>> inlined = true;
>> }
>> if (inlined)
>> @@ -1977,7 +1979,7 @@ early_inline_small_functions (struct cgraph_node *
>> fprintf (dump_file, " Inlining %s into %s.\n",
>> xstrdup (cgraph_node_name (callee)),
>> xstrdup (cgraph_node_name (e->caller)));
>> - inline_call (e, true, NULL, NULL, true);
>> + inline_call (e, true, NULL, NULL, true, true);
>> inlined = true;
>> }
>>
>> Index: ipa-inline.h
>> ===================================================================
>> --- ipa-inline.h (revision 201461)
>> +++ ipa-inline.h (working copy)
>> @@ -228,7 +228,8 @@ void free_growth_caches (void);
>> void compute_inline_parameters (struct cgraph_node *, bool);
>>
>> /* In ipa-inline-transform.c */
>> -bool inline_call (struct cgraph_edge *, bool, vec<cgraph_edge_p> *,
>> int *, bool);
>> +bool inline_call (struct cgraph_edge *, bool, vec<cgraph_edge_p> *, int *,
>> + bool, bool);
>> unsigned int inline_transform (struct cgraph_node *);
>> void clone_inlined_nodes (struct cgraph_edge *e, bool, bool, int *);
>>
>> Index: testsuite/gcc.dg/pr40209.c
>> ===================================================================
>> --- testsuite/gcc.dg/pr40209.c (revision 201461)
>> +++ testsuite/gcc.dg/pr40209.c (working copy)
>> @@ -1,5 +1,5 @@
>> /* { dg-do compile } */
>> -/* { dg-options "-O2 -fprofile-use" } */
>> +/* { dg-options "-O2 -fprofile-use -fopt-info" } */
>>
>> void process(const char *s);
>>
>> Index: testsuite/gcc.dg/pr26570.c
>> ===================================================================
>> --- testsuite/gcc.dg/pr26570.c (revision 201461)
>> +++ testsuite/gcc.dg/pr26570.c (working copy)
>> @@ -1,5 +1,5 @@
>> /* { dg-do compile } */
>> -/* { dg-options "-O2 -fprofile-generate -fprofile-use" } */
>> +/* { dg-options "-O2 -fprofile-generate -fprofile-use -fopt-info" } */
>>
>> unsigned test (unsigned a, unsigned b)
>> {
>> Index: testsuite/gcc.dg/pr32773.c
>> ===================================================================
>> --- testsuite/gcc.dg/pr32773.c (revision 201461)
>> +++ testsuite/gcc.dg/pr32773.c (working copy)
>> @@ -1,6 +1,6 @@
>> /* { dg-do compile } */
>> -/* { dg-options "-O -fprofile-use" } */
>> -/* { dg-options "-O -m4 -fprofile-use" { target sh-*-* } } */
>> +/* { dg-options "-O -fprofile-use -fopt-info" } */
>> +/* { dg-options "-O -m4 -fprofile-use -fopt-info" { target sh-*-* } } */
>>
>> void foo (int *p)
>> {
>> Index: testsuite/g++.dg/tree-ssa/dom-invalid.C
>> ===================================================================
>> --- testsuite/g++.dg/tree-ssa/dom-invalid.C (revision 201461)
>> +++ testsuite/g++.dg/tree-ssa/dom-invalid.C (working copy)
>> @@ -1,7 +1,7 @@
>> // PR tree-optimization/39557
>> // invalid post-dom info leads to infinite loop
>> // { dg-do run }
>> -// { dg-options "-Wall -fno-exceptions -O2 -fprofile-use -fno-rtti" }
>> +// { dg-options "-Wall -fno-exceptions -O2 -fprofile-use -fopt-info
>> -fno-rtti" }
>>
>> struct C
>> {
>> Index: testsuite/gcc.dg/inline-dump.c
>> ===================================================================
>> --- testsuite/gcc.dg/inline-dump.c (revision 0)
>> +++ testsuite/gcc.dg/inline-dump.c (revision 0)
>> @@ -0,0 +1,11 @@
>> +/* Verify that -fopt-info can output correct inline info. */
>> +/* { dg-do compile } */
>> +/* { dg-options "-Wall -fopt-info-inline=stderr -O2 -fno-early-inlining" } */
>> +static inline int leaf() {
>> + int i, ret = 0;
>> + for (i = 0; i < 10; i++)
>> + ret += i;
>> + return ret;
>> +}
>> +static inline int foo(void) { return leaf(); } /* { dg-message "note:
>> leaf .*inlined into bar .*via inline instance foo.*\n" } */
>> +int bar(void) { return foo(); }
>>>
>>> Thanks,
>>> Teresa
>>>
>>>>
>>>> Thanks,
>>>>
>>>> Martin
>>>
>>>
>>>
>>> --
>>> Teresa Johnson | Software Engineer | tejohnson@google.com | 408-460-2413
>>
>>
>>
>> --
>> Teresa Johnson | Software Engineer | tejohnson@google.com | 408-460-2413
>
>
>
> --
> Teresa Johnson | Software Engineer | tejohnson@google.com | 408-460-2413
--
Teresa Johnson | Software Engineer | tejohnson@google.com | 408-460-2413
More information about the Gcc-patches
mailing list