profile-count.c (safe_scale_64bit): Fix GCC4.x path.
authorJan Hubicka <hubicka@ucw.cz>
Thu, 12 Oct 2017 18:48:59 +0000 (20:48 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 12 Oct 2017 18:48:59 +0000 (18:48 +0000)
* profile-count.c (safe_scale_64bit): Fix GCC4.x path.
(profile_probability): Set max_probability
to (uint32_t) 1 << (n_bits - 2) and update accessors to avoid overlfows
in temporaries.
* profile-count.c (profile_probability::differs_from_p): Do not
rely on max_probaiblity == 10000

* gcc.dg/predict-13.c: Update template for probaility change.
* gcc.dg/predict-8.c: Likewise.

From-SVN: r253692

gcc/ChangeLog
gcc/profile-count.c
gcc/profile-count.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/ipa/inlinehint-4.c
gcc/testsuite/gcc.dg/predict-13.c
gcc/testsuite/gcc.dg/predict-8.c

index d5ee088e77f4eb4c32cd79313ae06e8d81843176..92cdc5f0c9a9942aa9aee420c458aa1c7d3c695b 100644 (file)
@@ -1,3 +1,12 @@
+2017-10-12  Jan Hubicka  <hubicka@ucw.cz>
+
+       * profile-count.h (safe_scale_64bit): Fix GCC4.x path.
+       (profile_probability): Set max_probability
+       to (uint32_t) 1 << (n_bits - 2) and update accessors to avoid overlfows
+       in temporaries.
+       * profile-count.c (profile_probability::differs_from_p): Do not
+       rely on max_probaiblity == 10000
+
 2017-10-12  Jeff Law  <law@redhat.com>
 
        * tree-ssa-dse.c (valid_ao_ref_for_dse): Reject ao_refs with
index 02c9ec241d40a98b9c4130cbab3e551c3da5c950..44ceaed2d66140d32a4d1c7ccb7c2c961a21871a 100644 (file)
@@ -147,12 +147,12 @@ profile_probability::differs_from_p (profile_probability other) const
 {
   if (!initialized_p () || !other.initialized_p ())
     return false;
-  if ((uint64_t)m_val - (uint64_t)other.m_val < 10
-      || (uint64_t)other.m_val - (uint64_t)m_val < 10)
+  if ((uint64_t)m_val - (uint64_t)other.m_val < max_probability / 1000
+      || (uint64_t)other.m_val - (uint64_t)max_probability < 1000)
     return false;
   if (!other.m_val)
     return true;
-  int64_t ratio = m_val * 100 / other.m_val;
+  int64_t ratio = (int64_t)m_val * 100 / other.m_val;
   return ratio < 99 || ratio > 101;
 }
 
index cb1aa365c9555625d25e1e29964d182a7ac6225e..4546e199f24016b25311e06f7475352ea57852ee 100644 (file)
@@ -67,7 +67,10 @@ safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
   if (a < ((uint64_t)1 << 31)
       && b < ((uint64_t)1 << 31)
       && c < ((uint64_t)1 << 31))
-    return (a * b + (c / 2)) / c;
+    {
+      *res = (a * b + (c / 2)) / c;
+      return true;
+    }
 #endif
   return slow_safe_scale_64bit (a, b, c, res);
 }
@@ -111,11 +114,10 @@ safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
 
 class GTY((user)) profile_probability
 {
-  /* For now use values in range 0...REG_BR_PROB_BASE.  Later we can use full
-     precision of 30 bits available.  */
-
   static const int n_bits = 30;
-  static const uint32_t max_probability = REG_BR_PROB_BASE;
+  /* We can technically use ((uint32_t) 1 << (n_bits - 1)) - 2 but that
+     will lead to harder multiplication sequences.  */
+  static const uint32_t max_probability = (uint32_t) 1 << (n_bits - 2);
   static const uint32_t uninitialized_probability
                 = ((uint32_t) 1 << (n_bits - 1)) - 1;
 
@@ -210,14 +212,14 @@ public:
     {
       profile_probability ret;
       gcc_checking_assert (v >= 0 && v <= REG_BR_PROB_BASE);
-      ret.m_val = RDIV (v * max_probability, REG_BR_PROB_BASE);
+      ret.m_val = RDIV (v * (uint64_t) max_probability, REG_BR_PROB_BASE);
       ret.m_quality = profile_guessed;
       return ret;
     }
   int to_reg_br_prob_base () const
     {
       gcc_checking_assert (initialized_p ());
-      return RDIV (m_val * REG_BR_PROB_BASE, max_probability);
+      return RDIV (m_val * (uint64_t) REG_BR_PROB_BASE, max_probability);
     }
 
   /* Conversion to and from RTL representation of profile probabilities.  */
@@ -246,7 +248,12 @@ public:
       if (val1 > val2)
        ret.m_val = max_probability;
       else
-       ret.m_val = RDIV (val1 * max_probability, val2);
+       {
+         uint64_t tmp;
+         safe_scale_64bit (val1, max_probability, val2, &tmp);
+         gcc_checking_assert (tmp <= max_probability);
+         ret.m_val = tmp;
+       }
       ret.m_quality = profile_precise;
       return ret;
     }
