This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Disable profile-use if no .gcda file is found
- From: Neil Vachharajani <nvachhar at google dot com>
- To: gcc-patches at gcc dot gnu dot org, jh at suse dot cz
- Date: Tue, 29 Sep 2009 11:21:04 -0700
- Subject: [PATCH] Disable profile-use if no .gcda file is found
If -fprofile-use is specified, but no .gcda file is found, reset all
the flags back to the values they would have had if -fprofile-use was
not specified. Since the code path where -fprofile-use is on and
.gcda files are not found is not a well tested pass, this will
increase the robustness of FDO. Further, in the event an ICE is found
when doing FDO, this allows users to delete .gcda files as a work
around without having to implement complex modifications to the build
system. To ensure the testsuite still passes (and is relevant), some
tests which used -fprofile-use but had no .gcda file had to be moved
so that they would have a .gcda file generated. This also involved
adding a main to these unit tests.
Bootstrapped and regtested on x86_64. Ok for trunk?
2009-09-29 Neil Vachharajani <nvachhar@google.com>
* coverage.c (read_counts_file): Disable profile use if no .gcda
file is found.
* opts.c (common_handle_option): Call set_profile_use instead of
directly setting parameters in -fprofile-use.
(set_profile_use): New function.
* opts.h (set_profile_use): New function.
* testsuite/g++.dg/tree-ssa/dom-invalid.C: Moved to
testsuite/g++.dg/tree-prof.
* testsuite/g++.dg/tree-prof/dom-invalid.C: See above.
* testsuite/gcc.dg/pr26570.c: Moved to
testsuite/gcc.dg/tree-prof.
* testsuite/gcc.dg/tree-prof/pr26570.c: See above. main added.
* testsuite/gcc.dg/pr32773.c: Moved to
testsuite/gcc.dg/tree-prof.
* testsuite/gcc.dg/tree-prof/pr32773.c: See above. main added.
--- gcc.orig/coverage.c 2009-09-23 17:49:57.000000000 -0700
+++ gcc/coverage.c 2009-09-23 19:24:27.000000000 -0700
@@ -46,6 +46,7 @@
#include "tree-iterator.h"
#include "cgraph.h"
#include "tree-pass.h"
+#include "opts.h"
#include "gcov-io.h"
#include "gcov-io.c"
@@ -186,6 +187,7 @@
static void
read_counts_file (void)
{
+ static int warned = 0;
gcov_unsigned_t fn_ident = 0;
char *name = NULL;
counts_entry_t *summaried = NULL;
@@ -196,7 +198,17 @@
unsigned cfg_checksum = 0;
if (!gcov_open (da_file_name, 1))
- return;
+ {
+ if (!warned)
+ {
+ warned = 1;
+ inform (input_location,
+ "file %s not found, disabling profile use",
+ da_file_name);
+ }
+ set_profile_use (false, true);
+ return;
+ }
if (!gcov_magic (gcov_read_unsigned (), GCOV_DATA_MAGIC))
{
Index: gcc/opts.c
===================================================================
--- gcc.orig/opts.c 2009-09-23 17:45:36.000000000 -0700
+++ gcc/opts.c 2009-09-23 17:51:22.000000000 -0700
@@ -1821,35 +1821,10 @@
case OPT_fprofile_use_:
profile_data_prefix = xstrdup (arg);
- flag_profile_use = true;
value = true;
/* No break here - do -fprofile-use processing. */
case OPT_fprofile_use:
- if (!flag_branch_probabilities_set)
- flag_branch_probabilities = value;
- if (!flag_profile_values_set)
- flag_profile_values = value;
- if (!flag_unroll_loops_set)
- flag_unroll_loops = value;
- if (!flag_peel_loops_set)
- flag_peel_loops = value;
- if (!flag_tracer_set)
- flag_tracer = value;
- if (!flag_value_profile_transformations_set)
- flag_value_profile_transformations = value;
- if (!flag_inline_functions_set)
- flag_inline_functions = value;
- if (!flag_ipa_cp_set)
- flag_ipa_cp = value;
- if (!flag_ipa_cp_clone_set
- && value && flag_ipa_cp)
- flag_ipa_cp_clone = value;
- if (!flag_predictive_commoning_set)
- flag_predictive_commoning = value;
- if (!flag_unswitch_loops_set)
- flag_unswitch_loops = value;
- if (!flag_gcse_after_reload_set)
- flag_gcse_after_reload = value;
+ set_profile_use (value, false);
break;
case OPT_fprofile_generate_:
@@ -2351,3 +2326,42 @@
}
free (new_option);
}
+
+/* Set FLAG_PROFILE_USE and dependent flags based on VALUE. This
+ function is used to handle the -f(no)profile-use option as well as
+ to reset flags if a .gcda file is not found. */
+
+void
+set_profile_use (bool value, bool force)
+{
+ flag_profile_use = value;
+ if (!flag_branch_probabilities_set || force)
+ flag_branch_probabilities = value;
+ if (!flag_profile_values_set || force)
+ flag_profile_values = value;
+ if (!flag_unroll_loops_set)
+ flag_unroll_loops = value;
+ if (!flag_peel_loops_set)
+ flag_peel_loops = value;
+ if (!flag_tracer_set)
+ flag_tracer = value;
+ if (!flag_value_profile_transformations_set || force)
+ flag_value_profile_transformations = value;
+ if (!flag_inline_functions_set)
+ flag_inline_functions = value;
+ if (!flag_ipa_cp_set)
+ flag_ipa_cp = value;
+ if (!flag_ipa_cp_clone_set)
+ {
+ if (!flag_ipa_cp_set || flag_ipa_cp)
+ flag_ipa_cp_clone = value;
+ }
+ if (!flag_predictive_commoning_set)
+ flag_predictive_commoning = value;
+ if (!flag_unswitch_loops_set)
+ flag_unswitch_loops = value;
+ if (!flag_gcse_after_reload_set)
+ flag_gcse_after_reload = value;
+}
+
+
Index: gcc/opts.h
===================================================================
--- gcc.orig/opts.h 2009-09-23 17:45:36.000000000 -0700
+++ gcc/opts.h 2009-09-23 17:51:22.000000000 -0700
@@ -107,4 +107,5 @@
extern void enable_warning_as_error (const char *arg, int value,
unsigned int lang_mask);
extern void print_ignored_options (void);
+extern void set_profile_use (bool value, bool force);
#endif
Index: gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C
===================================================================
--- gcc.orig/testsuite/g++.dg/tree-ssa/dom-invalid.C 2009-09-23
17:45:36.000000000 -0700
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,52 +0,0 @@
-// 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" }
-
-struct C
-{
- virtual const char *bar () const;
-};
-
-struct D
-{
- D () : d1 (0) { }
- C *d2[4];
- int d1;
- inline const C & baz (int i) const { return *d2[i]; }
-};
-
-struct E
-{
- unsigned char e1[2];
- D e2;
- bool foo () const { return (e1[1] & 1) != 0; }
- virtual const char *bar () const __attribute__ ((noinline));
-};
-
-const char *
-C::bar () const
-{
- return 0;
-}
-
-C c;
-
-const char *
-E::bar () const
-{
- const char *e = __null;
- if (foo () && (e = c.C::bar ()))
- return e;
- for (int i = 0, n = e2.d1; i < n; i++)
- if ((e = e2.baz (i).C::bar ()))
- return e;
- return e;
-}
-
-int
-main ()
-{
- E e;
- e.bar ();
-} // { dg-message "note: file" "" }
Index: gcc/testsuite/gcc.dg/pr26570.c
===================================================================
--- gcc.orig/testsuite/gcc.dg/pr26570.c 2009-09-23 17:45:36.000000000 -0700
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,9 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O2 -fprofile-generate -fprofile-use" } */
-
-unsigned test (unsigned a, unsigned b)
-{
- return a / b;
-} /* { dg-message "note: \[^\n\]*execution counts estimated" } */
-
-/* { dg-final { cleanup-coverage-files } } */
Index: gcc/testsuite/gcc.dg/pr32773.c
===================================================================
--- gcc.orig/testsuite/gcc.dg/pr32773.c 2009-09-23 17:45:36.000000000 -0700
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,11 +0,0 @@
-/* { dg-do compile } */
-/* { dg-options "-O -fprofile-use" } */
-/* { dg-options "-O -m4 -fprofile-use" { target sh-*-* } } */
-
-void foo (int *p)
-{
- if (p)
- *p = 0;
-} /* { dg-message "note: \[^\n\]*execution counts estimated" } */
-
-/* { dg-final { cleanup-coverage-files } } */
Index: gcc/testsuite/g++.dg/tree-prof/dom-invalid.C
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/g++.dg/tree-prof/dom-invalid.C 2009-09-23
17:51:22.000000000 -0700
@@ -0,0 +1,51 @@
+// PR tree-optimization/39557
+// invalid post-dom info leads to infinite loop
+// { dg-options "-Wall -fno-exceptions -O2 -fno-rtti" }
+
+struct C
+{
+ virtual const char *bar () const;
+};
+
+struct D
+{
+ D () : d1 (0) { }
+ C *d2[4];
+ int d1;
+ inline const C & baz (int i) const { return *d2[i]; }
+};
+
+struct E
+{
+ unsigned char e1[2];
+ D e2;
+ bool foo () const { return (e1[1] & 1) != 0; }
+ virtual const char *bar () const __attribute__ ((noinline));
+};
+
+const char *
+C::bar () const
+{
+ return 0;
+}
+
+C c;
+
+const char *
+E::bar () const
+{
+ const char *e = __null;
+ if (foo () && (e = c.C::bar ()))
+ return e;
+ for (int i = 0, n = e2.d1; i < n; i++)
+ if ((e = e2.baz (i).C::bar ()))
+ return e;
+ return e;
+}
+
+int
+main ()
+{
+ E e;
+ e.bar ();
+}
Index: gcc/testsuite/gcc.dg/tree-prof/pr26570.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.dg/tree-prof/pr26570.c 2009-09-23 17:51:22.000000000 -0700
@@ -0,0 +1,13 @@
+/* { dg-options "-O2" } */
+
+unsigned test (unsigned a, unsigned b)
+{
+ return a / b;
+}
+
+int main()
+{
+ return test (6, 3) - 2;
+}
+
+/* { dg-final { cleanup-coverage-files } } */
Index: gcc/testsuite/gcc.dg/tree-prof/pr32773.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ gcc/testsuite/gcc.dg/tree-prof/pr32773.c 2009-09-23 17:51:22.000000000 -0700
@@ -0,0 +1,17 @@
+/* { dg-options "-O" } */
+/* { dg-options "-O -m4" { target sh-*-* } } */
+
+void foo (int *p)
+{
+ if (p)
+ *p = 0;
+}
+
+int main()
+{
+ int x;
+ foo (&x);
+ return 0;
+}
+
+/* { dg-final { cleanup-coverage-files } } */