LCOV - code coverage report
Current view: top level - gcc - poly-int.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 99.5 % 371 369
Test Date: 2026-02-28 14:20:25 Functions: 92.9 % 169 157
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Polynomial integer classes.
       2              :    Copyright (C) 2014-2026 Free Software Foundation, Inc.
       3              : 
       4              : This file is part of GCC.
       5              : 
       6              : GCC is free software; you can redistribute it and/or modify it under
       7              : the terms of the GNU General Public License as published by the Free
       8              : Software Foundation; either version 3, or (at your option) any later
       9              : version.
      10              : 
      11              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14              : for more details.
      15              : 
      16              : You should have received a copy of the GNU General Public License
      17              : along with GCC; see the file COPYING3.  If not see
      18              : <http://www.gnu.org/licenses/>.  */
      19              : 
      20              : /* This file provides a representation of sizes and offsets whose exact
      21              :    values depend on certain runtime properties.  The motivating example
      22              :    is the Arm SVE ISA, in which the number of vector elements is only
      23              :    known at runtime.  See doc/poly-int.texi for more details.
      24              : 
      25              :    Tests for poly-int.h are located in testsuite/gcc.dg/plugin,
      26              :    since they are too expensive (in terms of binary size) to be
      27              :    included as selftests.  */
      28              : 
      29              : #ifndef HAVE_POLY_INT_H
      30              : #define HAVE_POLY_INT_H
      31              : 
      32              : template<unsigned int N, typename T> class poly_int;
      33              : 
      34              : /* poly_coeff_traiits<T> describes the properties of a poly_int
      35              :    coefficient type T:
      36              : 
      37              :    - poly_coeff_traits<T1>::rank is less than poly_coeff_traits<T2>::rank
      38              :      if T1 can promote to T2.  For C-like types the rank is:
      39              : 
      40              :        (2 * number of bytes) + (unsigned ? 1 : 0)
      41              : 
      42              :      wide_ints don't have a normal rank and so use a value of INT_MAX.
      43              :      Any fixed-width integer should be promoted to wide_int if possible
      44              :      and lead to an error otherwise.
      45              : 
      46              :    - poly_coeff_traits<T>::int_type is the type to which an integer
      47              :      literal should be cast before comparing it with T.
      48              : 
      49              :    - poly_coeff_traits<T>::precision is the number of bits that T can hold.
      50              : 
      51              :    - poly_coeff_traits<T>::signedness is:
      52              :         0 if T is unsigned
      53              :         1 if T is signed
      54              :        -1 if T has no inherent sign (as for wide_int).
      55              : 
      56              :    - poly_coeff_traits<T>::max_value, if defined, is the maximum value of T.
      57              : 
      58              :    - poly_coeff_traits<T>::result is a type that can hold results of
      59              :      operations on T.  This is different from T itself in cases where T
      60              :      is the result of an accessor like wi::to_offset.
      61              : 
      62              :    - poly_coeff_traits<T>::init_cast<Arg>::type is the type to which
      63              :      an argument of type Arg should be casted before being used to
      64              :      initialize a coefficient of type T.  */
      65              : template<typename T, wi::precision_type = wi::int_traits<T>::precision_type>
      66              : struct poly_coeff_traits;
      67              : 
      68              : template<typename T>
      69              : struct poly_coeff_traits<T, wi::FLEXIBLE_PRECISION>
      70              : {
      71              :   typedef T result;
      72              :   typedef T int_type;
      73              :   static const int signedness = (T (0) >= T (-1));
      74              :   static const int precision = sizeof (T) * CHAR_BIT;
      75              :   static const T max_value = (signedness
      76              :                               ? ((T (1) << (precision - 2))
      77              :                                  + ((T (1) << (precision - 2)) - 1))
      78              :                               : T (-1));
      79              :   static const int rank = sizeof (T) * 2 + !signedness;
      80              : 
      81              :   template<typename Arg>
      82              :   struct init_cast { using type = T; };
      83              : };
      84              : 
      85              : template<typename T>
      86              : struct poly_coeff_traits<T, wi::VAR_PRECISION>
      87              : {
      88              :   typedef T result;
      89              :   typedef int int_type;
      90              :   static const int signedness = -1;
      91              :   static const int precision = WIDE_INT_MAX_PRECISION;
      92              :   static const int rank = INT_MAX;
      93              : 
      94              :   template<typename Arg>
      95              :   struct init_cast { using type = const Arg &; };
      96              : };
      97              : 
      98              : template<typename T>
      99              : struct poly_coeff_traits<T, wi::INL_CONST_PRECISION>
     100              : {
     101              :   typedef WI_UNARY_RESULT (T) result;
     102              :   typedef int int_type;
     103              :   /* These types are always signed.  */
     104              :   static const int signedness = 1;
     105              :   static const int precision = wi::int_traits<T>::precision;
     106              :   static const int rank = precision * 2 / CHAR_BIT;
     107              : 
     108              :   template<typename Arg>
     109              :   struct init_cast { using type = const Arg &; };
     110              : };
     111              : 
     112              : template<typename T>
     113              : struct poly_coeff_traits<T, wi::CONST_PRECISION>
     114              : {
     115              :   typedef WI_UNARY_RESULT (T) result;
     116              :   typedef int int_type;
     117              :   /* These types are always signed.  */
     118              :   static const int signedness = 1;
     119              :   static const int precision = wi::int_traits<T>::precision;
     120              :   static const int rank = precision * 2 / CHAR_BIT;
     121              : 
     122              :   template<typename Arg>
     123              :   struct init_cast { using type = const Arg &; };
     124              : };
     125              : 
     126              : /* Information about a pair of coefficient types.  */
     127              : template<typename T1, typename T2>
     128              : struct poly_coeff_pair_traits
     129              : {
     130              :   /* True if T1 can represent all the values of T2.
     131              : 
     132              :      Either:
     133              : 
     134              :      - T1 should be a type with the same signedness as T2 and no less
     135              :        precision.  This allows things like int16_t -> int16_t and
     136              :        uint32_t -> uint64_t.
     137              : 
     138              :      - T1 should be signed, T2 should be unsigned, and T1 should be
     139              :        wider than T2.  This allows things like uint16_t -> int32_t.
     140              : 
     141              :      This rules out cases in which T1 has less precision than T2 or where
     142              :      the conversion would reinterpret the top bit.  E.g. int16_t -> uint32_t
     143              :      can be dangerous and should have an explicit cast if deliberate.  */
     144              :   static const bool lossless_p = (poly_coeff_traits<T1>::signedness
     145              :                                   == poly_coeff_traits<T2>::signedness
     146              :                                   ? (poly_coeff_traits<T1>::precision
     147              :                                      >= poly_coeff_traits<T2>::precision)
     148              :                                   : (poly_coeff_traits<T1>::signedness == 1
     149              :                                      && poly_coeff_traits<T2>::signedness == 0
     150              :                                      && (poly_coeff_traits<T1>::precision
     151              :                                          > poly_coeff_traits<T2>::precision)));
     152              : 
     153              :   /* 0 if T1 op T2 should promote to HOST_WIDE_INT,
     154              :      1 if T1 op T2 should promote to unsigned HOST_WIDE_INT,
     155              :      2 if T1 op T2 should use wide-int rules.  */
     156              : #define RANK(X) poly_coeff_traits<X>::rank
     157              :   static const int result_kind
     158              :     = ((RANK (T1) <= RANK (HOST_WIDE_INT)
     159              :         && RANK (T2) <= RANK (HOST_WIDE_INT))
     160              :        ? 0
     161              :        : (RANK (T1) <= RANK (unsigned HOST_WIDE_INT)
     162              :           && RANK (T2) <= RANK (unsigned HOST_WIDE_INT))
     163              :        ? 1 : 2);
     164              : #undef RANK
     165              : };
     166              : 
     167              : /* SFINAE class that makes T3 available as "type" if T2 can represent all the
     168              :    values in T1.  */
     169              : template<typename T1, typename T2, typename T3,
     170              :          bool lossless_p = poly_coeff_pair_traits<T1, T2>::lossless_p>
     171              : struct if_lossless;
     172              : template<typename T1, typename T2, typename T3>
     173              : struct if_lossless<T1, T2, T3, true>
     174              : {
     175              :   typedef T3 type;
     176              : };
     177              : 
     178              : /* poly_int_traits<T> describes an integer type T that might be polynomial
     179              :    or non-polynomial:
     180              : 
     181              :    - poly_int_traits<T>::is_poly is true if T is a poly_int-based type
     182              :      and false otherwise.
     183              : 
     184              :    - poly_int_traits<T>::num_coeffs gives the number of coefficients in T
     185              :      if T is a poly_int and 1 otherwise.
     186              : 
     187              :    - poly_int_traits<T>::coeff_type gives the coefficent type of T if T
     188              :      is a poly_int and T itself otherwise
     189              : 
     190              :    - poly_int_traits<T>::int_type is a shorthand for
     191              :      typename poly_coeff_traits<coeff_type>::int_type.  */
     192              : template<typename T>
     193              : struct poly_int_traits
     194              : {
     195              :   static const bool is_poly = false;
     196              :   static const unsigned int num_coeffs = 1;
     197              :   typedef T coeff_type;
     198              :   typedef typename poly_coeff_traits<T>::int_type int_type;
     199              : };
     200              : template<unsigned int N, typename C>
     201              : struct poly_int_traits<poly_int<N, C> >
     202              : {
     203              :   static const bool is_poly = true;
     204              :   static const unsigned int num_coeffs = N;
     205              :   typedef C coeff_type;
     206              :   typedef typename poly_coeff_traits<C>::int_type int_type;
     207              : };
     208              : 
     209              : /* SFINAE class that makes T2 available as "type" if T1 is a non-polynomial
     210              :    type.  */
     211              : template<typename T1, typename T2 = T1,
     212              :          bool is_poly = poly_int_traits<T1>::is_poly>
     213              : struct if_nonpoly {};
     214              : template<typename T1, typename T2>
     215              : struct if_nonpoly<T1, T2, false>
     216              : {
     217              :   typedef T2 type;
     218              : };
     219              : 
     220              : /* SFINAE class that makes T3 available as "type" if both T1 and T2 are
     221              :    non-polynomial types.  */
     222              : template<typename T1, typename T2, typename T3,
     223              :          bool is_poly1 = poly_int_traits<T1>::is_poly,
     224              :          bool is_poly2 = poly_int_traits<T2>::is_poly>
     225              : struct if_nonpoly2 {};
     226              : template<typename T1, typename T2, typename T3>
     227              : struct if_nonpoly2<T1, T2, T3, false, false>
     228              : {
     229              :   typedef T3 type;
     230              : };
     231              : 
     232              : /* SFINAE class that makes T2 available as "type" if T1 is a polynomial
     233              :    type.  */
     234              : template<typename T1, typename T2 = T1,
     235              :          bool is_poly = poly_int_traits<T1>::is_poly>
     236              : struct if_poly {};
     237              : template<typename T1, typename T2>
     238              : struct if_poly<T1, T2, true>
     239              : {
     240              :   typedef T2 type;
     241              : };
     242              : 
     243              : /* poly_result<T1, T2> describes the result of an operation on two
     244              :    types T1 and T2, where at least one of the types is polynomial:
     245              : 
     246              :    - poly_result<T1, T2>::type gives the result type for the operation.
     247              :      The intention is to provide normal C-like rules for integer ranks,
     248              :      except that everything smaller than HOST_WIDE_INT promotes to
     249              :      HOST_WIDE_INT.
     250              : 
     251              :    - poly_result<T1, T2>::cast is the type to which an operand of type
     252              :      T1 should be cast before doing the operation, to ensure that
     253              :      the operation is done at the right precision.  Casting to
     254              :      poly_result<T1, T2>::type would also work, but casting to this
     255              :      type is more efficient.  */
     256              : template<typename T1, typename T2 = T1,
     257              :          int result_kind = poly_coeff_pair_traits<T1, T2>::result_kind>
     258              : struct poly_result;
     259              : 
     260              : /* Promote pair to HOST_WIDE_INT.  */
     261              : template<typename T1, typename T2>
     262              : struct poly_result<T1, T2, 0>
     263              : {
     264              :   typedef HOST_WIDE_INT type;
     265              :   /* T1 and T2 are primitive types, so cast values to T before operating
     266              :      on them.  */
     267              :   typedef type cast;
     268              : };
     269              : 
     270              : /* Promote pair to unsigned HOST_WIDE_INT.  */
     271              : template<typename T1, typename T2>
     272              : struct poly_result<T1, T2, 1>
     273              : {
     274              :   typedef unsigned HOST_WIDE_INT type;
     275              :   /* T1 and T2 are primitive types, so cast values to T before operating
     276              :      on them.  */
     277              :   typedef type cast;
     278              : };
     279              : 
     280              : /* Use normal wide-int rules.  */
     281              : template<typename T1, typename T2>
     282              : struct poly_result<T1, T2, 2>
     283              : {
     284              :   typedef WI_BINARY_RESULT (T1, T2) type;
     285              :   /* Don't cast values before operating on them; leave the wi:: routines
     286              :      to handle promotion as necessary.  */
     287              :   typedef const T1 &cast;
     288              : };
     289              : 
     290              : /* The coefficient type for the result of a binary operation on two
     291              :    poly_ints, the first of which has coefficients of type C1 and the
     292              :    second of which has coefficients of type C2.  */
     293              : #define POLY_POLY_COEFF(C1, C2) typename poly_result<C1, C2>::type
     294              : 
     295              : /* Enforce that T2 is non-polynomial and provide the cofficient type of
     296              :    the result of a binary operation in which the first operand is a
     297              :    poly_int with coefficients of type C1 and the second operand is
     298              :    a constant of type T2.  */
     299              : #define POLY_CONST_COEFF(C1, T2) \
     300              :   POLY_POLY_COEFF (C1, typename if_nonpoly<T2>::type)
     301              : 
     302              : /* Likewise in reverse.  */
     303              : #define CONST_POLY_COEFF(T1, C2) \
     304              :   POLY_POLY_COEFF (typename if_nonpoly<T1>::type, C2)
     305              : 
     306              : /* The result type for a binary operation on poly_int<N, C1> and
     307              :    poly_int<N, C2>.  */
     308              : #define POLY_POLY_RESULT(N, C1, C2) poly_int<N, POLY_POLY_COEFF (C1, C2)>
     309              : 
     310              : /* Enforce that T2 is non-polynomial and provide the result type
     311              :    for a binary operation on poly_int<N, C1> and T2.  */
     312              : #define POLY_CONST_RESULT(N, C1, T2) poly_int<N, POLY_CONST_COEFF (C1, T2)>
     313              : 
     314              : /* Enforce that T1 is non-polynomial and provide the result type
     315              :    for a binary operation on T1 and poly_int<N, C2>.  */
     316              : #define CONST_POLY_RESULT(N, T1, C2) poly_int<N, CONST_POLY_COEFF (T1, C2)>
     317              : 
     318              : /* Enforce that T1 and T2 are non-polynomial and provide the result type
     319              :    for a binary operation on T1 and T2.  */
     320              : #define CONST_CONST_RESULT(N, T1, T2) \
     321              :   POLY_POLY_COEFF (typename if_nonpoly<T1>::type, \
     322              :                    typename if_nonpoly<T2>::type)
     323              : 
     324              : /* The type to which a coefficient of type C1 should be cast before
     325              :    using it in a binary operation with a coefficient of type C2.  */
     326              : #define POLY_CAST(C1, C2) typename poly_result<C1, C2>::cast
     327              : 
     328              : /* Provide the coefficient type for the result of T1 op T2, where T1
     329              :    and T2 can be polynomial or non-polynomial.  */
     330              : #define POLY_BINARY_COEFF(T1, T2) \
     331              :   typename poly_result<typename poly_int_traits<T1>::coeff_type, \
     332              :                        typename poly_int_traits<T2>::coeff_type>::type
     333              : 
     334              : /* The type to which an integer constant should be cast before
     335              :    comparing it with T.  */
     336              : #define POLY_INT_TYPE(T) typename poly_int_traits<T>::int_type
     337              : 
     338              : /* RES is a poly_int result that has coefficients of type C and that
     339              :    is being built up a coefficient at a time.  Set coefficient number I
     340              :    to VALUE in the most efficient way possible.
     341              : 
     342              :    For primitive C it is better to assign directly, since it avoids
     343              :    any further calls and so is more efficient when the compiler is
     344              :    built at -O0.  But for wide-int based C it is better to construct
     345              :    the value in-place.  This means that calls out to a wide-int.cc
     346              :    routine can take the address of RES rather than the address of
     347              :    a temporary.
     348              : 
     349              :    The dummy self-comparison against C * is just a way of checking
     350              :    that C gives the right type.  */
     351              : #define POLY_SET_COEFF(C, RES, I, VALUE) \
     352              :   ((void) (&(RES).coeffs[0] == (C *) (void *) &(RES).coeffs[0]), \
     353              :    wi::int_traits<C>::precision_type == wi::FLEXIBLE_PRECISION \
     354              :    ? (void) ((RES).coeffs[I] = VALUE) \
     355              :    : (void) ((RES).coeffs[I].~C (), new (&(RES).coeffs[I]) C (VALUE)))
     356              : 
     357              : /* Number of bits needed to represent maximum value of
     358              :    NUM_POLY_INT_COEFFS defined by any target.  */
     359              : #define MAX_NUM_POLY_INT_COEFFS_BITS    2
     360              : 
     361              : /* poly_int_full and poly_int_hungry are used internally within poly_int
     362              :    for delegated initializers.  poly_int_full indicates that a parameter
     363              :    pack has enough elements to initialize every coefficient.  poly_int_hungry
     364              :    indicates that at least one extra zero must be added.  */
     365              : struct poly_int_full {};
     366              : struct poly_int_hungry {};
     367              : 
     368              : /* poly_int_fullness<B>::type is poly_int_full when B is true and
     369              :    poly_int_hungry when B is false.  */
     370              : template<bool> struct poly_int_fullness;
     371              : template<> struct poly_int_fullness<false> { using type = poly_int_hungry; };
     372              : template<> struct poly_int_fullness<true> { using type = poly_int_full; };
     373              : 
     374              : /* A class containing polynomial integers.  The polynomial has N coefficients
     375              :    of type C, and N - 1 indeterminates.  */
     376              : template<unsigned int N, typename C>
     377              : class poly_int
     378              : {
     379              : public:
     380  13829301641 :   poly_int () = default;
     381       689468 :   poly_int (const poly_int &) = default;
     382              : 
     383              :   template<typename Ca>
     384              :   poly_int (const poly_int<N, Ca> &);
     385              : 
     386              :   template<typename ...Cs>
     387              :   constexpr poly_int (const Cs &...);
     388              : 
     389    492180636 :   poly_int &operator = (const poly_int &) = default;
     390              : 
     391              :   template<typename Ca>
     392              :   poly_int &operator = (const poly_int<N, Ca> &);
     393              :   template<typename Ca>
     394              :   typename if_nonpoly<Ca, poly_int>::type &operator = (const Ca &);
     395              : 
     396              :   template<typename Ca>
     397              :   poly_int &operator += (const poly_int<N, Ca> &);
     398              :   template<typename Ca>
     399              :   typename if_nonpoly<Ca, poly_int>::type &operator += (const Ca &);
     400              : 
     401              :   template<typename Ca>
     402              :   poly_int &operator -= (const poly_int<N, Ca> &);
     403              :   template<typename Ca>
     404              :   typename if_nonpoly<Ca, poly_int>::type &operator -= (const Ca &);
     405              : 
     406              :   template<typename Ca>
     407              :   typename if_nonpoly<Ca, poly_int>::type &operator *= (const Ca &);
     408              : 
     409              :   poly_int &operator <<= (unsigned int);
     410              : 
     411              :   bool is_constant () const;
     412              : 
     413              :   template<typename T>
     414              :   typename if_lossless<T, C, bool>::type is_constant (T *) const;
     415              : 
     416              :   C to_constant () const;
     417              : 
     418              :   template<typename Ca>
     419              :   static poly_int<N, C> from (const poly_int<N, Ca> &, unsigned int,
     420              :                               signop);
     421              :   template<typename Ca>
     422              :   static poly_int<N, C> from (const poly_int<N, Ca> &, signop);
     423              : 
     424              :   bool to_shwi (poly_int<N, HOST_WIDE_INT> *) const;
     425              :   bool to_uhwi (poly_int<N, unsigned HOST_WIDE_INT> *) const;
     426              :   poly_int<N, HOST_WIDE_INT> force_shwi () const;
     427              :   poly_int<N, unsigned HOST_WIDE_INT> force_uhwi () const;
     428              : 
     429              : #if POLY_INT_CONVERSION
     430              :   operator C () const;
     431              : #endif
     432              : 
     433              :   C coeffs[N];
     434              : 
     435              : private:
     436              :   template<typename ...Cs>
     437              :   constexpr poly_int (poly_int_full, const Cs &...);
     438              : 
     439              :   template<typename C0, typename ...Cs>
     440              :   constexpr poly_int (poly_int_hungry, const C0 &, const Cs &...);
     441              : };
     442              : 
     443              : template<unsigned int N, typename C>
     444              : template<typename Ca>
     445              : inline
     446  41483703972 : poly_int<N, C>::poly_int (const poly_int<N, Ca> &a)
     447              : {
     448  52652780968 :   for (unsigned int i = 0; i < N; i++)
     449  16741644680 :     POLY_SET_COEFF (C, *this, i, a.coeffs[i]);
     450  10193169218 : }
     451              : 
     452              : template<unsigned int N, typename C>
     453              : template<typename ...Cs>
     454              : inline constexpr
     455  26839709731 : poly_int<N, C>::poly_int (const Cs &... cs)
     456              :   : poly_int (typename poly_int_fullness<sizeof... (Cs) >= N>::type (),
     457  22104292679 :               cs...) {}
     458              : 
     459              : /* Initialize with c0, cs..., and some trailing zeros.  */
     460              : template<unsigned int N, typename C>
     461              : template<typename C0, typename ...Cs>
     462              : inline constexpr
     463              : poly_int<N, C>::poly_int (poly_int_hungry, const C0 &c0, const Cs &... cs)
     464              :   : poly_int (c0, cs..., wi::ints_for<C>::zero (c0)) {}
     465              : 
     466              : /* Initialize with cs... directly, casting where necessary.  */
     467              : template<unsigned int N, typename C>
     468              : template<typename ...Cs>
     469              : inline constexpr
     470  16177626017 : poly_int<N, C>::poly_int (poly_int_full, const Cs &... cs)
     471  15222012311 :   : coeffs { (typename poly_coeff_traits<C>::
     472   5312913119 :               template init_cast<Cs>::type (cs))... } {}
     473              : 
     474              : template<unsigned int N, typename C>
     475              : template<typename Ca>
     476              : inline poly_int<N, C>&
     477   3495725664 : poly_int<N, C>::operator = (const poly_int<N, Ca> &a)
     478              : {
     479   7081733969 :   for (unsigned int i = 0; i < N; i++)
     480   3755707255 :     POLY_SET_COEFF (C, *this, i, a.coeffs[i]);
     481      5506420 :   return *this;
     482              : }
     483              : 
     484              : template<unsigned int N, typename C>
     485              : template<typename Ca>
     486              : inline typename if_nonpoly<Ca, poly_int<N, C> >::type &
     487   8911263192 : poly_int<N, C>::operator = (const Ca &a)
     488              : {
     489   9799538936 :   POLY_SET_COEFF (C, *this, 0, a);
     490              :   if (N >= 2)
     491              :     for (unsigned int i = 1; i < N; i++)
     492              :       POLY_SET_COEFF (C, *this, i, wi::ints_for<C>::zero (this->coeffs[0]));
     493   1719234654 :   return *this;
     494              : }
     495              : 
     496              : template<unsigned int N, typename C>
     497              : template<typename Ca>
     498              : inline poly_int<N, C>&
     499   4948217039 : poly_int<N, C>::operator += (const poly_int<N, Ca> &a)
     500              : {
     501   6004746109 :   for (unsigned int i = 0; i < N; i++)
     502   5960099109 :     this->coeffs[i] += a.coeffs[i];
     503        10358 :   return *this;
     504              : }
     505              : 
     506              : template<unsigned int N, typename C>
     507              : template<typename Ca>
     508              : inline typename if_nonpoly<Ca, poly_int<N, C> >::type &
     509   2379110375 : poly_int<N, C>::operator += (const Ca &a)
     510              : {
     511   2373647288 :   this->coeffs[0] += a;
     512        73099 :   return *this;
     513              : }
     514              : 
     515              : template<unsigned int N, typename C>
     516              : template<typename Ca>
     517              : inline poly_int<N, C>&
     518     39179227 : poly_int<N, C>::operator -= (const poly_int<N, Ca> &a)
     519              : {
     520   1387991387 :   for (unsigned int i = 0; i < N; i++)
     521   1430046060 :     this->coeffs[i] -= a.coeffs[i];
     522              :   return *this;
     523              : }
     524              : 
     525              : template<unsigned int N, typename C>
     526              : template<typename Ca>
     527              : inline typename if_nonpoly<Ca, poly_int<N, C> >::type &
     528     33657454 : poly_int<N, C>::operator -= (const Ca &a)
     529              : {
     530     27758725 :   this->coeffs[0] -= a;
     531      7847303 :   return *this;
     532              : }
     533              : 
     534              : template<unsigned int N, typename C>
     535              : template<typename Ca>
     536              : inline typename if_nonpoly<Ca, poly_int<N, C> >::type &
     537    706584374 : poly_int<N, C>::operator *= (const Ca &a)
     538              : {
     539    704964150 :   for (unsigned int i = 0; i < N; i++)
     540    704964150 :     this->coeffs[i] *= a;
     541              :   return *this;
     542              : }
     543              : 
     544              : template<unsigned int N, typename C>
     545              : inline poly_int<N, C>&
     546   1292636351 : poly_int<N, C>::operator <<= (unsigned int a)
     547              : {
     548   1292636351 :   for (unsigned int i = 0; i < N; i++)
     549   1292636351 :     this->coeffs[i] <<= a;
     550              :   return *this;
     551              : }
     552              : 
     553              : /* Return true if the polynomial value is a compile-time constant.  */
     554              : 
     555              : template<unsigned int N, typename C>
     556              : inline bool
     557              : poly_int<N, C>::is_constant () const
     558              : {
     559              :   if (N >= 2)
     560              :     for (unsigned int i = 1; i < N; i++)
     561              :       if (this->coeffs[i] != 0)
     562              :         return false;
     563              :   return true;
     564              : }
     565              : 
     566              : /* Return true if the polynomial value is a compile-time constant,
     567              :    storing its value in CONST_VALUE if so.  */
     568              : 
     569              : template<unsigned int N, typename C>
     570              : template<typename T>
     571              : inline typename if_lossless<T, C, bool>::type
     572    746418670 : poly_int<N, C>::is_constant (T *const_value) const
     573              : {
     574              :   if (is_constant ())
     575              :     {
     576    877389684 :       *const_value = this->coeffs[0];
     577              :       return true;
     578              :     }
     579              :   return false;
     580              : }
     581              : 
     582              : /* Return the value of a polynomial that is already known to be a
     583              :    compile-time constant.
     584              : 
     585              :    NOTE: When using this function, please add a comment above the call
     586              :    explaining why we know the value is constant in that context.  */
     587              : 
     588              : template<unsigned int N, typename C>
     589              : inline C
     590     93000413 : poly_int<N, C>::to_constant () const
     591              : {
     592              :   gcc_checking_assert (is_constant ());
     593     91116546 :   return this->coeffs[0];
     594              : }
     595              : 
     596              : /* Convert X to a wide_int-based polynomial in which each coefficient
     597              :    has BITSIZE bits.  If X's coefficients are smaller than BITSIZE,
     598              :    extend them according to SGN.  */
     599              : 
     600              : template<unsigned int N, typename C>
     601              : template<typename Ca>
     602              : inline poly_int<N, C>
     603      1316378 : poly_int<N, C>::from (const poly_int<N, Ca> &a, unsigned int bitsize,
     604              :                       signop sgn)
     605              : {
     606      2632756 :   poly_int<N, C> r;
     607      2632756 :   for (unsigned int i = 0; i < N; i++)
     608      1316378 :     POLY_SET_COEFF (C, r, i, C::from (a.coeffs[i], bitsize, sgn));
     609      1316378 :   return r;
     610              : }
     611              : 
     612              : /* Convert X to a fixed_wide_int-based polynomial, extending according
     613              :    to SGN.  */
     614              : 
     615              : template<unsigned int N, typename C>
     616              : template<typename Ca>
     617              : inline poly_int<N, C>
     618   1260749316 : poly_int<N, C>::from (const poly_int<N, Ca> &a, signop sgn)
     619              : {
     620   1260749316 :   poly_int<N, C> r;
     621   2521498632 :   for (unsigned int i = 0; i < N; i++)
     622   1260749316 :     POLY_SET_COEFF (C, r, i, C::from (a.coeffs[i], sgn));
     623   1260749316 :   return r;
     624              : }
     625              : 
     626              : /* Return true if the coefficients of this generic_wide_int-based
     627              :    polynomial can be represented as signed HOST_WIDE_INTs without loss
     628              :    of precision.  Store the HOST_WIDE_INT representation in *R if so.  */
     629              : 
     630              : template<unsigned int N, typename C>
     631              : inline bool
     632  11666020419 : poly_int<N, C>::to_shwi (poly_int<N, HOST_WIDE_INT> *r) const
     633              : {
     634  23332022043 :   for (unsigned int i = 0; i < N; i++)
     635  11666020419 :     if (!wi::fits_shwi_p (this->coeffs[i]))
     636              :       return false;
     637  23332003248 :   for (unsigned int i = 0; i < N; i++)
     638  11666001624 :     r->coeffs[i] = this->coeffs[i].to_shwi ();
     639              :   return true;
     640              : }
     641              : 
     642              : /* Return true if the coefficients of this generic_wide_int-based
     643              :    polynomial can be represented as unsigned HOST_WIDE_INTs without
     644              :    loss of precision.  Store the unsigned HOST_WIDE_INT representation
     645              :    in *R if so.  */
     646              : 
     647              : template<unsigned int N, typename C>
     648              : inline bool
     649        18898 : poly_int<N, C>::to_uhwi (poly_int<N, unsigned HOST_WIDE_INT> *r) const
     650              : {
     651        37794 :   for (unsigned int i = 0; i < N; i++)
     652        18898 :     if (!wi::fits_uhwi_p (this->coeffs[i]))
     653              :       return false;
     654        37792 :   for (unsigned int i = 0; i < N; i++)
     655        18896 :     r->coeffs[i] = this->coeffs[i].to_uhwi ();
     656              :   return true;
     657              : }
     658              : 
     659              : /* Force a generic_wide_int-based constant to HOST_WIDE_INT precision,
     660              :    truncating if necessary.  */
     661              : 
     662              : template<unsigned int N, typename C>
     663              : inline poly_int<N, HOST_WIDE_INT>
     664     31215875 : poly_int<N, C>::force_shwi () const
     665              : {
     666              :   poly_int<N, HOST_WIDE_INT> r;
     667    131764065 :   for (unsigned int i = 0; i < N; i++)
     668    132692708 :     r.coeffs[i] = this->coeffs[i].to_shwi ();
     669       871620 :   return r;
     670              : }
     671              : 
     672              : /* Force a generic_wide_int-based constant to unsigned HOST_WIDE_INT precision,
     673              :    truncating if necessary.  */
     674              : 
     675              : template<unsigned int N, typename C>
     676              : inline poly_int<N, unsigned HOST_WIDE_INT>
     677          702 : poly_int<N, C>::force_uhwi () const
     678              : {
     679              :   poly_int<N, unsigned HOST_WIDE_INT> r;
     680         1404 :   for (unsigned int i = 0; i < N; i++)
     681          702 :     r.coeffs[i] = this->coeffs[i].to_uhwi ();
     682          702 :   return r;
     683              : }
     684              : 
     685              : #if POLY_INT_CONVERSION
     686              : /* Provide a conversion operator to constants.  */
     687              : 
     688              : template<unsigned int N, typename C>
     689              : inline
     690     81512542 : poly_int<N, C>::operator C () const
     691              : {
     692              :   gcc_checking_assert (this->is_constant ());
     693     81486646 :   return this->coeffs[0];
     694              : }
     695              : #endif
     696              : 
     697              : /* Return true if every coefficient of A is in the inclusive range [B, C].  */
     698              : 
     699              : template<typename Ca, typename Cb, typename Cc>
     700              : inline typename if_nonpoly<Ca, bool>::type
     701              : coeffs_in_range_p (const Ca &a, const Cb &b, const Cc &c)
     702              : {
     703              :   return a >= b && a <= c;
     704              : }
     705              : 
     706              : template<unsigned int N, typename Ca, typename Cb, typename Cc>
     707              : inline typename if_nonpoly<Ca, bool>::type
     708      3933112 : coeffs_in_range_p (const poly_int<N, Ca> &a, const Cb &b, const Cc &c)
     709              : {
     710     37320727 :   for (unsigned int i = 0; i < N; i++)
     711     37320727 :     if (a.coeffs[i] < b || a.coeffs[i] > c)
     712              :       return false;
     713              :   return true;
     714              : }
     715              : 
     716              : namespace wi {
     717              : /* Poly version of wi::shwi, with the same interface.  */
     718              : 
     719              : template<unsigned int N>
     720              : inline poly_int<N, hwi_with_prec>
     721   7675423460 : shwi (const poly_int<N, HOST_WIDE_INT> &a, unsigned int precision)
     722              : {
     723   7675423460 :   poly_int<N, hwi_with_prec> r;
     724  15350846920 :   for (unsigned int i = 0; i < N; i++)
     725   7675423460 :     POLY_SET_COEFF (hwi_with_prec, r, i, wi::shwi (a.coeffs[i], precision));
     726   7675423460 :   return r;
     727              : }
     728              : 
     729              : /* Poly version of wi::uhwi, with the same interface.  */
     730              : 
     731              : template<unsigned int N>
     732              : inline poly_int<N, hwi_with_prec>
     733      9398429 : uhwi (const poly_int<N, unsigned HOST_WIDE_INT> &a, unsigned int precision)
     734              : {
     735      9398429 :   poly_int<N, hwi_with_prec> r;
     736     18796858 :   for (unsigned int i = 0; i < N; i++)
     737      9398429 :     POLY_SET_COEFF (hwi_with_prec, r, i, wi::uhwi (a.coeffs[i], precision));
     738      9398429 :   return r;
     739              : }
     740              : 
     741              : /* Poly version of wi::sext, with the same interface.  */
     742              : 
     743              : template<unsigned int N, typename Ca>
     744              : inline POLY_POLY_RESULT (N, Ca, Ca)
     745    821372940 : sext (const poly_int<N, Ca> &a, unsigned int precision)
     746              : {
     747              :   typedef POLY_POLY_COEFF (Ca, Ca) C;
     748   1331829469 :   poly_int<N, C> r;
     749   1978006031 :   for (unsigned int i = 0; i < N; i++)
     750   1467549502 :     POLY_SET_COEFF (C, r, i, wi::sext (a.coeffs[i], precision));
     751    510456529 :   return r;
     752              : }
     753              : 
     754              : /* Poly version of wi::zext, with the same interface.  */
     755              : 
     756              : template<unsigned int N, typename Ca>
     757              : inline POLY_POLY_RESULT (N, Ca, Ca)
     758   2771263817 : zext (const poly_int<N, Ca> &a, unsigned int precision)
     759              : {
     760              :   typedef POLY_POLY_COEFF (Ca, Ca) C;
     761   5542527483 :   poly_int<N, C> r;
     762   5542527483 :   for (unsigned int i = 0; i < N; i++)
     763   2771263817 :     POLY_SET_COEFF (C, r, i, wi::zext (a.coeffs[i], precision));
     764   2771263666 :   return r;
     765              : }
     766              : }
     767              : 
     768              : template<unsigned int N, typename Ca, typename Cb>
     769              : inline POLY_POLY_RESULT (N, Ca, Cb)
     770   2046668825 : operator + (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
     771              : {
     772              :   typedef POLY_CAST (Ca, Cb) NCa;
     773              :   typedef POLY_POLY_COEFF (Ca, Cb) C;
     774    775828077 :   poly_int<N, C> r;
     775   2330148022 :   for (unsigned int i = 0; i < N; i++)
     776   1697423169 :     POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]) + b.coeffs[i]);
     777     92858122 :   return r;
     778              : }
     779              : 
     780              : template<unsigned int N, typename Ca, typename Cb>
     781              : inline POLY_CONST_RESULT (N, Ca, Cb)
     782    770719018 : operator + (const poly_int<N, Ca> &a, const Cb &b)
     783              : {
     784              :   typedef POLY_CAST (Ca, Cb) NCa;
     785              :   typedef POLY_CONST_COEFF (Ca, Cb) C;
     786    213889067 :   poly_int<N, C> r;
     787    494830695 :   POLY_SET_COEFF (C, r, 0, NCa (a.coeffs[0]) + b);
     788              :   if (N >= 2)
     789              :     for (unsigned int i = 1; i < N; i++)
     790              :       POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]));
     791              :   return r;
     792              : }
     793              : 
     794              : template<unsigned int N, typename Ca, typename Cb>
     795              : inline CONST_POLY_RESULT (N, Ca, Cb)
     796      7614893 : operator + (const Ca &a, const poly_int<N, Cb> &b)
     797              : {
     798              :   typedef POLY_CAST (Cb, Ca) NCb;
     799              :   typedef CONST_POLY_COEFF (Ca, Cb) C;
     800              :   poly_int<N, C> r;
     801      7614893 :   POLY_SET_COEFF (C, r, 0, a + NCb (b.coeffs[0]));
     802              :   if (N >= 2)
     803              :     for (unsigned int i = 1; i < N; i++)
     804              :       POLY_SET_COEFF (C, r, i, NCb (b.coeffs[i]));
     805              :   return r;
     806              : }
     807              : 
     808              : namespace wi {
     809              : /* Poly versions of wi::add, with the same interface.  */
     810              : 
     811              : template<unsigned int N, typename Ca, typename Cb>
     812              : inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
     813              : add (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
     814              : {
     815              :   typedef WI_BINARY_RESULT (Ca, Cb) C;
     816              :   poly_int<N, C> r;
     817              :   for (unsigned int i = 0; i < N; i++)
     818              :     POLY_SET_COEFF (C, r, i, wi::add (a.coeffs[i], b.coeffs[i]));
     819              :   return r;
     820              : }
     821              : 
     822              : template<unsigned int N, typename Ca, typename Cb>
     823              : inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
     824              : add (const poly_int<N, Ca> &a, const Cb &b)
     825              : {
     826              :   typedef WI_BINARY_RESULT (Ca, Cb) C;
     827              :   poly_int<N, C> r;
     828              :   POLY_SET_COEFF (C, r, 0, wi::add (a.coeffs[0], b));
     829              :   for (unsigned int i = 1; i < N; i++)
     830              :     POLY_SET_COEFF (C, r, i, wi::add (a.coeffs[i],
     831              :                                       wi::ints_for<Cb>::zero (b)));
     832              :   return r;
     833              : }
     834              : 
     835              : template<unsigned int N, typename Ca, typename Cb>
     836              : inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
     837    494418264 : add (const Ca &a, const poly_int<N, Cb> &b)
     838              : {
     839              :   typedef WI_BINARY_RESULT (Ca, Cb) C;
     840    494418264 :   poly_int<N, C> r;
     841    494418264 :   POLY_SET_COEFF (C, r, 0, wi::add (a, b.coeffs[0]));
     842    494418264 :   for (unsigned int i = 1; i < N; i++)
     843              :     POLY_SET_COEFF (C, r, i, wi::add (wi::ints_for<Ca>::zero (a),
     844              :                                       b.coeffs[i]));
     845              :   return r;
     846              : }
     847              : 
     848              : template<unsigned int N, typename Ca, typename Cb>
     849              : inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
     850         4140 : add (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b,
     851              :      signop sgn, wi::overflow_type *overflow)
     852              : {
     853              :   typedef WI_BINARY_RESULT (Ca, Cb) C;
     854         4140 :   poly_int<N, C> r;
     855         4140 :   POLY_SET_COEFF (C, r, 0, wi::add (a.coeffs[0], b.coeffs[0], sgn, overflow));
     856         4140 :   for (unsigned int i = 1; i < N; i++)
     857              :     {
     858              :       wi::overflow_type suboverflow;
     859              :       POLY_SET_COEFF (C, r, i, wi::add (a.coeffs[i], b.coeffs[i], sgn,
     860              :                                         &suboverflow));
     861              :       wi::accumulate_overflow (*overflow, suboverflow);
     862              :     }
     863              :   return r;
     864              : }
     865              : }
     866              : 
     867              : template<unsigned int N, typename Ca, typename Cb>
     868              : inline POLY_POLY_RESULT (N, Ca, Cb)
     869   1906365558 : operator - (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
     870              : {
     871              :   typedef POLY_CAST (Ca, Cb) NCa;
     872              :   typedef POLY_POLY_COEFF (Ca, Cb) C;
     873    942323102 :   poly_int<N, C> r;
     874   2978082101 :   for (unsigned int i = 0; i < N; i++)
     875   2284438342 :     POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]) - b.coeffs[i]);
     876     17326430 :   return r;
     877              : }
     878              : 
     879              : template<unsigned int N, typename Ca, typename Cb>
     880              : inline POLY_CONST_RESULT (N, Ca, Cb)
     881    423818229 : operator - (const poly_int<N, Ca> &a, const Cb &b)
     882              : {
     883              :   typedef POLY_CAST (Ca, Cb) NCa;
     884              :   typedef POLY_CONST_COEFF (Ca, Cb) C;
     885      5290333 :   poly_int<N, C> r;
     886    426247285 :   POLY_SET_COEFF (C, r, 0, NCa (a.coeffs[0]) - b);
     887              :   if (N >= 2)
     888              :     for (unsigned int i = 1; i < N; i++)
     889              :       POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]));
     890              :   return r;
     891              : }
     892              : 
     893              : template<unsigned int N, typename Ca, typename Cb>
     894              : inline CONST_POLY_RESULT (N, Ca, Cb)
     895    155842293 : operator - (const Ca &a, const poly_int<N, Cb> &b)
     896              : {
     897              :   typedef POLY_CAST (Cb, Ca) NCb;
     898              :   typedef CONST_POLY_COEFF (Ca, Cb) C;
     899    126585325 :   poly_int<N, C> r;
     900    155816906 :   POLY_SET_COEFF (C, r, 0, a - NCb (b.coeffs[0]));
     901              :   if (N >= 2)
     902              :     for (unsigned int i = 1; i < N; i++)
     903              :       POLY_SET_COEFF (C, r, i, -NCb (b.coeffs[i]));
     904              :   return r;
     905              : }
     906              : 
     907              : namespace wi {
     908              : /* Poly versions of wi::sub, with the same interface.  */
     909              : 
     910              : template<unsigned int N, typename Ca, typename Cb>
     911              : inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
     912              : sub (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
     913              : {
     914              :   typedef WI_BINARY_RESULT (Ca, Cb) C;
     915              :   poly_int<N, C> r;
     916              :   for (unsigned int i = 0; i < N; i++)
     917              :     POLY_SET_COEFF (C, r, i, wi::sub (a.coeffs[i], b.coeffs[i]));
     918              :   return r;
     919              : }
     920              : 
     921              : template<unsigned int N, typename Ca, typename Cb>
     922              : inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
     923              : sub (const poly_int<N, Ca> &a, const Cb &b)
     924              : {
     925              :   typedef WI_BINARY_RESULT (Ca, Cb) C;
     926              :   poly_int<N, C> r;
     927              :   POLY_SET_COEFF (C, r, 0, wi::sub (a.coeffs[0], b));
     928              :   for (unsigned int i = 1; i < N; i++)
     929              :     POLY_SET_COEFF (C, r, i, wi::sub (a.coeffs[i],
     930              :                                       wi::ints_for<Cb>::zero (b)));
     931              :   return r;
     932              : }
     933              : 
     934              : template<unsigned int N, typename Ca, typename Cb>
     935              : inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
     936        64880 : sub (const Ca &a, const poly_int<N, Cb> &b)
     937              : {
     938              :   typedef WI_BINARY_RESULT (Ca, Cb) C;
     939        64880 :   poly_int<N, C> r;
     940        64880 :   POLY_SET_COEFF (C, r, 0, wi::sub (a, b.coeffs[0]));
     941        64880 :   for (unsigned int i = 1; i < N; i++)
     942              :     POLY_SET_COEFF (C, r, i, wi::sub (wi::ints_for<Ca>::zero (a),
     943              :                                       b.coeffs[i]));
     944              :   return r;
     945              : }
     946              : 
     947              : template<unsigned int N, typename Ca, typename Cb>
     948              : inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
     949              : sub (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b,
     950              :      signop sgn, wi::overflow_type *overflow)
     951              : {
     952              :   typedef WI_BINARY_RESULT (Ca, Cb) C;
     953              :   poly_int<N, C> r;
     954              :   POLY_SET_COEFF (C, r, 0, wi::sub (a.coeffs[0], b.coeffs[0], sgn, overflow));
     955              :   for (unsigned int i = 1; i < N; i++)
     956              :     {
     957              :       wi::overflow_type suboverflow;
     958              :       POLY_SET_COEFF (C, r, i, wi::sub (a.coeffs[i], b.coeffs[i], sgn,
     959              :                                         &suboverflow));
     960              :       wi::accumulate_overflow (*overflow, suboverflow);
     961              :     }
     962              :   return r;
     963              : }
     964              : }
     965              : 
     966              : template<unsigned int N, typename Ca>
     967              : inline POLY_POLY_RESULT (N, Ca, Ca)
     968    525882481 : operator - (const poly_int<N, Ca> &a)
     969              : {
     970              :   typedef POLY_CAST (Ca, Ca) NCa;
     971              :   typedef POLY_POLY_COEFF (Ca, Ca) C;
     972     22354098 :   poly_int<N, C> r;
     973    625886601 :   for (unsigned int i = 0; i < N; i++)
     974    147022120 :     POLY_SET_COEFF (C, r, i, -NCa (a.coeffs[i]));
     975     35324417 :   return r;
     976              : }
     977              : 
     978              : namespace wi {
     979              : /* Poly version of wi::neg, with the same interface.  */
     980              : 
     981              : template<unsigned int N, typename Ca>
     982              : inline poly_int<N, WI_UNARY_RESULT (Ca)>
     983              : neg (const poly_int<N, Ca> &a)
     984              : {
     985              :   typedef WI_UNARY_RESULT (Ca) C;
     986              :   poly_int<N, C> r;
     987              :   for (unsigned int i = 0; i < N; i++)
     988              :     POLY_SET_COEFF (C, r, i, wi::neg (a.coeffs[i]));
     989              :   return r;
     990              : }
     991              : 
     992              : template<unsigned int N, typename Ca>
     993              : inline poly_int<N, WI_UNARY_RESULT (Ca)>
     994     30310459 : neg (const poly_int<N, Ca> &a, wi::overflow_type *overflow)
     995              : {
     996              :   typedef WI_UNARY_RESULT (Ca) C;
     997     30310459 :   poly_int<N, C> r;
     998     30310459 :   POLY_SET_COEFF (C, r, 0, wi::neg (a.coeffs[0], overflow));
     999     30310459 :   for (unsigned int i = 1; i < N; i++)
    1000              :     {
    1001              :       wi::overflow_type suboverflow;
    1002              :       POLY_SET_COEFF (C, r, i, wi::neg (a.coeffs[i], &suboverflow));
    1003              :       wi::accumulate_overflow (*overflow, suboverflow);
    1004              :     }
    1005              :   return r;
    1006              : }
    1007              : }
    1008              : 
    1009              : template<unsigned int N, typename Ca>
    1010              : inline POLY_POLY_RESULT (N, Ca, Ca)
    1011              : operator ~ (const poly_int<N, Ca> &a)
    1012              : {
    1013              :   if (N >= 2)
    1014              :     return -1 - a;
    1015              :   return ~a.coeffs[0];
    1016              : }
    1017              : 
    1018              : template<unsigned int N, typename Ca, typename Cb>
    1019              : inline POLY_CONST_RESULT (N, Ca, Cb)
    1020  14815159873 : operator * (const poly_int<N, Ca> &a, const Cb &b)
    1021              : {
    1022              :   typedef POLY_CAST (Ca, Cb) NCa;
    1023              :   typedef POLY_CONST_COEFF (Ca, Cb) C;
    1024    132107284 :   poly_int<N, C> r;
    1025  15001157711 :   for (unsigned int i = 0; i < N; i++)
    1026  14777453074 :     POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]) * b);
    1027        10358 :   return r;
    1028              : }
    1029              : 
    1030              : template<unsigned int N, typename Ca, typename Cb>
    1031              : inline CONST_POLY_RESULT (N, Ca, Cb)
    1032    250601116 : operator * (const Ca &a, const poly_int<N, Cb> &b)
    1033              : {
    1034              :   typedef POLY_CAST (Ca, Cb) NCa;
    1035              :   typedef CONST_POLY_COEFF (Ca, Cb) C;
    1036     65684258 :   poly_int<N, C> r;
    1037    506999783 :   for (unsigned int i = 0; i < N; i++)
    1038    335465408 :     POLY_SET_COEFF (C, r, i, NCa (a) * b.coeffs[i]);
    1039    168793738 :   return r;
    1040              : }
    1041              : 
    1042              : namespace wi {
    1043              : /* Poly versions of wi::mul, with the same interface.  */
    1044              : 
    1045              : template<unsigned int N, typename Ca, typename Cb>
    1046              : inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
    1047              : mul (const poly_int<N, Ca> &a, const Cb &b)
    1048              : {
    1049              :   typedef WI_BINARY_RESULT (Ca, Cb) C;
    1050              :   poly_int<N, C> r;
    1051              :   for (unsigned int i = 0; i < N; i++)
    1052              :     POLY_SET_COEFF (C, r, i, wi::mul (a.coeffs[i], b));
    1053              :   return r;
    1054              : }
    1055              : 
    1056              : template<unsigned int N, typename Ca, typename Cb>
    1057              : inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
    1058          115 : mul (const Ca &a, const poly_int<N, Cb> &b)
    1059              : {
    1060              :   typedef WI_BINARY_RESULT (Ca, Cb) C;
    1061          230 :   poly_int<N, C> r;
    1062          230 :   for (unsigned int i = 0; i < N; i++)
    1063          115 :     POLY_SET_COEFF (C, r, i, wi::mul (a, b.coeffs[i]));
    1064          115 :   return r;
    1065              : }
    1066              : 
    1067              : template<unsigned int N, typename Ca, typename Cb>
    1068              : inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
    1069              : mul (const poly_int<N, Ca> &a, const Cb &b,
    1070              :      signop sgn, wi::overflow_type *overflow)
    1071              : {
    1072              :   typedef WI_BINARY_RESULT (Ca, Cb) C;
    1073              :   poly_int<N, C> r;
    1074              :   POLY_SET_COEFF (C, r, 0, wi::mul (a.coeffs[0], b, sgn, overflow));
    1075              :   for (unsigned int i = 1; i < N; i++)
    1076              :     {
    1077              :       wi::overflow_type suboverflow;
    1078              :       POLY_SET_COEFF (C, r, i, wi::mul (a.coeffs[i], b, sgn, &suboverflow));
    1079              :       wi::accumulate_overflow (*overflow, suboverflow);
    1080              :     }
    1081              :   return r;
    1082              : }
    1083              : }
    1084              : 
    1085              : template<unsigned int N, typename Ca, typename Cb>
    1086              : inline POLY_POLY_RESULT (N, Ca, Ca)
    1087   2343465439 : operator << (const poly_int<N, Ca> &a, const Cb &b)
    1088              : {
    1089              :   typedef POLY_CAST (Ca, Ca) NCa;
    1090              :   typedef POLY_POLY_COEFF (Ca, Ca) C;
    1091   2702411783 :   poly_int<N, C> r;
    1092   4683994704 :   for (unsigned int i = 0; i < N; i++)
    1093   2674959752 :     POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]) << b);
    1094              :   return r;
    1095              : }
    1096              : 
    1097              : namespace wi {
    1098              : /* Poly version of wi::lshift, with the same interface.  */
    1099              : 
    1100              : template<unsigned int N, typename Ca, typename Cb>
    1101              : inline poly_int<N, WI_BINARY_RESULT (Ca, Ca)>
    1102              : lshift (const poly_int<N, Ca> &a, const Cb &b)
    1103              : {
    1104              :   typedef WI_BINARY_RESULT (Ca, Ca) C;
    1105              :   poly_int<N, C> r;
    1106              :   for (unsigned int i = 0; i < N; i++)
    1107              :     POLY_SET_COEFF (C, r, i, wi::lshift (a.coeffs[i], b));
    1108              :   return r;
    1109              : }
    1110              : }
    1111              : 
    1112              : /* Poly version of sext_hwi, with the same interface.  */
    1113              : 
    1114              : template<unsigned int N, typename C>
    1115              : inline poly_int<N, HOST_WIDE_INT>
    1116              : sext_hwi (const poly_int<N, C> &a, unsigned int precision)
    1117              : {
    1118              :   poly_int<N, HOST_WIDE_INT> r;
    1119              :   for (unsigned int i = 0; i < N; i++)
    1120              :     r.coeffs[i] = sext_hwi (a.coeffs[i], precision);
    1121              :   return r;
    1122              : }
    1123              : 
    1124              : 
    1125              : /* Return true if a0 + a1 * x might equal b0 + b1 * x for some nonnegative
    1126              :    integer x.  */
    1127              : 
    1128              : template<typename Ca, typename Cb>
    1129              : inline bool
    1130              : maybe_eq_2 (const Ca &a0, const Ca &a1, const Cb &b0, const Cb &b1)
    1131              : {
    1132              :   if (a1 != b1)
    1133              :      /*      a0 + a1 * x == b0 + b1 * x
    1134              :        ==> (a1 - b1) * x == b0 - a0
    1135              :        ==>             x == (b0 - a0) / (a1 - b1)
    1136              : 
    1137              :        We need to test whether that's a valid value of x.
    1138              :        (b0 - a0) and (a1 - b1) must not have opposite signs
    1139              :        and the result must be integral.  */
    1140              :     return (a1 < b1
    1141              :             ? b0 <= a0 && (a0 - b0) % (b1 - a1) == 0
    1142              :             : b0 >= a0 && (b0 - a0) % (a1 - b1) == 0);
    1143              :   return a0 == b0;
    1144              : }
    1145              : 
    1146              : /* Return true if a0 + a1 * x might equal b for some nonnegative
    1147              :    integer x.  */
    1148              : 
    1149              : template<typename Ca, typename Cb>
    1150              : inline bool
    1151              : maybe_eq_2 (const Ca &a0, const Ca &a1, const Cb &b)
    1152              : {
    1153              :   if (a1 != 0)
    1154              :      /*      a0 + a1 * x == b
    1155              :        ==>             x == (b - a0) / a1
    1156              : 
    1157              :        We need to test whether that's a valid value of x.
    1158              :        (b - a0) and a1 must not have opposite signs and the
    1159              :        result must be integral.  */
    1160              :     return (a1 < 0
    1161              :             ? b <= a0 && (a0 - b) % a1 == 0
    1162              :             : b >= a0 && (b - a0) % a1 == 0);
    1163              :   return a0 == b;
    1164              : }
    1165              : 
    1166              : /* Return true if A might equal B for some indeterminate values.  */
    1167              : 
    1168              : template<unsigned int N, typename Ca, typename Cb>
    1169              : inline bool
    1170     12746614 : maybe_eq (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
    1171              : {
    1172              :   STATIC_ASSERT (N <= 2);
    1173              :   if (N == 2)
    1174              :     return maybe_eq_2 (a.coeffs[0], a.coeffs[1], b.coeffs[0], b.coeffs[1]);
    1175     12746614 :   return a.coeffs[0] == b.coeffs[0];
    1176              : }
    1177              : 
    1178              : template<unsigned int N, typename Ca, typename Cb>
    1179              : inline typename if_nonpoly<Cb, bool>::type
    1180     24614005 : maybe_eq (const poly_int<N, Ca> &a, const Cb &b)
    1181              : {
    1182              :   STATIC_ASSERT (N <= 2);
    1183              :   if (N == 2)
    1184              :     return maybe_eq_2 (a.coeffs[0], a.coeffs[1], b);
    1185     23614636 :   return a.coeffs[0] == b;
    1186              : }
    1187              : 
    1188              : template<unsigned int N, typename Ca, typename Cb>
    1189              : inline typename if_nonpoly<Ca, bool>::type
    1190              : maybe_eq (const Ca &a, const poly_int<N, Cb> &b)
    1191              : {
    1192              :   STATIC_ASSERT (N <= 2);
    1193              :   if (N == 2)
    1194              :     return maybe_eq_2 (b.coeffs[0], b.coeffs[1], a);
    1195              :   return a == b.coeffs[0];
    1196              : }
    1197              : 
    1198              : template<typename Ca, typename Cb>
    1199              : inline typename if_nonpoly2<Ca, Cb, bool>::type
    1200              : maybe_eq (const Ca &a, const Cb &b)
    1201              : {
    1202              :   return a == b;
    1203              : }
    1204              : 
    1205              : /* Return true if A might not equal B for some indeterminate values.  */
    1206              : 
    1207              : template<unsigned int N, typename Ca, typename Cb>
    1208              : inline bool
    1209   7366595522 : maybe_ne (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
    1210              : {
    1211              :   if (N >= 2)
    1212              :     for (unsigned int i = 1; i < N; i++)
    1213              :       if (a.coeffs[i] != b.coeffs[i])
    1214              :         return true;
    1215   7279477761 :   return a.coeffs[0] != b.coeffs[0];
    1216              : }
    1217              : 
    1218              : template<unsigned int N, typename Ca, typename Cb>
    1219              : inline typename if_nonpoly<Cb, bool>::type
    1220  13294963813 : maybe_ne (const poly_int<N, Ca> &a, const Cb &b)
    1221              : {
    1222              :   if (N >= 2)
    1223              :     for (unsigned int i = 1; i < N; i++)
    1224              :       if (a.coeffs[i] != 0)
    1225              :         return true;
    1226  11487292097 :   return a.coeffs[0] != b;
    1227              : }
    1228              : 
    1229              : template<unsigned int N, typename Ca, typename Cb>
    1230              : inline typename if_nonpoly<Ca, bool>::type
    1231    107527318 : maybe_ne (const Ca &a, const poly_int<N, Cb> &b)
    1232              : {
    1233              :   if (N >= 2)
    1234              :     for (unsigned int i = 1; i < N; i++)
    1235              :       if (b.coeffs[i] != 0)
    1236              :         return true;
    1237    107457439 :   return a != b.coeffs[0];
    1238              : }
    1239              : 
    1240              : template<typename Ca, typename Cb>
    1241              : inline typename if_nonpoly2<Ca, Cb, bool>::type
    1242    257738750 : maybe_ne (const Ca &a, const Cb &b)
    1243              : {
    1244    257738750 :   return a != b;
    1245              : }
    1246              : 
    1247              : /* Return true if A is known to be equal to B.  */
    1248              : #define known_eq(A, B) (!maybe_ne (A, B))
    1249              : 
    1250              : /* Return true if A is known to be unequal to B.  */
    1251              : #define known_ne(A, B) (!maybe_eq (A, B))
    1252              : 
    1253              : /* Return true if A might be less than or equal to B for some
    1254              :    indeterminate values.  */
    1255              : 
    1256              : template<unsigned int N, typename Ca, typename Cb>
    1257              : inline bool
    1258   1347642311 : maybe_le (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
    1259              : {
    1260              :   if (N >= 2)
    1261              :     for (unsigned int i = 1; i < N; i++)
    1262              :       if (a.coeffs[i] < b.coeffs[i])
    1263              :         return true;
    1264    676373815 :   return a.coeffs[0] <= b.coeffs[0];
    1265              : }
    1266              : 
    1267              : template<unsigned int N, typename Ca, typename Cb>
    1268              : inline typename if_nonpoly<Cb, bool>::type
    1269    295637319 : maybe_le (const poly_int<N, Ca> &a, const Cb &b)
    1270              : {
    1271              :   if (N >= 2)
    1272              :     for (unsigned int i = 1; i < N; i++)
    1273              :       if (a.coeffs[i] < 0)
    1274              :         return true;
    1275    189436138 :   return a.coeffs[0] <= b;
    1276              : }
    1277              : 
    1278              : template<unsigned int N, typename Ca, typename Cb>
    1279              : inline typename if_nonpoly<Ca, bool>::type
    1280     99348764 : maybe_le (const Ca &a, const poly_int<N, Cb> &b)
    1281              : {
    1282              :   if (N >= 2)
    1283              :     for (unsigned int i = 1; i < N; i++)
    1284              :       if (b.coeffs[i] > 0)
    1285              :         return true;
    1286     99176180 :   return a <= b.coeffs[0];
    1287              : }
    1288              : 
    1289              : template<typename Ca, typename Cb>
    1290              : inline typename if_nonpoly2<Ca, Cb, bool>::type
    1291      3433377 : maybe_le (const Ca &a, const Cb &b)
    1292              : {
    1293      3433377 :   return a <= b;
    1294              : }
    1295              : 
    1296              : /* Return true if A might be less than B for some indeterminate values.  */
    1297              : 
    1298              : template<unsigned int N, typename Ca, typename Cb>
    1299              : inline bool
    1300   2044291252 : maybe_lt (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
    1301              : {
    1302              :   if (N >= 2)
    1303              :     for (unsigned int i = 1; i < N; i++)
    1304              :       if (a.coeffs[i] < b.coeffs[i])
    1305              :         return true;
    1306   2515263100 :   return a.coeffs[0] < b.coeffs[0];
    1307              : }
    1308              : 
    1309              : template<unsigned int N, typename Ca, typename Cb>
    1310              : inline typename if_nonpoly<Cb, bool>::type
    1311  12861538387 : maybe_lt (const poly_int<N, Ca> &a, const Cb &b)
    1312              : {
    1313              :   if (N >= 2)
    1314              :     for (unsigned int i = 1; i < N; i++)
    1315              :       if (a.coeffs[i] < 0)
    1316              :         return true;
    1317  12860926883 :   return a.coeffs[0] < b;
    1318              : }
    1319              : 
    1320              : template<unsigned int N, typename Ca, typename Cb>
    1321              : inline typename if_nonpoly<Ca, bool>::type
    1322    323477593 : maybe_lt (const Ca &a, const poly_int<N, Cb> &b)
    1323              : {
    1324              :   if (N >= 2)
    1325              :     for (unsigned int i = 1; i < N; i++)
    1326              :       if (b.coeffs[i] > 0)
    1327              :         return true;
    1328    322904084 :   return a < b.coeffs[0];
    1329              : }
    1330              : 
    1331              : template<typename Ca, typename Cb>
    1332              : inline typename if_nonpoly2<Ca, Cb, bool>::type
    1333       559604 : maybe_lt (const Ca &a, const Cb &b)
    1334              : {
    1335       559604 :   return a < b;
    1336              : }
    1337              : 
    1338              : /* Return true if A may be greater than or equal to B.  */
    1339              : #define maybe_ge(A, B) maybe_le (B, A)
    1340              : 
    1341              : /* Return true if A may be greater than B.  */
    1342              : #define maybe_gt(A, B) maybe_lt (B, A)
    1343              : 
    1344              : /* Return true if A is known to be less than or equal to B.  */
    1345              : #define known_le(A, B) (!maybe_gt (A, B))
    1346              : 
    1347              : /* Return true if A is known to be less than B.  */
    1348              : #define known_lt(A, B) (!maybe_ge (A, B))
    1349              : 
    1350              : /* Return true if A is known to be greater than B.  */
    1351              : #define known_gt(A, B) (!maybe_le (A, B))
    1352              : 
    1353              : /* Return true if A is known to be greater than or equal to B.  */
    1354              : #define known_ge(A, B) (!maybe_lt (A, B))
    1355              : 
    1356              : /* Return true if A and B are ordered by the partial ordering known_le.  */
    1357              : 
    1358              : template<typename T1, typename T2>
    1359              : inline bool
    1360              : ordered_p (const T1 &a, const T2 &b)
    1361              : {
    1362              :   return ((poly_int_traits<T1>::num_coeffs == 1
    1363              :            && poly_int_traits<T2>::num_coeffs == 1)
    1364              :           || known_le (a, b)
    1365              :           || known_le (b, a));
    1366              : }
    1367              : 
    1368              : /* Assert that A and B are known to be ordered and return the minimum
    1369              :    of the two.
    1370              : 
    1371              :    NOTE: When using this function, please add a comment above the call
    1372              :    explaining why we know the values are ordered in that context.  */
    1373              : 
    1374              : template<unsigned int N, typename Ca, typename Cb>
    1375              : inline POLY_POLY_RESULT (N, Ca, Cb)
    1376     13999685 : ordered_min (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
    1377              : {
    1378     13999685 :   if (known_le (a, b))
    1379              :     return a;
    1380              :   else
    1381              :     {
    1382              :       if (N > 1)
    1383              :         gcc_checking_assert (known_le (b, a));
    1384              :       return b;
    1385              :     }
    1386              : }
    1387              : 
    1388              : template<unsigned int N, typename Ca, typename Cb>
    1389              : inline CONST_POLY_RESULT (N, Ca, Cb)
    1390              : ordered_min (const Ca &a, const poly_int<N, Cb> &b)
    1391              : {
    1392              :   if (known_le (a, b))
    1393              :     return a;
    1394              :   else
    1395              :     {
    1396              :       if (N > 1)
    1397              :         gcc_checking_assert (known_le (b, a));
    1398              :       return b;
    1399              :     }
    1400              : }
    1401              : 
    1402              : template<unsigned int N, typename Ca, typename Cb>
    1403              : inline POLY_CONST_RESULT (N, Ca, Cb)
    1404              : ordered_min (const poly_int<N, Ca> &a, const Cb &b)
    1405              : {
    1406              :   if (known_le (a, b))
    1407              :     return a;
    1408              :   else
    1409              :     {
    1410              :       if (N > 1)
    1411              :         gcc_checking_assert (known_le (b, a));
    1412              :       return b;
    1413              :     }
    1414              : }
    1415              : 
    1416              : /* Assert that A and B are known to be ordered and return the maximum
    1417              :    of the two.
    1418              : 
    1419              :    NOTE: When using this function, please add a comment above the call
    1420              :    explaining why we know the values are ordered in that context.  */
    1421              : 
    1422              : template<unsigned int N, typename Ca, typename Cb>
    1423              : inline POLY_POLY_RESULT (N, Ca, Cb)
    1424       103588 : ordered_max (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
    1425              : {
    1426       103588 :   if (known_le (a, b))
    1427              :     return b;
    1428              :   else
    1429              :     {
    1430              :       if (N > 1)
    1431              :         gcc_checking_assert (known_le (b, a));
    1432              :       return a;
    1433              :     }
    1434              : }
    1435              : 
    1436              : template<unsigned int N, typename Ca, typename Cb>
    1437              : inline CONST_POLY_RESULT (N, Ca, Cb)
    1438       321935 : ordered_max (const Ca &a, const poly_int<N, Cb> &b)
    1439              : {
    1440       321935 :   if (known_le (a, b))
    1441       320293 :     return b;
    1442              :   else
    1443              :     {
    1444              :       if (N > 1)
    1445              :         gcc_checking_assert (known_le (b, a));
    1446         1642 :       return a;
    1447              :     }
    1448              : }
    1449              : 
    1450              : template<unsigned int N, typename Ca, typename Cb>
    1451              : inline POLY_CONST_RESULT (N, Ca, Cb)
    1452        83755 : ordered_max (const poly_int<N, Ca> &a, const Cb &b)
    1453              : {
    1454        83755 :   if (known_le (a, b))
    1455              :     return b;
    1456              :   else
    1457              :     {
    1458              :       if (N > 1)
    1459              :         gcc_checking_assert (known_le (b, a));
    1460              :       return a;
    1461              :     }
    1462              : }
    1463              : 
    1464              : /* Return a constant lower bound on the value of A, which is known
    1465              :    to be nonnegative.  */
    1466              : 
    1467              : template<unsigned int N, typename Ca>
    1468              : inline Ca
    1469     43157106 : constant_lower_bound (const poly_int<N, Ca> &a)
    1470              : {
    1471      3826595 :   gcc_checking_assert (known_ge (a, POLY_INT_TYPE (Ca) (0)));
    1472     40807272 :   return a.coeffs[0];
    1473              : }
    1474              : 
    1475              : /* Return the constant lower bound of A, given that it is no less than B.  */
    1476              : 
    1477              : template<unsigned int N, typename Ca, typename Cb>
    1478              : inline POLY_CONST_COEFF (Ca, Cb)
    1479              : constant_lower_bound_with_limit (const poly_int<N, Ca> &a, const Cb &b)
    1480              : {
    1481              :   if (known_ge (a, b))
    1482              :     return a.coeffs[0];
    1483              :   return b;
    1484              : }
    1485              : 
    1486              : /* Return the constant upper bound of A, given that it is no greater
    1487              :    than B.  */
    1488              : 
    1489              : template<unsigned int N, typename Ca, typename Cb>
    1490              : inline POLY_CONST_COEFF (Ca, Cb)
    1491              : constant_upper_bound_with_limit (const poly_int<N, Ca> &a, const Cb &b)
    1492              : {
    1493              :   if (known_le (a, b))
    1494              :     return a.coeffs[0];
    1495              :   return b;
    1496              : }
    1497              : 
    1498              : /* Return a value that is known to be no greater than A and B.  This
    1499              :    will be the greatest lower bound for some indeterminate values but
    1500              :    not necessarily for all.  */
    1501              : 
    1502              : template<unsigned int N, typename Ca, typename Cb>
    1503              : inline POLY_CONST_RESULT (N, Ca, Cb)
    1504           24 : lower_bound (const poly_int<N, Ca> &a, const Cb &b)
    1505              : {
    1506              :   typedef POLY_CAST (Ca, Cb) NCa;
    1507              :   typedef POLY_CAST (Cb, Ca) NCb;
    1508              :   typedef POLY_INT_TYPE (Cb) ICb;
    1509              :   typedef POLY_CONST_COEFF (Ca, Cb) C;
    1510              : 
    1511              :   poly_int<N, C> r;
    1512           24 :   POLY_SET_COEFF (C, r, 0, MIN (NCa (a.coeffs[0]), NCb (b)));
    1513              :   if (N >= 2)
    1514              :     for (unsigned int i = 1; i < N; i++)
    1515              :       POLY_SET_COEFF (C, r, i, MIN (NCa (a.coeffs[i]), ICb (0)));
    1516              :   return r;
    1517              : }
    1518              : 
    1519              : template<unsigned int N, typename Ca, typename Cb>
    1520              : inline CONST_POLY_RESULT (N, Ca, Cb)
    1521              : lower_bound (const Ca &a, const poly_int<N, Cb> &b)
    1522              : {
    1523              :   return lower_bound (b, a);
    1524              : }
    1525              : 
    1526              : template<unsigned int N, typename Ca, typename Cb>
    1527              : inline POLY_POLY_RESULT (N, Ca, Cb)
    1528         8042 : lower_bound (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
    1529              : {
    1530              :   typedef POLY_CAST (Ca, Cb) NCa;
    1531              :   typedef POLY_CAST (Cb, Ca) NCb;
    1532              :   typedef POLY_POLY_COEFF (Ca, Cb) C;
    1533              : 
    1534         8042 :   poly_int<N, C> r;
    1535       124938 :   for (unsigned int i = 0; i < N; i++)
    1536        78259 :     POLY_SET_COEFF (C, r, i, MIN (NCa (a.coeffs[i]), NCb (b.coeffs[i])));
    1537         8042 :   return r;
    1538              : }
    1539              : 
    1540              : template<typename Ca, typename Cb>
    1541              : inline CONST_CONST_RESULT (N, Ca, Cb)
    1542      1298200 : lower_bound (const Ca &a, const Cb &b)
    1543              : {
    1544      1298200 :   return a < b ? a : b;
    1545              : }
    1546              : 
    1547              : /* Return a value that is known to be no less than A and B.  This will
    1548              :    be the least upper bound for some indeterminate values but not
    1549              :    necessarily for all.  */
    1550              : 
    1551              : template<unsigned int N, typename Ca, typename Cb>
    1552              : inline POLY_CONST_RESULT (N, Ca, Cb)
    1553      7429866 : upper_bound (const poly_int<N, Ca> &a, const Cb &b)
    1554              : {
    1555              :   typedef POLY_CAST (Ca, Cb) NCa;
    1556              :   typedef POLY_CAST (Cb, Ca) NCb;
    1557              :   typedef POLY_INT_TYPE (Cb) ICb;
    1558              :   typedef POLY_CONST_COEFF (Ca, Cb) C;
    1559              : 
    1560              :   poly_int<N, C> r;
    1561      7429866 :   POLY_SET_COEFF (C, r, 0, MAX (NCa (a.coeffs[0]), NCb (b)));
    1562              :   if (N >= 2)
    1563              :     for (unsigned int i = 1; i < N; i++)
    1564              :       POLY_SET_COEFF (C, r, i, MAX (NCa (a.coeffs[i]), ICb (0)));
    1565              :   return r;
    1566              : }
    1567              : 
    1568              : template<unsigned int N, typename Ca, typename Cb>
    1569              : inline CONST_POLY_RESULT (N, Ca, Cb)
    1570              : upper_bound (const Ca &a, const poly_int<N, Cb> &b)
    1571              : {
    1572              :   return upper_bound (b, a);
    1573              : }
    1574              : 
    1575              : template<unsigned int N, typename Ca, typename Cb>
    1576              : inline POLY_POLY_RESULT (N, Ca, Cb)
    1577      7485501 : upper_bound (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
    1578              : {
    1579              :   typedef POLY_CAST (Ca, Cb) NCa;
    1580              :   typedef POLY_CAST (Cb, Ca) NCb;
    1581              :   typedef POLY_POLY_COEFF (Ca, Cb) C;
    1582              : 
    1583              :   poly_int<N, C> r;
    1584    591195132 :   for (unsigned int i = 0; i < N; i++)
    1585    360409118 :     POLY_SET_COEFF (C, r, i, MAX (NCa (a.coeffs[i]), NCb (b.coeffs[i])));
    1586              :   return r;
    1587              : }
    1588              : 
    1589              : /* Return the greatest common divisor of all nonzero coefficients, or zero
    1590              :    if all coefficients are zero.  */
    1591              : 
    1592              : template<unsigned int N, typename Ca>
    1593              : inline POLY_BINARY_COEFF (Ca, Ca)
    1594     14454683 : coeff_gcd (const poly_int<N, Ca> &a)
    1595              : {
    1596              :   /* Find the first nonzero coefficient, stopping at 0 whatever happens.  */
    1597              :   unsigned int i;
    1598     14454683 :   for (i = N - 1; i > 0; --i)
    1599              :     if (a.coeffs[i] != 0)
    1600              :       break;
    1601              :   typedef POLY_BINARY_COEFF (Ca, Ca) C;
    1602     14454683 :   C r = a.coeffs[i];
    1603              :   for (unsigned int j = 0; j < i; ++j)
    1604              :     if (a.coeffs[j] != 0)
    1605              :       r = gcd (r, C (a.coeffs[j]));
    1606              :   return r;
    1607              : }
    1608              : 
    1609              : /* Return a value that is a multiple of both A and B.  This will be the
    1610              :    least common multiple for some indeterminate values but necessarily
    1611              :    for all.  */
    1612              : 
    1613              : template<unsigned int N, typename Ca, typename Cb>
    1614              : POLY_CONST_RESULT (N, Ca, Cb)
    1615     14454683 : common_multiple (const poly_int<N, Ca> &a, Cb b)
    1616              : {
    1617     14454683 :   POLY_BINARY_COEFF (Ca, Ca) xgcd = coeff_gcd (a);
    1618     14454683 :   return a * (least_common_multiple (xgcd, b) / xgcd);
    1619              : }
    1620              : 
    1621              : template<unsigned int N, typename Ca, typename Cb>
    1622              : inline CONST_POLY_RESULT (N, Ca, Cb)
    1623              : common_multiple (const Ca &a, const poly_int<N, Cb> &b)
    1624              : {
    1625              :   return common_multiple (b, a);
    1626              : }
    1627              : 
    1628              : /* Return a value that is a multiple of both A and B, asserting that
    1629              :    such a value exists.  The result will be the least common multiple
    1630              :    for some indeterminate values but necessarily for all.
    1631              : 
    1632              :    NOTE: When using this function, please add a comment above the call
    1633              :    explaining why we know the values have a common multiple (which might
    1634              :    for example be because we know A / B is rational).  */
    1635              : 
    1636              : template<unsigned int N, typename Ca, typename Cb>
    1637              : POLY_POLY_RESULT (N, Ca, Cb)
    1638     10787694 : force_common_multiple (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
    1639              : {
    1640              :   if (b.is_constant ())
    1641     10787694 :     return common_multiple (a, b.coeffs[0]);
    1642              :   if (a.is_constant ())
    1643              :     return common_multiple (a.coeffs[0], b);
    1644              : 
    1645              :   typedef POLY_CAST (Ca, Cb) NCa;
    1646              :   typedef POLY_CAST (Cb, Ca) NCb;
    1647              :   typedef POLY_BINARY_COEFF (Ca, Cb) C;
    1648              :   typedef POLY_INT_TYPE (Ca) ICa;
    1649              : 
    1650              :   for (unsigned int i = 1; i < N; ++i)
    1651              :     if (a.coeffs[i] != ICa (0))
    1652              :       {
    1653              :         C lcm = least_common_multiple (NCa (a.coeffs[i]), NCb (b.coeffs[i]));
    1654              :         C amul = lcm / a.coeffs[i];
    1655              :         C bmul = lcm / b.coeffs[i];
    1656              :         for (unsigned int j = 0; j < N; ++j)
    1657              :           gcc_checking_assert (a.coeffs[j] * amul == b.coeffs[j] * bmul);
    1658              :         return a * amul;
    1659              :       }
    1660              :   gcc_unreachable ();
    1661              : }
    1662              : 
    1663              : /* Compare A and B for sorting purposes, returning -1 if A should come
    1664              :    before B, 0 if A and B are identical, and 1 if A should come after B.
    1665              :    This is a lexicographical compare of the coefficients in reverse order.
    1666              : 
    1667              :    A consequence of this is that all constant sizes come before all
    1668              :    non-constant ones, regardless of magnitude (since a size is never
    1669              :    negative).  This is what most callers want.  For example, when laying
    1670              :    data out on the stack, it's better to keep all the constant-sized
    1671              :    data together so that it can be accessed as a constant offset from a
    1672              :    single base.  */
    1673              : 
    1674              : template<unsigned int N, typename Ca, typename Cb>
    1675              : inline int
    1676     11310099 : compare_sizes_for_sort (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
    1677              : {
    1678     20715804 :   for (unsigned int i = N; i-- > 0; )
    1679     30499024 :     if (a.coeffs[i] != b.coeffs[i])
    1680     12734642 :       return a.coeffs[i] < b.coeffs[i] ? -1 : 1;
    1681              :   return 0;
    1682              : }
    1683              : 
    1684              : /* Return true if we can calculate VALUE & (ALIGN - 1) at compile time.  */
    1685              : 
    1686              : template<unsigned int N, typename Ca, typename Cb>
    1687              : inline bool
    1688              : can_align_p (const poly_int<N, Ca> &value, Cb align)
    1689              : {
    1690              :   for (unsigned int i = 1; i < N; i++)
    1691              :     if ((value.coeffs[i] & (align - 1)) != 0)
    1692              :       return false;
    1693              :   return true;
    1694              : }
    1695              : 
    1696              : /* Return true if we can align VALUE up to the smallest multiple of
    1697              :    ALIGN that is >= VALUE.  Store the aligned value in *ALIGNED if so.  */
    1698              : 
    1699              : template<unsigned int N, typename Ca, typename Cb>
    1700              : inline bool
    1701       244066 : can_align_up (const poly_int<N, Ca> &value, Cb align,
    1702              :               poly_int<N, Ca> *aligned)
    1703              : {
    1704              :   if (!can_align_p (value, align))
    1705              :     return false;
    1706       244066 :   *aligned = value + (-value.coeffs[0] & (align - 1));
    1707              :   return true;
    1708              : }
    1709              : 
    1710              : /* Return true if we can align VALUE down to the largest multiple of
    1711              :    ALIGN that is <= VALUE.  Store the aligned value in *ALIGNED if so.  */
    1712              : 
    1713              : template<unsigned int N, typename Ca, typename Cb>
    1714              : inline bool
    1715              : can_align_down (const poly_int<N, Ca> &value, Cb align,
    1716              :                 poly_int<N, Ca> *aligned)
    1717              : {
    1718              :   if (!can_align_p (value, align))
    1719              :     return false;
    1720      1423548 :   *aligned = value - (value.coeffs[0] & (align - 1));
    1721              :   return true;
    1722              : }
    1723              : 
    1724              : /* Return true if we can align A and B up to the smallest multiples of
    1725              :    ALIGN that are >= A and B respectively, and if doing so gives the
    1726              :    same value.  */
    1727              : 
    1728              : template<unsigned int N, typename Ca, typename Cb, typename Cc>
    1729              : inline bool
    1730       244066 : known_equal_after_align_up (const poly_int<N, Ca> &a,
    1731              :                             const poly_int<N, Cb> &b,
    1732              :                             Cc align)
    1733              : {
    1734              :   poly_int<N, Ca> aligned_a;
    1735              :   poly_int<N, Cb> aligned_b;
    1736       244066 :   return (can_align_up (a, align, &aligned_a)
    1737       244066 :           && can_align_up (b, align, &aligned_b)
    1738       244066 :           && known_eq (aligned_a, aligned_b));
    1739              : }
    1740              : 
    1741              : /* Return true if we can align A and B down to the largest multiples of
    1742              :    ALIGN that are <= A and B respectively, and if doing so gives the
    1743              :    same value.  */
    1744              : 
    1745              : template<unsigned int N, typename Ca, typename Cb, typename Cc>
    1746              : inline bool
    1747      1423548 : known_equal_after_align_down (const poly_int<N, Ca> &a,
    1748              :                               const poly_int<N, Cb> &b,
    1749              :                               Cc align)
    1750              : {
    1751              :   poly_int<N, Ca> aligned_a;
    1752              :   poly_int<N, Cb> aligned_b;
    1753      1423548 :   return (can_align_down (a, align, &aligned_a)
    1754      1423548 :           && can_align_down (b, align, &aligned_b)
    1755      1423548 :           && known_eq (aligned_a, aligned_b));
    1756              : }
    1757              : 
    1758              : /* Assert that we can align VALUE to ALIGN at compile time and return
    1759              :    the smallest multiple of ALIGN that is >= VALUE.
    1760              : 
    1761              :    NOTE: When using this function, please add a comment above the call
    1762              :    explaining why we know the non-constant coefficients must already
    1763              :    be a multiple of ALIGN.  */
    1764              : 
    1765              : template<unsigned int N, typename Ca, typename Cb>
    1766              : inline poly_int<N, Ca>
    1767      7322631 : force_align_up (const poly_int<N, Ca> &value, Cb align)
    1768              : {
    1769              :   gcc_checking_assert (can_align_p (value, align));
    1770      7322631 :   return value + (-value.coeffs[0] & (align - 1));
    1771              : }
    1772              : 
    1773              : /* Assert that we can align VALUE to ALIGN at compile time and return
    1774              :    the largest multiple of ALIGN that is <= VALUE.
    1775              : 
    1776              :    NOTE: When using this function, please add a comment above the call
    1777              :    explaining why we know the non-constant coefficients must already
    1778              :    be a multiple of ALIGN.  */
    1779              : 
    1780              : template<unsigned int N, typename Ca, typename Cb>
    1781              : inline poly_int<N, Ca>
    1782      5459863 : force_align_down (const poly_int<N, Ca> &value, Cb align)
    1783              : {
    1784              :   gcc_checking_assert (can_align_p (value, align));
    1785      5459863 :   return value - (value.coeffs[0] & (align - 1));
    1786              : }
    1787              : 
    1788              : /* Return a value <= VALUE that is a multiple of ALIGN.  It will be the
    1789              :    greatest such value for some indeterminate values but not necessarily
    1790              :    for all.  */
    1791              : 
    1792              : template<unsigned int N, typename Ca, typename Cb>
    1793              : inline poly_int<N, Ca>
    1794    238999161 : aligned_lower_bound (const poly_int<N, Ca> &value, Cb align)
    1795              : {
    1796              :   poly_int<N, Ca> r;
    1797    238999161 :   for (unsigned int i = 0; i < N; i++)
    1798              :     /* This form copes correctly with more type combinations than
    1799              :        value.coeffs[i] & -align would.  */
    1800    238999161 :     POLY_SET_COEFF (Ca, r, i, (value.coeffs[i]
    1801              :                                - (value.coeffs[i] & (align - 1))));
    1802              :   return r;
    1803              : }
    1804              : 
    1805              : /* Return a value >= VALUE that is a multiple of ALIGN.  It will be the
    1806              :    least such value for some indeterminate values but not necessarily
    1807              :    for all.  */
    1808              : 
    1809              : template<unsigned int N, typename Ca, typename Cb>
    1810              : inline poly_int<N, Ca>
    1811    240899556 : aligned_upper_bound (const poly_int<N, Ca> &value, Cb align)
    1812              : {
    1813              :   poly_int<N, Ca> r;
    1814    240899556 :   for (unsigned int i = 0; i < N; i++)
    1815    240889672 :     POLY_SET_COEFF (Ca, r, i, (value.coeffs[i]
    1816              :                                + (-value.coeffs[i] & (align - 1))));
    1817         9884 :   return r;
    1818              : }
    1819              : 
    1820              : /* Assert that we can align VALUE to ALIGN at compile time.  Align VALUE
    1821              :    down to the largest multiple of ALIGN that is <= VALUE, then divide by
    1822              :    ALIGN.
    1823              : 
    1824              :    NOTE: When using this function, please add a comment above the call
    1825              :    explaining why we know the non-constant coefficients must already
    1826              :    be a multiple of ALIGN.  */
    1827              : 
    1828              : template<unsigned int N, typename Ca, typename Cb>
    1829              : inline poly_int<N, Ca>
    1830     15307419 : force_align_down_and_div (const poly_int<N, Ca> &value, Cb align)
    1831              : {
    1832              :   gcc_checking_assert (can_align_p (value, align));
    1833              : 
    1834         4658 :   poly_int<N, Ca> r;
    1835     15307419 :   POLY_SET_COEFF (Ca, r, 0, ((value.coeffs[0]
    1836              :                               - (value.coeffs[0] & (align - 1)))
    1837              :                              / align));
    1838              :   if (N >= 2)
    1839              :     for (unsigned int i = 1; i < N; i++)
    1840              :       POLY_SET_COEFF (Ca, r, i, value.coeffs[i] / align);
    1841         4658 :   return r;
    1842              : }
    1843              : 
    1844              : /* Assert that we can align VALUE to ALIGN at compile time.  Align VALUE
    1845              :    up to the smallest multiple of ALIGN that is >= VALUE, then divide by
    1846              :    ALIGN.
    1847              : 
    1848              :    NOTE: When using this function, please add a comment above the call
    1849              :    explaining why we know the non-constant coefficients must already
    1850              :    be a multiple of ALIGN.  */
    1851              : 
    1852              : template<unsigned int N, typename Ca, typename Cb>
    1853              : inline poly_int<N, Ca>
    1854      5558040 : force_align_up_and_div (const poly_int<N, Ca> &value, Cb align)
    1855              : {
    1856              :   gcc_checking_assert (can_align_p (value, align));
    1857              : 
    1858              :   poly_int<N, Ca> r;
    1859      5558040 :   POLY_SET_COEFF (Ca, r, 0, ((value.coeffs[0]
    1860              :                               + (-value.coeffs[0] & (align - 1)))
    1861              :                              / align));
    1862              :   if (N >= 2)
    1863              :     for (unsigned int i = 1; i < N; i++)
    1864              :       POLY_SET_COEFF (Ca, r, i, value.coeffs[i] / align);
    1865              :   return r;
    1866              : }
    1867              : 
    1868              : /* Return true if we know at compile time the difference between VALUE
    1869              :    and the equal or preceding multiple of ALIGN.  Store the value in
    1870              :    *MISALIGN if so.  */
    1871              : 
    1872              : template<unsigned int N, typename Ca, typename Cb, typename Cm>
    1873              : inline bool
    1874     20909995 : known_misalignment (const poly_int<N, Ca> &value, Cb align, Cm *misalign)
    1875              : {
    1876     20909995 :   gcc_checking_assert (align != 0);
    1877              :   if (!can_align_p (value, align))
    1878              :     return false;
    1879     20909995 :   *misalign = value.coeffs[0] & (align - 1);
    1880              :   return true;
    1881              : }
    1882              : 
    1883              : /* Return X & (Y - 1), asserting that this value is known.  Please add
    1884              :    an a comment above callers to this function to explain why the condition
    1885              :    is known to hold.  */
    1886              : 
    1887              : template<unsigned int N, typename Ca, typename Cb>
    1888              : inline POLY_BINARY_COEFF (Ca, Ca)
    1889      1345684 : force_get_misalignment (const poly_int<N, Ca> &a, Cb align)
    1890              : {
    1891              :   gcc_checking_assert (can_align_p (a, align));
    1892      1345684 :   return a.coeffs[0] & (align - 1);
    1893              : }
    1894              : 
    1895              : /* Return the maximum alignment that A is known to have.  Return 0
    1896              :    if A is known to be zero.  */
    1897              : 
    1898              : template<unsigned int N, typename Ca>
    1899              : inline POLY_BINARY_COEFF (Ca, Ca)
    1900     51844592 : known_alignment (const poly_int<N, Ca> &a)
    1901              : {
    1902              :   typedef POLY_BINARY_COEFF (Ca, Ca) C;
    1903      4467167 :   C r = a.coeffs[0];
    1904              :   for (unsigned int i = 1; i < N; ++i)
    1905              :     r |= a.coeffs[i];
    1906    160517729 :   return r & -r;
    1907              : }
    1908              : 
    1909              : /* Return true if we can compute A & B at compile time, storing the
    1910              :    result in RES if so.  */
    1911              : 
    1912              : template<unsigned int N, typename Ca, typename Cb, typename Cr>
    1913              : inline typename if_nonpoly<Cb, bool>::type
    1914              : can_and_p (const poly_int<N, Ca> &a, Cb b, Cr *result)
    1915              : {
    1916              :   /* Coefficients 1 and above must be a multiple of something greater
    1917              :      than ~B.  */
    1918              :   typedef POLY_INT_TYPE (Ca) int_type;
    1919              :   if (N >= 2)
    1920              :     for (unsigned int i = 1; i < N; i++)
    1921              :       if ((-(a.coeffs[i] & -a.coeffs[i]) & ~b) != int_type (0))
    1922              :         return false;
    1923              :   *result = a;
    1924              :   result->coeffs[0] &= b;
    1925              :   return true;
    1926              : }
    1927              : 
    1928              : /* Return true if we can compute A | B at compile time, storing the
    1929              :    result in RES if so.  */
    1930              : 
    1931              : template<unsigned int N, typename Ca, typename Cb, typename Cr>
    1932              : inline typename if_nonpoly<Cb, bool>::type
    1933            0 : can_ior_p (const poly_int<N, Ca> &a, Cb b, Cr *result)
    1934              : {
    1935              :   /* Coefficients 1 and above must be a multiple of something greater
    1936              :      than B.  */
    1937              :   typedef POLY_INT_TYPE (Ca) int_type;
    1938              :   if (N >= 2)
    1939              :     for (unsigned int i = 1; i < N; i++)
    1940              :       if ((-(a.coeffs[i] & -a.coeffs[i]) & b) != int_type (0))
    1941              :         return false;
    1942              :   *result = a;
    1943            0 :   result->coeffs[0] |= b;
    1944              :   return true;
    1945              : }
    1946              : 
    1947              : /* Return true if A is a constant multiple of B, storing the
    1948              :    multiple in *MULTIPLE if so.  */
    1949              : 
    1950              : template<unsigned int N, typename Ca, typename Cb, typename Cm>
    1951              : inline typename if_nonpoly<Cb, bool>::type
    1952       150645 : constant_multiple_p (const poly_int<N, Ca> &a, Cb b, Cm *multiple)
    1953              : {
    1954              :   typedef POLY_CAST (Ca, Cb) NCa;
    1955              :   typedef POLY_CAST (Cb, Ca) NCb;
    1956              : 
    1957              :   /* Do the modulus before the constant check, to catch divide by
    1958              :      zero errors.  */
    1959       150645 :   if (NCa (a.coeffs[0]) % NCb (b) != 0 || !a.is_constant ())
    1960              :     return false;
    1961       150645 :   *multiple = NCa (a.coeffs[0]) / NCb (b);
    1962       117071 :   return true;
    1963              : }
    1964              : 
    1965              : template<unsigned int N, typename Ca, typename Cb, typename Cm>
    1966              : inline typename if_nonpoly<Ca, bool>::type
    1967              : constant_multiple_p (Ca a, const poly_int<N, Cb> &b, Cm *multiple)
    1968              : {
    1969              :   typedef POLY_CAST (Ca, Cb) NCa;
    1970              :   typedef POLY_CAST (Cb, Ca) NCb;
    1971              :   typedef POLY_INT_TYPE (Ca) int_type;
    1972              : 
    1973              :   /* Do the modulus before the constant check, to catch divide by
    1974              :      zero errors.  */
    1975              :   if (NCa (a) % NCb (b.coeffs[0]) != 0
    1976              :       || (a != int_type (0) && !b.is_constant ()))
    1977              :     return false;
    1978              :   *multiple = NCa (a) / NCb (b.coeffs[0]);
    1979              :   return true;
    1980              : }
    1981              : 
    1982              : template<unsigned int N, typename Ca, typename Cb, typename Cm>
    1983              : inline bool
    1984    116355476 : constant_multiple_p (const poly_int<N, Ca> &a,
    1985              :                      const poly_int<N, Cb> &b, Cm *multiple)
    1986              : {
    1987              :   typedef POLY_CAST (Ca, Cb) NCa;
    1988              :   typedef POLY_CAST (Cb, Ca) NCb;
    1989              :   typedef POLY_INT_TYPE (Ca) ICa;
    1990              :   typedef POLY_INT_TYPE (Cb) ICb;
    1991              :   typedef POLY_BINARY_COEFF (Ca, Cb) C;
    1992              : 
    1993    116355476 :   if (NCa (a.coeffs[0]) % NCb (b.coeffs[0]) != 0)
    1994              :     return false;
    1995              : 
    1996    115880132 :   C r = NCa (a.coeffs[0]) / NCb (b.coeffs[0]);
    1997     39632817 :   for (unsigned int i = 1; i < N; ++i)
    1998              :     if (b.coeffs[i] == ICb (0)
    1999              :         ? a.coeffs[i] != ICa (0)
    2000              :         : (NCa (a.coeffs[i]) % NCb (b.coeffs[i]) != 0
    2001              :            || NCa (a.coeffs[i]) / NCb (b.coeffs[i]) != r))
    2002              :       return false;
    2003              : 
    2004     52873022 :   *multiple = r;
    2005     39632817 :   return true;
    2006              : }
    2007              : 
    2008              : /* Return true if A is a constant multiple of B.  */
    2009              : 
    2010              : template<unsigned int N, typename Ca, typename Cb>
    2011              : inline typename if_nonpoly<Cb, bool>::type
    2012        22083 : constant_multiple_p (const poly_int<N, Ca> &a, Cb b)
    2013              : {
    2014              :   typedef POLY_CAST (Ca, Cb) NCa;
    2015              :   typedef POLY_CAST (Cb, Ca) NCb;
    2016              : 
    2017              :   /* Do the modulus before the constant check, to catch divide by
    2018              :      zero errors.  */
    2019        22083 :   if (NCa (a.coeffs[0]) % NCb (b) != 0 || !a.is_constant ())
    2020              :     return false;
    2021              :   return true;
    2022              : }
    2023              : 
    2024              : template<unsigned int N, typename Ca, typename Cb>
    2025              : inline typename if_nonpoly<Ca, bool>::type
    2026              : constant_multiple_p (Ca a, const poly_int<N, Cb> &b)
    2027              : {
    2028              :   typedef POLY_CAST (Ca, Cb) NCa;
    2029              :   typedef POLY_CAST (Cb, Ca) NCb;
    2030              :   typedef POLY_INT_TYPE (Ca) int_type;
    2031              : 
    2032              :   /* Do the modulus before the constant check, to catch divide by
    2033              :      zero errors.  */
    2034              :   if (NCa (a) % NCb (b.coeffs[0]) != 0
    2035              :       || (a != int_type (0) && !b.is_constant ()))
    2036              :     return false;
    2037              :   return true;
    2038              : }
    2039              : 
    2040              : template<unsigned int N, typename Ca, typename Cb>
    2041              : inline bool
    2042     30352830 : constant_multiple_p (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
    2043              : {
    2044              :   typedef POLY_CAST (Ca, Cb) NCa;
    2045              :   typedef POLY_CAST (Cb, Ca) NCb;
    2046              :   typedef POLY_INT_TYPE (Ca) ICa;
    2047              :   typedef POLY_INT_TYPE (Cb) ICb;
    2048              :   typedef POLY_BINARY_COEFF (Ca, Cb) C;
    2049              : 
    2050     30352830 :   if (NCa (a.coeffs[0]) % NCb (b.coeffs[0]) != 0)
    2051              :     return false;
    2052              : 
    2053              :   C r = NCa (a.coeffs[0]) / NCb (b.coeffs[0]);
    2054              :   for (unsigned int i = 1; i < N; ++i)
    2055              :     if (b.coeffs[i] == ICb (0)
    2056              :         ? a.coeffs[i] != ICa (0)
    2057              :         : (NCa (a.coeffs[i]) % NCb (b.coeffs[i]) != 0
    2058              :            || NCa (a.coeffs[i]) / NCb (b.coeffs[i]) != r))
    2059              :       return false;
    2060              :   return true;
    2061              : }
    2062              : 
    2063              : 
    2064              : /* Return true if A is a multiple of B.  */
    2065              : 
    2066              : template<typename Ca, typename Cb>
    2067              : inline typename if_nonpoly2<Ca, Cb, bool>::type
    2068      1839879 : multiple_p (Ca a, Cb b)
    2069              : {
    2070      1839879 :   return a % b == 0;
    2071              : }
    2072              : 
    2073              : /* Return true if A is a (polynomial) multiple of B.  */
    2074              : 
    2075              : template<unsigned int N, typename Ca, typename Cb>
    2076              : inline typename if_nonpoly<Cb, bool>::type
    2077    416223291 : multiple_p (const poly_int<N, Ca> &a, Cb b)
    2078              : {
    2079    607598260 :   for (unsigned int i = 0; i < N; ++i)
    2080    332654859 :     if (a.coeffs[i] % b != 0)
    2081              :       return false;
    2082              :   return true;
    2083              : }
    2084              : 
    2085              : /* Return true if A is a (constant) multiple of B.  */
    2086              : 
    2087              : template<unsigned int N, typename Ca, typename Cb>
    2088              : inline typename if_nonpoly<Ca, bool>::type
    2089     23137282 : multiple_p (Ca a, const poly_int<N, Cb> &b)
    2090              : {
    2091              :   typedef POLY_INT_TYPE (Ca) int_type;
    2092              : 
    2093              :   /* Do the modulus before the constant check, to catch divide by
    2094              :      potential zeros.  */
    2095     23137282 :   return a % b.coeffs[0] == 0 && (a == int_type (0) || b.is_constant ());
    2096              : }
    2097              : 
    2098              : /* Return true if A is a (polynomial) multiple of B.  This handles cases
    2099              :    where either B is constant or the multiple is constant.  */
    2100              : 
    2101              : template<unsigned int N, typename Ca, typename Cb>
    2102              : inline bool
    2103    124860378 : multiple_p (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
    2104              : {
    2105              :   if (b.is_constant ())
    2106    127829860 :     return multiple_p (a, b.coeffs[0]);
    2107              :   POLY_BINARY_COEFF (Ca, Ca) tmp;
    2108              :   return constant_multiple_p (a, b, &tmp);
    2109              : }
    2110              : 
    2111              : /* Return true if A is a (constant) multiple of B, storing the
    2112              :    multiple in *MULTIPLE if so.  */
    2113              : 
    2114              : template<typename Ca, typename Cb, typename Cm>
    2115              : inline typename if_nonpoly2<Ca, Cb, bool>::type
    2116            2 : multiple_p (Ca a, Cb b, Cm *multiple)
    2117              : {
    2118            2 :   if (a % b != 0)
    2119              :     return false;
    2120            2 :   *multiple = a / b;
    2121              :   return true;
    2122              : }
    2123              : 
    2124              : /* Return true if A is a (polynomial) multiple of B, storing the
    2125              :    multiple in *MULTIPLE if so.  */
    2126              : 
    2127              : template<unsigned int N, typename Ca, typename Cb, typename Cm>
    2128              : inline typename if_nonpoly<Cb, bool>::type
    2129    130197066 : multiple_p (const poly_int<N, Ca> &a, Cb b, poly_int<N, Cm> *multiple)
    2130              : {
    2131    110258849 :   if (!multiple_p (a, b))
    2132              :     return false;
    2133    149856005 :   for (unsigned int i = 0; i < N; ++i)
    2134    124219513 :     multiple->coeffs[i] = a.coeffs[i] / b;
    2135              :   return true;
    2136              : }
    2137              : 
    2138              : /* Return true if B is a constant and A is a (constant) multiple of B,
    2139              :    storing the multiple in *MULTIPLE if so.  */
    2140              : 
    2141              : template<unsigned int N, typename Ca, typename Cb, typename Cm>
    2142              : inline typename if_nonpoly<Ca, bool>::type
    2143        42111 : multiple_p (Ca a, const poly_int<N, Cb> &b, Cm *multiple)
    2144              : {
    2145              :   typedef POLY_CAST (Ca, Cb) NCa;
    2146              : 
    2147              :   /* Do the modulus before the constant check, to catch divide by
    2148              :      potential zeros.  */
    2149        22740 :   if (a % b.coeffs[0] != 0 || (NCa (a) != 0 && !b.is_constant ()))
    2150              :     return false;
    2151        19371 :   *multiple = a / b.coeffs[0];
    2152              :   return true;
    2153              : }
    2154              : 
    2155              : /* Return true if A is a (polynomial) multiple of B, storing the
    2156              :    multiple in *MULTIPLE if so.  This handles cases where either
    2157              :    B is constant or the multiple is constant.  */
    2158              : 
    2159              : template<unsigned int N, typename Ca, typename Cb, typename Cm>
    2160              : inline bool
    2161     16361087 : multiple_p (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b,
    2162              :             poly_int<N, Cm> *multiple)
    2163              : {
    2164              :   if (b.is_constant ())
    2165     16361087 :     return multiple_p (a, b.coeffs[0], multiple);
    2166              :   return constant_multiple_p (a, b, multiple);
    2167              : }
    2168              : 
    2169              : /* Return A / B, given that A is known to be a multiple of B.  */
    2170              : 
    2171              : template<unsigned int N, typename Ca, typename Cb>
    2172              : inline POLY_CONST_RESULT (N, Ca, Cb)
    2173     66617878 : exact_div (const poly_int<N, Ca> &a, Cb b)
    2174              : {
    2175              :   typedef POLY_CONST_COEFF (Ca, Cb) C;
    2176              :   poly_int<N, C> r;
    2177    133235756 :   for (unsigned int i = 0; i < N; i++)
    2178              :     {
    2179     66617878 :       gcc_checking_assert (a.coeffs[i] % b == 0);
    2180     66617878 :       POLY_SET_COEFF (C, r, i, a.coeffs[i] / b);
    2181              :     }
    2182     66617878 :   return r;
    2183              : }
    2184              : 
    2185              : /* Return A / B, given that A is known to be a multiple of B.  */
    2186              : 
    2187              : template<unsigned int N, typename Ca, typename Cb>
    2188              : inline POLY_POLY_RESULT (N, Ca, Cb)
    2189     11483654 : exact_div (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
    2190              : {
    2191              :   if (b.is_constant ())
    2192     11353869 :     return exact_div (a, b.coeffs[0]);
    2193              : 
    2194              :   typedef POLY_CAST (Ca, Cb) NCa;
    2195              :   typedef POLY_CAST (Cb, Ca) NCb;
    2196              :   typedef POLY_BINARY_COEFF (Ca, Cb) C;
    2197              :   typedef POLY_INT_TYPE (Cb) int_type;
    2198              : 
    2199              :   gcc_checking_assert (a.coeffs[0] % b.coeffs[0] == 0);
    2200              :   C r = NCa (a.coeffs[0]) / NCb (b.coeffs[0]);
    2201              :   for (unsigned int i = 1; i < N; ++i)
    2202              :     gcc_checking_assert (b.coeffs[i] == int_type (0)
    2203              :                          ? a.coeffs[i] == int_type (0)
    2204              :                          : (a.coeffs[i] % b.coeffs[i] == 0
    2205              :                             && NCa (a.coeffs[i]) / NCb (b.coeffs[i]) == r));
    2206              : 
    2207              :   return r;
    2208              : }
    2209              : 
    2210              : /* Return true if there is some constant Q and polynomial r such that:
    2211              : 
    2212              :      (1) a = b * Q + r
    2213              :      (2) |b * Q| <= |a|
    2214              :      (3) |r| < |b|
    2215              : 
    2216              :    Store the value Q in *QUOTIENT if so.  */
    2217              : 
    2218              : template<unsigned int N, typename Ca, typename Cb, typename Cq>
    2219              : inline typename if_nonpoly2<Cb, Cq, bool>::type
    2220      1018892 : can_div_trunc_p (const poly_int<N, Ca> &a, Cb b, Cq *quotient)
    2221              : {
    2222              :   typedef POLY_CAST (Ca, Cb) NCa;
    2223              :   typedef POLY_CAST (Cb, Ca) NCb;
    2224              : 
    2225              :   /* Do the division before the constant check, to catch divide by
    2226              :      zero errors.  */
    2227      1018892 :   Cq q = NCa (a.coeffs[0]) / NCb (b);
    2228              :   if (!a.is_constant ())
    2229              :     return false;
    2230      1018892 :   *quotient = q;
    2231              :   return true;
    2232              : }
    2233              : 
    2234              : template<unsigned int N, typename Ca, typename Cb, typename Cq>
    2235              : inline typename if_nonpoly<Cq, bool>::type
    2236     71421638 : can_div_trunc_p (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b,
    2237              :                  Cq *quotient)
    2238              : {
    2239              :   /* We can calculate Q from the case in which the indeterminates
    2240              :      are zero.  */
    2241              :   typedef POLY_CAST (Ca, Cb) NCa;
    2242              :   typedef POLY_CAST (Cb, Ca) NCb;
    2243              :   typedef POLY_INT_TYPE (Ca) ICa;
    2244              :   typedef POLY_INT_TYPE (Cb) ICb;
    2245              :   typedef POLY_BINARY_COEFF (Ca, Cb) C;
    2246    121618627 :   C q = NCa (a.coeffs[0]) / NCb (b.coeffs[0]);
    2247              : 
    2248              :   /* Check the other coefficients and record whether the division is exact.
    2249              :      The only difficult case is when it isn't.  If we require a and b to
    2250              :      ordered wrt zero, there can be no two coefficients of the same value
    2251              :      that have opposite signs.  This means that:
    2252              : 
    2253              :          |a| = |a0| + |a1 * x1| + |a2 * x2| + ...
    2254              :          |b| = |b0| + |b1 * x1| + |b2 * x2| + ...
    2255              : 
    2256              :       The Q we've just calculated guarantees:
    2257              : 
    2258              :          |b0 * Q| <= |a0|
    2259              :          |a0 - b0 * Q| < |b0|
    2260              : 
    2261              :       and so:
    2262              : 
    2263              :          (2) |b * Q| <= |a|
    2264              : 
    2265              :       is satisfied if:
    2266              : 
    2267              :          |bi * xi * Q| <= |ai * xi|
    2268              : 
    2269              :       for each i in [1, N].  This is trivially true when xi is zero.
    2270              :       When it isn't we need:
    2271              : 
    2272              :          (2') |bi * Q| <= |ai|
    2273              : 
    2274              :       r is calculated as:
    2275              : 
    2276              :          r = r0 + r1 * x1 + r2 * x2 + ...
    2277              :          where ri = ai - bi * Q
    2278              : 
    2279              :       Restricting to ordered a and b also guarantees that no two ris
    2280              :       have opposite signs, so we have:
    2281              : 
    2282              :          |r| = |r0| + |r1 * x1| + |r2 * x2| + ...
    2283              : 
    2284              :       We know from the calculation of Q that |r0| < |b0|, so:
    2285              : 
    2286              :          (3) |r| < |b|
    2287              : 
    2288              :       is satisfied if:
    2289              : 
    2290              :          (3') |ai - bi * Q| <= |bi|
    2291              : 
    2292              :       for each i in [1, N].  */
    2293    121618627 :   bool rem_p = NCa (a.coeffs[0]) % NCb (b.coeffs[0]) != 0;
    2294              :   for (unsigned int i = 1; i < N; ++i)
    2295              :     {
    2296              :       if (b.coeffs[i] == ICb (0))
    2297              :         {
    2298              :           /* For bi == 0 we simply need: (3') |ai| == 0.  */
    2299              :           if (a.coeffs[i] != ICa (0))
    2300              :             return false;
    2301              :         }
    2302              :       else
    2303              :         {
    2304              :           /* The only unconditional arithmetic that we can do on ai,
    2305              :              bi and Q is ai / bi and ai % bi.  (ai == minimum int and
    2306              :              bi == -1 would be UB in the caller.)  Anything else runs
    2307              :              the risk of overflow.  */
    2308              :           auto qi = NCa (a.coeffs[i]) / NCb (b.coeffs[i]);
    2309              :           auto ri = NCa (a.coeffs[i]) % NCb (b.coeffs[i]);
    2310              :           /* (2') and (3') are satisfied when ai /[trunc] bi == q.
    2311              :              So is the stricter condition |ai - bi * Q| < |bi|.  */
    2312              :           if (qi == q)
    2313              :             rem_p |= (ri != 0);
    2314              :           /* The only other case is when:
    2315              : 
    2316              :                  |bi * Q| + |bi| = |ai| (for (2'))
    2317              :              and |ai - bi * Q|   = |bi| (for (3'))
    2318              : 
    2319              :              The first is equivalent to |bi|(|Q| + 1) == |ai|.
    2320              :              The second requires ai == bi * (Q + 1) or ai == bi * (Q - 1).  */
    2321              :           else if (ri != 0)
    2322              :             return false;
    2323              :           else if (q <= 0 && qi < q && qi + 1 == q)
    2324              :             ;
    2325              :           else if (q >= 0 && qi > q && qi - 1 == q)
    2326              :             ;
    2327              :           else
    2328              :             return false;
    2329              :         }
    2330              :     }
    2331              : 
    2332              :   /* If the division isn't exact, require both values to be ordered wrt 0,
    2333              :      so that we can guarantee conditions (2) and (3) for all indeterminate
    2334              :      values.  */
    2335              :   if (rem_p && (!ordered_p (a, ICa (0)) || !ordered_p (b, ICb (0))))
    2336              :     return false;
    2337              : 
    2338    121110504 :   *quotient = q;
    2339              :   return true;
    2340              : }
    2341              : 
    2342              : /* Likewise, but also store r in *REMAINDER.  */
    2343              : 
    2344              : template<unsigned int N, typename Ca, typename Cb, typename Cq, typename Cr>
    2345              : inline typename if_nonpoly<Cq, bool>::type
    2346     14763579 : can_div_trunc_p (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b,
    2347              :                  Cq *quotient, Cr *remainder)
    2348              : {
    2349     64960568 :   if (!can_div_trunc_p (a, b, quotient))
    2350              :     return false;
    2351     64960568 :   *remainder = a - *quotient * b;
    2352              :   return true;
    2353              : }
    2354              : 
    2355              : /* Return true if there is some polynomial q and constant R such that:
    2356              : 
    2357              :      (1) a = B * q + R
    2358              :      (2) |B * q| <= |a|
    2359              :      (3) |R| < |B|
    2360              : 
    2361              :    Store the value q in *QUOTIENT if so.  */
    2362              : 
    2363              : template<unsigned int N, typename Ca, typename Cb, typename Cq>
    2364              : inline typename if_nonpoly<Cb, bool>::type
    2365       705697 : can_div_trunc_p (const poly_int<N, Ca> &a, Cb b,
    2366              :                  poly_int<N, Cq> *quotient)
    2367              : {
    2368              :   /* The remainder must be constant.  */
    2369       705697 :   for (unsigned int i = 1; i < N; ++i)
    2370              :     if (a.coeffs[i] % b != 0)
    2371              :       return false;
    2372       705697 :   for (unsigned int i = 0; i < N; ++i)
    2373       705697 :     quotient->coeffs[i] = a.coeffs[i] / b;
    2374              :   return true;
    2375              : }
    2376              : 
    2377              : /* Likewise, but also store R in *REMAINDER.  */
    2378              : 
    2379              : template<unsigned int N, typename Ca, typename Cb, typename Cq, typename Cr>
    2380              : inline typename if_nonpoly<Cb, bool>::type
    2381       275150 : can_div_trunc_p (const poly_int<N, Ca> &a, Cb b,
    2382              :                  poly_int<N, Cq> *quotient, Cr *remainder)
    2383              : {
    2384       275150 :   if (!can_div_trunc_p (a, b, quotient))
    2385              :     return false;
    2386       275150 :   *remainder = a.coeffs[0] % b;
    2387              :   return true;
    2388              : }
    2389              : 
    2390              : /* Return true if we can compute A / B at compile time, rounding towards zero.
    2391              :    Store the result in QUOTIENT if so.
    2392              : 
    2393              :    This handles cases in which either B is constant or the result is
    2394              :    constant.  */
    2395              : 
    2396              : template<unsigned int N, typename Ca, typename Cb, typename Cq>
    2397              : inline bool
    2398       300864 : can_div_trunc_p (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b,
    2399              :                  poly_int<N, Cq> *quotient)
    2400              : {
    2401              :   if (b.is_constant ())
    2402       300864 :     return can_div_trunc_p (a, b.coeffs[0], quotient);
    2403              :   if (!can_div_trunc_p (a, b, &quotient->coeffs[0]))
    2404              :     return false;
    2405              :   for (unsigned int i = 1; i < N; ++i)
    2406              :     quotient->coeffs[i] = 0;
    2407              :   return true;
    2408              : }
    2409              : 
    2410              : /* Return true if there is some constant Q and polynomial r such that:
    2411              : 
    2412              :      (1) a = b * Q + r
    2413              :      (2) |a| <= |b * Q|
    2414              :      (3) |r| < |b|
    2415              : 
    2416              :    Store the value Q in *QUOTIENT if so.  */
    2417              : 
    2418              : template<unsigned int N, typename Ca, typename Cb, typename Cq>
    2419              : inline typename if_nonpoly<Cq, bool>::type
    2420     56657940 : can_div_away_from_zero_p (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b,
    2421              :                           Cq *quotient)
    2422              : {
    2423     56657940 :   if (!can_div_trunc_p (a, b, quotient))
    2424              :     return false;
    2425     44404016 :   if (maybe_ne (*quotient * b, a))
    2426     29729546 :     *quotient += (*quotient < 0 ? -1 : 1);
    2427              :   return true;
    2428              : }
    2429              : 
    2430              : /* Use print_dec to print VALUE to FILE, where SGN is the sign
    2431              :    of the values.  */
    2432              : 
    2433              : template<unsigned int N, typename C>
    2434              : void
    2435         3143 : print_dec (const poly_int<N, C> &value, FILE *file, signop sgn)
    2436              : {
    2437              :   if (value.is_constant ())
    2438         3143 :     print_dec (value.coeffs[0], file, sgn);
    2439              :   else
    2440              :     {
    2441              :       fprintf (file, "[");
    2442              :       for (unsigned int i = 0; i < N; ++i)
    2443              :         {
    2444              :           print_dec (value.coeffs[i], file, sgn);
    2445              :           fputc (i == N - 1 ? ']' : ',', file);
    2446              :         }
    2447              :     }
    2448         3143 : }
    2449              : 
    2450              : /* Likewise without the signop argument, for coefficients that have an
    2451              :    inherent signedness.  */
    2452              : 
    2453              : template<unsigned int N, typename C>
    2454              : void
    2455         1585 : print_dec (const poly_int<N, C> &value, FILE *file)
    2456              : {
    2457              :   STATIC_ASSERT (poly_coeff_traits<C>::signedness >= 0);
    2458         1585 :   print_dec (value, file,
    2459              :              poly_coeff_traits<C>::signedness ? SIGNED : UNSIGNED);
    2460              : }
    2461              : 
    2462              : /* Use print_hex to print VALUE to FILE.  */
    2463              : 
    2464              : template<unsigned int N, typename C>
    2465              : void
    2466       168238 : print_hex (const poly_int<N, C> &value, FILE *file)
    2467              : {
    2468              :   if (value.is_constant ())
    2469       168238 :     print_hex (value.coeffs[0], file);
    2470              :   else
    2471              :     {
    2472              :       fprintf (file, "[");
    2473              :       for (unsigned int i = 0; i < N; ++i)
    2474              :         {
    2475              :           print_hex (value.coeffs[i], file);
    2476              :           fputc (i == N - 1 ? ']' : ',', file);
    2477              :         }
    2478              :     }
    2479       168238 : }
    2480              : 
    2481              : /* Helper for calculating the distance between two points P1 and P2,
    2482              :    in cases where known_le (P1, P2).  T1 and T2 are the types of the
    2483              :    two positions, in either order.  The coefficients of P2 - P1 have
    2484              :    type unsigned HOST_WIDE_INT if the coefficients of both T1 and T2
    2485              :    have C++ primitive type, otherwise P2 - P1 has its usual
    2486              :    wide-int-based type.
    2487              : 
    2488              :    The actual subtraction should look something like this:
    2489              : 
    2490              :      typedef poly_span_traits<T1, T2> span_traits;
    2491              :      span_traits::cast (P2) - span_traits::cast (P1)
    2492              : 
    2493              :    Applying the cast before the subtraction avoids undefined overflow
    2494              :    for signed T1 and T2.
    2495              : 
    2496              :    The implementation of the cast tries to avoid unnecessary arithmetic
    2497              :    or copying.  */
    2498              : template<typename T1, typename T2,
    2499              :          typename Res = POLY_BINARY_COEFF (POLY_BINARY_COEFF (T1, T2),
    2500              :                                            unsigned HOST_WIDE_INT)>
    2501              : struct poly_span_traits
    2502              : {
    2503              :   template<typename T>
    2504              :   static const T &cast (const T &x) { return x; }
    2505              : };
    2506              : 
    2507              : template<typename T1, typename T2>
    2508              : struct poly_span_traits<T1, T2, unsigned HOST_WIDE_INT>
    2509              : {
    2510              :   template<typename T>
    2511              :   static typename if_nonpoly<T, unsigned HOST_WIDE_INT>::type
    2512      6078304 :   cast (const T &x) { return x; }
    2513              : 
    2514              :   template<unsigned int N, typename T>
    2515              :   static poly_int<N, unsigned HOST_WIDE_INT>
    2516    464006277 :   cast (const poly_int<N, T> &x) { return x; }
    2517              : };
    2518              : 
    2519              : /* Return true if SIZE represents a known size, assuming that all-ones
    2520              :    indicates an unknown size.  */
    2521              : 
    2522              : template<typename T>
    2523              : inline bool
    2524   9651970406 : known_size_p (const T &a)
    2525              : {
    2526   5780592436 :   return maybe_ne (a, POLY_INT_TYPE (T) (-1));
    2527              : }
    2528              : 
    2529              : /* Return true if range [POS, POS + SIZE) might include VAL.
    2530              :    SIZE can be the special value -1, in which case the range is
    2531              :    open-ended.  */
    2532              : 
    2533              : template<typename T1, typename T2, typename T3>
    2534              : inline bool
    2535    952799583 : maybe_in_range_p (const T1 &val, const T2 &pos, const T3 &size)
    2536              : {
    2537              :   typedef poly_span_traits<T1, T2> start_span;
    2538              :   typedef poly_span_traits<T3, T3> size_span;
    2539    952762053 :   if (known_lt (val, pos))
    2540              :     return false;
    2541    590214474 :   if (!known_size_p (size))
    2542              :     return true;
    2543              :   if ((poly_int_traits<T1>::num_coeffs > 1
    2544              :        || poly_int_traits<T2>::num_coeffs > 1)
    2545              :       && maybe_lt (val, pos))
    2546              :     /* In this case we don't know whether VAL >= POS is true at compile
    2547              :        time, so we can't prove that VAL >= POS + SIZE.  */
    2548              :     return true;
    2549    401251232 :   return maybe_lt (start_span::cast (val) - start_span::cast (pos),
    2550    521154042 :                    size_span::cast (size));
    2551              : }
    2552              : 
    2553              : /* Return true if range [POS, POS + SIZE) is known to include VAL.
    2554              :    SIZE can be the special value -1, in which case the range is
    2555              :    open-ended.  */
    2556              : 
    2557              : template<typename T1, typename T2, typename T3>
    2558              : inline bool
    2559     13786379 : known_in_range_p (const T1 &val, const T2 &pos, const T3 &size)
    2560              : {
    2561              :   typedef poly_span_traits<T1, T2> start_span;
    2562              :   typedef poly_span_traits<T3, T3> size_span;
    2563     13786379 :   return (known_size_p (size)
    2564     13786379 :           && known_ge (val, pos)
    2565     26451923 :           && known_lt (start_span::cast (val) - start_span::cast (pos),
    2566              :                        size_span::cast (size)));
    2567              : }
    2568              : 
    2569              : /* Return true if the two ranges [POS1, POS1 + SIZE1) and [POS2, POS2 + SIZE2)
    2570              :    might overlap.  SIZE1 and/or SIZE2 can be the special value -1, in which
    2571              :    case the range is open-ended.  */
    2572              : 
    2573              : template<typename T1, typename T2, typename T3, typename T4>
    2574              : inline bool
    2575    590211794 : ranges_maybe_overlap_p (const T1 &pos1, const T2 &size1,
    2576              :                         const T3 &pos2, const T4 &size2)
    2577              : {
    2578    589842267 :   if (maybe_in_range_p (pos2, pos1, size1))
    2579    227623448 :     return maybe_ne (size2, POLY_INT_TYPE (T4) (0));
    2580    314578464 :   if (maybe_in_range_p (pos1, pos2, size2))
    2581     67256223 :     return maybe_ne (size1, POLY_INT_TYPE (T2) (0));
    2582              :   return false;
    2583              : }
    2584              : 
    2585              : /* Return true if the two ranges [POS1, POS1 + SIZE1) and [POS2, POS2 + SIZE2)
    2586              :    are known to overlap.  SIZE1 and/or SIZE2 can be the special value -1,
    2587              :    in which case the range is open-ended.  */
    2588              : 
    2589              : template<typename T1, typename T2, typename T3, typename T4>
    2590              : inline bool
    2591      1423263 : ranges_known_overlap_p (const T1 &pos1, const T2 &size1,
    2592              :                         const T3 &pos2, const T4 &size2)
    2593              : {
    2594              :   typedef poly_span_traits<T1, T3> start_span;
    2595              :   typedef poly_span_traits<T2, T2> size1_span;
    2596              :   typedef poly_span_traits<T4, T4> size2_span;
    2597              :   /* known_gt (POS1 + SIZE1, POS2)                         [infinite precision]
    2598              :      --> known_gt (SIZE1, POS2 - POS1)                     [infinite precision]
    2599              :      --> known_gt (SIZE1, POS2 - lower_bound (POS1, POS2)) [infinite precision]
    2600              :                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ always nonnegative
    2601              :      --> known_gt (SIZE1, span1::cast (POS2 - lower_bound (POS1, POS2))).
    2602              : 
    2603              :      Using the saturating subtraction enforces that SIZE1 must be
    2604              :      nonzero, since known_gt (0, x) is false for all nonnegative x.
    2605              :      If POS2.coeff[I] < POS1.coeff[I] for some I > 0, increasing
    2606              :      indeterminate number I makes the unsaturated condition easier to
    2607              :      satisfy, so using a saturated coefficient of zero tests the case in
    2608              :      which the indeterminate is zero (the minimum value).  */
    2609      1423263 :   return (known_size_p (size1)
    2610      1337017 :           && known_size_p (size2)
    2611      1337013 :           && known_lt (start_span::cast (pos2)
    2612              :                        - start_span::cast (lower_bound (pos1, pos2)),
    2613              :                        size1_span::cast (size1))
    2614      2575567 :           && known_lt (start_span::cast (pos1)
    2615              :                        - start_span::cast (lower_bound (pos1, pos2)),
    2616      1423263 :                        size2_span::cast (size2)));
    2617              : }
    2618              : 
    2619              : /* Return true if range [POS1, POS1 + SIZE1) is known to be a subrange of
    2620              :    [POS2, POS2 + SIZE2).  SIZE1 and/or SIZE2 can be the special value -1,
    2621              :    in which case the range is open-ended.  */
    2622              : 
    2623              : template<typename T1, typename T2, typename T3, typename T4>
    2624              : inline bool
    2625    273326812 : known_subrange_p (const T1 &pos1, const T2 &size1,
    2626              :                   const T3 &pos2, const T4 &size2)
    2627              : {
    2628              :   typedef typename poly_int_traits<T2>::coeff_type C2;
    2629              :   typedef poly_span_traits<T1, T3> start_span;
    2630              :   typedef poly_span_traits<T2, T4> size_span;
    2631    273326812 :   return (known_gt (size1, POLY_INT_TYPE (T2) (0))
    2632        12800 :           && (poly_coeff_traits<C2>::signedness > 0
    2633        12800 :               || known_size_p (size1))
    2634    273260861 :           && known_size_p (size2)
    2635    272532935 :           && known_ge (pos1, pos2)
    2636     75841438 :           && known_le (size1, size2)
    2637    335817170 :           && known_le (start_span::cast (pos1) - start_span::cast (pos2),
    2638    273326812 :                        size_span::cast (size2) - size_span::cast (size1)));
    2639              : }
    2640              : 
    2641              : /* Return true if the endpoint of the range [POS, POS + SIZE) can be
    2642              :    stored in a T, or if SIZE is the special value -1, which makes the
    2643              :    range open-ended.  */
    2644              : 
    2645              : template<typename T>
    2646              : inline typename if_nonpoly<T, bool>::type
    2647              : endpoint_representable_p (const T &pos, const T &size)
    2648              : {
    2649              :   return (!known_size_p (size)
    2650              :           || pos <= poly_coeff_traits<T>::max_value - size);
    2651              : }
    2652              : 
    2653              : template<unsigned int N, typename C>
    2654              : inline bool
    2655   6142430472 : endpoint_representable_p (const poly_int<N, C> &pos,
    2656              :                           const poly_int<N, C> &size)
    2657              : {
    2658   3078806449 :   if (known_size_p (size))
    2659   6142430260 :     for (unsigned int i = 0; i < N; ++i)
    2660   6142430472 :       if (pos.coeffs[i] > poly_coeff_traits<C>::max_value - size.coeffs[i])
    2661              :         return false;
    2662              :   return true;
    2663              : }
    2664              : 
    2665              : template<unsigned int N, typename C>
    2666              : void
    2667              : gt_ggc_mx (poly_int<N, C> *)
    2668              : {
    2669              : }
    2670              : 
    2671              : template<unsigned int N, typename C>
    2672              : void
    2673              : gt_pch_nx (poly_int<N, C> *)
    2674              : {
    2675              : }
    2676              : 
    2677              : template<unsigned int N, typename C>
    2678              : void
    2679              : gt_pch_nx (poly_int<N, C> *, gt_pointer_operator, void *)
    2680              : {
    2681              : }
    2682              : 
    2683              : #undef POLY_SET_COEFF
    2684              : #undef POLY_INT_TYPE
    2685              : #undef POLY_BINARY_COEFF
    2686              : #undef CONST_CONST_RESULT
    2687              : #undef POLY_CONST_RESULT
    2688              : #undef CONST_POLY_RESULT
    2689              : #undef POLY_POLY_RESULT
    2690              : #undef POLY_CONST_COEFF
    2691              : #undef CONST_POLY_COEFF
    2692              : #undef POLY_POLY_COEFF
    2693              : 
    2694              : #endif
        

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.