LCOV - code coverage report
Current view: top level - gcc - poly-int.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 97.7 % 391 382
Test Date: 2024-04-20 14:03:02 Functions: 89.8 % 325 292
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

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

Generated by: LCOV version 2.1-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.