After some off-line discussion, we decided to use a more general approach to control the printing of optimization messages/warnings. We will introduce a new option -fopt-info: * fopt-info=0 or fno-opt-info: no message will be emitted. * fopt-info or fopt-info=1: emit important warnings and optimization messages with large performance impact. * fopt-info=2: warnings and optimization messages targeting power users. * fopt-info=3: informational messages for compiler developers.
2011-10-19 Rong Xu <x...@google.com> * gcc/common.opt (fopt-info): New flag. (fopt-info=) Ditto. * gcc/opts.c (common_handle_option): Handle OPT_fopt_info_. * gcc/flag-types.h (opt_info_verbosity_levels): New enum. * gcc/value-prof.c (check_ic_counter): guard warnings/notes by flag_opt_info. (find_func_by_funcdef_no): Ditto. (check_ic_target): Ditto. (check_counter): Ditto. (check_ic_counter): Ditto. * gcc/mcf.c (find_minimum_cost_flow): Ditto. * gcc/profile.c (read_profile_edge_counts): Ditto. (compute_branch_probabilities): Ditto. * gcc/coverage.c (read_counts_file): Ditto. (get_coverage_counts): Ditto. * gcc/tree-profile.c: (gimple_gen_reusedist): Ditto. (maybe_issue_profile_use_note): Ditto. (optimize_reusedist): Ditto. * gcc/testsuite/gcc.dg/pr32773.c: add -fopt-info. * gcc/testsuite/gcc.dg/pr40209.c: Ditto. * gcc/testsuite/gcc.dg/pr26570.c: Ditto. * gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C: Ditto. Index: gcc/value-prof.c =================================================================== --- gcc/value-prof.c (revision 180106) +++ gcc/value-prof.c (working copy) @@ -472,9 +472,10 @@ : 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 (flag_opt_info >= OPT_INFO_MAX) + inform (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; @@ -510,33 +511,42 @@ location_t locus; if (*count1 > all && flag_profile_correction) { - locus = (stmt != NULL) - ? gimple_location (stmt) - : DECL_SOURCE_LOCATION (current_function_decl); - inform (locus, "Correcting inconsistent value profile: " - "ic (topn) profiler top target count (%ld) exceeds " - "BB count (%ld)", (long)*count1, (long)all); + if (flag_opt_info >= OPT_INFO_MAX) + { + locus = (stmt != NULL) + ? gimple_location (stmt) + : DECL_SOURCE_LOCATION (current_function_decl); + inform (locus, "Correcting inconsistent value profile: " + "ic (topn) profiler top target count (%ld) exceeds " + "BB count (%ld)", (long)*count1, (long)all); + } *count1 = all; } if (*count2 > all && flag_profile_correction) { - locus = (stmt != NULL) - ? gimple_location (stmt) - : DECL_SOURCE_LOCATION (current_function_decl); - inform (locus, "Correcting inconsistent value profile: " - "ic (topn) profiler second target count (%ld) exceeds " - "BB count (%ld)", (long)*count2, (long)all); + if (flag_opt_info >= OPT_INFO_MAX) + { + locus = (stmt != NULL) + ? gimple_location (stmt) + : DECL_SOURCE_LOCATION (current_function_decl); + inform (locus, "Correcting inconsistent value profile: " + "ic (topn) profiler second target count (%ld) exceeds " + "BB count (%ld)", (long)*count2, (long)all); + } *count2 = all; } if (*count2 > *count1) { - locus = (stmt != NULL) - ? gimple_location (stmt) - : DECL_SOURCE_LOCATION (current_function_decl); - inform (locus, "Corrupted topn ic value profile: " - "first target count (%ld) is less than the second " - "target count (%ld)", (long)*count1, (long)*count2); + if (flag_opt_info >= OPT_INFO_MAX) + { + locus = (stmt != NULL) + ? gimple_location (stmt) + : DECL_SOURCE_LOCATION (current_function_decl); + inform (locus, "Corrupted topn ic value profile: " + "first target count (%ld) is less than the second " + "target count (%ld)", (long)*count1, (long)*count2); + } return true; } @@ -548,12 +558,16 @@ *count2 = all - *count1; else { - locus = (stmt != NULL) - ? gimple_location (stmt) - : DECL_SOURCE_LOCATION (current_function_decl); - inform (locus, "Corrupted topn ic value profile: top two targets's" - " total count (%ld) exceeds bb count (%ld)", - (long)(*count1 + *count2), (long)all); + if (flag_opt_info >= OPT_INFO_MAX) + { + locus = (stmt != NULL) + ? gimple_location (stmt) + : DECL_SOURCE_LOCATION (current_function_decl); + inform (locus, + "Corrupted topn ic value profile: top two targets's" + " total count (%ld) exceeds bb count (%ld)", + (long)(*count1 + *count2), (long)all); + } return true; } } @@ -1177,8 +1191,11 @@ func_id) == NULL) { if (flag_profile_correction) - inform (DECL_SOURCE_LOCATION (current_function_decl), + { + if (flag_opt_info >= OPT_INFO_MED) + inform (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); @@ -1308,8 +1325,9 @@ return true; locus = gimple_location (call_stmt); - inform (locus, "Skipping target %s with mismatching types for icall ", - cgraph_node_name (target)); + if (flag_opt_info >= OPT_INFO_MAX) + inform (locus, "Skipping target %s with mismatching types for icall ", + cgraph_node_name (target)); return false; } @@ -1571,7 +1589,7 @@ if (direct_call1 == NULL || !check_ic_target (stmt, direct_call1)) { - if (flag_ripa_verbose) + if (flag_opt_info >= OPT_INFO_MAX) { if (!direct_call1) inform (locus, "Can not find indirect call target decl " @@ -1597,7 +1615,7 @@ return false; modify1 = gimple_ic (stmt, direct_call1, prob1, count1, all); - if (flag_ripa_verbose) + if (flag_opt_info >= OPT_INFO_MIN) inform (locus, "Promote indirect call to target (call count:%u) %s", (unsigned) count1, lang_hooks.decl_printable_name (direct_call1->decl, 3)); @@ -1635,7 +1653,7 @@ modify2 = gimple_ic (stmt, direct_call2, prob2, count2, all - count1); - if (flag_ripa_verbose) + if (flag_opt_info >= OPT_INFO_MIN) inform (locus, "Promote indirect call to target (call count:%u) %s", (unsigned) count2, lang_hooks.decl_printable_name (direct_call2->decl, 3)); Index: gcc/mcf.c =================================================================== --- gcc/mcf.c (revision 180106) +++ gcc/mcf.c (working copy) @@ -1442,7 +1442,8 @@ if (iteration > MAX_ITER (fixup_graph->num_vertices, fixup_graph->num_edges)) { - inform (DECL_SOURCE_LOCATION (current_function_decl), + if (flag_opt_info >= OPT_INFO_MAX) + inform (DECL_SOURCE_LOCATION (current_function_decl), "Exiting profile correction early to avoid excessive " "compile time"); break; Index: gcc/testsuite/gcc.dg/pr32773.c =================================================================== --- gcc/testsuite/gcc.dg/pr32773.c (revision 180106) +++ gcc/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: gcc/testsuite/gcc.dg/pr40209.c =================================================================== --- gcc/testsuite/gcc.dg/pr40209.c (revision 180106) +++ gcc/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: gcc/testsuite/gcc.dg/pr26570.c =================================================================== --- gcc/testsuite/gcc.dg/pr26570.c (revision 180106) +++ gcc/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: gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C =================================================================== --- gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C (revision 180106) +++ gcc/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: gcc/opts.c =================================================================== --- gcc/opts.c (revision 180106) +++ gcc/opts.c (working copy) @@ -1579,6 +1579,15 @@ pp_set_line_maximum_length (dc->printer, value); break; + case OPT_fopt_info_: + if (value < 0 || value > OPT_INFO_MAX) + error_at (loc, + "%d: invalid value for opt_info", + value); + else + opts->x_flag_opt_info = value; + break; + case OPT_fpack_struct_: if (value <= 0 || (value & (value - 1)) || value > 16) error_at (loc, Index: gcc/profile.c =================================================================== --- gcc/profile.c (revision 180106) +++ gcc/profile.c (working copy) @@ -414,7 +414,7 @@ if (flag_profile_correction) { static bool informed = 0; - if (!informed) + if ((flag_opt_info >= OPT_INFO_MAX) && !informed) inform (input_location, "corrupted profile info: edge count exceeds maximal count"); informed = 1; @@ -635,7 +635,7 @@ { /* Inconsistency detected. Make it flow-consistent. */ static int informed = 0; - if (informed == 0) + if ((flag_opt_info >= OPT_INFO_MAX) && informed == 0) { informed = 1; inform (input_location, "correcting inconsistent profile data"); Index: gcc/flag-types.h =================================================================== --- gcc/flag-types.h (revision 180106) +++ gcc/flag-types.h (working copy) @@ -204,4 +204,11 @@ MAX_VERBOSITY_LEVEL }; +/* flag_opt_info verbosity levels. */ +enum opt_info_verbosity_levels { + OPT_INFO_NONE = 0, + OPT_INFO_MIN = 1, + OPT_INFO_MED = 2, + OPT_INFO_MAX = 3 +}; #endif /* ! GCC_FLAG_TYPES_H */ Index: gcc/coverage.c =================================================================== --- gcc/coverage.c (revision 180106) +++ gcc/coverage.c (working copy) @@ -355,7 +355,8 @@ warning (OPT_Wripa_opt_mismatch, "command line arguments mismatch for %s " "and %s", mod_info1->source_filename, mod_info2->source_filename); - if (warn_ripa_opt_mismatch && non_warning_mismatch && flag_ripa_verbose) + if (warn_ripa_opt_mismatch && non_warning_mismatch + && (flag_opt_info >= OPT_INFO_MED)) { inform (UNKNOWN_LOCATION, "Options for %s", mod_info1->source_filename); for (i = 0; i < num_non_warning_opts1; i++) @@ -575,29 +576,47 @@ int fd; char *aux_da_filename = get_da_file_name (mod_info->da_filename); gcc_assert (!mod_info->is_primary); - if (pointer_set_insert (modset, (void *)(size_t)mod_info->ident)) - inform (input_location, "Not importing %s: already imported", - mod_info->source_filename); - else if ((module_infos[0]->lang & GCOV_MODULE_LANG_MASK) != - (mod_info->lang & GCOV_MODULE_LANG_MASK)) - inform (input_location, "Not importing %s: source language" - " different from primary module's source language", - mod_info->source_filename); - else if (module_infos_read == max_group) - inform (input_location, "Not importing %s: maximum group size" - " reached", mod_info->source_filename); - else if (incompatible_cl_args (module_infos[0], mod_info)) - inform (input_location, "Not importing %s: command-line" - " arguments not compatible with primary module", - mod_info->source_filename); - else if ((fd = open (aux_da_filename, O_RDONLY)) < 0) - inform (input_location, "Not importing %s: couldn't open %s", - mod_info->source_filename, aux_da_filename); - else if ((mod_info->lang & GCOV_MODULE_ASM_STMTS) - && flag_ripa_disallow_asm_modules) - inform (input_location, "Not importing %s: contains assembler" - " statements", mod_info->source_filename); - else + if (pointer_set_insert (modset, (void *)(size_t)mod_info->ident)) + { + if (flag_opt_info >= OPT_INFO_MAX) + inform (input_location, "Not importing %s: already imported", + mod_info->source_filename); + } + else if ((module_infos[0]->lang & GCOV_MODULE_LANG_MASK) != + (mod_info->lang & GCOV_MODULE_LANG_MASK)) + { + if (flag_opt_info >= OPT_INFO_MAX) + inform (input_location, "Not importing %s: source language" + " different from primary module's source language", + mod_info->source_filename); + } + else if (module_infos_read == max_group) + { + if (flag_opt_info >= OPT_INFO_MAX) + inform (input_location, "Not importing %s: maximum group" + " size reached", mod_info->source_filename); + } + else if (incompatible_cl_args (module_infos[0], mod_info)) + { + if (flag_opt_info >= OPT_INFO_MAX) + inform (input_location, "Not importing %s: command-line" + " arguments not compatible with primary module", + mod_info->source_filename); + } + else if ((fd = open (aux_da_filename, O_RDONLY)) < 0) + { + if (flag_opt_info >= OPT_INFO_MAX) + inform (input_location, "Not importing %s: couldn't open %s", + mod_info->source_filename, aux_da_filename); + } + else if ((mod_info->lang & GCOV_MODULE_ASM_STMTS) + && flag_ripa_disallow_asm_modules) + { + if (flag_opt_info >= OPT_INFO_MAX) + inform (input_location, "Not importing %s: contains " + "assembler statements", mod_info->source_filename); + } + else { close (fd); module_infos_read++; @@ -612,7 +631,7 @@ } } - if (flag_ripa_verbose) + if (flag_opt_info >= OPT_INFO_MAX) { inform (input_location, "MODULE Id=%d, Is_Primary=%s," @@ -676,7 +695,7 @@ { static int warned = 0; - if (!warned++) + if ((flag_opt_info >= OPT_INFO_MIN) && !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"), @@ -688,7 +707,7 @@ if (!entry) { - if (!flag_dyn_ipa) + if ((flag_opt_info >= OPT_INFO_MIN) && !flag_dyn_ipa) warning (0, "no coverage for function %qE found", DECL_ASSEMBLER_NAME (current_function_decl)); return NULL; @@ -705,7 +724,7 @@ 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 ((flag_opt_info >= OPT_INFO_MIN) && warning_printed) { inform (input_location, "Use -Wno-error=coverage-mismatch to tolerate " "the mismatch but performance may drop if the function is hot"); @@ -727,7 +746,8 @@ } else if (entry->lineno_checksum != lineno_checksum) { - warning (0, "Source location for function %qE have changed," + warning (OPT_Wcoverage_mismatch, + "Source location for function %qE have changed," " the profile data may be out of date", DECL_ASSEMBLER_NAME (current_function_decl)); } Index: gcc/common.opt =================================================================== --- gcc/common.opt (revision 180106) +++ gcc/common.opt (working copy) @@ -1125,11 +1125,6 @@ Don't promote always inline static functions assuming they will be inlined and no copy is needed. - -fripa-verbose -Common Report Var(flag_ripa_verbose) -Enable verbose informational messages for LIPO compilation - fearly-inlining Common Report Var(flag_early_inlining) Init(1) Optimization Perform early inlining @@ -1572,6 +1567,19 @@ Common Report Var(flag_omit_frame_pointer) Optimization When possible do not generate stack frames +fopt-info +Common Report Var(flag_opt_info) Optimization Init(1) +Enable verbose informational messages for optimizations (same as -fopt-info=1) + +; fopt-info=0: no message will be emitted. +; fopt-info or fopt-info=1: emit important warnings and optimization messages with +; large performance impact. +; fopt-info=2: warnings and optimization messages targeting power users. +; fopt-info=3: informational messages for compiler developers. +fopt-info= +Common RejectNegative Joined UInteger Optimization +-fopt-info=[0|1|2|3] Set the verbose level of informational messages for optimizations + foptimize-register-move Common Report Var(flag_regmove) Optimization Do the full register move optimization pass Index: gcc/tree-profile.c =================================================================== --- gcc/tree-profile.c (revision 180106) +++ gcc/tree-profile.c (working copy) @@ -1096,13 +1096,16 @@ reusedist_make_instr_call (stmt, subst, counters), GSI_NEW_STMT); - locus = (stmt != NULL) - ? gimple_location (stmt) - : DECL_SOURCE_LOCATION (current_function_decl); - inform (locus, - "inserted reuse distance instrumentation for %qs, using " - "%d gcov counters", subst->original_name, - subst->num_ptr_args * RD_NUM_COUNTERS); + if (flag_opt_info >= OPT_INFO_MAX) + { + locus = (stmt != NULL) + ? gimple_location (stmt) + : DECL_SOURCE_LOCATION (current_function_decl); + inform (locus, + "inserted reuse distance instrumentation for %qs, using " + "%d gcov counters", subst->original_name, + subst->num_ptr_args * RD_NUM_COUNTERS); + } } } } @@ -1214,7 +1217,7 @@ reusedist_from_counters (counters, &rd); - if (rd.count) + if ((flag_opt_info >= OPT_INFO_MAX) && rd.count) inform (locus, "reuse distance counters for arg %d: %lld %lld %lld %lld", arg, (long long int)rd.mean_dist, (long long int)rd.mean_size, (long long int)rd.count, (long long int)rd.dist_x_size); @@ -1283,9 +1286,10 @@ subst_decl = reusedist_get_nt_decl (gimple_call_fndecl (stmt), subst, suffix); gimple_call_set_fndecl (stmt, subst_decl); - inform (locus, "replaced %qs with non-temporal %qs", - subst->original_name, - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (subst_decl))); + if (flag_opt_info >= OPT_INFO_MED) + inform (locus, "replaced %qs with non-temporal %qs", + subst->original_name, + IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (subst_decl))); } /* Replace string operations with equivalent nontemporal, when profitable. */ @@ -1323,11 +1327,13 @@ if (counter_index != n_counters) { - warning (0, "coverage mismatch for reuse distance counters " + warning (OPT_Wcoverage_mismatch, + "coverage mismatch for reuse distance counters " "in function %qs", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); - inform (input_location, "number of counters is %u instead of %u", - n_counters, counter_index); + if (flag_opt_info >= OPT_INFO_MAX) + inform (input_location, "number of counters is %u instead of %u", + n_counters, counter_index); } } -- This patch is available for review at http://codereview.appspot.com/5294043