diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8213ceec2d5..2a8cde814b1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2007-01-25 Richard Guenther + + * doc/invoke.texi (-Wcoverage-mismatch): Document. + * common.opt (-Wcoverage-mismatch): New warning option. + * coverage.c (get_coverage_counts): Ignore coverage mismatch + if -Wcoverage-mismatch is given. + 2007-01-25 Razya Ladelsky * ipa-cp.c (ipcp_insert_stage, ipcp_driver): Support for SSA. diff --git a/gcc/common.opt b/gcc/common.opt index dfcda946aa2..0a0d287c78a 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -197,6 +197,10 @@ Wvolatile-register-var Common Var(warn_register_var) Warn when a register variable is declared volatile +Wcoverage-mismatch +Common RejectNegative Var(warn_coverage_mismatch) +Warn instead of error in case profiles in -fprofile-use do not match + aux-info Common Separate -aux-info Emit declaration information into diff --git a/gcc/coverage.c b/gcc/coverage.c index 399eb6ea6c6..ba9f1285fc2 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -347,25 +347,46 @@ get_coverage_counts (unsigned counter, unsigned expected, { warning (0, "no coverage for function %qs found", IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl))); - return 0; + return NULL; } checksum = compute_checksum (); - if (entry->checksum != checksum) + if (entry->checksum != checksum + || entry->summary.num != expected) { - error ("coverage mismatch for function %qs while reading counter %qs", - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)), - ctr_names[counter]); - error ("checksum is %x instead of %x", entry->checksum, checksum); - return 0; - } - else if (entry->summary.num != expected) - { - error ("coverage mismatch for function %qs while reading counter %qs", - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl)), - ctr_names[counter]); - error ("number of counters is %d instead of %d", entry->summary.num, expected); - return 0; + static int warned = 0; + const char *id = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME + (current_function_decl)); + + if (warn_coverage_mismatch) + warning (OPT_Wcoverage_mismatch, "coverage mismatch for function " + "%qs while reading counter %qs", id, ctr_names[counter]); + else + error ("coverage mismatch for function %qs while reading counter %qs", + id, ctr_names[counter]); + + if (!inhibit_warnings) + { + if (entry->checksum != checksum) + inform ("checksum is %x instead of %x", entry->checksum, checksum); + else + inform ("number of counters is %d instead of %d", + entry->summary.num, expected); + } + + if (warn_coverage_mismatch + && !inhibit_warnings + && !warned++) + { + inform ("coverage mismatch ignored due to -Wcoverage-mismatch"); + inform (flag_guess_branch_prob + ? "execution counts estimated" + : "execution counts assumed to be zero"); + if (!flag_guess_branch_prob) + inform ("this can result in poorly optimized code"); + } + + return NULL; } if (summary) diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 18fee96e520..fee5871dc89 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -225,7 +225,7 @@ Objective-C and Objective-C++ Dialects}. -w -Wextra -Wall -Waggregate-return -Walways-true -Warray-bounds @gol -Wno-attributes -Wc++-compat -Wc++0x-compat -Wcast-align -Wcast-qual @gol -Wchar-subscripts -Wclobbered -Wcomment @gol --Wconversion -Wno-deprecated-declarations @gol +-Wconversion -Wcoverage-mismatch -Wno-deprecated-declarations @gol -Wdisabled-optimization -Wno-div-by-zero @gol -Wempty-body -Wno-endif-labels @gol -Werror -Werror-* -Werror-implicit-function-declaration @gol @@ -2282,6 +2282,20 @@ diagnostic emitted, which indicates which command line option directly controls that diagnostic, when such an option is known to the diagnostic machinery. +@item -Wcoverage-mismatch +@opindex Wcoverage-mismatch +Warn if feedback profiles do not match when using the +@option{-fprofile-use} option. +If a source file was changed between @option{-fprofile-gen} and +@option{-fprofile-use}, the files with the profile feedback can fail +to match the source file and GCC can not use the profile feedback +information. By default, GCC emits an error message in this case. +The option @option{-Wcoverage-mismatch} emits a warning instead of an +error. GCC does not use appropriate feedback profiles, so using this +option can result in poorly optimized code. This option is useful +only in the case of very minor changes such as bugfixes to an +existing code-base. + @end table @node Warning Options @@ -5613,6 +5627,10 @@ generally profitable only with profile feedback available. The following options are enabled: @code{-fbranch-probabilities}, @code{-fvpt}, @code{-funroll-loops}, @code{-fpeel-loops}, @code{-ftracer} +By default, GCC emits an error message if the feedback profiles do not +match the source code. This error can be turned into a warning by using +@option{-Wcoverage-mismatch}. Note this may result in poorly optimized +code. @end table The following options control compiler behavior regarding floating diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6ac5d273a25..a769a061955 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2007-01-25 Richard Guenther + + * gcc.dg/tree-prof/tree-prof.exp: Define _PROFILE_GENERATE + and _PROFILE_USE. + * gcc.dg/tree-prof/wcoverage-mismatch.c: New testcase. + 2007-01-25 Razya Ladelsky * gcc.dg/ipa/ipa-1.c: Update scan tree dump. diff --git a/gcc/testsuite/gcc.dg/tree-prof/tree-prof.exp b/gcc/testsuite/gcc.dg/tree-prof/tree-prof.exp index f7438194396..70b2d4e17dd 100644 --- a/gcc/testsuite/gcc.dg/tree-prof/tree-prof.exp +++ b/gcc/testsuite/gcc.dg/tree-prof/tree-prof.exp @@ -41,8 +41,8 @@ load_lib profopt.exp # These are globals used by profopt-execute. The first is options # needed to generate profile data, the second is options to use the # profile data. -set profile_option "-fprofile-generate" -set feedback_option "-fprofile-use" +set profile_option "-fprofile-generate -D_PROFILE_GENERATE" +set feedback_option "-fprofile-use -D_PROFILE_USE" foreach src [lsort [glob -nocomplain $srcdir/$subdir/*.c]] { # If we're only testing specific files and this isn't one of them, skip it. diff --git a/gcc/testsuite/gcc.dg/tree-prof/wcoverage-mismatch.c b/gcc/testsuite/gcc.dg/tree-prof/wcoverage-mismatch.c new file mode 100644 index 00000000000..74fe7f8e9c8 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-prof/wcoverage-mismatch.c @@ -0,0 +1,20 @@ +/* { dg-options "-O2 -Wcoverage-mismatch -w" } */ + +int __attribute__((noinline)) bar (void) +{ +} + +int foo (int i) +{ +#ifdef _PROFILE_USE + if (i) + bar (); +#endif + return 0; +} + +int main(int argc, char **argv) +{ + foo (argc); + return 0; +}