@@ -443,8 +450,9 @@ public:
       if (!initialized_p ())
        return profile_probability::uninitialized ();
       profile_probability ret;
-      ret.m_val = MIN (RDIV (m_val * num, den),
-                      max_probability);
+      uint64_t tmp;
+      safe_scale_64bit (m_val, num, den, &tmp);
+      ret.m_val = MIN (tmp, max_probability);
       ret.m_quality = MIN (m_quality, profile_adjusted);
       return ret;
     }
@@ -482,7 +490,7 @@ public:
       if (m_val == uninitialized_probability)
        return m_quality == profile_guessed;
       else
-       return m_val <= REG_BR_PROB_BASE;
+       return m_val <= max_probability;
     }
 
   /* Comparsions are three-state and conservative.  False is returned if
@@ -781,8 +789,10 @@ public:
       if (!initialized_p ())
        return profile_count::uninitialized ();
       profile_count ret;
-      ret.m_val = RDIV (m_val * prob.m_val,
-                       profile_probability::max_probability);
+      uint64_t tmp;
+      safe_scale_64bit (m_val, prob.m_val, profile_probability::max_probability,
+                       &tmp);
+      ret.m_val = tmp;
       ret.m_quality = MIN (m_quality, prob.m_quality);
       return ret;
     }
@@ -794,11 +804,11 @@ public:
       if (!initialized_p ())
        return profile_count::uninitialized ();
       profile_count ret;
+      uint64_t tmp;
+
       gcc_checking_assert (num >= 0 && den > 0);
-      /* FIXME: shrink wrapping violates this sanity check.  */
-      gcc_checking_assert ((num <= REG_BR_PROB_BASE
-                           || den <= REG_BR_PROB_BASE) || 1);
-      ret.m_val = RDIV (m_val * num, den);
+      safe_scale_64bit (m_val, num, den, &tmp);
+      ret.m_val = MIN (tmp, max_count);
       ret.m_quality = MIN (m_quality, profile_adjusted);
       return ret;
     }
index 79642b88d8236c33be49865c6dff11ff9c67ed76..c8043641a4b02efe0e015b09c6e5c68faabe3431 100644 (file)
@@ -1,3 +1,8 @@
+2017-10-12  Jan Hubicka  <hubicka@ucw.cz>
+
+       * gcc.dg/predict-13.c: Update template for probaility change.
+       * gcc.dg/predict-8.c: Likewise.
+
 2017-10-12  David Malcolm  <dmalcolm@redhat.com>
 
        * c-c++-common/cilk-plus/AN/parser_errors.c: Update expected
index 441a0c708551e17a406edf6de0d63ac5c27fef7b..71b16f80be2c17dad5c3482b5ae44c849e8310e7 100644 (file)
@@ -35,5 +35,5 @@ test (int i)
     lookup (9 * i);
 }
 /* { dg-final { scan-ipa-dump "Wrapper penalty"  "inline"  } } */
-/* { dg-final { scan-ipa-dump-not "Inlining lookup_slow to lookup"  "inline"  } } */
-/* { dg-final { scan-ipa-dump "Inlining lookup to test"  "inline"  } } */
+/* { dg-final { scan-ipa-dump-not "Inlined lookup_slow into lookup"  "inline"  } } */
+/* { dg-final { scan-ipa-dump "Inlined lookup into test"  "inline"  } } */
index 7fe714a0d72f6bebc9a7f73b05b14865deb6110c..385be9e138901a0cd215a6245ff60da0d5d5ad42 100644 (file)
@@ -21,4 +21,4 @@ int main(int argc, char **argv)
 }
 
 /* { dg-final { scan-tree-dump-times "combined heuristics of edge\[^:\]*: 33.3%" 3 "profile_estimate"} } */
-/* { dg-final { scan-tree-dump-times "combined heuristics of edge\[^:\]*: 0.0%" 2 "profile_estimate"} } */
+/* { dg-final { scan-tree-dump-times "combined heuristics of edge\[^:\]*: 0.1%" 2 "profile_estimate"} } */
index e13cc006f3af52a05eef908e1d17b0e8646ef40a..fa975b3d95f9711dcda74541ce4353a15d5b6d1f 100644 (file)
@@ -1,5 +1,5 @@
 /* { dg-do compile { target { i?86-*-* x86_64-*-* } } } */
-/* { dg-options "-O2 -fdump-rtl-expand" } */
+/* { dg-options "-O2 -fdump-rtl-expand-details-blocks" } */
 
 int foo(float a, float b) {
   if (a == b)
@@ -8,4 +8,4 @@ int foo(float a, float b) {
     return 2;
 }
 
-/* { dg-final { scan-rtl-dump-times "REG_BR_PROB 400 " 1 "expand"} } */
+/* { dg-final { scan-rtl-dump-times "99.0. .guessed" 2 "expand"} } */