LCOV - code coverage report
Current view: top level - gcc - sreal.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 96.3 % 108 104
Test Date: 2024-12-21 13:15:12 Functions: 100.0 % 8 8
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* Definitions for simple data type for real numbers.
       2                 :             :    Copyright (C) 2002-2024 Free Software Foundation, Inc.
       3                 :             : 
       4                 :             : This file is part of GCC.
       5                 :             : 
       6                 :             : GCC is free software; you can redistribute it and/or modify it under
       7                 :             : the terms of the GNU General Public License as published by the Free
       8                 :             : Software Foundation; either version 3, or (at your option) any later
       9                 :             : version.
      10                 :             : 
      11                 :             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12                 :             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13                 :             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14                 :             : for more details.
      15                 :             : 
      16                 :             : You should have received a copy of the GNU General Public License
      17                 :             : along with GCC; see the file COPYING3.  If not see
      18                 :             : <http://www.gnu.org/licenses/>.  */
      19                 :             : 
      20                 :             : #ifndef GCC_SREAL_H
      21                 :             : #define GCC_SREAL_H
      22                 :             : 
      23                 :             : #define SREAL_PART_BITS 31
      24                 :             : 
      25                 :             : #define UINT64_BITS     64
      26                 :             : 
      27                 :             : #define SREAL_MIN_SIG ((int64_t) 1 << (SREAL_PART_BITS - 2))
      28                 :             : #define SREAL_MAX_SIG (((int64_t) 1 << (SREAL_PART_BITS - 1)) - 1)
      29                 :             : #define SREAL_MAX_EXP (INT_MAX / 4)
      30                 :             : 
      31                 :             : #define SREAL_BITS SREAL_PART_BITS
      32                 :             : 
      33                 :             : #define SREAL_SIGN(v) (v < 0 ? -1 : 1)
      34                 :             : #define SREAL_ABS(v) (v < 0 ? -v : v)
      35                 :             : 
      36                 :             : struct output_block;
      37                 :             : class lto_input_block;
      38                 :             : 
      39                 :             : /* Structure for holding a simple real number.  */
      40                 :             : class sreal
      41                 :             : {
      42                 :             : public:
      43                 :             :   /* Construct an uninitialized sreal.  */
      44                 :  1439325478 :   sreal () : m_sig (-1), m_exp (-1) {}
      45                 :             : 
      46                 :             :   /* Construct a sreal.  */
      47                 :  2711922608 :   sreal (int64_t sig, int exp = 0)
      48                 :  2711922608 :   {
      49                 :  2327095748 :     normalize (sig, exp);
      50                 :     1867063 :   }
      51                 :             : 
      52                 :             :   void dump (FILE *) const;
      53                 :             :   int64_t to_int () const;
      54                 :             :   int64_t to_nearest_int () const;
      55                 :             :   double to_double () const;
      56                 :             :   void stream_out (struct output_block *);
      57                 :             :   static sreal stream_in (class lto_input_block *);
      58                 :             :   sreal operator+ (const sreal &other) const;
      59                 :             :   sreal operator- (const sreal &other) const;
      60                 :             :   sreal operator* (const sreal &other) const;
      61                 :             :   sreal operator/ (const sreal &other) const;
      62                 :             : 
      63                 :   507652167 :   bool operator< (const sreal &other) const
      64                 :             :   {
      65                 :   507652167 :     if (m_exp == other.m_exp)
      66                 :    28348245 :       return m_sig < other.m_sig;
      67                 :             :     else
      68                 :             :     {
      69                 :   479303922 :       bool negative = m_sig < 0;
      70                 :   479303922 :       bool other_negative = other.m_sig < 0;
      71                 :             : 
      72                 :   479303922 :       if (negative != other_negative)
      73                 :    32670374 :         return negative > other_negative;
      74                 :             : 
      75                 :   446633548 :       bool r = m_exp < other.m_exp;
      76                 :   446633548 :       return negative ? !r : r;
      77                 :             :     }
      78                 :             :   }
      79                 :             : 
      80                 :   904394386 :   bool operator== (const sreal &other) const
      81                 :             :   {
      82                 :   215313781 :     return m_exp == other.m_exp && m_sig == other.m_sig;
      83                 :             :   }
      84                 :             : 
      85                 :     8503935 :   sreal operator- () const
      86                 :             :   {
      87                 :     8503935 :     sreal tmp = *this;
      88                 :     8503935 :     tmp.m_sig *= -1;
      89                 :             : 
      90                 :     8503935 :     return tmp;
      91                 :             :   }
      92                 :             : 
      93                 :    55298417 :   sreal shift (int s) const
      94                 :             :   {
      95                 :             :     /* Zero needs no shifting.  */
      96                 :    55298417 :     if (!m_sig)
      97                 :     5786463 :       return *this;
      98                 :    49511954 :     gcc_checking_assert (s <= SREAL_MAX_EXP);
      99                 :    49511954 :     gcc_checking_assert (s >= -SREAL_MAX_EXP);
     100                 :             : 
     101                 :             :     /* Overflows/drop to 0 could be handled gracefully, but hopefully we do not
     102                 :             :        need to do so.  */
     103                 :    49511954 :     gcc_checking_assert (m_exp + s <= SREAL_MAX_EXP);
     104                 :    49511954 :     gcc_checking_assert (m_exp + s >= -SREAL_MAX_EXP);
     105                 :             : 
     106                 :    49511954 :     sreal tmp = *this;
     107                 :    49511954 :     tmp.m_exp += s;
     108                 :             : 
     109                 :    49511954 :     return tmp;
     110                 :             :   }
     111                 :             : 
     112                 :             :   /* Global minimum sreal can hold.  */
     113                 :      992800 :   inline static sreal min ()
     114                 :             :   {
     115                 :      992800 :     sreal min;
     116                 :             :     /* This never needs normalization.  */
     117                 :      992800 :     min.m_sig = -SREAL_MAX_SIG;
     118                 :      992800 :     min.m_exp = SREAL_MAX_EXP;
     119                 :      992800 :     return min;
     120                 :             :   }
     121                 :             : 
     122                 :             :   /* Global minimum sreal can hold.  */
     123                 :     2043279 :   inline static sreal max ()
     124                 :             :   {
     125                 :     2043279 :     sreal max;
     126                 :             :     /* This never needs normalization.  */
     127                 :     2043279 :     max.m_sig = SREAL_MAX_SIG;
     128                 :     2043279 :     max.m_exp = SREAL_MAX_EXP;
     129                 :      354511 :     return max;
     130                 :             :   }
     131                 :             : 
     132                 :             : private:
     133                 :             :   inline void normalize (int64_t new_sig, signed int new_exp);
     134                 :             :   inline void normalize_up (int64_t new_sig, signed int new_exp);
     135                 :             :   inline void normalize_down (int64_t new_sig, signed int new_exp);
     136                 :             :   void shift_right (int amount);
     137                 :             :   static sreal signedless_plus (const sreal &a, const sreal &b, bool negative);
     138                 :             :   static sreal signedless_minus (const sreal &a, const sreal &b, bool negative);
     139                 :             : 
     140                 :             :   int32_t m_sig;                        /* Significant.  */
     141                 :             :   signed int m_exp;                     /* Exponent.  */
     142                 :             : };
     143                 :             : 
     144                 :             : extern void debug (const sreal &ref);
     145                 :             : extern void debug (const sreal *ptr);
     146                 :             : 
     147                 :   569974883 : inline sreal &operator+= (sreal &a, const sreal &b)
     148                 :             : {
     149                 :   568972584 :   return a = a + b;
     150                 :             : }
     151                 :             : 
     152                 :      375322 : inline sreal &operator-= (sreal &a, const sreal &b)
     153                 :             : {
     154                 :      375322 :   return a = a - b;
     155                 :             : }
     156                 :             : 
     157                 :      250609 : inline sreal &operator/= (sreal &a, const sreal &b)
     158                 :             : {
     159                 :      250609 :   return a = a / b;
     160                 :             : }
     161                 :             : 
     162                 :    14939370 : inline sreal &operator*= (sreal &a, const sreal &b)
     163                 :             : {
     164                 :    14939370 :   return a = a  * b;
     165                 :             : }
     166                 :             : 
     167                 :    61094548 : inline bool operator!= (const sreal &a, const sreal &b)
     168                 :             : {
     169                 :    91459113 :   return !(a == b);
     170                 :             : }
     171                 :             : 
     172                 :   364727905 : inline bool operator> (const sreal &a, const sreal &b)
     173                 :             : {
     174                 :   375758285 :   return !(a == b || a < b);
     175                 :             : }
     176                 :             : 
     177                 :    10130212 : inline bool operator<= (const sreal &a, const sreal &b)
     178                 :             : {
     179                 :    10130212 :   return a < b || a == b;
     180                 :             : }
     181                 :             : 
     182                 :   415552701 : inline bool operator>= (const sreal &a, const sreal &b)
     183                 :             : {
     184                 :   417138092 :   return a == b || a > b;
     185                 :             : }
     186                 :             : 
     187                 :     2757855 : inline sreal operator<< (const sreal &a, int exp)
     188                 :             : {
     189                 :     2757855 :   return a.shift (exp);
     190                 :             : }
     191                 :             : 
     192                 :    44312199 : inline sreal operator>> (const sreal &a, int exp)
     193                 :             : {
     194                 :    44312199 :   return a.shift (-exp);
     195                 :             : }
     196                 :             : 
     197                 :             : /* Make significant to be >= SREAL_MIN_SIG.
     198                 :             : 
     199                 :             :    Make this separate method so inliner can handle hot path better.  */
     200                 :             : 
     201                 :             : inline void
     202                 :  1011704285 : sreal::normalize_up (int64_t new_sig, signed int new_exp)
     203                 :             : {
     204                 :  1011704285 :   unsigned HOST_WIDE_INT sig = absu_hwi (new_sig);
     205                 :  1011704285 :   int shift = SREAL_PART_BITS - 2 - floor_log2 (sig);
     206                 :             : 
     207                 :  1011704285 :   gcc_checking_assert (shift > 0);
     208                 :  1011704285 :   sig <<= shift;
     209                 :  1011704285 :   new_exp -= shift;
     210                 :  1011704285 :   gcc_checking_assert (sig <= SREAL_MAX_SIG && sig >= SREAL_MIN_SIG);
     211                 :             : 
     212                 :             :   /* Check underflow.  */
     213                 :  1011704285 :   if (new_exp < -SREAL_MAX_EXP)
     214                 :             :     {
     215                 :           0 :       new_exp = -SREAL_MAX_EXP;
     216                 :           0 :       sig = 0;
     217                 :             :     }
     218                 :  1011704285 :   m_exp = new_exp;
     219                 :  1011704285 :   if (SREAL_SIGN (new_sig) == -1)
     220                 :    37466222 :     m_sig = -sig;
     221                 :             :   else
     222                 :   974238063 :     m_sig = sig;
     223                 :  1011704285 : }
     224                 :             : 
     225                 :             : /* Make significant to be <= SREAL_MAX_SIG.
     226                 :             : 
     227                 :             :    Make this separate method so inliner can handle hot path better.  */
     228                 :             : 
     229                 :             : inline void
     230                 :   825852062 : sreal::normalize_down (int64_t new_sig, signed int new_exp)
     231                 :             : {
     232                 :   825852062 :   int last_bit;
     233                 :   825852062 :   unsigned HOST_WIDE_INT sig = absu_hwi (new_sig);
     234                 :   825852062 :   int shift = floor_log2 (sig) - SREAL_PART_BITS + 2;
     235                 :             : 
     236                 :   825852062 :   gcc_checking_assert (shift > 0);
     237                 :   825852062 :   last_bit = (sig >> (shift-1)) & 1;
     238                 :   825852062 :   sig >>= shift;
     239                 :   825852062 :   new_exp += shift;
     240                 :   825852062 :   gcc_checking_assert (sig <= SREAL_MAX_SIG && sig >= SREAL_MIN_SIG);
     241                 :             : 
     242                 :             :   /* Round the number.  */
     243                 :   825852062 :   sig += last_bit;
     244                 :   825852062 :   if (sig > SREAL_MAX_SIG)
     245                 :             :     {
     246                 :      469974 :       sig >>= 1;
     247                 :      469974 :       new_exp++;
     248                 :             :     }
     249                 :             : 
     250                 :             :   /* Check overflow.  */
     251                 :   825852062 :   if (new_exp > SREAL_MAX_EXP)
     252                 :             :     {
     253                 :           0 :       new_exp = SREAL_MAX_EXP;
     254                 :           0 :       sig = SREAL_MAX_SIG;
     255                 :             :     }
     256                 :   825852062 :   m_exp = new_exp;
     257                 :   825852062 :   if (SREAL_SIGN (new_sig) == -1)
     258                 :    12739929 :     m_sig = -sig;
     259                 :             :   else
     260                 :   813112133 :     m_sig = sig;
     261                 :   825852062 : }
     262                 :             : 
     263                 :             : /* Normalize *this; the hot path.  */
     264                 :             : 
     265                 :             : inline void
     266                 :  3148371264 : sreal::normalize (int64_t new_sig, signed int new_exp)
     267                 :             : {
     268                 :  3148371264 :   unsigned HOST_WIDE_INT sig = absu_hwi (new_sig);
     269                 :             : 
     270                 :  3148371264 :   if (sig == 0)
     271                 :             :     {
     272                 :   946425321 :       m_sig = 0;
     273                 :   946425321 :       m_exp = -SREAL_MAX_EXP;
     274                 :             :     }
     275                 :  2201945943 :   else if (sig > SREAL_MAX_SIG)
     276                 :   825852062 :     normalize_down (new_sig, new_exp);
     277                 :  1376093881 :   else if (sig < SREAL_MIN_SIG)
     278                 :  1011704285 :     normalize_up (new_sig, new_exp);
     279                 :             :   else
     280                 :             :     {
     281                 :   364389596 :       m_sig = new_sig;
     282                 :   364389596 :       m_exp = new_exp;
     283                 :             :     }
     284                 :  3148371264 : }
     285                 :             : 
     286                 :             : #endif
        

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.