LCOV - code coverage report
Current view: top level - gcc - profile-count.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 81.6 % 255 208
Test Date: 2025-06-21 16:26:05 Functions: 83.3 % 30 25
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Profile counter container type.
       2                 :             :    Copyright (C) 2017-2025 Free Software Foundation, Inc.
       3                 :             :    Contributed by Jan Hubicka
       4                 :             : 
       5                 :             : This file is part of GCC.
       6                 :             : 
       7                 :             : GCC is free software; you can redistribute it and/or modify it under
       8                 :             : the terms of the GNU General Public License as published by the Free
       9                 :             : Software Foundation; either version 3, or (at your option) any later
      10                 :             : version.
      11                 :             : 
      12                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15                 :             : for more details.
      16                 :             : 
      17                 :             : You should have received a copy of the GNU General Public License
      18                 :             : along with GCC; see the file COPYING3.  If not see
      19                 :             : <http://www.gnu.org/licenses/>.  */
      20                 :             : 
      21                 :             : #include "config.h"
      22                 :             : #include "system.h"
      23                 :             : #include "coretypes.h"
      24                 :             : #include "profile-count.h"
      25                 :             : #include "options.h"
      26                 :             : #include "tree.h"
      27                 :             : #include "basic-block.h"
      28                 :             : #include "function.h"
      29                 :             : #include "cfg.h"
      30                 :             : #include "gimple.h"
      31                 :             : #include "data-streamer.h"
      32                 :             : #include "cgraph.h"
      33                 :             : #include "wide-int.h"
      34                 :             : #include "sreal.h"
      35                 :             : 
      36                 :             : /* Names from profile_quality enum values.  */
      37                 :             : 
      38                 :             : const char *profile_quality_names[] =
      39                 :             : {
      40                 :             :   "uninitialized",
      41                 :             :   "guessed_local",
      42                 :             :   "guessed_global0",
      43                 :             :   "guessed_global0adjusted",
      44                 :             :   "guessed",
      45                 :             :   "afdo",
      46                 :             :   "adjusted",
      47                 :             :   "precise"
      48                 :             : };
      49                 :             : 
      50                 :             : /* Get a string describing QUALITY.  */
      51                 :             : 
      52                 :             : const char *
      53                 :       51236 : profile_quality_as_string (enum profile_quality quality)
      54                 :             : {
      55                 :       51236 :   return profile_quality_names[quality];
      56                 :             : }
      57                 :             : 
      58                 :             : /* Parse VALUE as profile quality and return true when a valid QUALITY.  */
      59                 :             : 
      60                 :             : bool
      61                 :         384 : parse_profile_quality (const char *value, profile_quality *quality)
      62                 :             : {
      63                 :        2330 :   for (unsigned i = 0; i < ARRAY_SIZE (profile_quality_names); i++)
      64                 :        2181 :     if (strcmp (profile_quality_names[i], value) == 0)
      65                 :             :       {
      66                 :         235 :         *quality = (profile_quality)i;
      67                 :         235 :         return true;
      68                 :             :       }
      69                 :             : 
      70                 :             :   return false;
      71                 :             : }
      72                 :             : 
      73                 :             : /* Display names from profile_quality enum values.  */
      74                 :             : 
      75                 :             : const char *profile_quality_display_names[] =
      76                 :             : {
      77                 :             :   NULL,
      78                 :             :   "estimated locally",
      79                 :             :   "estimated locally, globally 0",
      80                 :             :   "estimated locally, globally 0 adjusted",
      81                 :             :   "guessed",
      82                 :             :   "auto FDO",
      83                 :             :   "adjusted",
      84                 :             :   "precise"
      85                 :             : };
      86                 :             : 
      87                 :             : /* Dump THIS to F.  */
      88                 :             : 
      89                 :             : void
      90                 :       79447 : profile_count::dump (FILE *f, struct function *fun) const
      91                 :             : {
      92                 :       79447 :   if (!initialized_p ())
      93                 :          17 :     fprintf (f, "uninitialized");
      94                 :      131389 :   else if (fun && initialized_p ()
      95                 :       51959 :            && fun->cfg
      96                 :      131389 :            && ENTRY_BLOCK_PTR_FOR_FN (fun)->count.initialized_p ())
      97                 :             :     {
      98                 :       51959 :       if (compatible_p (ENTRY_BLOCK_PTR_FOR_FN (fun)->count))
      99                 :       51959 :         fprintf (f, "%" PRId64 " (%s, freq %.4f)", m_val,
     100                 :       51959 :                  profile_quality_display_names[m_quality],
     101                 :             :                  to_sreal_scale
     102                 :      103918 :                    (ENTRY_BLOCK_PTR_FOR_FN (fun)->count).to_double ());
     103                 :             :       else
     104                 :           0 :         fprintf (f, "%" PRId64 " (%s, incompatible with entry block count)",
     105                 :           0 :                  m_val, profile_quality_display_names[m_quality]);
     106                 :             :     }
     107                 :             :   else
     108                 :       27471 :     fprintf (f, "%" PRId64 " (%s)", m_val,
     109                 :       27471 :              profile_quality_display_names[m_quality]);
     110                 :       79447 : }
     111                 :             : 
     112                 :             : /* Dump THIS to stderr.  */
     113                 :             : 
     114                 :             : void
     115                 :           0 : profile_count::debug () const
     116                 :             : {
     117                 :           0 :   dump (stderr, cfun);
     118                 :           0 :   fprintf (stderr, "\n");
     119                 :           0 : }
     120                 :             : 
     121                 :             : /* Return true if THIS differs from OTHER; tolerate small differences.  */
     122                 :             : 
     123                 :             : bool
     124                 :    53475851 : profile_count::differs_from_p (profile_count other) const
     125                 :             : {
     126                 :    53475851 :   gcc_checking_assert (compatible_p (other));
     127                 :    53475851 :   if (!initialized_p () || !other.initialized_p ())
     128                 :          51 :     return initialized_p () != other.initialized_p ();
     129                 :    53475800 :   if ((uint64_t)m_val - (uint64_t)other.m_val < 100
     130                 :      972763 :       || (uint64_t)other.m_val - (uint64_t)m_val < 100)
     131                 :             :     return false;
     132                 :      305280 :   if (!other.m_val)
     133                 :             :     return true;
     134                 :      304448 :   uint64_t ratio;
     135                 :      304448 :   safe_scale_64bit (m_val, 100, other.m_val, &ratio);
     136                 :      304448 :   return ratio < 99 || ratio > 101;
     137                 :             : }
     138                 :             : 
     139                 :             : /* Stream THIS from IB.  */
     140                 :             : 
     141                 :             : profile_count
     142                 :     1535866 : profile_count::stream_in (class lto_input_block *ib)
     143                 :             : {
     144                 :     1535866 :   profile_count ret;
     145                 :     1535866 :   ret.m_val = streamer_read_gcov_count (ib);
     146                 :     1535866 :   ret.m_quality = (profile_quality) streamer_read_uhwi (ib);
     147                 :     1535866 :   return ret;
     148                 :             : }
     149                 :             : 
     150                 :             : /* Stream THIS to OB.  */
     151                 :             : 
     152                 :             : void
     153                 :      902731 : profile_count::stream_out (struct output_block *ob)
     154                 :             : {
     155                 :      902731 :   streamer_write_gcov_count (ob, m_val);
     156                 :      902731 :   streamer_write_uhwi (ob, m_quality);
     157                 :      902731 : }
     158                 :             : 
     159                 :             : /* Stream THIS to OB.  */
     160                 :             : 
     161                 :             : void
     162                 :     1046802 : profile_count::stream_out (struct lto_output_stream *ob)
     163                 :             : {
     164                 :     1046802 :   streamer_write_gcov_count_stream (ob, m_val);
     165                 :     1046802 :   streamer_write_uhwi_stream (ob, m_quality);
     166                 :     1046802 : }
     167                 :             : 
     168                 :             : 
     169                 :             : /* Output THIS to BUFFER.  */
     170                 :             : 
     171                 :             : void
     172                 :       59044 : profile_probability::dump (char *buffer) const
     173                 :             : {
     174                 :       59044 :   if (!initialized_p ())
     175                 :           0 :     sprintf (buffer, "uninitialized");
     176                 :             :   else
     177                 :             :     {
     178                 :             :       /* Make difference between 0.00 as a roundoff error and actual 0.
     179                 :             :          Similarly for 1.  */
     180                 :       59044 :       if (m_val == 0)
     181                 :        2976 :         buffer += sprintf (buffer, "never");
     182                 :       56068 :       else if (m_val == max_probability)
     183                 :       20331 :         buffer += sprintf (buffer, "always");
     184                 :             :       else
     185                 :       35737 :         buffer += sprintf (buffer, "%3.1f%%", (double)m_val * 100 / max_probability);
     186                 :             : 
     187                 :       59044 :       if (m_quality == ADJUSTED)
     188                 :        5357 :         sprintf (buffer, " (adjusted)");
     189                 :       53687 :       else if (m_quality == AFDO)
     190                 :           0 :         sprintf (buffer, " (auto FDO)");
     191                 :       53687 :       else if (m_quality == GUESSED)
     192                 :       31847 :         sprintf (buffer, " (guessed)");
     193                 :             :     }
     194                 :       59044 : }
     195                 :             : 
     196                 :             : /* Dump THIS to F.  */
     197                 :             : 
     198                 :             : void
     199                 :       59030 : profile_probability::dump (FILE *f) const
     200                 :             : {
     201                 :       59030 :   char buffer[64];
     202                 :       59030 :   dump (buffer);
     203                 :       59030 :   fputs (buffer, f);
     204                 :       59030 : }
     205                 :             : 
     206                 :             : /* Dump THIS to stderr.  */
     207                 :             : 
     208                 :             : void
     209                 :           0 : profile_probability::debug () const
     210                 :             : {
     211                 :           0 :   dump (stderr);
     212                 :           0 :   fprintf (stderr, "\n");
     213                 :           0 : }
     214                 :             : 
     215                 :             : /* Return true if THIS differs from OTHER; tolerate small differences.  */
     216                 :             : 
     217                 :             : bool
     218                 :       10917 : profile_probability::differs_from_p (profile_probability other) const
     219                 :             : {
     220                 :       10917 :   if (!initialized_p () || !other.initialized_p ())
     221                 :             :     return false;
     222                 :       10917 :   if ((uint64_t)m_val - (uint64_t)other.m_val < max_probability / 1000
     223                 :          14 :       || (uint64_t)other.m_val - (uint64_t)max_probability < 1000)
     224                 :             :     return false;
     225                 :           0 :   if (!other.m_val)
     226                 :             :     return true;
     227                 :           0 :   int64_t ratio = (int64_t)m_val * 100 / other.m_val;
     228                 :           0 :   return ratio < 99 || ratio > 101;
     229                 :             : }
     230                 :             : 
     231                 :             : /* Return true if THIS differs significantly from OTHER.  */
     232                 :             : 
     233                 :             : bool
     234                 :      236735 : profile_probability::differs_lot_from_p (profile_probability other) const
     235                 :             : {
     236                 :      236735 :   if (!initialized_p () || !other.initialized_p ())
     237                 :             :     return false;
     238                 :      236627 :   uint32_t d = m_val > other.m_val ? m_val - other.m_val : other.m_val - m_val;
     239                 :      236627 :   return d > max_probability / 2;
     240                 :             : }
     241                 :             : 
     242                 :             : /* Stream THIS from IB.  */
     243                 :             : 
     244                 :             : profile_probability
     245                 :      854715 : profile_probability::stream_in (class lto_input_block *ib)
     246                 :             : {
     247                 :      854715 :   profile_probability ret;
     248                 :      854715 :   ret.m_val = streamer_read_uhwi (ib);
     249                 :      854715 :   ret.m_quality = (profile_quality) streamer_read_uhwi (ib);
     250                 :      854715 :   return ret;
     251                 :             : }
     252                 :             : 
     253                 :             : /* Stream THIS to OB.  */
     254                 :             : 
     255                 :             : void
     256                 :     1026338 : profile_probability::stream_out (struct output_block *ob)
     257                 :             : {
     258                 :     1026338 :   streamer_write_uhwi (ob, m_val);
     259                 :     1026338 :   streamer_write_uhwi (ob, m_quality);
     260                 :     1026338 : }
     261                 :             : 
     262                 :             : /* Stream THIS to OB.  */
     263                 :             : 
     264                 :             : void
     265                 :           0 : profile_probability::stream_out (struct lto_output_stream *ob)
     266                 :             : {
     267                 :           0 :   streamer_write_uhwi_stream (ob, m_val);
     268                 :           0 :   streamer_write_uhwi_stream (ob, m_quality);
     269                 :           0 : }
     270                 :             : 
     271                 :             : /* Compute RES=(a*b + c/2)/c capping and return false if overflow happened.  */
     272                 :             : 
     273                 :             : bool
     274                 :      583103 : slow_safe_scale_64bit (uint64_t a, uint64_t b, uint64_t c, uint64_t *res)
     275                 :             : {
     276                 :      583103 :   FIXED_WIDE_INT (128) tmp = a;
     277                 :      583103 :   wi::overflow_type overflow;
     278                 :      583103 :   tmp = wi::udiv_floor (wi::umul (tmp, b, &overflow) + (c / 2), c);
     279                 :      583103 :   gcc_checking_assert (!overflow);
     280                 :      583103 :   if (wi::fits_uhwi_p (tmp))
     281                 :             :     {
     282                 :      581816 :       *res = tmp.to_uhwi ();
     283                 :      581816 :       return true;
     284                 :             :     }
     285                 :        1287 :   *res = (uint64_t) -1;
     286                 :        1287 :   return false;
     287                 :             : }
     288                 :             : 
     289                 :             : /* Return count as frequency within FUN scaled in range 0 to REG_FREQ_MAX
     290                 :             :    Used for legacy code and should not be used anymore.  */
     291                 :             : 
     292                 :             : int
     293                 :  1099285826 : profile_count::to_frequency (struct function *fun) const
     294                 :             : {
     295                 :  1099285826 :   if (!initialized_p ())
     296                 :             :     return BB_FREQ_MAX;
     297                 :  1097497249 :   if (*this == zero ())
     298                 :    15986627 :     return 0;
     299                 :  1081510622 :   STATIC_ASSERT (REG_BR_PROB_BASE == BB_FREQ_MAX);
     300                 :  1081510622 :   gcc_assert (fun->cfg->count_max.initialized_p ());
     301                 :  1081510622 :   profile_probability prob = probability_in (fun->cfg->count_max);
     302                 :  1081510622 :   if (!prob.initialized_p ())
     303                 :             :     return REG_BR_PROB_BASE;
     304                 :  1081510234 :   return prob.to_reg_br_prob_base ();
     305                 :             : }
     306                 :             : 
     307                 :             : /* Return count as frequency within FUN scaled in range 0 to CGRAPH_FREQ_MAX
     308                 :             :    where CGRAPH_FREQ_BASE means that count equals to entry block count.
     309                 :             :    Used for legacy code and should not be used anymore.  */
     310                 :             : 
     311                 :             : int
     312                 :      187693 : profile_count::to_cgraph_frequency (profile_count entry_bb_count) const
     313                 :             : {
     314                 :      187693 :   if (!initialized_p () || !entry_bb_count.initialized_p ())
     315                 :             :     return CGRAPH_FREQ_BASE;
     316                 :      184319 :   if (*this == zero ())
     317                 :         176 :     return 0;
     318                 :      184143 :   gcc_checking_assert (entry_bb_count.initialized_p ());
     319                 :      184143 :   uint64_t scale;
     320                 :      184143 :   gcc_checking_assert (compatible_p (entry_bb_count));
     321                 :      368286 :   if (!safe_scale_64bit (!entry_bb_count.m_val ? m_val + 1 : m_val,
     322                 :      184143 :                          CGRAPH_FREQ_BASE, MAX (1, entry_bb_count.m_val), &scale))
     323                 :             :     return CGRAPH_FREQ_MAX;
     324                 :      184143 :   return MIN (scale, CGRAPH_FREQ_MAX);
     325                 :             : }
     326                 :             : 
     327                 :             : /* Return THIS/IN as sreal value.  */
     328                 :             : 
     329                 :             : sreal
     330                 :   305495668 : profile_count::to_sreal_scale (profile_count in, bool *known) const
     331                 :             : {
     332                 :   327436856 :   if (*this == zero ()
     333                 :    21941188 :       && !(in == zero ()))
     334                 :             :   {
     335                 :    21721107 :     if (known)
     336                 :           5 :       *known = true;
     337                 :    21721107 :     return 0;
     338                 :             :   }
     339                 :   283774561 :   if (!initialized_p () || !in.initialized_p ())
     340                 :             :     {
     341                 :    38166692 :       if (known)
     342                 :          14 :         *known = false;
     343                 :    38166692 :       return 1;
     344                 :             :     }
     345                 :   245607869 :   if (known)
     346                 :     8750579 :     *known = in.m_val != 0;
     347                 :   245607869 :   if (*this == in)
     348                 :    46220164 :     return 1;
     349                 :   199387705 :   gcc_checking_assert (compatible_p (in));
     350                 :   199387705 :   if (m_val == in.m_val)
     351                 :         427 :     return 1;
     352                 :   199387278 :   if (!in.m_val)
     353                 :       10572 :     return m_val * 4;
     354                 :             :   /* Auto-FDO 0 really just means that we have no samples.
     355                 :             :      Treat it as small non-zero frequency.  */
     356                 :   199376706 :   if (!m_val && quality () == AFDO)
     357                 :           0 :     return (sreal)1 / (sreal)in.m_val;
     358                 :   199376706 :   return (sreal)m_val / (sreal)in.m_val;
     359                 :             : }
     360                 :             : 
     361                 :             : /* We want to scale profile across function boundary from NUM to DEN.
     362                 :             :    Take care of the side case when DEN is zeros.  We still want to behave
     363                 :             :    sanely here which means
     364                 :             :      - scale to profile_count::zero () if NUM is profile_count::zero
     365                 :             :      - do not affect anything if NUM == DEN
     366                 :             :      - preserve counter value but adjust quality in other cases.  */
     367                 :             : 
     368                 :             : void
     369                 :    26504197 : profile_count::adjust_for_ipa_scaling (profile_count *num,
     370                 :             :                                        profile_count *den)
     371                 :             : {
     372                 :             :   /* Scaling is no-op if NUM and DEN are the same.  */
     373                 :    26504197 :   if (*num == *den)
     374                 :             :     return;
     375                 :             :   /* Scaling to zero is always zero.  */
     376                 :    20336812 :   if (*num == zero ())
     377                 :       97239 :     return;
     378                 :             :   /* If den is non-zero we are safe.
     379                 :             :      However take care of zeros in AFDO profiles since
     380                 :             :      they simply means that no useful samples were collected.
     381                 :             :      Called function still may contain important loop.  */
     382                 :    40437242 :   if (den->force_nonzero () == *den
     383                 :    20197669 :       && num->quality () != AFDO)
     384                 :    20197669 :     return;
     385                 :             :   /* Force both to non-zero so we do not push profiles to 0 when
     386                 :             :      both num == 0 and den == 0.  */
     387                 :       41904 :   *den = den->force_nonzero ();
     388                 :       41904 :   *num = num->force_nonzero ();
     389                 :             : }
     390                 :             : 
     391                 :             : /* THIS is a count of bb which is known to be executed IPA times.
     392                 :             :    Combine this information into bb counter.  This means returning IPA
     393                 :             :    if it is nonzero, not changing anything if IPA is uninitialized
     394                 :             :    and if IPA is zero, turning THIS into corresponding local profile with
     395                 :             :    global0.  */
     396                 :             : 
     397                 :             : profile_count
     398                 :    25760568 : profile_count::combine_with_ipa_count (profile_count ipa)
     399                 :             : {
     400                 :    25760568 :   if (!initialized_p ())
     401                 :       18340 :     return *this;
     402                 :    25742228 :   ipa = ipa.ipa ();
     403                 :    25742228 :   if (ipa.nonzero_p ())
     404                 :         108 :     return ipa;
     405                 :    26684993 :   if (!ipa.initialized_p () || *this == zero ())
     406                 :    25742037 :     return *this;
     407                 :          83 :   if (ipa == zero ())
     408                 :          44 :     return this->global0 ();
     409                 :          39 :   return this->global0adjusted ();
     410                 :             : }
     411                 :             : 
     412                 :             : /* Same as profile_count::combine_with_ipa_count but within function with count
     413                 :             :    IPA2.  */
     414                 :             : profile_count
     415                 :     6480803 : profile_count::combine_with_ipa_count_within (profile_count ipa,
     416                 :             :                                               profile_count ipa2)
     417                 :             : {
     418                 :     6480803 :   profile_count ret;
     419                 :     6480803 :   if (!initialized_p ())
     420                 :      796816 :     return *this;
     421                 :     5892863 :   if (ipa2.ipa () == ipa2 && ipa.initialized_p ())
     422                 :      208876 :     ret = ipa;
     423                 :             :   else
     424                 :             :     {
     425                 :             :       /* For inconsistent profiles we may end up having ipa2 of GLOBAL0
     426                 :             :          while ipa is non-zero (i.e. non-zero IPA counters within function
     427                 :             :          executed 0 times).  Be sure we produce GLOBAL0 as well
     428                 :             :          so counters remain compatible.  */
     429                 :     5475111 :       if (ipa.nonzero_p ()
     430                 :     5475111 :           && ipa2.ipa ().initialized_p ())
     431                 :           0 :         ipa = ipa2.ipa ();
     432                 :     5475111 :       ret = combine_with_ipa_count (ipa);
     433                 :             :     }
     434                 :     5683987 :   gcc_checking_assert (ret.compatible_p (ipa2));
     435                 :     5683987 :   return ret;
     436                 :             : }
     437                 :             : 
     438                 :             : /* The profiling runtime uses gcov_type, which is usually 64bit integer.
     439                 :             :    Conversions back and forth are used to read the coverage and get it
     440                 :             :    into internal representation.  */
     441                 :             : 
     442                 :             : profile_count
     443                 : 18133725081 : profile_count::from_gcov_type (gcov_type v, profile_quality quality)
     444                 :             : {
     445                 : 18133725081 :   profile_count ret;
     446                 : 18133725081 :   gcc_checking_assert (v >= 0);
     447                 : 18133725081 :   if (dump_file && v >= (gcov_type)max_count)
     448                 :           0 :     fprintf (dump_file,
     449                 :             :              "Capping gcov count %" PRId64 " to max_count %" PRId64 "\n",
     450                 :             :              (int64_t) v, (int64_t) max_count);
     451                 : 18133725081 :   ret.m_val = MIN (v, (gcov_type)max_count);
     452                 : 18133725081 :   ret.m_quality = quality;
     453                 : 18133725081 :   return ret;
     454                 :             : }
     455                 :             : 
     456                 :             : /* COUNT1 times event happens with *THIS probability, COUNT2 times OTHER
     457                 :             :    happens with COUNT2 probability.  Return probability that either *THIS or
     458                 :             :    OTHER happens.  */
     459                 :             : 
     460                 :             : profile_probability
     461                 :     1327580 : profile_probability::combine_with_count (profile_count count1,
     462                 :             :                                          profile_probability other,
     463                 :             :                                          profile_count count2) const
     464                 :             : {
     465                 :             :   /* If probabilities are same, we are done.
     466                 :             :      If counts are nonzero we can distribute accordingly. In remaining
     467                 :             :      cases just average the values and hope for the best.  */
     468                 :     1340876 :   if (*this == other || count1 == count2
     469                 :       42061 :       || (count2 == profile_count::zero ()
     470                 :          40 :           && !(count1 == profile_count::zero ())))
     471                 :     1285599 :     return *this;
     472                 :       42595 :   if (count1 == profile_count::zero () && !(count2 == profile_count::zero ()))
     473                 :         614 :     return other;
     474                 :       44363 :   else if (count1.nonzero_p () || count2.nonzero_p ())
     475                 :       41367 :     return *this * count1.probability_in (count1 + count2)
     476                 :       82734 :            + other * count2.probability_in (count1 + count2);
     477                 :             :   else
     478                 :           0 :     return *this * even () + other * even ();
     479                 :             : }
     480                 :             : 
     481                 :             : /* Return probability as sreal in range [0, 1].  */
     482                 :             : 
     483                 :             : sreal
     484                 :    48250827 : profile_probability::to_sreal () const
     485                 :             : {
     486                 :    48250827 :   gcc_checking_assert (initialized_p ());
     487                 :    48250827 :   return ((sreal)m_val) >> (n_bits - 2);
     488                 :             : }
     489                 :             : 
     490                 :             : /* Compute square root.  */
     491                 :             : 
     492                 :             : profile_probability
     493                 :        2443 : profile_probability::sqrt () const
     494                 :             : {
     495                 :        2443 :   if (!initialized_p () || *this == never () || *this == always ())
     496                 :           0 :     return *this;
     497                 :        2443 :   profile_probability ret = *this;
     498                 :        2443 :   ret.m_quality = MIN (ret.m_quality, ADJUSTED);
     499                 :        2443 :   uint32_t min_range = m_val;
     500                 :        2443 :   uint32_t max_range = max_probability;
     501                 :        2443 :   if (!m_val)
     502                 :           0 :     max_range = 0;
     503                 :        2443 :   if (m_val == max_probability)
     504                 :           0 :     min_range = max_probability;
     505                 :       61075 :   while (min_range != max_range)
     506                 :             :     {
     507                 :       58632 :       uint32_t val = (min_range + max_range) / 2;
     508                 :       58632 :       uint32_t val2 = RDIV ((uint64_t)val * val, max_probability);
     509                 :       58632 :       if (val2 == m_val)
     510                 :             :         min_range = max_range = m_val;
     511                 :       58632 :       else if (val2 > m_val)
     512                 :       21987 :         max_range = val - 1;
     513                 :       36645 :       else if (val2 < m_val)
     514                 :       36645 :         min_range = val + 1;
     515                 :             :     }
     516                 :        2443 :   ret.m_val = min_range;
     517                 :        2443 :   return ret;
     518                 :             : }
     519                 :             : 
     520                 :             : /* Compute n-th power of THIS.  */
     521                 :             : 
     522                 :             : profile_probability
     523                 :           0 : profile_probability::pow (int n) const
     524                 :             : {
     525                 :           0 :   if (n == 1 || !initialized_p ())
     526                 :           0 :     return *this;
     527                 :           0 :   if (!n)
     528                 :           0 :     return profile_probability::always ();
     529                 :           0 :   if (!nonzero_p ()
     530                 :           0 :       || !(profile_probability::always () - *this).nonzero_p ())
     531                 :           0 :     return *this;
     532                 :           0 :   profile_probability ret = profile_probability::always ();
     533                 :           0 :   profile_probability v = *this;
     534                 :           0 :   int p = 1;
     535                 :           0 :   while (true)
     536                 :             :     {
     537                 :           0 :       if (n & p)
     538                 :           0 :         ret = ret * v;
     539                 :           0 :       p <<= 1;
     540                 :           0 :       if (p > n)
     541                 :             :         break;
     542                 :           0 :       v = v * v;
     543                 :             :     }
     544                 :           0 :   return ret;
     545                 :             : }
     546                 :             : profile_count
     547                 :     4201714 : profile_count::operator* (const sreal &num) const
     548                 :             : {
     549                 :     4201714 :   if (m_val == 0)
     550                 :      969097 :     return *this;
     551                 :     3232617 :   if (!initialized_p ())
     552                 :           0 :     return uninitialized ();
     553                 :     3232617 :   sreal scaled = num * m_val;
     554                 :     3232617 :   gcc_checking_assert (scaled >= 0);
     555                 :     3232617 :   profile_count ret;
     556                 :     3232617 :   if (m_val > max_count)
     557                 :             :     ret.m_val = max_count;
     558                 :             :   else
     559                 :     3232617 :     ret.m_val = scaled.to_nearest_int ();
     560                 :     3232617 :   ret.m_quality = MIN (m_quality, ADJUSTED);
     561                 :     3232617 :   return ret;
     562                 :             : }
     563                 :             : 
     564                 :             : profile_count
     565                 :           0 : profile_count::operator*= (const sreal &num)
     566                 :             : {
     567                 :           0 :   return *this * num;
     568                 :             : }
        

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.