Ping. Thanks, Teresa On Mon, Aug 12, 2013 at 6:54 AM, Teresa Johnson <tejohn...@google.com> wrote: > On Tue, Aug 6, 2013 at 10:23 PM, Teresa Johnson <tejohn...@google.com> wrote: >> On Tue, Aug 6, 2013 at 9:29 AM, Teresa Johnson <tejohn...@google.com> wrote: >>> On Tue, Aug 6, 2013 at 9:01 AM, Martin Jambor <mjam...@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 <mjam...@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 <tejohn...@google.com> >>>>> >> Dehao Chen <de...@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 <tejohn...@google.com> >> Dehao Chen <de...@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 | tejohn...@google.com | 408-460-2413 >> >> >> >> -- >> Teresa Johnson | Software Engineer | tejohn...@google.com | 408-460-2413 > > > > -- > Teresa Johnson | Software Engineer | tejohn...@google.com | 408-460-2413
-- Teresa Johnson | Software Engineer | tejohn...@google.com | 408-460-2413