LCOV - code coverage report
Current view: top level - gcc - sreal.h (source / functions) Hit Total Coverage
Test: gcc.info Lines: 102 106 96.2 %
Date: 2020-03-28 11:57:23 Functions: 7 7 100.0 %
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-2020 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                 :  762364111 :   sreal () : m_sig (-1), m_exp (-1) {}
      45                 :            : 
      46                 :            :   /* Construct a sreal.  */
      47                 : 1313457300 :   sreal (int64_t sig, int exp = 0)
      48                 : 1313457300 :   {
      49                 : 1165705831 :     normalize (sig, exp);
      50                 :    1116150 :   }
      51                 :            : 
      52                 :            :   void dump (FILE *) const;
      53                 :            :   int64_t to_int () const;
      54                 :            :   double to_double () const;
      55                 :            :   void stream_out (struct output_block *);
      56                 :            :   static sreal stream_in (class lto_input_block *);
      57                 :            :   sreal operator+ (const sreal &other) const;
      58                 :            :   sreal operator- (const sreal &other) const;
      59                 :            :   sreal operator* (const sreal &other) const;
      60                 :            :   sreal operator/ (const sreal &other) const;
      61                 :            : 
      62                 :  268493353 :   bool operator< (const sreal &other) const
      63                 :            :   {
      64                 :   97243797 :     if (m_exp == other.m_exp)
      65                 :   13307224 :       return m_sig < other.m_sig;
      66                 :            :     else
      67                 :            :     {
      68                 :  255185737 :       bool negative = m_sig < 0;
      69                 :  255185737 :       bool other_negative = other.m_sig < 0;
      70                 :            : 
      71                 :  255185737 :       if (negative != other_negative)
      72                 :   17325548 :         return negative > other_negative;
      73                 :            : 
      74                 :  237859929 :       bool r = m_exp < other.m_exp;
      75                 :  237859929 :       return negative ? !r : r;
      76                 :            :     }
      77                 :            :   }
      78                 :            : 
      79                 :  429346560 :   bool operator== (const sreal &other) const
      80                 :            :   {
      81                 :  102241438 :     return m_exp == other.m_exp && m_sig == other.m_sig;
      82                 :            :   }
      83                 :            : 
      84                 :    3828728 :   sreal operator- () const
      85                 :            :   {
      86                 :    3828728 :     sreal tmp = *this;
      87                 :    3828728 :     tmp.m_sig *= -1;
      88                 :            : 
      89                 :    3828728 :     return tmp;
      90                 :            :   }
      91                 :            : 
      92                 :   43587646 :   sreal shift (int s) const
      93                 :            :   {
      94                 :            :     /* Zero needs no shifting.  */
      95                 :   43587646 :     if (!m_sig)
      96                 :    4869222 :       return *this;
      97                 :   38718380 :     gcc_checking_assert (s <= SREAL_MAX_EXP);
      98                 :   38718380 :     gcc_checking_assert (s >= -SREAL_MAX_EXP);
      99                 :            : 
     100                 :            :     /* Overflows/drop to 0 could be handled gracefully, but hopefully we do not
     101                 :            :        need to do so.  */
     102                 :   38718380 :     gcc_checking_assert (m_exp + s <= SREAL_MAX_EXP);
     103                 :   38718380 :     gcc_checking_assert (m_exp + s >= -SREAL_MAX_EXP);
     104                 :            : 
     105                 :   38718380 :     sreal tmp = *this;
     106                 :   38718380 :     tmp.m_exp += s;
     107                 :            : 
     108                 :   38718380 :     return tmp;
     109                 :            :   }
     110                 :            : 
     111                 :            :   /* Global minimum sreal can hold.  */
     112                 :     164949 :   inline static sreal min ()
     113                 :            :   {
     114                 :     164949 :     sreal min;
     115                 :            :     /* This never needs normalization.  */
     116                 :     164949 :     min.m_sig = -SREAL_MAX_SIG;
     117                 :     164949 :     min.m_exp = SREAL_MAX_EXP;
     118                 :     164949 :     return min;
     119                 :            :   }
     120                 :            : 
     121                 :            :   /* Global minimum sreal can hold.  */
     122                 :      20305 :   inline static sreal max ()
     123                 :            :   {
     124                 :      20305 :     sreal max;
     125                 :            :     /* This never needs normalization.  */
     126                 :      20305 :     max.m_sig = SREAL_MAX_SIG;
     127                 :      20305 :     max.m_exp = SREAL_MAX_EXP;
     128                 :      20305 :     return max;
     129                 :            :   }
     130                 :            : 
     131                 :            : private:
     132                 :            :   inline void normalize (int64_t new_sig, signed int new_exp);
     133                 :            :   inline void normalize_up (int64_t new_sig, signed int new_exp);
     134                 :            :   inline void normalize_down (int64_t new_sig, signed int new_exp);
     135                 :            :   void shift_right (int amount);
     136                 :            :   static sreal signedless_plus (const sreal &a, const sreal &b, bool negative);
     137                 :            :   static sreal signedless_minus (const sreal &a, const sreal &b, bool negative);
     138                 :            : 
     139                 :            :   int32_t m_sig;                        /* Significant.  */
     140                 :            :   signed int m_exp;                     /* Exponent.  */
     141                 :            : };
     142                 :            : 
     143                 :            : extern void debug (const sreal &ref);
     144                 :            : extern void debug (const sreal *ptr);
     145                 :            : 
     146                 :  289388920 : inline sreal &operator+= (sreal &a, const sreal &b)
     147                 :            : {
     148                 :  289388920 :   return a = a + b;
     149                 :            : }
     150                 :            : 
     151                 :     503217 : inline sreal &operator-= (sreal &a, const sreal &b)
     152                 :            : {
     153                 :     503217 :   return a = a - b;
     154                 :            : }
     155                 :            : 
     156                 :            : inline sreal &operator/= (sreal &a, const sreal &b)
     157                 :            : {
     158                 :            :   return a = a / b;
     159                 :            : }
     160                 :            : 
     161                 :    6528960 : inline sreal &operator*= (sreal &a, const sreal &b)
     162                 :            : {
     163                 :    6528960 :   return a = a  * b;
     164                 :            : }
     165                 :            : 
     166                 :    7884178 : inline bool operator!= (const sreal &a, const sreal &b)
     167                 :            : {
     168                 :    7884340 :   return !(a == b);
     169                 :            : }
     170                 :            : 
     171                 :  178353597 : inline bool operator> (const sreal &a, const sreal &b)
     172                 :            : {
     173                 :  352461990 :   return !(a == b || a < b);
     174                 :            : }
     175                 :            : 
     176                 :    4029215 : inline bool operator<= (const sreal &a, const sreal &b)
     177                 :            : {
     178                 :    8058430 :   return a < b || a == b;
     179                 :            : }
     180                 :            : 
     181                 :  205861272 : inline bool operator>= (const sreal &a, const sreal &b)
     182                 :            : {
     183                 :  206300036 :   return a == b || a > b;
     184                 :            : }
     185                 :            : 
     186                 :    1878991 : inline sreal operator<< (const sreal &a, int exp)
     187                 :            : {
     188                 :    1878991 :   return a.shift (exp);
     189                 :            : }
     190                 :            : 
     191                 :   38164513 : inline sreal operator>> (const sreal &a, int exp)
     192                 :            : {
     193                 :   38164513 :   return a.shift (-exp);
     194                 :            : }
     195                 :            : 
     196                 :            : /* Make significant to be >= SREAL_MIN_SIG.
     197                 :            : 
     198                 :            :    Make this separate method so inliner can handle hot path better.  */
     199                 :            : 
     200                 :            : inline void
     201                 :  479991554 : sreal::normalize_up (int64_t new_sig, signed int new_exp)
     202                 :            : {
     203                 :  479991554 :   unsigned HOST_WIDE_INT sig = absu_hwi (new_sig);
     204                 :  479991554 :   int shift = SREAL_PART_BITS - 2 - floor_log2 (sig);
     205                 :            : 
     206                 :  479991554 :   gcc_checking_assert (shift > 0);
     207                 :  479991554 :   sig <<= shift;
     208                 :  479991554 :   new_exp -= shift;
     209                 :  479991554 :   gcc_checking_assert (sig <= SREAL_MAX_SIG && sig >= SREAL_MIN_SIG);
     210                 :            : 
     211                 :            :   /* Check underflow.  */
     212                 :  479991554 :   if (new_exp < -SREAL_MAX_EXP)
     213                 :            :     {
     214                 :          0 :       new_exp = -SREAL_MAX_EXP;
     215                 :          0 :       sig = 0;
     216                 :            :     }
     217                 :  479991554 :   m_exp = new_exp;
     218                 :  479991554 :   if (SREAL_SIGN (new_sig) == -1)
     219                 :   16805805 :     m_sig = -sig;
     220                 :            :   else
     221                 :  463185499 :     m_sig = sig;
     222                 :  479991554 : }
     223                 :            : 
     224                 :            : /* Make significant to be <= SREAL_MAX_SIG.
     225                 :            : 
     226                 :            :    Make this separate method so inliner can handle hot path better.  */
     227                 :            : 
     228                 :            : inline void
     229                 :  405726000 : sreal::normalize_down (int64_t new_sig, signed int new_exp)
     230                 :            : {
     231                 :  405726000 :   int last_bit;
     232                 :  405726000 :   unsigned HOST_WIDE_INT sig = absu_hwi (new_sig);
     233                 :  405726000 :   int shift = floor_log2 (sig) - SREAL_PART_BITS + 2;
     234                 :            : 
     235                 :  405726000 :   gcc_checking_assert (shift > 0);
     236                 :  405726000 :   last_bit = (sig >> (shift-1)) & 1;
     237                 :  405726000 :   sig >>= shift;
     238                 :  405726000 :   new_exp += shift;
     239                 :  405726000 :   gcc_checking_assert (sig <= SREAL_MAX_SIG && sig >= SREAL_MIN_SIG);
     240                 :            : 
     241                 :            :   /* Round the number.  */
     242                 :  405726000 :   sig += last_bit;
     243                 :  405726000 :   if (sig > SREAL_MAX_SIG)
     244                 :            :     {
     245                 :     423840 :       sig >>= 1;
     246                 :     423840 :       new_exp++;
     247                 :            :     }
     248                 :            : 
     249                 :            :   /* Check overflow.  */
     250                 :  405726000 :   if (new_exp > SREAL_MAX_EXP)
     251                 :            :     {
     252                 :          0 :       new_exp = SREAL_MAX_EXP;
     253                 :          0 :       sig = SREAL_MAX_SIG;
     254                 :            :     }
     255                 :  405726000 :   m_exp = new_exp;
     256                 :  405726000 :   if (SREAL_SIGN (new_sig) == -1)
     257                 :    3355610 :     m_sig = -sig;
     258                 :            :   else
     259                 :  402371000 :     m_sig = sig;
     260                 :  405726000 : }
     261                 :            : 
     262                 :            : /* Normalize *this; the hot path.  */
     263                 :            : 
     264                 :            : inline void
     265                 : 1553132468 : sreal::normalize (int64_t new_sig, signed int new_exp)
     266                 :            : {
     267                 : 1553132468 :   unsigned HOST_WIDE_INT sig = absu_hwi (new_sig);
     268                 :            : 
     269                 : 1553132468 :   if (sig == 0)
     270                 :            :     {
     271                 :  470197556 :       m_sig = 0;
     272                 :  470197556 :       m_exp = -SREAL_MAX_EXP;
     273                 :            :     }
     274                 : 1082934421 :   else if (sig > SREAL_MAX_SIG)
     275                 :  405726000 :     normalize_down (new_sig, new_exp);
     276                 :  677208421 :   else if (sig < SREAL_MIN_SIG)
     277                 :  479991554 :     normalize_up (new_sig, new_exp);
     278                 :            :   else
     279                 :            :     {
     280                 :  197217661 :       m_sig = new_sig;
     281                 :  197217661 :       m_exp = new_exp;
     282                 :            :     }
     283                 : 1553132468 : }
     284                 :            : 
     285                 :            : #endif

Generated by: LCOV version 1.0

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 --enable-host-shared. GCC test suite is run with the built compiler.