LCOV - code coverage report
Current view: top level - gcc - value-range.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 93.3 % 611 570
Test Date: 2026-08-22 16:33:35 Functions: 79.9 % 134 107
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Support routines for value ranges.
       2              :    Copyright (C) 2019-2026 Free Software Foundation, Inc.
       3              :    Contributed by Aldy Hernandez <aldyh@redhat.com> and
       4              :    Andrew Macleod <amacleod@redhat.com>.
       5              : 
       6              : This file is part of GCC.
       7              : 
       8              : GCC is free software; you can redistribute it and/or modify
       9              : it under the terms of the GNU General Public License as published by
      10              : the Free Software Foundation; either version 3, or (at your option)
      11              : any later version.
      12              : 
      13              : GCC is distributed in the hope that it will be useful,
      14              : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15              : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16              : GNU General Public License for more details.
      17              : 
      18              : You should have received a copy of the GNU General Public License
      19              : along with GCC; see the file COPYING3.  If not see
      20              : <http://www.gnu.org/licenses/>.  */
      21              : 
      22              : #ifndef GCC_VALUE_RANGE_H
      23              : #define GCC_VALUE_RANGE_H
      24              : 
      25              : class irange;
      26              : 
      27              : // Types of value ranges.
      28              : enum value_range_kind
      29              : {
      30              :   /* Empty range.  */
      31              :   VR_UNDEFINED,
      32              :   /* Range spans the entire domain.  */
      33              :   VR_VARYING,
      34              :   /* Range is [MIN, MAX].  */
      35              :   VR_RANGE,
      36              :   /* Range is ~[MIN, MAX].  */
      37              :   VR_ANTI_RANGE,
      38              :   /* Range is a NAN.  */
      39              :   VR_NAN,
      40              :   /* Range is a nice guy.  */
      41              :   VR_LAST
      42              : };
      43              : 
      44              : // Discriminator between different vrange types.
      45              : 
      46              : enum value_range_discriminator
      47              : {
      48              :   // Range holds an integer or pointer.
      49              :   VR_IRANGE,
      50              :   // Pointer range.
      51              :   VR_PRANGE,
      52              :   // Floating point range.
      53              :   VR_FRANGE,
      54              :   // Range holds an unsupported type.
      55              :   VR_UNKNOWN
      56              : };
      57              : 
      58              : // Abstract class for representing subsets of values for various
      59              : // supported types, such as the possible values of a variable.
      60              : //
      61              : // There are subclasses for each of integer, floating point, and pointer
      62              : // types, each with their own strategies for efficiently representing
      63              : // subsets of values.
      64              : //
      65              : // For efficiency, we can't precisely represent any arbitrary subset
      66              : // of values of a type (which could require 2^N bits for a type of size N)
      67              : // Hence operations on the subclasses may introduce imprecision
      68              : // due to over-approximating the possible subsets.
      69              : //
      70              : // To query what types ranger and the entire ecosystem can support,
      71              : // use value_range::supports_type_p(tree type).  This is a static
      72              : // method available independently of any vrange object.
      73              : //
      74              : // To query what a given vrange variant can support, use:
      75              : //    irange::supports_p ()
      76              : //    frange::supports_p ()
      77              : //    etc
      78              : //
      79              : // To query what a range object can support, use:
      80              : //    void foo (vrange &v, irange &i, frange &f)
      81              : //    {
      82              : //      if (v.supports_type_p (type)) ...
      83              : //      if (i.supports_type_p (type)) ...
      84              : //      if (f.supports_type_p (type)) ...
      85              : //    }
      86              : 
      87              : class vrange
      88              : {
      89              :   template <typename T> friend bool is_a (vrange &);
      90              :   friend class value_range;
      91              :   friend void streamer_write_vrange (struct output_block *, const vrange &);
      92              :   friend class range_op_handler;
      93              : public:
      94              :   virtual void accept (const class vrange_visitor &v) const = 0;
      95              :   virtual void set (tree, tree, value_range_kind = VR_RANGE) = 0;
      96              :   virtual tree type () const = 0;
      97              :   virtual bool supports_type_p (const_tree type) const = 0;
      98              :   virtual void set_varying (tree type) = 0;
      99              :   virtual void set_undefined () = 0;
     100              :   virtual bool union_ (const vrange &) = 0;
     101              :   virtual bool intersect (const vrange &) = 0;
     102              :   virtual bool singleton_p (tree *result = NULL) const = 0;
     103              :   virtual bool contains_p (tree cst) const = 0;
     104              :   virtual bool zero_p () const = 0;
     105              :   // True if val == 0 may hold for some value in the range; for a float
     106              :   // range that means +0.0 or -0.0.
     107              :   virtual bool contains_zero_p () const = 0;
     108              :   virtual void set_nonzero (tree type) = 0;
     109              :   virtual void set_zero (tree type) = 0;
     110              :   virtual void set_nonnegative (tree type) = 0;
     111              :   virtual bool fits_p (const vrange &r) const = 0;
     112   5111316142 :   virtual ~vrange () { }
     113              :   virtual tree lbound () const = 0;
     114              :   virtual tree ubound () const = 0;
     115              :   virtual void update_bitmask (const class irange_bitmask &);
     116              :   virtual irange_bitmask get_bitmask () const;
     117              :   wide_int get_nonzero_bits () const;
     118              :   void set_nonzero_bits (const wide_int &bits);
     119              : 
     120              :   bool varying_p () const;
     121              :   bool undefined_p () const;
     122              :   vrange& operator= (const vrange &);
     123              :   bool operator== (const vrange &) const;
     124     14098366 :   bool operator!= (const vrange &r) const { return !(*this == r); }
     125              :   void dump (FILE *) const;
     126            0 :   virtual void verify_range () const { }
     127              : protected:
     128   6950650558 :   vrange (enum value_range_discriminator d) : m_discriminator (d) { }
     129              :   enum value_range_kind m_kind : 8;
     130              :   const enum value_range_discriminator m_discriminator : 4;
     131              : };
     132              : 
     133              : namespace inchash
     134              : {
     135              :   extern void add_vrange (const vrange &, hash &, unsigned flags = 0);
     136              : }
     137              : 
     138              : // A pair of values representing the known bits of a value.  Zero bits
     139              : // in MASK cover constant values.  Set bits in MASK cover unknown
     140              : // values.  VALUE are the known bits for the bits where MASK is zero,
     141              : // and must be zero for the unknown bits where MASK is set (needed as an
     142              : // optimization of union and intersect)
     143              : // For example:
     144              : // VALUE: [..., 0, 1, 0]
     145              : // MASK:  [..., 1, 0, 0]
     146              : //              ^  ^  ^
     147              : //              |  |  known bit: {0}
     148              : //              |  known bit: {1}
     149              : //              unknown bit: {0, 1}
     150              : 
     151              : class irange_bitmask
     152              : {
     153              : public:
     154   6725422991 :   irange_bitmask () { /* uninitialized */ }
     155            0 :   irange_bitmask (unsigned prec) { set_unknown (prec); }
     156              :   irange_bitmask (const wide_int &value, const wide_int &mask);
     157              :   irange_bitmask (tree type, const wide_int &min, const wide_int &max);
     158              : 
     159   1565620319 :   wide_int value () const { return m_value; }
     160   1888514036 :   wide_int mask () const { return m_mask; }
     161              :   void set_unknown (unsigned prec);
     162              :   bool unknown_p () const;
     163              :   unsigned get_precision () const;
     164              :   void union_ (const irange_bitmask &src);
     165              :   bool intersect (const irange_bitmask &src);
     166              :   bool operator== (const irange_bitmask &src) const;
     167      8362758 :   bool operator!= (const irange_bitmask &src) const { return !(*this == src); }
     168              :   void verify_mask () const;
     169              :   void dump (FILE *) const;
     170              :   bool range_from_mask (irange &r, tree type) const;
     171              : 
     172              :   bool member_p (const wide_int &val) const;
     173              : 
     174              :   // Convenience functions for nonzero bitmask compatibility.
     175              :   wide_int get_nonzero_bits () const;
     176              :   void set_nonzero_bits (const wide_int &bits);
     177              : private:
     178              :   wide_int m_value;
     179              :   wide_int m_mask;
     180              : };
     181              : 
     182              : inline void
     183   3903247546 : irange_bitmask::set_unknown (unsigned prec)
     184              : {
     185   3903247546 :   m_value = wi::zero (prec);
     186   3903247546 :   m_mask = wi::minus_one (prec);
     187   3903247546 :   if (flag_checking)
     188   3903234603 :     verify_mask ();
     189   3903247546 : }
     190              : 
     191              : // Return TRUE if THIS does not have any meaningful information.
     192              : 
     193              : inline bool
     194   5354483706 : irange_bitmask::unknown_p () const
     195              : {
     196   2412028996 :   return m_mask == -1;
     197              : }
     198              : 
     199              : inline
     200   1178359727 : irange_bitmask::irange_bitmask (const wide_int &value, const wide_int &mask)
     201              : {
     202   1178359727 :   m_value = value;
     203   1178359727 :   m_mask = mask;
     204   1178359727 :   if (flag_checking)
     205   1178356133 :     verify_mask ();
     206   1178359727 : }
     207              : 
     208              : inline unsigned
     209              : irange_bitmask::get_precision () const
     210              : {
     211              :   return m_mask.get_precision ();
     212              : }
     213              : 
     214              : // The following two functions are meant for backwards compatibility
     215              : // with the nonzero bitmask.  A cleared bit means the value must be 0.
     216              : // A set bit means we have no information for the bit.
     217              : 
     218              : // Return the nonzero bits.
     219              : inline wide_int
     220         4637 : irange_bitmask::get_nonzero_bits () const
     221              : {
     222         4637 :   return m_value | m_mask;
     223              : }
     224              : 
     225              : // Set the bitmask to the nonzero bits in BITS.
     226              : inline void
     227              : irange_bitmask::set_nonzero_bits (const wide_int &bits)
     228              : {
     229              :   m_value = wi::zero (bits.get_precision ());
     230              :   m_mask = bits;
     231              :   if (flag_checking)
     232              :     verify_mask ();
     233              : }
     234              : 
     235              : // Return TRUE if val could be a valid value with this bitmask.
     236              : 
     237              : inline bool
     238    261545006 : irange_bitmask::member_p (const wide_int &val) const
     239              : {
     240    261545006 :   if (unknown_p ())
     241              :     return true;
     242     31227023 :   wide_int res = m_mask & val;
     243     31227023 :   if (m_value != 0)
     244      1004134 :     res |= ~m_mask & m_value;
     245     31227023 :   return res == val;
     246     31227023 : }
     247              : 
     248              : inline bool
     249   1235441200 : irange_bitmask::operator== (const irange_bitmask &src) const
     250              : {
     251   1235441200 :   bool unknown1 = unknown_p ();
     252   1235441200 :   bool unknown2 = src.unknown_p ();
     253   1235441200 :   if (unknown1 || unknown2)
     254    942815655 :     return unknown1 == unknown2;
     255    292625545 :   return m_value == src.m_value && m_mask == src.m_mask;
     256              : }
     257              : 
     258              : inline void
     259     18916367 : irange_bitmask::union_ (const irange_bitmask &src)
     260              : {
     261     18916953 :   m_mask = (m_mask | src.m_mask) | (m_value ^ src.m_value);
     262     18916367 :   m_value = m_value & src.m_value;
     263     18916367 :   if (flag_checking)
     264     18916367 :     verify_mask ();
     265     18916367 : }
     266              : 
     267              : // Return FALSE if the bitmask intersection is undefined.
     268              : 
     269              : inline bool
     270    818478991 : irange_bitmask::intersect (const irange_bitmask &src)
     271              : {
     272              :   // If we have two known bits that are incompatible, the resulting
     273              :   // bit and therefore entire range is undefined.  Return FALSE.
     274   1637098030 :   if (wi::bit_and (~(m_mask | src.m_mask),
     275   2455436973 :                    m_value ^ src.m_value) != 0)
     276              :     return false;
     277              :   else
     278              :     {
     279    818430411 :       m_mask = m_mask & src.m_mask;
     280    818430411 :       m_value = m_value | src.m_value;
     281              :     }
     282    818430411 :   if (flag_checking)
     283    818427848 :     verify_mask ();
     284              :   return true;
     285              : }
     286              : 
     287              : // A subset of possible values for an integer type, leaving
     288              : // allocation of storage to subclasses.
     289              : 
     290  10665494824 : class irange : public vrange
     291              : {
     292              :   friend class irange_storage;
     293              :   friend class vrange_printer;
     294              : public:
     295              :   // In-place setters.
     296              :   void set (tree type, const wide_int &, const wide_int &,
     297              :             value_range_kind = VR_RANGE);
     298              :   virtual void set_nonzero (tree type) override;
     299              :   virtual void set_zero (tree type) override;
     300              :   virtual void set_nonnegative (tree type) override;
     301              :   virtual void set_varying (tree type) override;
     302              :   virtual void set_undefined () override;
     303              : 
     304              :   // Range types.
     305              :   static bool supports_p (const_tree type);
     306              :   virtual bool supports_type_p (const_tree type) const override;
     307              :   virtual tree type () const override;
     308              : 
     309              :   // Iteration over sub-ranges.
     310              :   unsigned num_pairs () const;
     311              :   wide_int lower_bound (unsigned = 0) const;
     312              :   wide_int upper_bound (unsigned) const;
     313              :   wide_int upper_bound () const;
     314              :   virtual tree lbound () const override;
     315              :   virtual tree ubound () const override;
     316              : 
     317              :   // Predicates.
     318              :   virtual bool zero_p () const override;
     319              :   virtual bool contains_zero_p () const override;
     320              :   virtual bool singleton_p (tree *result = NULL) const override;
     321              :   bool singleton_p (wide_int &) const;
     322              :   bool contains_p (const wide_int &) const;
     323              :   bool nonnegative_p () const;
     324              :   bool nonpositive_p () const;
     325              : 
     326              :   // In-place operators.
     327              :   virtual bool union_ (const vrange &) override;
     328              :   virtual bool intersect (const vrange &) override;
     329              :   bool invert ();
     330              : 
     331              :   // Operator overloads.
     332              :   irange& operator= (const irange &);
     333              :   bool operator== (const irange &) const;
     334              :   bool operator!= (const irange &r) const { return !(*this == r); }
     335              : 
     336              :   // Misc methods.
     337              :   virtual bool fits_p (const vrange &r) const override;
     338              :   virtual void accept (const vrange_visitor &v) const override;
     339              : 
     340              :   virtual void update_bitmask (const class irange_bitmask &) override;
     341              :   virtual irange_bitmask get_bitmask () const override;
     342              : 
     343              :   virtual void verify_range () const override;
     344              : protected:
     345              :   void maybe_resize (int needed);
     346              :   virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
     347              :   virtual bool contains_p (tree cst) const override;
     348              :   irange (wide_int *, unsigned nranges, bool resizable);
     349              : 
     350              :    // In-place operators.
     351              :   bool irange_contains_p (const irange &) const;
     352              :   bool irange_single_pair_union (const irange &r);
     353              : 
     354              :   void normalize_kind ();
     355              : 
     356              : 
     357              :   // Hard limit on max ranges allowed.
     358              :   static const int HARD_MAX_RANGES = 255;
     359              : private:
     360              :   bool varying_compatible_p () const;
     361              :   bool intersect_bitmask (const irange &r);
     362              :   bool union_bitmask (const irange &r);
     363              :   bool set_range_from_bitmask ();
     364              :   bool snap_subranges ();
     365              :   bool snap (const wide_int &, const wide_int &, wide_int &, wide_int &,
     366              :              bool &);
     367              : 
     368              :   bool intersect (const wide_int& lb, const wide_int& ub);
     369              :   bool union_append (const irange &r);
     370              :   unsigned char m_num_ranges;
     371              :   bool m_resizable;
     372              :   unsigned char m_max_ranges;
     373              :   tree m_type;
     374              :   irange_bitmask m_bitmask;
     375              : protected:
     376              :   wide_int *m_base;
     377              : };
     378              : 
     379              : // Here we describe an irange with N pairs of ranges.  The storage for
     380              : // the pairs is embedded in the class as an array.
     381              : //
     382              : // If RESIZABLE is true, the storage will be resized on the heap when
     383              : // the number of ranges needed goes past N up to a max of
     384              : // HARD_MAX_RANGES.  This new storage is freed upon destruction.
     385              : 
     386              : template<unsigned N, bool RESIZABLE = false>
     387              : class int_range final : public irange
     388              : {
     389              : public:
     390              :   int_range ();
     391              :   int_range (tree type, const wide_int &, const wide_int &,
     392              :              value_range_kind = VR_RANGE);
     393              :   int_range (tree type);
     394              :   int_range (const int_range &);
     395              :   int_range (const irange &);
     396              :   ~int_range () final override;
     397              :   int_range& operator= (const int_range &);
     398              : protected:
     399              :   int_range (tree, tree, value_range_kind = VR_RANGE);
     400              : private:
     401              :   wide_int m_ranges[N*2];
     402              : };
     403              : 
     404              : class prange final : public vrange
     405              : {
     406              :   friend class prange_storage;
     407              :   friend class vrange_printer;
     408              : public:
     409              :   prange ();
     410              :   prange (const prange &);
     411              :   prange (tree type);
     412              :   prange (tree type, const wide_int &, const wide_int &,
     413              :           value_range_kind = VR_RANGE);
     414              :   static bool supports_p (const_tree type);
     415              :   virtual bool supports_type_p (const_tree type) const final override;
     416              :   virtual void accept (const vrange_visitor &v) const final override;
     417              :   virtual void set_undefined () final override;
     418              :   virtual void set_varying (tree type) final override;
     419              :   virtual void set_nonzero (tree type) final override;
     420              :   virtual void set_zero (tree type) final override;
     421              :   virtual void set_nonnegative (tree type) final override;
     422              :   virtual bool contains_p (tree cst) const final override;
     423              :   virtual bool fits_p (const vrange &v) const final override;
     424              :   virtual bool singleton_p (tree *result = NULL) const final override;
     425              :   virtual bool zero_p () const final override;
     426              :   virtual bool contains_zero_p () const final override;
     427              :   virtual void set (tree, tree, value_range_kind = VR_RANGE) final override;
     428              :   virtual tree type () const final override;
     429              :   virtual bool union_ (const vrange &v) final override;
     430              :   virtual bool intersect (const vrange &v) final override;
     431              :   virtual tree lbound () const final override;
     432              :   virtual tree ubound () const final override;
     433              : 
     434              :   prange& operator= (const prange &);
     435              :   bool operator== (const prange &) const;
     436              :   void set (tree type, const wide_int &, const wide_int &,
     437              :             value_range_kind = VR_RANGE);
     438              :   bool invert ();
     439              :   bool contains_p (const wide_int &) const;
     440              :   wide_int lower_bound () const;
     441              :   wide_int upper_bound () const;
     442              :   virtual void verify_range () const final override;
     443              :   irange_bitmask get_bitmask () const final override;
     444              :   void update_bitmask (const irange_bitmask &) final override;
     445              : 
     446              :   // prange interface to points to information.
     447              :   // It can point_to or point_away from an object.  This represents both
     448              :   // sides of a conditional. ie:
     449              :   //   if (p == &foo)
     450              :   //     // p points to foo.
     451              :   //   else
     452              :   //     // p points away from foo.
     453              :   // pt_invariant () and pt_invariant_away () - Return pt if this is invariant.
     454              :   void set_pt (const prange &r);
     455              :   void set_pt (tree ptr, bool points_to_p = true);
     456              : 
     457              :   // unknown_p () is true if no object is pointed to.
     458              :   void set_pt_unknown ();
     459              :   bool pt_unknown_p () const;
     460              : 
     461              :   // Invariant points-to are is_gimple_min_invariant_p ().
     462              :   // Return expression or NULL_TREE for points-to or away
     463              :   tree pt_invariant () const;
     464              :   tree pt_invariant_away () const;
     465              : 
     466              :   // Return true if THIS and R both point to the same object.
     467              :   bool pt_invariant_p (const prange &r) const;
     468              :   // Return true if THIS and R both point away from the same object.
     469              :   bool pt_invariant_away_p (const prange &r) const;
     470              :   // Return true if THIS and R refer to the same object, and one is inverted
     471              :   // from the other,  Ie, both to and away.
     472              :   bool pt_inverted_p (const prange &r) const;
     473              : 
     474              :   // Invert THIS if it points either to or away from an object.
     475              :   bool pt_invert ();
     476              : 
     477              :   // pt_base () - object/allocation the pointer refers into.
     478              :   tree pt_base () const;
     479              :   // pt_offset () - possible byte offset range from BASE.
     480              :   void pt_offset (irange &) const;
     481              :   // pt_size () - possible size range of the referenced object.
     482              :   void pt_size (irange &) const;
     483              : 
     484              : protected:
     485              :   bool varying_compatible_p () const;
     486              : 
     487              :   tree m_type;
     488              :   wide_int m_min;
     489              :   wide_int m_max;
     490              :   irange_bitmask m_bitmask;
     491              : 
     492              :    // A prange can point to an object, or NOT point to an object.
     493              :   tree m_pt;            // object points-to refers to.
     494              :   bool m_points_to_p;   // Does it point to it (TRUE), or not (FALSE).
     495              :   // If P has the same points to fields as THIS.
     496              :   bool pt_equal_p (const class prange &p) const;
     497              : };
     498              : 
     499              : // Unsupported temporaries may be created by ranger before it's known
     500              : // they're unsupported, or by vr_values::get_value_range.
     501              : 
     502            0 : class unsupported_range : public vrange
     503              : {
     504              : public:
     505     74818874 :   unsupported_range ()
     506     74818874 :     : vrange (VR_UNKNOWN)
     507              :   {
     508     74818874 :     set_undefined ();
     509              :   }
     510       652680 :   unsupported_range (const unsupported_range &src)
     511       652680 :     : vrange (VR_UNKNOWN)
     512              :   {
     513       652680 :     unsupported_range::operator= (src);
     514              :   }
     515              :   void set (tree min, tree, value_range_kind = VR_RANGE) final override;
     516              :   tree type () const final override;
     517              :   bool supports_type_p (const_tree) const final override;
     518              :   void set_varying (tree) final override;
     519              :   void set_undefined () final override;
     520              :   void accept (const vrange_visitor &v) const final override;
     521              :   bool union_ (const vrange &r) final override;
     522              :   bool intersect (const vrange &r) final override;
     523              :   bool singleton_p (tree * = NULL) const final override;
     524              :   bool contains_p (tree) const final override;
     525              :   bool zero_p () const final override;
     526              :   bool contains_zero_p () const final override;
     527              :   void set_nonzero (tree type) final override;
     528              :   void set_zero (tree type) final override;
     529              :   void set_nonnegative (tree type) final override;
     530              :   bool fits_p (const vrange &) const final override;
     531              :   unsupported_range& operator= (const unsupported_range &r);
     532              :   tree lbound () const final override;
     533              :   tree ubound () const final override;
     534              : };
     535              : 
     536              : // The possible NAN state of a floating point value as an opaque object.
     537              : // This represents one of the four subsets of { -NaN, +NaN },
     538              : // i.e. one of {}, { -NaN }, { +NaN}, or { -NaN, +NaN }.
     539              : 
     540              : class nan_state
     541              : {
     542              : public:
     543              :   nan_state (bool);
     544              :   nan_state (bool pos_nan, bool neg_nan);
     545              :   bool neg_p () const;
     546              :   bool pos_p () const;
     547              : private:
     548              :   bool m_pos_nan;
     549              :   bool m_neg_nan;
     550              : };
     551              : 
     552              : // Set NAN state to +-NAN if NAN_P is true.  Otherwise set NAN state
     553              : // to false.
     554              : 
     555              : inline
     556     35499634 : nan_state::nan_state (bool nan_p)
     557              : {
     558     35499634 :   m_pos_nan = nan_p;
     559     31269565 :   m_neg_nan = nan_p;
     560              : }
     561              : 
     562              : // Constructor initializing the object to +NAN if POS_NAN is set, -NAN
     563              : // if NEG_NAN is set, or +-NAN if both are set.  Otherwise POS_NAN and
     564              : // NEG_NAN are clear, and the object cannot be a NAN.
     565              : 
     566              : inline
     567      3439708 : nan_state::nan_state (bool pos_nan, bool neg_nan)
     568              : {
     569      3439708 :   m_pos_nan = pos_nan;
     570      3428911 :   m_neg_nan = neg_nan;
     571              : }
     572              : 
     573              : // Return if +NAN is possible.
     574              : 
     575              : inline bool
     576     38496387 : nan_state::pos_p () const
     577              : {
     578     38390581 :   return m_pos_nan;
     579              : }
     580              : 
     581              : // Return if -NAN is possible.
     582              : 
     583              : inline bool
     584     38237174 : nan_state::neg_p () const
     585              : {
     586     38184227 :   return m_neg_nan;
     587              : }
     588              : 
     589              : // A sub-range in an frange.
     590              : 
     591              : struct frange_pair
     592              : {
     593              :   REAL_VALUE_TYPE min;
     594              :   REAL_VALUE_TYPE max;
     595              : };
     596              : 
     597              : // A subset of possible values for a floating point type.
     598              : //
     599              : // The representation is a handful of disjoint intervals, unioned with a
     600              : // subset of { -NaN, +NaN }.
     601              : 
     602     26633125 : class frange final : public vrange
     603              : {
     604              :   friend class frange_storage;
     605              :   friend class vrange_printer;
     606              : public:
     607              :   frange ();
     608              :   frange (const frange &);
     609              :   frange (tree, tree, value_range_kind = VR_RANGE);
     610              :   frange (tree type);
     611              :   frange (tree type, const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
     612              :           value_range_kind = VR_RANGE);
     613    502692066 :   static bool supports_p (const_tree type)
     614              :   {
     615              :     // ?? Decimal floats can have multiple representations for the
     616              :     // same number.  Supporting them may be as simple as just
     617              :     // disabling them in singleton_p.  No clue.
     618    502692066 :     return SCALAR_FLOAT_TYPE_P (type) && !DECIMAL_FLOAT_TYPE_P (type);
     619              :   }
     620              :   virtual tree type () const override;
     621              :   void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
     622              :             value_range_kind = VR_RANGE);
     623              :   void set (tree type, const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
     624              :             const nan_state &, value_range_kind = VR_RANGE);
     625              :   void set_nan (tree type);
     626              :   void set_nan (tree type, bool sign);
     627              :   void set_nan (tree type, const nan_state &);
     628              :   virtual void set_varying (tree type) override;
     629              :   virtual void set_undefined () override;
     630              :   virtual bool union_ (const vrange &) override;
     631              :   virtual bool intersect (const vrange &) override;
     632              :   bool contains_p (const REAL_VALUE_TYPE &) const;
     633              :   virtual bool singleton_p (tree *result = NULL) const override;
     634              :   bool singleton_p (REAL_VALUE_TYPE &r) const;
     635              :   virtual bool supports_type_p (const_tree type) const override;
     636              :   virtual void accept (const vrange_visitor &v) const override;
     637              :   virtual bool zero_p () const override;
     638              :   virtual bool contains_zero_p () const override;
     639              :   virtual void set_nonzero (tree type) override;
     640              :   virtual void set_zero (tree type) override;
     641              :   virtual void set_nonnegative (tree type) override;
     642              :   virtual bool fits_p (const vrange &) const override;
     643              :   frange& operator= (const frange &);
     644              :   bool operator== (const frange &) const;
     645     10236670 :   bool operator!= (const frange &r) const { return !(*this == r); }
     646              :   const REAL_VALUE_TYPE &lower_bound () const;
     647              :   const REAL_VALUE_TYPE &upper_bound () const;
     648              :   virtual tree lbound () const override;
     649              :   virtual tree ubound () const override;
     650              :   nan_state get_nan_state () const;
     651              :   void update_nan ();
     652              :   void update_nan (bool sign);
     653              :   void update_nan (tree) = delete; // Disallow silent conversion to bool.
     654              :   void update_nan (const nan_state &);
     655              :   void clear_nan ();
     656              :   void flush_denormals_to_zero ();
     657              : 
     658              :   // fpclassify like API
     659              :   bool known_isfinite () const;
     660              :   bool known_isnan () const;
     661              :   bool known_isinf () const;
     662              :   bool maybe_isnan () const;
     663              :   bool maybe_isnan (bool sign) const;
     664              :   bool maybe_isinf () const;
     665              :   bool signbit_p (bool &signbit) const;
     666              :   bool nan_signbit_p (bool &signbit) const;
     667              :   bool known_isnormal () const;
     668              :   bool known_isdenormal_or_zero () const;
     669              :   virtual void verify_range () const override;
     670              : 
     671              :   static const unsigned int MAX_PAIRS = 2;
     672     34858613 :   unsigned num_pairs () const { return m_num_ranges; }
     673              :   const REAL_VALUE_TYPE &lower_bound (unsigned pair) const;
     674              :   const REAL_VALUE_TYPE &upper_bound (unsigned pair) const;
     675              : 
     676              :   void widen (tree);
     677              : protected:
     678              :   virtual bool contains_p (tree cst) const override;
     679              :   virtual void set (tree, tree, value_range_kind = VR_RANGE) override;
     680              : 
     681              : private:
     682              :   bool internal_singleton_p (REAL_VALUE_TYPE * = NULL) const;
     683              :   bool normalize_kind ();
     684              :   bool union_nans (const frange &);
     685              :   bool intersect_nans (const frange &);
     686              :   void set_pairs (frange_pair *, unsigned);
     687              :   void canonicalize_zeros (frange_pair &);
     688              :   void set_excluding (tree type, const REAL_VALUE_TYPE &,
     689              :                       const REAL_VALUE_TYPE &, const nan_state &);
     690              : 
     691              :   tree m_type;
     692              :   frange_pair m_pairs[MAX_PAIRS];
     693              :   unsigned char m_num_ranges;
     694              :   bool m_pos_nan;
     695              :   bool m_neg_nan;
     696              : };
     697              : 
     698              : inline const REAL_VALUE_TYPE &
     699      6695808 : frange::lower_bound () const
     700              : {
     701      6695808 :   gcc_checking_assert (!undefined_p () && !known_isnan ());
     702      6695808 :   return m_pairs[0].min;
     703              : }
     704              : 
     705              : inline const REAL_VALUE_TYPE &
     706      4865166 : frange::upper_bound () const
     707              : {
     708      4865166 :   gcc_checking_assert (!undefined_p () && !known_isnan ());
     709      4865166 :   return m_pairs[m_num_ranges - 1].max;
     710              : }
     711              : 
     712              : inline const REAL_VALUE_TYPE &
     713     14145412 : frange::lower_bound (unsigned pair) const
     714              : {
     715     14145412 :   gcc_checking_assert (!undefined_p () && !known_isnan ());
     716     14145412 :   gcc_checking_assert (pair < m_num_ranges);
     717     14145412 :   return m_pairs[pair].min;
     718              : }
     719              : 
     720              : inline const REAL_VALUE_TYPE &
     721     14145412 : frange::upper_bound (unsigned pair) const
     722              : {
     723     14145412 :   gcc_checking_assert (!undefined_p () && !known_isnan ());
     724     14145412 :   gcc_checking_assert (pair < m_num_ranges);
     725     14145412 :   return m_pairs[pair].max;
     726              : }
     727              : 
     728              : // Return the NAN state.
     729              : 
     730              : inline nan_state
     731      1135212 : frange::get_nan_state () const
     732              : {
     733      1135212 :   return nan_state (m_pos_nan, m_neg_nan);
     734              : }
     735              : 
     736              : // is_a<> and as_a<> implementation for vrange.
     737              : 
     738              : // Anything we haven't specialized is a hard fail.
     739              : template <typename T>
     740              : inline bool
     741              : is_a (vrange &)
     742              : {
     743              :   gcc_unreachable ();
     744              :   return false;
     745              : }
     746              : 
     747              : template <typename T>
     748              : inline bool
     749   4530585018 : is_a (const vrange &v)
     750              : {
     751              :   // Reuse is_a <vrange> to implement the const version.
     752   4742150827 :   const T &derived = static_cast<const T &> (v);
     753   2060206347 :   return is_a <T> (const_cast<T &> (derived));
     754              : }
     755              : 
     756              : template <typename T>
     757              : inline T &
     758   2681663314 : as_a (vrange &v)
     759              : {
     760            0 :   gcc_checking_assert (is_a <T> (v));
     761   2681663314 :   return static_cast <T &> (v);
     762              : }
     763              : 
     764              : template <typename T>
     765              : inline const T &
     766   3874955166 : as_a (const vrange &v)
     767              : {
     768            0 :   gcc_checking_assert (is_a <T> (v));
     769   3874955166 :   return static_cast <const T &> (v);
     770              : }
     771              : 
     772              : // Specializations for the different range types.
     773              : 
     774              : template <>
     775              : inline bool
     776   7661820494 : is_a <irange> (vrange &v)
     777              : {
     778   7530144929 :   return v.m_discriminator == VR_IRANGE;
     779              : }
     780              : 
     781              : template <>
     782              : inline bool
     783   1538913373 : is_a <prange> (vrange &v)
     784              : {
     785   1393053087 :   return v.m_discriminator == VR_PRANGE;
     786              : }
     787              : 
     788              : template <>
     789              : inline bool
     790    217822069 : is_a <frange> (vrange &v)
     791              : {
     792    217822069 :   return v.m_discriminator == VR_FRANGE;
     793              : }
     794              : 
     795              : template <>
     796              : inline bool
     797       652680 : is_a <unsupported_range> (vrange &v)
     798              : {
     799       652680 :   return v.m_discriminator == VR_UNKNOWN;
     800              : }
     801              : 
     802              : // For resizable ranges, resize the range up to HARD_MAX_RANGES if the
     803              : // NEEDED pairs is greater than the current capacity of the range.
     804              : 
     805              : inline void
     806   1387072194 : irange::maybe_resize (int needed)
     807              : {
     808   1387072194 :   if (!m_resizable || m_max_ranges == HARD_MAX_RANGES)
     809              :     return;
     810              : 
     811    895472703 :   if (needed > m_max_ranges)
     812              :     {
     813     65277876 :       m_max_ranges = HARD_MAX_RANGES;
     814  33356994636 :       wide_int *newmem = new wide_int[m_max_ranges * 2];
     815     65277876 :       unsigned n = num_pairs () * 2;
     816    374343690 :       for (unsigned i = 0; i < n; ++i)
     817    309065814 :         newmem[i] = m_base[i];
     818     65277876 :       m_base = newmem;
     819              :     }
     820              : }
     821              : 
     822              : template<unsigned N, bool RESIZABLE>
     823              : inline
     824   5332747412 : int_range<N, RESIZABLE>::~int_range ()
     825              : {
     826   3963860644 :   if (RESIZABLE && m_base != m_ranges)
     827  33356994636 :     delete[] m_base;
     828  33084606972 : }
     829              : 
     830              : // This is an "infinite" precision irange for use in temporary
     831              : // calculations.  It starts with a sensible default covering 99% of
     832              : // uses, and goes up to HARD_MAX_RANGES when needed.  Any allocated
     833              : // storage is freed upon destruction.
     834              : typedef int_range<3, /*RESIZABLE=*/true> int_range_max;
     835              : 
     836        40713 : class vrange_visitor
     837              : {
     838              : public:
     839            0 :   virtual void visit (const irange &) const { }
     840            0 :   virtual void visit (const prange &) const { }
     841            0 :   virtual void visit (const frange &) const { }
     842            0 :   virtual void visit (const unsupported_range &) const { }
     843              : };
     844              : 
     845              : // This is an "infinite" precision range object for use in temporary
     846              : // calculations for any of the handled types.  The object can be
     847              : // transparently used as a vrange.
     848              : //
     849              : // Using any of the various constructors initializes the object
     850              : // appropriately, but the default constructor is uninitialized and
     851              : // must be initialized either with set_range_class() or by assigning into it.
     852              : //
     853              : // Assigning between incompatible types is allowed.  For example if a
     854              : // temporary holds an irange, you can assign an frange into it, and
     855              : // all the right things will happen.  However, before passing this
     856              : // object to a function accepting a vrange, the correct type must be
     857              : // set.  If it isn't, you can do so with set_range_class().
     858              : 
     859              : class value_range
     860              : {
     861              : public:
     862              :   value_range ();
     863              :   value_range (const vrange &r);
     864              :   value_range (tree type);
     865              :   value_range (tree, tree, value_range_kind kind = VR_RANGE);
     866              :   value_range (const value_range &);
     867              :   ~value_range ();
     868              :   void set_range_class (tree type);
     869              :   vrange& operator= (const vrange &);
     870              :   value_range& operator= (const value_range &);
     871              :   bool operator== (const value_range &r) const;
     872              :   bool operator!= (const value_range &r) const;
     873              :   operator vrange &();
     874              :   operator const vrange &() const;
     875              :   void dump (FILE *) const;
     876              :   void print (pretty_printer *) const;
     877              :   static bool supports_type_p (const_tree type);
     878              : 
     879      3554184 :   tree type () { return m_vrange->type (); }
     880    156982068 :   bool varying_p () const { return m_vrange->varying_p (); }
     881    161611700 :   bool undefined_p () const { return m_vrange->undefined_p (); }
     882    328138911 :   void set_varying (tree type) { init (type); m_vrange->set_varying (type); }
     883     23233480 :   void set_undefined () { m_vrange->set_undefined (); }
     884     18667579 :   bool union_ (const vrange &r) { return m_vrange->union_ (r); }
     885    100649796 :   bool intersect (const vrange &r) { return m_vrange->intersect (r); }
     886      1537352 :   bool contains_p (tree cst) const { return m_vrange->contains_p (cst); }
     887    379532976 :   bool singleton_p (tree *result = NULL) const
     888    379532976 :     { return m_vrange->singleton_p (result); }
     889              :   void set_zero (tree type) { init (type); return m_vrange->set_zero (type); }
     890            0 :   void set_nonzero (tree type)
     891            0 :     { init (type); return m_vrange->set_nonzero (type); }
     892       267738 :   bool contains_zero_p () const { return m_vrange->contains_zero_p (); }
     893         4718 :   bool zero_p () const { return m_vrange->zero_p (); }
     894     10949306 :   tree lbound () const { return m_vrange->lbound (); }
     895       351760 :   tree ubound () const { return m_vrange->ubound (); }
     896       513823 :   irange_bitmask get_bitmask () const { return m_vrange->get_bitmask (); }
     897      1445670 :   void update_bitmask (const class irange_bitmask &bm)
     898      1445670 :   { return m_vrange->update_bitmask (bm); }
     899         2815 :   void accept (const vrange_visitor &v) const { m_vrange->accept (v); }
     900              :   void verify_range () const { m_vrange->verify_range (); }
     901              : private:
     902              :   void init (tree type);
     903              :   void init (const vrange &);
     904              : 
     905              :   vrange *m_vrange;
     906              :   union buffer_type {
     907              :     int_range_max ints;
     908              :     frange floats;
     909              :     unsupported_range unsupported;
     910              :     prange pointers;
     911   7101885211 :     buffer_type () { }
     912   7231141007 :     ~buffer_type () { }
     913              :   } m_buffer;
     914              : };
     915              : 
     916              : // The default constructor is uninitialized and must be initialized
     917              : // with either set_range_class() or with an assignment into it.
     918              : 
     919              : inline
     920   4024801103 : value_range::value_range ()
     921   4024801103 :   : m_buffer ()
     922              : {
     923   4024801103 :   m_vrange = NULL;
     924              : }
     925              : 
     926              : // Copy constructor.
     927              : 
     928              : inline
     929     12415140 : value_range::value_range (const value_range &r)
     930              : {
     931     12415140 :   init (*r.m_vrange);
     932              : }
     933              : 
     934              : // Copy constructor from a vrange.
     935              : 
     936              : inline
     937     84434398 : value_range::value_range (const vrange &r)
     938              : {
     939     84434398 :   init (r);
     940              : }
     941              : 
     942              : // Construct an UNDEFINED range that can hold ranges of TYPE.  If TYPE
     943              : // is not supported, default to unsupported_range.
     944              : 
     945              : inline
     946   2980181238 : value_range::value_range (tree type)
     947              : {
     948   2796932756 :   init (type);
     949              : }
     950              : 
     951              : // Construct a range that can hold a range of [MIN, MAX], where MIN
     952              : // and MAX are trees.
     953              : 
     954              : inline
     955        53332 : value_range::value_range (tree min, tree max, value_range_kind kind)
     956              : {
     957        53332 :   init (TREE_TYPE (min));
     958        53332 :   m_vrange->set (min, max, kind);
     959        53332 : }
     960              : 
     961              : inline
     962   7231141007 : value_range::~value_range ()
     963              : {
     964   7231141007 :   if (m_vrange)
     965   3355793385 :     m_vrange->~vrange ();
     966   7231141007 : }
     967              : 
     968              : // Initialize object to an UNDEFINED range that can hold ranges of
     969              : // TYPE.  Clean-up memory if there was a previous object.
     970              : // Note that this does *not* set the type of the underlying vrange.
     971              : 
     972              : inline void
     973    106602580 : value_range::set_range_class (tree type)
     974              : {
     975    106602580 :   if (m_vrange)
     976      9142874 :     m_vrange->~vrange ();
     977    106602580 :   init (type);
     978    106602580 : }
     979              : 
     980              : // Initialize object to an UNDEFINED range that can hold ranges of
     981              : // TYPE.
     982              : // Note that this does *not* set the type of the underlying vrange.
     983              : 
     984              : inline void
     985   3414976061 : value_range::init (tree type)
     986              : {
     987   3414976061 :   gcc_checking_assert (TYPE_P (type));
     988              : 
     989   3414976061 :   if (irange::supports_p (type))
     990   2415683479 :     m_vrange = new (&m_buffer.ints) int_range_max ();
     991    999292582 :   else if (prange::supports_p (type))
     992    816717436 :     m_vrange = new (&m_buffer.pointers) prange ();
     993    182575146 :   else if (frange::supports_p (type))
     994    107756272 :     m_vrange = new (&m_buffer.floats) frange ();
     995              :   else
     996     74818874 :     m_vrange = new (&m_buffer.unsupported) unsupported_range ();
     997   3414976061 : }
     998              : 
     999              : // Initialize object with a copy of R.
    1000              : 
    1001              : inline void
    1002    131236886 : value_range::init (const vrange &r)
    1003              : {
    1004    131236886 :   if (is_a <irange> (r))
    1005     78549127 :     m_vrange = new (&m_buffer.ints) int_range_max (as_a <irange> (r));
    1006     52687759 :   else if (is_a <prange> (r))
    1007    103639564 :     m_vrange = new (&m_buffer.pointers) prange (as_a <prange> (r));
    1008       867977 :   else if (is_a <frange> (r))
    1009       430594 :     m_vrange = new (&m_buffer.floats) frange (as_a <frange> (r));
    1010              :   else
    1011      1305360 :     m_vrange = new (&m_buffer.unsupported)
    1012       652680 :       unsupported_range (as_a <unsupported_range> (r));
    1013    131236886 : }
    1014              : 
    1015              : // Assignment operator.  Copying incompatible types is allowed.  That
    1016              : // is, assigning an frange to an object holding an irange does the
    1017              : // right thing.
    1018              : 
    1019              : inline vrange &
    1020     34387348 : value_range::operator= (const vrange &r)
    1021              : {
    1022     34387348 :   if (m_vrange)
    1023     10327787 :     m_vrange->~vrange ();
    1024     34387348 :   init (r);
    1025     34387348 :   return *m_vrange;
    1026              : }
    1027              : 
    1028              : inline value_range &
    1029     10381091 : value_range::operator= (const value_range &r)
    1030              : {
    1031              :   // No need to call the m_vrange destructor here, as we will do so in
    1032              :   // the assignment below.
    1033      1513805 :   *this = *r.m_vrange;
    1034     10381091 :   return *this;
    1035              : }
    1036              : 
    1037              : inline bool
    1038     26064012 : value_range::operator== (const value_range &r) const
    1039              : {
    1040     26064012 :   return *m_vrange == *r.m_vrange;
    1041              : }
    1042              : 
    1043              : inline bool
    1044     13603733 : value_range::operator!= (const value_range &r) const
    1045              : {
    1046     13603733 :   return *m_vrange != *r.m_vrange;
    1047              : }
    1048              : 
    1049              : inline
    1050   4940343904 : value_range::operator vrange &()
    1051              : {
    1052   4634883066 :   return *m_vrange;
    1053              : }
    1054              : 
    1055              : inline
    1056     44773019 : value_range::operator const vrange &() const
    1057              : {
    1058     44773019 :   return *m_vrange;
    1059              : }
    1060              : 
    1061              : // Return TRUE if TYPE is supported by the vrange infrastructure.
    1062              : 
    1063              : inline bool
    1064   6280551327 : value_range::supports_type_p (const_tree type)
    1065              : {
    1066   6280551327 :   return irange::supports_p (type)
    1067   1610611190 :     || prange::supports_p (type)
    1068    235695063 :     || frange::supports_p (type);
    1069              : }
    1070              : 
    1071              : extern value_range_kind get_legacy_range (const vrange &, tree &min, tree &max);
    1072              : extern void dump_value_range (FILE *, const vrange *);
    1073              : extern bool vrp_operand_equal_p (const_tree, const_tree);
    1074              : inline REAL_VALUE_TYPE frange_val_min (const_tree type);
    1075              : inline REAL_VALUE_TYPE frange_val_max (const_tree type);
    1076              : 
    1077              : // Number of sub-ranges in a range.
    1078              : 
    1079              : inline unsigned
    1080  34942808959 : irange::num_pairs () const
    1081              : {
    1082   5726313754 :   return m_num_ranges;
    1083              : }
    1084              : 
    1085              : inline tree
    1086  12237903652 : irange::type () const
    1087              : {
    1088  12237903652 :   gcc_checking_assert (m_num_ranges > 0);
    1089  12237903652 :   return m_type;
    1090              : }
    1091              : 
    1092              : inline bool
    1093   5221972336 : irange::varying_compatible_p () const
    1094              : {
    1095   5221972336 :   if (m_num_ranges != 1)
    1096              :     return false;
    1097              : 
    1098   3892640146 :   const wide_int &l = m_base[0];
    1099   3892640146 :   const wide_int &u = m_base[1];
    1100   3892640146 :   tree t = m_type;
    1101              : 
    1102   3892640146 :   if (m_kind == VR_VARYING)
    1103              :     return true;
    1104              : 
    1105   3633688391 :   unsigned prec = TYPE_PRECISION (t);
    1106   3633688391 :   signop sign = TYPE_SIGN (t);
    1107   3633688391 :   if (INTEGRAL_TYPE_P (t) || POINTER_TYPE_P (t))
    1108   7267376782 :     return (l == wi::min_value (prec, sign)
    1109   4748382167 :             && u == wi::max_value (prec, sign)
    1110   3640756780 :             && m_bitmask.unknown_p ());
    1111              :   return true;
    1112              : }
    1113              : 
    1114              : inline bool
    1115   1064174278 : vrange::varying_p () const
    1116              : {
    1117   1060434687 :   return m_kind == VR_VARYING;
    1118              : }
    1119              : 
    1120              : inline bool
    1121  22535710467 : vrange::undefined_p () const
    1122              : {
    1123  12201595524 :   return m_kind == VR_UNDEFINED;
    1124              : }
    1125              : 
    1126              : inline bool
    1127    225290631 : irange::zero_p () const
    1128              : {
    1129    212816444 :   return (m_kind == VR_RANGE && m_num_ranges == 1
    1130    413814854 :           && lower_bound (0) == 0
    1131    438107092 :           && upper_bound (0) == 0);
    1132              : }
    1133              : 
    1134              : inline bool
    1135     28297670 : irange::contains_zero_p () const
    1136              : {
    1137     28297670 :   if (undefined_p ())
    1138              :     return false;
    1139              : 
    1140     28297670 :   wide_int zero = wi::zero (TYPE_PRECISION (type ()));
    1141     28297670 :   return contains_p (zero);
    1142     28297670 : }
    1143              : 
    1144              : inline bool
    1145  15942336517 : irange::supports_p (const_tree type)
    1146              : {
    1147  15055458610 :   return INTEGRAL_TYPE_P (type);
    1148              : }
    1149              : 
    1150              : inline bool
    1151     72697453 : irange::contains_p (tree cst) const
    1152              : {
    1153     72697453 :   return contains_p (wi::to_wide (cst));
    1154              : }
    1155              : 
    1156              : inline bool
    1157     37583962 : range_includes_zero_p (const vrange &vr)
    1158              : {
    1159     37583962 :   if (vr.undefined_p ())
    1160              :     return false;
    1161              : 
    1162     37583962 :   if (vr.varying_p ())
    1163              :     return true;
    1164              : 
    1165     28628585 :   return vr.contains_p (build_zero_cst (vr.type ()));
    1166              : }
    1167              : 
    1168              : // Constructors for irange
    1169              : 
    1170              : inline
    1171   5454734342 : irange::irange (wide_int *base, unsigned nranges, bool resizable)
    1172              :   : vrange (VR_IRANGE),
    1173   5454734342 :     m_resizable (resizable),
    1174   5454734342 :     m_max_ranges (nranges)
    1175              : {
    1176   5454734342 :   m_base = base;
    1177   5454734342 :   set_undefined ();
    1178              : }
    1179              : 
    1180              : // Constructors for int_range<>.
    1181              : 
    1182              : template<unsigned N, bool RESIZABLE>
    1183              : inline
    1184   4083229515 : int_range<N, RESIZABLE>::int_range ()
    1185  27862344963 :   : irange (m_ranges, N, RESIZABLE)
    1186              : {
    1187   4083229515 : }
    1188              : 
    1189              : template<unsigned N, bool RESIZABLE>
    1190       419516 : int_range<N, RESIZABLE>::int_range (const int_range &other)
    1191      2936604 :   : irange (m_ranges, N, RESIZABLE)
    1192              : {
    1193       419516 :   irange::operator= (other);
    1194       419516 : }
    1195              : 
    1196              : template<unsigned N, bool RESIZABLE>
    1197              : int_range<N, RESIZABLE>::int_range (tree min, tree max, value_range_kind kind)
    1198              :   : irange (m_ranges, N, RESIZABLE)
    1199              : {
    1200              :   irange::set (min, max, kind);
    1201              : }
    1202              : 
    1203              : template<unsigned N, bool RESIZABLE>
    1204    166172926 : int_range<N, RESIZABLE>::int_range (tree type)
    1205    657973872 :   : irange (m_ranges, N, RESIZABLE)
    1206              : {
    1207    166172926 :   set_varying (type);
    1208    166172926 : }
    1209              : 
    1210              : template<unsigned N, bool RESIZABLE>
    1211    805011316 : int_range<N, RESIZABLE>::int_range (tree type, const wide_int &wmin, const wide_int &wmax,
    1212              :                          value_range_kind kind)
    1213   2787184356 :   : irange (m_ranges, N, RESIZABLE)
    1214              : {
    1215    805011316 :   set (type, wmin, wmax, kind);
    1216    805011316 : }
    1217              : 
    1218              : template<unsigned N, bool RESIZABLE>
    1219    399901069 : int_range<N, RESIZABLE>::int_range (const irange &other)
    1220   2562797811 :   : irange (m_ranges, N, RESIZABLE)
    1221              : {
    1222    399901069 :   irange::operator= (other);
    1223    399901069 : }
    1224              : 
    1225              : template<unsigned N, bool RESIZABLE>
    1226              : int_range<N, RESIZABLE>&
    1227     67079919 : int_range<N, RESIZABLE>::operator= (const int_range &src)
    1228              : {
    1229     67072451 :   irange::operator= (src);
    1230            0 :   return *this;
    1231              : }
    1232              : 
    1233              : inline void
    1234   5834379364 : irange::set_undefined ()
    1235              : {
    1236   5834379364 :   m_kind = VR_UNDEFINED;
    1237   5740984965 :   m_num_ranges = 0;
    1238    374689144 : }
    1239              : 
    1240              : inline void
    1241   1252730277 : irange::set_varying (tree type)
    1242              : {
    1243   1252730277 :   m_kind = VR_VARYING;
    1244   1252730277 :   m_num_ranges = 1;
    1245   1252730277 :   m_bitmask.set_unknown (TYPE_PRECISION (type));
    1246              : 
    1247   1252730277 :   if (INTEGRAL_TYPE_P (type) || POINTER_TYPE_P (type))
    1248              :     {
    1249   1252730277 :       m_type = type;
    1250              :       // Strict enum's require varying to be not TYPE_MIN/MAX, but rather
    1251              :       // min_value and max_value.
    1252   1252730277 :       m_base[0] = wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
    1253   1252745093 :       m_base[1] = wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
    1254              :     }
    1255              :   else
    1256            0 :     m_type = error_mark_node;
    1257   1252730277 : }
    1258              : 
    1259              : // Return the lower bound of a sub-range.  PAIR is the sub-range in
    1260              : // question.
    1261              : 
    1262              : inline wide_int
    1263  12022707553 : irange::lower_bound (unsigned pair) const
    1264              : {
    1265  12022707553 :   gcc_checking_assert (m_num_ranges > 0);
    1266  12022707553 :   gcc_checking_assert (pair + 1 <= num_pairs ());
    1267  12022707553 :   return m_base[pair * 2];
    1268              : }
    1269              : 
    1270              : // Return the upper bound of a sub-range.  PAIR is the sub-range in
    1271              : // question.
    1272              : 
    1273              : inline wide_int
    1274  13780035945 : irange::upper_bound (unsigned pair) const
    1275              : {
    1276  13780035945 :   gcc_checking_assert (m_num_ranges > 0);
    1277  13780035945 :   gcc_checking_assert (pair + 1 <= num_pairs ());
    1278  13780035945 :   return m_base[pair * 2 + 1];
    1279              : }
    1280              : 
    1281              : // Return the highest bound of a range.
    1282              : 
    1283              : inline wide_int
    1284   3689561024 : irange::upper_bound () const
    1285              : {
    1286   3689561024 :   unsigned pairs = num_pairs ();
    1287   3689561024 :   gcc_checking_assert (pairs > 0);
    1288   3689561024 :   return upper_bound (pairs - 1);
    1289              : }
    1290              : 
    1291              : // Set value range VR to a nonzero range of type TYPE.
    1292              : 
    1293              : inline void
    1294      3745009 : irange::set_nonzero (tree type)
    1295              : {
    1296      3745009 :   unsigned prec = TYPE_PRECISION (type);
    1297              : 
    1298      3745009 :   if (TYPE_UNSIGNED (type))
    1299              :     {
    1300      3330040 :       m_type = type;
    1301      3330040 :       m_kind = VR_RANGE;
    1302      3330040 :       m_base[0] = wi::one (prec);
    1303      3330040 :       m_base[1] = wi::minus_one (prec);
    1304      3330040 :       m_bitmask.set_unknown (prec);
    1305      3330040 :       m_num_ranges = 1;
    1306              : 
    1307      3330040 :       if (flag_checking)
    1308      3330040 :         verify_range ();
    1309              :     }
    1310              :   else
    1311              :     {
    1312       414969 :       wide_int zero = wi::zero (prec);
    1313       414969 :       set (type, zero, zero, VR_ANTI_RANGE);
    1314       414969 :     }
    1315      3745009 : }
    1316              : 
    1317              : // Set value range VR to a ZERO range of type TYPE.
    1318              : 
    1319              : inline void
    1320      3431173 : irange::set_zero (tree type)
    1321              : {
    1322      3431173 :   wide_int zero = wi::zero (TYPE_PRECISION (type));
    1323      3431173 :   set (type, zero, zero);
    1324      3431173 : }
    1325              : 
    1326              : // Normalize a range to VARYING or UNDEFINED if possible.
    1327              : 
    1328              : inline void
    1329    578875352 : irange::normalize_kind ()
    1330              : {
    1331    578875352 :   if (m_num_ranges == 0)
    1332        18653 :     set_undefined ();
    1333    578856699 :   else if (varying_compatible_p ())
    1334              :     {
    1335     27941000 :       if (m_kind == VR_RANGE)
    1336      6915776 :         m_kind = VR_VARYING;
    1337     21025224 :       else if (m_kind == VR_ANTI_RANGE)
    1338            0 :         set_undefined ();
    1339              :     }
    1340    578875352 :   if (flag_checking)
    1341    578874509 :     verify_range ();
    1342    578875352 : }
    1343              : 
    1344              : inline wide_int
    1345     95539601 : irange_val_min (const_tree type)
    1346              : {
    1347     95539601 :   gcc_checking_assert (irange::supports_p (type));
    1348     95539601 :   return wi::min_value (TYPE_PRECISION (type), TYPE_SIGN (type));
    1349              : }
    1350              : 
    1351              : inline wide_int
    1352     93486638 : irange_val_max (const_tree type)
    1353              : {
    1354     93486638 :   gcc_checking_assert (irange::supports_p (type));
    1355     93486638 :   return wi::max_value (TYPE_PRECISION (type), TYPE_SIGN (type));
    1356              : }
    1357              : 
    1358              : inline
    1359    980759568 : prange::prange ()
    1360    980759568 :   : vrange (VR_PRANGE)
    1361              : {
    1362    980759568 :   set_undefined ();
    1363              : }
    1364              : 
    1365              : inline
    1366    126418462 : prange::prange (const prange &r)
    1367    126418462 :   : vrange (VR_PRANGE)
    1368              : {
    1369    126418462 :   *this = r;
    1370              : }
    1371              : 
    1372              : inline
    1373    160202345 : prange::prange (tree type)
    1374    160202345 :   : vrange (VR_PRANGE)
    1375              : {
    1376    160202345 :   set_varying (type);
    1377              : }
    1378              : 
    1379              : inline
    1380      3224828 : prange::prange (tree type, const wide_int &lb, const wide_int &ub,
    1381              :                 value_range_kind kind)
    1382      3224828 :   : vrange (VR_PRANGE)
    1383              : {
    1384      3224828 :   set (type, lb, ub, kind);
    1385              : }
    1386              : 
    1387              : inline bool
    1388   4240157540 : prange::supports_p (const_tree type)
    1389              : {
    1390   4240157540 :   return POINTER_TYPE_P (type);
    1391              : }
    1392              : 
    1393              : inline bool
    1394    494942284 : prange::supports_type_p (const_tree type) const
    1395              : {
    1396    494942284 :   return POINTER_TYPE_P (type);
    1397              : }
    1398              : 
    1399              : inline void
    1400   1114647546 : prange::set_undefined ()
    1401              : {
    1402   1114647546 :   m_kind = VR_UNDEFINED;
    1403   1114647546 :   set_pt_unknown ();
    1404    132420364 : }
    1405              : 
    1406              : inline void
    1407    650182605 : prange::set_varying (tree type)
    1408              : {
    1409    650182605 :   m_kind = VR_VARYING;
    1410    650182605 :   m_type = type;
    1411    650182605 :   m_min = wi::zero (TYPE_PRECISION (type));
    1412    650182605 :   m_max = wi::max_value (TYPE_PRECISION (type), UNSIGNED);
    1413    650182605 :   m_bitmask.set_unknown (TYPE_PRECISION (type));
    1414    650182605 :   set_pt_unknown ();
    1415              : 
    1416    650182605 :   if (flag_checking)
    1417    650182482 :     verify_range ();
    1418    650182605 : }
    1419              : 
    1420              : inline void
    1421    382814921 : prange::set_nonzero (tree type)
    1422              : {
    1423    382814921 :   m_kind = VR_RANGE;
    1424    382814921 :   m_type = type;
    1425    382814921 :   m_min = wi::one (TYPE_PRECISION (type));
    1426    382814921 :   m_max = wi::max_value (TYPE_PRECISION (type), UNSIGNED);
    1427    382814921 :   m_bitmask.set_unknown (TYPE_PRECISION (type));
    1428    382814921 :   set_pt_unknown ();
    1429              : 
    1430    382814921 :   if (flag_checking)
    1431    382814564 :     verify_range ();
    1432    382814921 : }
    1433              : 
    1434              : inline void
    1435       856096 : prange::set_zero (tree type)
    1436              : {
    1437       856096 :   m_kind = VR_RANGE;
    1438       856096 :   m_type = type;
    1439       856096 :   wide_int zero = wi::zero (TYPE_PRECISION (type));
    1440       856096 :   m_min = m_max = zero;
    1441       856096 :   m_bitmask = irange_bitmask (zero, zero);
    1442       856096 :   set_pt_unknown ();
    1443              : 
    1444       856096 :   if (flag_checking)
    1445       856096 :     verify_range ();
    1446       856096 : }
    1447              : 
    1448              : inline bool
    1449       665693 : prange::contains_p (tree cst) const
    1450              : {
    1451       665693 :   return contains_p (wi::to_wide (cst));
    1452              : }
    1453              : 
    1454              : inline bool
    1455    266706429 : prange::zero_p () const
    1456              : {
    1457    266706429 :   bool ret = m_kind == VR_RANGE && m_min == 0 && m_max == 0;
    1458    266706429 :   return ret;
    1459              : }
    1460              : 
    1461              : inline bool
    1462     53696388 : prange::contains_zero_p () const
    1463              : {
    1464     53696388 :   if (undefined_p ())
    1465              :     return false;
    1466              : 
    1467     52771243 :   wide_int zero = wi::zero (TYPE_PRECISION (type ()));
    1468     52771243 :   return contains_p (zero);
    1469     52771243 : }
    1470              : 
    1471              : inline tree
    1472   2780580892 : prange::type () const
    1473              : {
    1474   2780580892 :   gcc_checking_assert (!undefined_p ());
    1475   2780580892 :   return m_type;
    1476              : }
    1477              : 
    1478              : inline wide_int
    1479    651561234 : prange::lower_bound () const
    1480              : {
    1481    651561234 :   gcc_checking_assert (!undefined_p ());
    1482    651561234 :   return m_min;
    1483              : }
    1484              : 
    1485              : inline wide_int
    1486    613280596 : prange::upper_bound () const
    1487              : {
    1488    613280596 :   gcc_checking_assert (!undefined_p ());
    1489    613280596 :   return m_max;
    1490              : }
    1491              : 
    1492              : inline bool
    1493   1860740816 : prange::varying_compatible_p () const
    1494              : {
    1495   1860740800 :   return (!undefined_p () && m_min == 0 && m_max == -1
    1496   3321707202 :           && get_bitmask ().unknown_p () && pt_unknown_p ());
    1497              : }
    1498              : 
    1499              : inline irange_bitmask
    1500   1035002868 : prange::get_bitmask () const
    1501              : {
    1502   1035002868 :   return m_bitmask;
    1503              : }
    1504              : 
    1505              : inline bool
    1506            0 : prange::fits_p (const vrange &) const
    1507              : {
    1508            0 :   return true;
    1509              : }
    1510              : 
    1511              : // Set this range's point-to object to PTR, and POINTS_TO_P is TRUE if it
    1512              : // does point to it, and FALSE if it does not point to it.
    1513              : 
    1514              : inline void
    1515    212350293 : prange::set_pt (const prange &r)
    1516              : {
    1517              :   // Do not set points-to info if this is zero or undefined.
    1518     14723589 :   if (!r.pt_unknown_p () && (undefined_p () || zero_p()))
    1519              :     return;
    1520              : 
    1521    212350291 :   m_pt = r.m_pt;
    1522    212350291 :   m_points_to_p = r.m_points_to_p;
    1523              : 
    1524    212350291 :   if (r.undefined_p ())
    1525              :     return;
    1526              :   // Check whether this is now VARYING or not.
    1527    212284677 :   if (varying_compatible_p ())
    1528     28002481 :     set_varying (type ());
    1529              :   else
    1530    184282196 :     m_kind = VR_RANGE;
    1531              : }
    1532              : 
    1533              : // prange_pt methods.
    1534              : // ------------------------------------------------------------------
    1535              : 
    1536              : inline void
    1537   2193278232 : prange::set_pt_unknown ()
    1538              : {
    1539   2193278232 :   m_pt = NULL_TREE;
    1540   2060857868 :   m_points_to_p = false;
    1541              : }
    1542              : 
    1543              : inline bool
    1544   1935520113 : prange::pt_unknown_p () const
    1545              : {
    1546   1876562679 :   return (m_pt == NULL_TREE);
    1547              : }
    1548              : 
    1549              : inline bool
    1550     68649894 : prange::pt_equal_p (const prange &p) const
    1551              : {
    1552              :   // A prange object invokes vrp_operand_equal_p as we want ranges to compare
    1553              :   // equal to each other if they refer to the same object, even if the
    1554              :   // tree has become unshared.
    1555     68649894 :   return (m_points_to_p == p.m_points_to_p
    1556     68649894 :           && vrp_operand_equal_p (m_pt, p.m_pt));
    1557              : }
    1558              : 
    1559              : inline bool
    1560     75033609 : prange::pt_inverted_p (const prange &r) const
    1561              : {
    1562       491134 :   return m_pt && vrp_operand_equal_p (m_pt, r.m_pt)
    1563     75151367 :          && m_points_to_p != r.m_points_to_p;
    1564              : }
    1565              : 
    1566              : inline bool
    1567      2744224 : prange::pt_invert ()
    1568              : {
    1569      2744224 :   if (m_pt)
    1570              :     {
    1571            0 :       m_points_to_p = !m_points_to_p;
    1572            0 :       return true;
    1573              :     }
    1574              :   return false;
    1575              : }
    1576              : 
    1577              : inline tree
    1578     84302626 : prange::pt_invariant () const
    1579              : {
    1580     84302626 :   if (m_pt && m_points_to_p)
    1581         7283 :     return m_pt;
    1582              :   return NULL_TREE;
    1583              : }
    1584              : 
    1585              : inline tree
    1586      1693507 : prange::pt_invariant_away () const
    1587              : {
    1588      1693507 :   if (m_pt && !m_points_to_p)
    1589            0 :     return m_pt;
    1590              :   return NULL_TREE;
    1591              : }
    1592              : 
    1593              : inline bool
    1594     18367135 : prange::pt_invariant_p (const prange &r) const
    1595              : {
    1596       209016 :   if (m_pt && m_points_to_p && vrp_operand_equal_p (r.m_pt, m_pt)
    1597     18385328 :       && m_points_to_p == r.m_points_to_p)
    1598        18193 :     return true;
    1599              :   return false;
    1600              : }
    1601              : 
    1602              : inline bool
    1603              : prange::pt_invariant_away_p (const prange &r) const
    1604              : {
    1605              :   if (m_pt && !m_points_to_p && vrp_operand_equal_p (r.m_pt, m_pt)
    1606              :       && m_points_to_p == r.m_points_to_p)
    1607              :     return true;
    1608              :   return false;
    1609              : }
    1610              : 
    1611              : 
    1612              : // -----------------------------------------------------------------------
    1613              : 
    1614              : inline
    1615    118360932 : frange::frange ()
    1616    118360932 :   : vrange (VR_FRANGE)
    1617              : {
    1618    118360868 :   set_undefined ();
    1619              : }
    1620              : 
    1621              : inline
    1622     13275120 : frange::frange (const frange &src)
    1623     13275120 :   : vrange (VR_FRANGE)
    1624              : {
    1625     12850526 :   *this = src;
    1626              : }
    1627              : 
    1628              : inline
    1629       789089 : frange::frange (tree type)
    1630       789089 :   : vrange (VR_FRANGE)
    1631              : {
    1632       789089 :   set_varying (type);
    1633              : }
    1634              : 
    1635              : // frange constructor from REAL_VALUE_TYPE endpoints.
    1636              : 
    1637              : inline
    1638     17414318 : frange::frange (tree type,
    1639              :                 const REAL_VALUE_TYPE &min, const REAL_VALUE_TYPE &max,
    1640              :                 value_range_kind kind)
    1641     17414318 :   : vrange (VR_FRANGE)
    1642              : {
    1643     17414318 :   set (type, min, max, kind);
    1644              : }
    1645              : 
    1646              : // frange constructor from trees.
    1647              : 
    1648              : inline
    1649              : frange::frange (tree min, tree max, value_range_kind kind)
    1650              :   : vrange (VR_FRANGE)
    1651              : {
    1652              :   set (min, max, kind);
    1653              : }
    1654              : 
    1655              : inline tree
    1656     71920393 : frange::type () const
    1657              : {
    1658     71920393 :   gcc_checking_assert (!undefined_p ());
    1659     71920393 :   return m_type;
    1660              : }
    1661              : 
    1662              : inline void
    1663     72742872 : frange::set_varying (tree type)
    1664              : {
    1665     72742872 :   m_kind = VR_VARYING;
    1666     72742872 :   m_type = type;
    1667     72742872 :   m_num_ranges = 1;
    1668     72742872 :   m_pairs[0].min = frange_val_min (type);
    1669     72742872 :   m_pairs[0].max = frange_val_max (type);
    1670     72742872 :   if (HONOR_NANS (m_type))
    1671              :     {
    1672              :       m_pos_nan = true;
    1673              :       m_neg_nan = true;
    1674              :     }
    1675              :   else
    1676              :     {
    1677      4115505 :       m_pos_nan = false;
    1678      4115505 :       m_neg_nan = false;
    1679              :     }
    1680     72742872 : }
    1681              : 
    1682              : inline void
    1683    157712617 : frange::set_undefined ()
    1684              : {
    1685    157712617 :   m_kind = VR_UNDEFINED;
    1686    157712617 :   m_type = NULL;
    1687    157712617 :   m_num_ranges = 1;
    1688    157712617 :   m_pos_nan = false;
    1689    157712617 :   m_neg_nan = false;
    1690              :   // Leave the rest undefined; as it speeds up initializing undefined ranges.
    1691    157712617 :   if (flag_checking)
    1692    157712617 :     verify_range ();
    1693    157712617 : }
    1694              : 
    1695              : // Set the NAN bits to NAN and adjust the range.
    1696              : 
    1697              : inline void
    1698      6297391 : frange::update_nan (const nan_state &nan)
    1699              : {
    1700      6297391 :   gcc_checking_assert (!undefined_p ());
    1701      6297391 :   if (HONOR_NANS (m_type))
    1702              :     {
    1703      6296889 :       m_pos_nan = nan.pos_p ();
    1704      6296889 :       m_neg_nan = nan.neg_p ();
    1705      6296889 :       normalize_kind ();
    1706      6296889 :       if (flag_checking)
    1707      6296889 :         verify_range ();
    1708              :     }
    1709      6297391 : }
    1710              : 
    1711              : // Set the NAN bit to +-NAN.
    1712              : 
    1713              : inline void
    1714      4181054 : frange::update_nan ()
    1715              : {
    1716      4181054 :   gcc_checking_assert (!undefined_p ());
    1717      4181054 :   nan_state nan (true);
    1718      4181054 :   update_nan (nan);
    1719      4181054 : }
    1720              : 
    1721              : // Like above, but set the sign of the NAN.
    1722              : 
    1723              : inline void
    1724      2116337 : frange::update_nan (bool sign)
    1725              : {
    1726      2116337 :   gcc_checking_assert (!undefined_p ());
    1727      2116337 :   nan_state nan (/*pos=*/!sign, /*neg=*/sign);
    1728      2116337 :   update_nan (nan);
    1729      2116337 : }
    1730              : 
    1731              : inline bool
    1732            0 : frange::contains_p (tree cst) const
    1733              : {
    1734            0 :   return contains_p (*TREE_REAL_CST_PTR (cst));
    1735              : }
    1736              : 
    1737              : // Clear the NAN bit and adjust the range.
    1738              : 
    1739              : inline void
    1740     13190093 : frange::clear_nan ()
    1741              : {
    1742     13190093 :   gcc_checking_assert (!undefined_p ());
    1743     13190093 :   m_pos_nan = false;
    1744     13190093 :   m_neg_nan = false;
    1745     13190093 :   normalize_kind ();
    1746     13190093 :   if (flag_checking)
    1747     13190093 :     verify_range ();
    1748     13190093 : }
    1749              : 
    1750              : // Set R to maximum representable value for TYPE.
    1751              : 
    1752              : inline REAL_VALUE_TYPE
    1753     15001938 : real_max_representable (const_tree type)
    1754              : {
    1755     15001938 :   REAL_VALUE_TYPE r;
    1756     15001938 :   char buf[128];
    1757     15001938 :   get_max_float (REAL_MODE_FORMAT (TYPE_MODE (type)),
    1758              :                  buf, sizeof (buf), false);
    1759     15001938 :   int res = real_from_string (&r, buf);
    1760     15001938 :   gcc_checking_assert (!res);
    1761     15001938 :   return r;
    1762              : }
    1763              : 
    1764              : // Return the minimum representable value for TYPE.
    1765              : 
    1766              : inline REAL_VALUE_TYPE
    1767      7918803 : real_min_representable (const_tree type)
    1768              : {
    1769      7918803 :   REAL_VALUE_TYPE r = real_max_representable (type);
    1770      7918803 :   r = real_value_negate (&r);
    1771      7918803 :   return r;
    1772              : }
    1773              : 
    1774              : // Return the minimum value for TYPE.
    1775              : 
    1776              : inline REAL_VALUE_TYPE
    1777    170410147 : frange_val_min (const_tree type)
    1778              : {
    1779    170410147 :   if (HONOR_INFINITIES (type))
    1780    163103750 :     return dconstninf;
    1781              :   else
    1782      7306397 :     return real_min_representable (type);
    1783              : }
    1784              : 
    1785              : // Return the maximum value for TYPE.
    1786              : 
    1787              : inline REAL_VALUE_TYPE
    1788    111674537 : frange_val_max (const_tree type)
    1789              : {
    1790    111674537 :   if (HONOR_INFINITIES (type))
    1791    105294497 :     return dconstinf;
    1792              :   else
    1793      6380040 :     return real_max_representable (type);
    1794              : }
    1795              : 
    1796              : // Return TRUE if R is the minimum value for TYPE.
    1797              : 
    1798              : inline bool
    1799     94213834 : frange_val_is_min (const REAL_VALUE_TYPE &r, const_tree type)
    1800              : {
    1801     94213834 :   REAL_VALUE_TYPE min = frange_val_min (type);
    1802     94213834 :   return real_identical (&min, &r);
    1803              : }
    1804              : 
    1805              : // Return TRUE if R is the max value for TYPE.
    1806              : 
    1807              : inline bool
    1808     35084465 : frange_val_is_max (const REAL_VALUE_TYPE &r, const_tree type)
    1809              : {
    1810     35084465 :   REAL_VALUE_TYPE max = frange_val_max (type);
    1811     35084465 :   return real_identical (&max, &r);
    1812              : }
    1813              : 
    1814              : // Build a NAN with a state of NAN.
    1815              : 
    1816              : inline void
    1817       423849 : frange::set_nan (tree type, const nan_state &nan)
    1818              : {
    1819       423849 :   gcc_checking_assert (nan.pos_p () || nan.neg_p ());
    1820       423849 :   if (HONOR_NANS (type))
    1821              :     {
    1822       423848 :       m_kind = VR_NAN;
    1823       423848 :       m_type = type;
    1824       423848 :       m_num_ranges = 1;
    1825       423848 :       m_neg_nan = nan.neg_p ();
    1826       423848 :       m_pos_nan = nan.pos_p ();
    1827       423848 :       if (flag_checking)
    1828       423848 :         verify_range ();
    1829              :     }
    1830              :   else
    1831            1 :     set_undefined ();
    1832       423849 : }
    1833              : 
    1834              : // Build a signless NAN of type TYPE.
    1835              : 
    1836              : inline void
    1837       155341 : frange::set_nan (tree type)
    1838              : {
    1839       155341 :   nan_state nan (true);
    1840       155329 :   set_nan (type, nan);
    1841              : }
    1842              : 
    1843              : // Build a NAN of type TYPE with SIGN.
    1844              : 
    1845              : inline void
    1846       186344 : frange::set_nan (tree type, bool sign)
    1847              : {
    1848       186344 :   nan_state nan (/*pos=*/!sign, /*neg=*/sign);
    1849       186340 :   set_nan (type, nan);
    1850              : }
    1851              : 
    1852              : // Return TRUE if range is known to be finite.
    1853              : 
    1854              : inline bool
    1855            0 : frange::known_isfinite () const
    1856              : {
    1857            0 :   if (undefined_p () || varying_p () || m_kind == VR_ANTI_RANGE)
    1858              :     return false;
    1859            0 :   return (!maybe_isnan ()
    1860            0 :           && !real_isinf (&lower_bound ())
    1861            0 :           && !real_isinf (&upper_bound ()));
    1862              : }
    1863              : 
    1864              : // Return TRUE if range is known to be normal.
    1865              : 
    1866              : inline bool
    1867            0 : frange::known_isnormal () const
    1868              : {
    1869            0 :   if (!known_isfinite ())
    1870              :     return false;
    1871              : 
    1872            0 :   machine_mode mode = TYPE_MODE (type ());
    1873            0 :   const REAL_VALUE_TYPE &min = lower_bound ();
    1874            0 :   const REAL_VALUE_TYPE &max = upper_bound ();
    1875            0 :   return (!real_isdenormal (&min, mode) && !real_isdenormal (&max, mode)
    1876            0 :           && !real_iszero (&min) && !real_iszero (&max)
    1877            0 :           && (!real_isneg (&min) || real_isneg (&max)));
    1878              : }
    1879              : 
    1880              : // Return TRUE if range is known to be denormal.
    1881              : 
    1882              : inline bool
    1883            0 : frange::known_isdenormal_or_zero () const
    1884              : {
    1885            0 :   if (!known_isfinite ())
    1886              :     return false;
    1887              : 
    1888            0 :   machine_mode mode = TYPE_MODE (type ());
    1889            0 :   const REAL_VALUE_TYPE &min = lower_bound ();
    1890            0 :   const REAL_VALUE_TYPE &max = upper_bound ();
    1891            0 :   return ((real_isdenormal (&min, mode) || real_iszero (&min))
    1892            0 :           && (real_isdenormal (&max, mode) || real_iszero (&max)));
    1893              : }
    1894              : 
    1895              : // Return TRUE if range may be infinite.
    1896              : 
    1897              : inline bool
    1898        38308 : frange::maybe_isinf () const
    1899              : {
    1900        38308 :   if (undefined_p () || m_kind == VR_ANTI_RANGE || m_kind == VR_NAN)
    1901              :     return false;
    1902        38308 :   if (varying_p ())
    1903              :     return true;
    1904        35758 :   return real_isinf (&lower_bound ()) || real_isinf (&upper_bound ());
    1905              : }
    1906              : 
    1907              : // Return TRUE if range is known to be the [-INF,-INF] or [+INF,+INF].
    1908              : 
    1909              : inline bool
    1910      5982425 : frange::known_isinf () const
    1911              : {
    1912      5982425 :   return (m_kind == VR_RANGE
    1913      1631425 :           && m_num_ranges == 1
    1914      8554007 :           && !maybe_isnan ()
    1915      1285785 :           && real_identical (&m_pairs[0].min, &m_pairs[0].max)
    1916      6019653 :           && real_isinf (&m_pairs[0].min));
    1917              : }
    1918              : 
    1919              : // Return TRUE if range is possibly a NAN.
    1920              : 
    1921              : inline bool
    1922     20141950 : frange::maybe_isnan () const
    1923              : {
    1924     18366718 :   if (undefined_p ())
    1925              :     return false;
    1926     20137402 :   return m_pos_nan || m_neg_nan;
    1927              : }
    1928              : 
    1929              : // Return TRUE if range is possibly a NAN with SIGN.
    1930              : 
    1931              : inline bool
    1932       158738 : frange::maybe_isnan (bool sign) const
    1933              : {
    1934       158738 :   if (undefined_p ())
    1935              :     return false;
    1936       158738 :   if (sign)
    1937       158738 :     return m_neg_nan;
    1938              :   return m_pos_nan;
    1939              : }
    1940              : 
    1941              : // Return TRUE if range is a +NAN or -NAN.
    1942              : 
    1943              : inline bool
    1944     28709468 : frange::known_isnan () const
    1945              : {
    1946     24513683 :   return m_kind == VR_NAN;
    1947              : }
    1948              : 
    1949              : // If the signbit for the range is known, set it in SIGNBIT and return
    1950              : // TRUE.
    1951              : 
    1952              : inline bool
    1953      1745275 : frange::signbit_p (bool &signbit) const
    1954              : {
    1955      1745275 :   if (undefined_p ())
    1956              :     return false;
    1957              : 
    1958              :   // NAN with unknown sign.
    1959      1745261 :   if (m_pos_nan && m_neg_nan)
    1960              :     return false;
    1961              :   // No NAN.
    1962       108420 :   if (!m_pos_nan && !m_neg_nan)
    1963              :     {
    1964        85366 :       if (lower_bound ().sign == upper_bound ().sign)
    1965              :         {
    1966        11724 :           signbit = lower_bound ().sign;
    1967        11724 :           return true;
    1968              :         }
    1969              :       return false;
    1970              :     }
    1971              :   // NAN with known sign.
    1972        23054 :   bool nan_sign = m_neg_nan;
    1973        23054 :   if (known_isnan ()
    1974        23054 :       || (nan_sign == lower_bound ().sign
    1975        21733 :           && nan_sign == upper_bound ().sign))
    1976              :     {
    1977        21854 :       signbit = nan_sign;
    1978        21854 :       return true;
    1979              :     }
    1980              :   return false;
    1981              : }
    1982              : 
    1983              : // If range has a NAN with a known sign, set it in SIGNBIT and return
    1984              : // TRUE.
    1985              : 
    1986              : inline bool
    1987        53986 : frange::nan_signbit_p (bool &signbit) const
    1988              : {
    1989        53986 :   if (undefined_p ())
    1990              :     return false;
    1991              : 
    1992        53986 :   if (m_pos_nan == m_neg_nan)
    1993              :     return false;
    1994              : 
    1995         2536 :   signbit = m_neg_nan;
    1996         2536 :   return true;
    1997              : }
    1998              : 
    1999              : void frange_nextafter (enum machine_mode, REAL_VALUE_TYPE &,
    2000              :                        const REAL_VALUE_TYPE &);
    2001              : void frange_arithmetic (enum tree_code, tree, REAL_VALUE_TYPE &,
    2002              :                         const REAL_VALUE_TYPE &, const REAL_VALUE_TYPE &,
    2003              :                         const REAL_VALUE_TYPE &);
    2004              : 
    2005              : // Return true if TYPE1 and TYPE2 are compatible range types.
    2006              : 
    2007              : inline bool
    2008   1671723931 : range_compatible_p (tree type1, tree type2)
    2009              : {
    2010              :   // types_compatible_p requires conversion in both directions to be useless.
    2011              :   // GIMPLE only requires a cast one way in order to be compatible.
    2012              :   // Ranges really only need the sign and precision to be the same.
    2013   1671723931 :   return (TYPE_PRECISION (type1) == TYPE_PRECISION (type2)
    2014   1671723931 :           && TYPE_SIGN (type1) == TYPE_SIGN (type2));
    2015              : }
    2016              : #endif // GCC_VALUE_RANGE_H
        

Generated by: LCOV version 2.4-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.