diff mbox series

Fix missing profiles with PGO (PR tree-optimization/83051).

Message ID 791bc219-eba0-ee14-9007-7a000c5786ff@suse.cz
State New
Headers show
Series Fix missing profiles with PGO (PR tree-optimization/83051). | expand

Commit Message

Martin Liška Jan. 19, 2018, 3:10 p.m. UTC
Hello.

Following ICE can be seen when we have -fprofile-generate or -fprofile-use w/ missing
gcda file. I hope the proper fix is to check for reliable profile.

Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.

Ready to be installed?
Martin

gcc/ChangeLog:

2018-01-19  Martin Liska  <mliska@suse.cz>

	PR tree-optimization/83051
	* predict.c (handle_missing_profiles): Consider profile only
	if it's reliable.

gcc/testsuite/ChangeLog:

2018-01-19  Martin Liska  <mliska@suse.cz>

	PR tree-optimization/83051
	* gcc.dg/torture/pr83055.c: New test.
---
 gcc/predict.c                          |  2 +-
 gcc/testsuite/gcc.dg/torture/pr83055.c | 13 +++++++++++++
 2 files changed, 14 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.dg/torture/pr83055.c

Comments

Jan Hubicka Jan. 25, 2018, 5:13 p.m. UTC | #1
> Hello.
> 
> Following ICE can be seen when we have -fprofile-generate or -fprofile-use w/ missing
> gcda file. I hope the proper fix is to check for reliable profile.
> 
> Patch can bootstrap on ppc64le-redhat-linux and survives regression tests.
> 
> Ready to be installed?
> Martin
> 
> gcc/ChangeLog:
> 
> 2018-01-19  Martin Liska  <mliska@suse.cz>
> 
> 	PR tree-optimization/83051
> 	* predict.c (handle_missing_profiles): Consider profile only
> 	if it's reliable.
> 
> gcc/testsuite/ChangeLog:
> 
> 2018-01-19  Martin Liska  <mliska@suse.cz>
> 
> 	PR tree-optimization/83051
> 	* gcc.dg/torture/pr83055.c: New test.

Hi,
the problem here is that zero profiles are detected incorrectly because
they should be done at IPA level.
While doing that I also noticed that drop_profile has bug where it does
not set up node's profile that eventually leads to ICE in IRA
if the logic for dropping profiles is bad.

Bootstrapped/regtested x86_64-linux, will commit it shortly.

	PR middle-end/83055
	* predict.c (drop_profile): Do not push/pop cfun; update also
	node->count.
	(handle_missing_profiles): Fix logic looking for zero profiles.

	* gcc.dg/torture/pr83055.c: New testcase.
Index: predict.c
===================================================================
--- predict.c	(revision 257010)
+++ predict.c	(working copy)
@@ -3311,32 +3311,28 @@ drop_profile (struct cgraph_node *node,
     }
 
   basic_block bb;
-  push_cfun (DECL_STRUCT_FUNCTION (node->decl));
-  if (flag_guess_branch_prob)
+  if (opt_for_fn (node->decl, flag_guess_branch_prob))
     {
       bool clear_zeros
-	 = ENTRY_BLOCK_PTR_FOR_FN
-		 (DECL_STRUCT_FUNCTION (node->decl))->count.nonzero_p ();
+	 = !ENTRY_BLOCK_PTR_FOR_FN (fn)->count.nonzero_p ();
       FOR_ALL_BB_FN (bb, fn)
 	if (clear_zeros || !(bb->count == profile_count::zero ()))
 	  bb->count = bb->count.guessed_local ();
-      DECL_STRUCT_FUNCTION (node->decl)->cfg->count_max =
-        DECL_STRUCT_FUNCTION (node->decl)->cfg->count_max.guessed_local ();
+      fn->cfg->count_max = fn->cfg->count_max.guessed_local ();
     }
   else
     {
       FOR_ALL_BB_FN (bb, fn)
 	bb->count = profile_count::uninitialized ();
-      DECL_STRUCT_FUNCTION (node->decl)->cfg->count_max
-	 = profile_count::uninitialized ();
+      fn->cfg->count_max = profile_count::uninitialized ();
     }
-  pop_cfun ();
 
   struct cgraph_edge *e;
   for (e = node->callees; e; e = e->next_callee)
     e->count = gimple_bb (e->call_stmt)->count;
   for (e = node->indirect_calls; e; e = e->next_callee)
     e->count = gimple_bb (e->call_stmt)->count;
+  node->count = ENTRY_BLOCK_PTR_FOR_FN (fn)->count;
   
   profile_status_for_fn (fn)
       = (flag_guess_branch_prob ? PROFILE_GUESSED : PROFILE_ABSENT);
@@ -3373,12 +3369,12 @@ handle_missing_profiles (void)
       gcov_type max_tp_first_run = 0;
       struct function *fn = DECL_STRUCT_FUNCTION (node->decl);
 
-      if (!(node->count == profile_count::zero ()))
+      if (node->count.ipa ().nonzero_p ())
         continue;
       for (e = node->callers; e; e = e->next_caller)
-	if (e->count.initialized_p () && e->count > 0)
+	if (e->count.ipa ().initialized_p () && e->count.ipa () > 0)
 	  {
-            call_count = call_count + e->count;
+            call_count = call_count + e->count.ipa ();
 
 	    if (e->caller->tp_first_run > max_tp_first_run)
 	      max_tp_first_run = e->caller->tp_first_run;
@@ -3411,7 +3407,8 @@ handle_missing_profiles (void)
           struct cgraph_node *callee = e->callee;
           struct function *fn = DECL_STRUCT_FUNCTION (callee->decl);
 
-          if (callee->count > 0)
+          if (!(e->count.ipa () == profile_count::zero ())
+	      && callee->count.ipa ().nonzero_p ())
             continue;
           if ((DECL_COMDAT (callee->decl) || DECL_EXTERNAL (callee->decl))
 	      && fn && fn->cfg
Index: testsuite/gcc.dg/torture/pr83055.c
===================================================================
--- testsuite/gcc.dg/torture/pr83055.c	(revision 0)
+++ testsuite/gcc.dg/torture/pr83055.c	(working copy)
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-fprofile-generate" } */
+
+void __attribute__ ((__cold__)) a (void);
+void b (void);
+void __attribute__ ((noinline)) c (void) { a (); }
+
+void
+d (void)
+{
+  b ();
+  c ();
+}
diff mbox series

Patch

diff --git a/gcc/predict.c b/gcc/predict.c
index 4c1e4489b55..c5144e49c8d 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -3357,7 +3357,7 @@  handle_missing_profiles (void)
       if (!(node->count == profile_count::zero ()))
         continue;
       for (e = node->callers; e; e = e->next_caller)
-	if (e->count.initialized_p () && e->count > 0)
+	if (e->count.initialized_p () && e->count.reliable_p ())
 	  {
             call_count = call_count + e->count;
 
diff --git a/gcc/testsuite/gcc.dg/torture/pr83055.c b/gcc/testsuite/gcc.dg/torture/pr83055.c
new file mode 100644
index 00000000000..9bc71c6cddf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr83055.c
@@ -0,0 +1,13 @@ 
+/* { dg-do compile } */
+/* { dg-additional-options "-fprofile-generate" } */
+
+void __attribute__ ((__cold__)) a (void);
+void b (void);
+void __attribute__ ((noinline)) c (void) { a (); }
+
+void
+d (void)
+{
+  b ();
+  c ();
+}