LCOV - code coverage report
Current view: top level - gcc - poly-int.h (source / functions) Hit Total Coverage
Test: gcc.info Lines: 29 31 93.5 %
Date: 2023-07-19 08:18:47 Functions: 4 4 100.0 %

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

Generated by: LCOV version 1.16