libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / poly-int.h
blob94708165961625da64238c7ed66463802a344c71
1 /* Polynomial integer classes.
2 Copyright (C) 2014-2024 Free Software Foundation, Inc.
4 This file is part of GCC.
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.
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.
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/>. */
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.
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. */
29 #ifndef HAVE_POLY_INT_H
30 #define HAVE_POLY_INT_H
32 template<unsigned int N, typename T> class poly_int;
34 /* poly_coeff_traiits<T> describes the properties of a poly_int
35 coefficient type T:
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:
40 (2 * number of bytes) + (unsigned ? 1 : 0)
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.
46 - poly_coeff_traits<T>::int_type is the type to which an integer
47 literal should be cast before comparing it with T.
49 - poly_coeff_traits<T>::precision is the number of bits that T can hold.
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).
56 - poly_coeff_traits<T>::max_value, if defined, is the maximum value of T.
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.
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;
68 template<typename T>
69 struct poly_coeff_traits<T, wi::FLEXIBLE_PRECISION>
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;
81 template<typename Arg>
82 struct init_cast { using type = T; };
85 template<typename T>
86 struct poly_coeff_traits<T, wi::VAR_PRECISION>
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;
94 template<typename Arg>
95 struct init_cast { using type = const Arg &; };
98 template<typename T>
99 struct poly_coeff_traits<T, wi::INL_CONST_PRECISION>
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;
108 template<typename Arg>
109 struct init_cast { using type = const Arg &; };
112 template<typename T>
113 struct poly_coeff_traits<T, wi::CONST_PRECISION>
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;
122 template<typename Arg>
123 struct init_cast { using type = const Arg &; };
126 /* Information about a pair of coefficient types. */
127 template<typename T1, typename T2>
128 struct poly_coeff_pair_traits
130 /* True if T1 can represent all the values of T2.
132 Either:
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.
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.
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)));
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))
161 : (RANK (T1) <= RANK (unsigned HOST_WIDE_INT)
162 && RANK (T2) <= RANK (unsigned HOST_WIDE_INT))
163 ? 1 : 2);
164 #undef RANK
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>
175 typedef T3 type;
178 /* poly_int_traits<T> describes an integer type T that might be polynomial
179 or non-polynomial:
181 - poly_int_traits<T>::is_poly is true if T is a poly_int-based type
182 and false otherwise.
184 - poly_int_traits<T>::num_coeffs gives the number of coefficients in T
185 if T is a poly_int and 1 otherwise.
187 - poly_int_traits<T>::coeff_type gives the coefficent type of T if T
188 is a poly_int and T itself otherwise
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
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;
200 template<unsigned int N, typename C>
201 struct poly_int_traits<poly_int<N, C> >
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;
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>
217 typedef T2 type;
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>
229 typedef T3 type;
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>
240 typedef T2 type;
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:
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.
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;
260 /* Promote pair to HOST_WIDE_INT. */
261 template<typename T1, typename T2>
262 struct poly_result<T1, T2, 0>
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;
270 /* Promote pair to unsigned HOST_WIDE_INT. */
271 template<typename T1, typename T2>
272 struct poly_result<T1, T2, 1>
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;
280 /* Use normal wide-int rules. */
281 template<typename T1, typename T2>
282 struct poly_result<T1, T2, 2>
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;
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
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)
302 /* Likewise in reverse. */
303 #define CONST_POLY_COEFF(T1, C2) \
304 POLY_POLY_COEFF (typename if_nonpoly<T1>::type, C2)
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)>
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)>
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)>
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)
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
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
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
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.
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.
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)))
357 /* Number of bits needed to represent maximum value of
358 NUM_POLY_INT_COEFFS defined by any target. */
359 #define MAX_NUM_POLY_INT_COEFFS_BITS 2
361 /* poly_int_full and poly_int_hungry are used internally within poly_int
362 for delegated initializers. poly_int_full indicates that a parameter
363 pack has enough elements to initialize every coefficient. poly_int_hungry
364 indicates that at least one extra zero must be added. */
365 struct poly_int_full {};
366 struct poly_int_hungry {};
368 /* poly_int_fullness<B>::type is poly_int_full when B is true and
369 poly_int_hungry when B is false. */
370 template<bool> struct poly_int_fullness;
371 template<> struct poly_int_fullness<false> { using type = poly_int_hungry; };
372 template<> struct poly_int_fullness<true> { using type = poly_int_full; };
374 /* A class containing polynomial integers. The polynomial has N coefficients
375 of type C, and N - 1 indeterminates. */
376 template<unsigned int N, typename C>
377 struct poly_int
379 public:
380 poly_int () = default;
381 poly_int (const poly_int &) = default;
383 template<typename Ca>
384 poly_int (const poly_int<N, Ca> &);
386 template<typename ...Cs>
387 constexpr poly_int (const Cs &...);
389 poly_int &operator = (const poly_int &) = default;
391 template<typename Ca>
392 poly_int &operator = (const poly_int<N, Ca> &);
393 template<typename Ca>
394 typename if_nonpoly<Ca, poly_int>::type &operator = (const Ca &);
396 template<typename Ca>
397 poly_int &operator += (const poly_int<N, Ca> &);
398 template<typename Ca>
399 typename if_nonpoly<Ca, poly_int>::type &operator += (const Ca &);
401 template<typename Ca>
402 poly_int &operator -= (const poly_int<N, Ca> &);
403 template<typename Ca>
404 typename if_nonpoly<Ca, poly_int>::type &operator -= (const Ca &);
406 template<typename Ca>
407 typename if_nonpoly<Ca, poly_int>::type &operator *= (const Ca &);
409 poly_int &operator <<= (unsigned int);
411 bool is_constant () const;
413 template<typename T>
414 typename if_lossless<T, C, bool>::type is_constant (T *) const;
416 C to_constant () const;
418 template<typename Ca>
419 static poly_int<N, C> from (const poly_int<N, Ca> &, unsigned int,
420 signop);
421 template<typename Ca>
422 static poly_int<N, C> from (const poly_int<N, Ca> &, signop);
424 bool to_shwi (poly_int<N, HOST_WIDE_INT> *) const;
425 bool to_uhwi (poly_int<N, unsigned HOST_WIDE_INT> *) const;
426 poly_int<N, HOST_WIDE_INT> force_shwi () const;
427 poly_int<N, unsigned HOST_WIDE_INT> force_uhwi () const;
429 #if POLY_INT_CONVERSION
430 operator C () const;
431 #endif
433 C coeffs[N];
435 private:
436 template<typename ...Cs>
437 constexpr poly_int (poly_int_full, const Cs &...);
439 template<typename C0, typename ...Cs>
440 constexpr poly_int (poly_int_hungry, const C0 &, const Cs &...);
443 template<unsigned int N, typename C>
444 template<typename Ca>
445 inline
446 poly_int<N, C>::poly_int (const poly_int<N, Ca> &a)
448 for (unsigned int i = 0; i < N; i++)
449 POLY_SET_COEFF (C, *this, i, a.coeffs[i]);
452 template<unsigned int N, typename C>
453 template<typename ...Cs>
454 inline constexpr
455 poly_int<N, C>::poly_int (const Cs &... cs)
456 : poly_int (typename poly_int_fullness<sizeof... (Cs) >= N>::type (),
457 cs...) {}
459 /* Initialize with c0, cs..., and some trailing zeros. */
460 template<unsigned int N, typename C>
461 template<typename C0, typename ...Cs>
462 inline constexpr
463 poly_int<N, C>::poly_int (poly_int_hungry, const C0 &c0, const Cs &... cs)
464 : poly_int (c0, cs..., wi::ints_for<C>::zero (c0)) {}
466 /* Initialize with cs... directly, casting where necessary. */
467 template<unsigned int N, typename C>
468 template<typename ...Cs>
469 inline constexpr
470 poly_int<N, C>::poly_int (poly_int_full, const Cs &... cs)
471 : coeffs { (typename poly_coeff_traits<C>::
472 template init_cast<Cs>::type (cs))... } {}
474 template<unsigned int N, typename C>
475 template<typename Ca>
476 inline poly_int<N, C>&
477 poly_int<N, C>::operator = (const poly_int<N, Ca> &a)
479 for (unsigned int i = 0; i < N; i++)
480 POLY_SET_COEFF (C, *this, i, a.coeffs[i]);
481 return *this;
484 template<unsigned int N, typename C>
485 template<typename Ca>
486 inline typename if_nonpoly<Ca, poly_int<N, C> >::type &
487 poly_int<N, C>::operator = (const Ca &a)
489 POLY_SET_COEFF (C, *this, 0, a);
490 if (N >= 2)
491 for (unsigned int i = 1; i < N; i++)
492 POLY_SET_COEFF (C, *this, i, wi::ints_for<C>::zero (this->coeffs[0]));
493 return *this;
496 template<unsigned int N, typename C>
497 template<typename Ca>
498 inline poly_int<N, C>&
499 poly_int<N, C>::operator += (const poly_int<N, Ca> &a)
501 for (unsigned int i = 0; i < N; i++)
502 this->coeffs[i] += a.coeffs[i];
503 return *this;
506 template<unsigned int N, typename C>
507 template<typename Ca>
508 inline typename if_nonpoly<Ca, poly_int<N, C> >::type &
509 poly_int<N, C>::operator += (const Ca &a)
511 this->coeffs[0] += a;
512 return *this;
515 template<unsigned int N, typename C>
516 template<typename Ca>
517 inline poly_int<N, C>&
518 poly_int<N, C>::operator -= (const poly_int<N, Ca> &a)
520 for (unsigned int i = 0; i < N; i++)
521 this->coeffs[i] -= a.coeffs[i];
522 return *this;
525 template<unsigned int N, typename C>
526 template<typename Ca>
527 inline typename if_nonpoly<Ca, poly_int<N, C> >::type &
528 poly_int<N, C>::operator -= (const Ca &a)
530 this->coeffs[0] -= a;
531 return *this;
534 template<unsigned int N, typename C>
535 template<typename Ca>
536 inline typename if_nonpoly<Ca, poly_int<N, C> >::type &
537 poly_int<N, C>::operator *= (const Ca &a)
539 for (unsigned int i = 0; i < N; i++)
540 this->coeffs[i] *= a;
541 return *this;
544 template<unsigned int N, typename C>
545 inline poly_int<N, C>&
546 poly_int<N, C>::operator <<= (unsigned int a)
548 for (unsigned int i = 0; i < N; i++)
549 this->coeffs[i] <<= a;
550 return *this;
553 /* Return true if the polynomial value is a compile-time constant. */
555 template<unsigned int N, typename C>
556 inline bool
557 poly_int<N, C>::is_constant () const
559 if (N >= 2)
560 for (unsigned int i = 1; i < N; i++)
561 if (this->coeffs[i] != 0)
562 return false;
563 return true;
566 /* Return true if the polynomial value is a compile-time constant,
567 storing its value in CONST_VALUE if so. */
569 template<unsigned int N, typename C>
570 template<typename T>
571 inline typename if_lossless<T, C, bool>::type
572 poly_int<N, C>::is_constant (T *const_value) const
574 if (is_constant ())
576 *const_value = this->coeffs[0];
577 return true;
579 return false;
582 /* Return the value of a polynomial that is already known to be a
583 compile-time constant.
585 NOTE: When using this function, please add a comment above the call
586 explaining why we know the value is constant in that context. */
588 template<unsigned int N, typename C>
589 inline C
590 poly_int<N, C>::to_constant () const
592 gcc_checking_assert (is_constant ());
593 return this->coeffs[0];
596 /* Convert X to a wide_int-based polynomial in which each coefficient
597 has BITSIZE bits. If X's coefficients are smaller than BITSIZE,
598 extend them according to SGN. */
600 template<unsigned int N, typename C>
601 template<typename Ca>
602 inline poly_int<N, C>
603 poly_int<N, C>::from (const poly_int<N, Ca> &a, unsigned int bitsize,
604 signop sgn)
606 poly_int<N, C> r;
607 for (unsigned int i = 0; i < N; i++)
608 POLY_SET_COEFF (C, r, i, C::from (a.coeffs[i], bitsize, sgn));
609 return r;
612 /* Convert X to a fixed_wide_int-based polynomial, extending according
613 to SGN. */
615 template<unsigned int N, typename C>
616 template<typename Ca>
617 inline poly_int<N, C>
618 poly_int<N, C>::from (const poly_int<N, Ca> &a, signop sgn)
620 poly_int<N, C> r;
621 for (unsigned int i = 0; i < N; i++)
622 POLY_SET_COEFF (C, r, i, C::from (a.coeffs[i], sgn));
623 return r;
626 /* Return true if the coefficients of this generic_wide_int-based
627 polynomial can be represented as signed HOST_WIDE_INTs without loss
628 of precision. Store the HOST_WIDE_INT representation in *R if so. */
630 template<unsigned int N, typename C>
631 inline bool
632 poly_int<N, C>::to_shwi (poly_int<N, HOST_WIDE_INT> *r) const
634 for (unsigned int i = 0; i < N; i++)
635 if (!wi::fits_shwi_p (this->coeffs[i]))
636 return false;
637 for (unsigned int i = 0; i < N; i++)
638 r->coeffs[i] = this->coeffs[i].to_shwi ();
639 return true;
642 /* Return true if the coefficients of this generic_wide_int-based
643 polynomial can be represented as unsigned HOST_WIDE_INTs without
644 loss of precision. Store the unsigned HOST_WIDE_INT representation
645 in *R if so. */
647 template<unsigned int N, typename C>
648 inline bool
649 poly_int<N, C>::to_uhwi (poly_int<N, unsigned HOST_WIDE_INT> *r) const
651 for (unsigned int i = 0; i < N; i++)
652 if (!wi::fits_uhwi_p (this->coeffs[i]))
653 return false;
654 for (unsigned int i = 0; i < N; i++)
655 r->coeffs[i] = this->coeffs[i].to_uhwi ();
656 return true;
659 /* Force a generic_wide_int-based constant to HOST_WIDE_INT precision,
660 truncating if necessary. */
662 template<unsigned int N, typename C>
663 inline poly_int<N, HOST_WIDE_INT>
664 poly_int<N, C>::force_shwi () const
666 poly_int<N, HOST_WIDE_INT> r;
667 for (unsigned int i = 0; i < N; i++)
668 r.coeffs[i] = this->coeffs[i].to_shwi ();
669 return r;
672 /* Force a generic_wide_int-based constant to unsigned HOST_WIDE_INT precision,
673 truncating if necessary. */
675 template<unsigned int N, typename C>
676 inline poly_int<N, unsigned HOST_WIDE_INT>
677 poly_int<N, C>::force_uhwi () const
679 poly_int<N, unsigned HOST_WIDE_INT> r;
680 for (unsigned int i = 0; i < N; i++)
681 r.coeffs[i] = this->coeffs[i].to_uhwi ();
682 return r;
685 #if POLY_INT_CONVERSION
686 /* Provide a conversion operator to constants. */
688 template<unsigned int N, typename C>
689 inline
690 poly_int<N, C>::operator C () const
692 gcc_checking_assert (this->is_constant ());
693 return this->coeffs[0];
695 #endif
697 /* Return true if every coefficient of A is in the inclusive range [B, C]. */
699 template<typename Ca, typename Cb, typename Cc>
700 inline typename if_nonpoly<Ca, bool>::type
701 coeffs_in_range_p (const Ca &a, const Cb &b, const Cc &c)
703 return a >= b && a <= c;
706 template<unsigned int N, typename Ca, typename Cb, typename Cc>
707 inline typename if_nonpoly<Ca, bool>::type
708 coeffs_in_range_p (const poly_int<N, Ca> &a, const Cb &b, const Cc &c)
710 for (unsigned int i = 0; i < N; i++)
711 if (a.coeffs[i] < b || a.coeffs[i] > c)
712 return false;
713 return true;
716 namespace wi {
717 /* Poly version of wi::shwi, with the same interface. */
719 template<unsigned int N>
720 inline poly_int<N, hwi_with_prec>
721 shwi (const poly_int<N, HOST_WIDE_INT> &a, unsigned int precision)
723 poly_int<N, hwi_with_prec> r;
724 for (unsigned int i = 0; i < N; i++)
725 POLY_SET_COEFF (hwi_with_prec, r, i, wi::shwi (a.coeffs[i], precision));
726 return r;
729 /* Poly version of wi::uhwi, with the same interface. */
731 template<unsigned int N>
732 inline poly_int<N, hwi_with_prec>
733 uhwi (const poly_int<N, unsigned HOST_WIDE_INT> &a, unsigned int precision)
735 poly_int<N, hwi_with_prec> r;
736 for (unsigned int i = 0; i < N; i++)
737 POLY_SET_COEFF (hwi_with_prec, r, i, wi::uhwi (a.coeffs[i], precision));
738 return r;
741 /* Poly version of wi::sext, with the same interface. */
743 template<unsigned int N, typename Ca>
744 inline POLY_POLY_RESULT (N, Ca, Ca)
745 sext (const poly_int<N, Ca> &a, unsigned int precision)
747 typedef POLY_POLY_COEFF (Ca, Ca) C;
748 poly_int<N, C> r;
749 for (unsigned int i = 0; i < N; i++)
750 POLY_SET_COEFF (C, r, i, wi::sext (a.coeffs[i], precision));
751 return r;
754 /* Poly version of wi::zext, with the same interface. */
756 template<unsigned int N, typename Ca>
757 inline POLY_POLY_RESULT (N, Ca, Ca)
758 zext (const poly_int<N, Ca> &a, unsigned int precision)
760 typedef POLY_POLY_COEFF (Ca, Ca) C;
761 poly_int<N, C> r;
762 for (unsigned int i = 0; i < N; i++)
763 POLY_SET_COEFF (C, r, i, wi::zext (a.coeffs[i], precision));
764 return r;
768 template<unsigned int N, typename Ca, typename Cb>
769 inline POLY_POLY_RESULT (N, Ca, Cb)
770 operator + (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
772 typedef POLY_CAST (Ca, Cb) NCa;
773 typedef POLY_POLY_COEFF (Ca, Cb) C;
774 poly_int<N, C> r;
775 for (unsigned int i = 0; i < N; i++)
776 POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]) + b.coeffs[i]);
777 return r;
780 template<unsigned int N, typename Ca, typename Cb>
781 inline POLY_CONST_RESULT (N, Ca, Cb)
782 operator + (const poly_int<N, Ca> &a, const Cb &b)
784 typedef POLY_CAST (Ca, Cb) NCa;
785 typedef POLY_CONST_COEFF (Ca, Cb) C;
786 poly_int<N, C> r;
787 POLY_SET_COEFF (C, r, 0, NCa (a.coeffs[0]) + b);
788 if (N >= 2)
789 for (unsigned int i = 1; i < N; i++)
790 POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]));
791 return r;
794 template<unsigned int N, typename Ca, typename Cb>
795 inline CONST_POLY_RESULT (N, Ca, Cb)
796 operator + (const Ca &a, const poly_int<N, Cb> &b)
798 typedef POLY_CAST (Cb, Ca) NCb;
799 typedef CONST_POLY_COEFF (Ca, Cb) C;
800 poly_int<N, C> r;
801 POLY_SET_COEFF (C, r, 0, a + NCb (b.coeffs[0]));
802 if (N >= 2)
803 for (unsigned int i = 1; i < N; i++)
804 POLY_SET_COEFF (C, r, i, NCb (b.coeffs[i]));
805 return r;
808 namespace wi {
809 /* Poly versions of wi::add, with the same interface. */
811 template<unsigned int N, typename Ca, typename Cb>
812 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
813 add (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
815 typedef WI_BINARY_RESULT (Ca, Cb) C;
816 poly_int<N, C> r;
817 for (unsigned int i = 0; i < N; i++)
818 POLY_SET_COEFF (C, r, i, wi::add (a.coeffs[i], b.coeffs[i]));
819 return r;
822 template<unsigned int N, typename Ca, typename Cb>
823 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
824 add (const poly_int<N, Ca> &a, const Cb &b)
826 typedef WI_BINARY_RESULT (Ca, Cb) C;
827 poly_int<N, C> r;
828 POLY_SET_COEFF (C, r, 0, wi::add (a.coeffs[0], b));
829 for (unsigned int i = 1; i < N; i++)
830 POLY_SET_COEFF (C, r, i, wi::add (a.coeffs[i],
831 wi::ints_for<Cb>::zero (b)));
832 return r;
835 template<unsigned int N, typename Ca, typename Cb>
836 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
837 add (const Ca &a, const poly_int<N, Cb> &b)
839 typedef WI_BINARY_RESULT (Ca, Cb) C;
840 poly_int<N, C> r;
841 POLY_SET_COEFF (C, r, 0, wi::add (a, b.coeffs[0]));
842 for (unsigned int i = 1; i < N; i++)
843 POLY_SET_COEFF (C, r, i, wi::add (wi::ints_for<Ca>::zero (a),
844 b.coeffs[i]));
845 return r;
848 template<unsigned int N, typename Ca, typename Cb>
849 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
850 add (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b,
851 signop sgn, wi::overflow_type *overflow)
853 typedef WI_BINARY_RESULT (Ca, Cb) C;
854 poly_int<N, C> r;
855 POLY_SET_COEFF (C, r, 0, wi::add (a.coeffs[0], b.coeffs[0], sgn, overflow));
856 for (unsigned int i = 1; i < N; i++)
858 wi::overflow_type suboverflow;
859 POLY_SET_COEFF (C, r, i, wi::add (a.coeffs[i], b.coeffs[i], sgn,
860 &suboverflow));
861 wi::accumulate_overflow (*overflow, suboverflow);
863 return r;
867 template<unsigned int N, typename Ca, typename Cb>
868 inline POLY_POLY_RESULT (N, Ca, Cb)
869 operator - (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
871 typedef POLY_CAST (Ca, Cb) NCa;
872 typedef POLY_POLY_COEFF (Ca, Cb) C;
873 poly_int<N, C> r;
874 for (unsigned int i = 0; i < N; i++)
875 POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]) - b.coeffs[i]);
876 return r;
879 template<unsigned int N, typename Ca, typename Cb>
880 inline POLY_CONST_RESULT (N, Ca, Cb)
881 operator - (const poly_int<N, Ca> &a, const Cb &b)
883 typedef POLY_CAST (Ca, Cb) NCa;
884 typedef POLY_CONST_COEFF (Ca, Cb) C;
885 poly_int<N, C> r;
886 POLY_SET_COEFF (C, r, 0, NCa (a.coeffs[0]) - b);
887 if (N >= 2)
888 for (unsigned int i = 1; i < N; i++)
889 POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]));
890 return r;
893 template<unsigned int N, typename Ca, typename Cb>
894 inline CONST_POLY_RESULT (N, Ca, Cb)
895 operator - (const Ca &a, const poly_int<N, Cb> &b)
897 typedef POLY_CAST (Cb, Ca) NCb;
898 typedef CONST_POLY_COEFF (Ca, Cb) C;
899 poly_int<N, C> r;
900 POLY_SET_COEFF (C, r, 0, a - NCb (b.coeffs[0]));
901 if (N >= 2)
902 for (unsigned int i = 1; i < N; i++)
903 POLY_SET_COEFF (C, r, i, -NCb (b.coeffs[i]));
904 return r;
907 namespace wi {
908 /* Poly versions of wi::sub, with the same interface. */
910 template<unsigned int N, typename Ca, typename Cb>
911 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
912 sub (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
914 typedef WI_BINARY_RESULT (Ca, Cb) C;
915 poly_int<N, C> r;
916 for (unsigned int i = 0; i < N; i++)
917 POLY_SET_COEFF (C, r, i, wi::sub (a.coeffs[i], b.coeffs[i]));
918 return r;
921 template<unsigned int N, typename Ca, typename Cb>
922 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
923 sub (const poly_int<N, Ca> &a, const Cb &b)
925 typedef WI_BINARY_RESULT (Ca, Cb) C;
926 poly_int<N, C> r;
927 POLY_SET_COEFF (C, r, 0, wi::sub (a.coeffs[0], b));
928 for (unsigned int i = 1; i < N; i++)
929 POLY_SET_COEFF (C, r, i, wi::sub (a.coeffs[i],
930 wi::ints_for<Cb>::zero (b)));
931 return r;
934 template<unsigned int N, typename Ca, typename Cb>
935 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
936 sub (const Ca &a, const poly_int<N, Cb> &b)
938 typedef WI_BINARY_RESULT (Ca, Cb) C;
939 poly_int<N, C> r;
940 POLY_SET_COEFF (C, r, 0, wi::sub (a, b.coeffs[0]));
941 for (unsigned int i = 1; i < N; i++)
942 POLY_SET_COEFF (C, r, i, wi::sub (wi::ints_for<Ca>::zero (a),
943 b.coeffs[i]));
944 return r;
947 template<unsigned int N, typename Ca, typename Cb>
948 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
949 sub (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b,
950 signop sgn, wi::overflow_type *overflow)
952 typedef WI_BINARY_RESULT (Ca, Cb) C;
953 poly_int<N, C> r;
954 POLY_SET_COEFF (C, r, 0, wi::sub (a.coeffs[0], b.coeffs[0], sgn, overflow));
955 for (unsigned int i = 1; i < N; i++)
957 wi::overflow_type suboverflow;
958 POLY_SET_COEFF (C, r, i, wi::sub (a.coeffs[i], b.coeffs[i], sgn,
959 &suboverflow));
960 wi::accumulate_overflow (*overflow, suboverflow);
962 return r;
966 template<unsigned int N, typename Ca>
967 inline POLY_POLY_RESULT (N, Ca, Ca)
968 operator - (const poly_int<N, Ca> &a)
970 typedef POLY_CAST (Ca, Ca) NCa;
971 typedef POLY_POLY_COEFF (Ca, Ca) C;
972 poly_int<N, C> r;
973 for (unsigned int i = 0; i < N; i++)
974 POLY_SET_COEFF (C, r, i, -NCa (a.coeffs[i]));
975 return r;
978 namespace wi {
979 /* Poly version of wi::neg, with the same interface. */
981 template<unsigned int N, typename Ca>
982 inline poly_int<N, WI_UNARY_RESULT (Ca)>
983 neg (const poly_int<N, Ca> &a)
985 typedef WI_UNARY_RESULT (Ca) C;
986 poly_int<N, C> r;
987 for (unsigned int i = 0; i < N; i++)
988 POLY_SET_COEFF (C, r, i, wi::neg (a.coeffs[i]));
989 return r;
992 template<unsigned int N, typename Ca>
993 inline poly_int<N, WI_UNARY_RESULT (Ca)>
994 neg (const poly_int<N, Ca> &a, wi::overflow_type *overflow)
996 typedef WI_UNARY_RESULT (Ca) C;
997 poly_int<N, C> r;
998 POLY_SET_COEFF (C, r, 0, wi::neg (a.coeffs[0], overflow));
999 for (unsigned int i = 1; i < N; i++)
1001 wi::overflow_type suboverflow;
1002 POLY_SET_COEFF (C, r, i, wi::neg (a.coeffs[i], &suboverflow));
1003 wi::accumulate_overflow (*overflow, suboverflow);
1005 return r;
1009 template<unsigned int N, typename Ca>
1010 inline POLY_POLY_RESULT (N, Ca, Ca)
1011 operator ~ (const poly_int<N, Ca> &a)
1013 if (N >= 2)
1014 return -1 - a;
1015 return ~a.coeffs[0];
1018 template<unsigned int N, typename Ca, typename Cb>
1019 inline POLY_CONST_RESULT (N, Ca, Cb)
1020 operator * (const poly_int<N, Ca> &a, const Cb &b)
1022 typedef POLY_CAST (Ca, Cb) NCa;
1023 typedef POLY_CONST_COEFF (Ca, Cb) C;
1024 poly_int<N, C> r;
1025 for (unsigned int i = 0; i < N; i++)
1026 POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]) * b);
1027 return r;
1030 template<unsigned int N, typename Ca, typename Cb>
1031 inline CONST_POLY_RESULT (N, Ca, Cb)
1032 operator * (const Ca &a, const poly_int<N, Cb> &b)
1034 typedef POLY_CAST (Ca, Cb) NCa;
1035 typedef CONST_POLY_COEFF (Ca, Cb) C;
1036 poly_int<N, C> r;
1037 for (unsigned int i = 0; i < N; i++)
1038 POLY_SET_COEFF (C, r, i, NCa (a) * b.coeffs[i]);
1039 return r;
1042 namespace wi {
1043 /* Poly versions of wi::mul, with the same interface. */
1045 template<unsigned int N, typename Ca, typename Cb>
1046 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
1047 mul (const poly_int<N, Ca> &a, const Cb &b)
1049 typedef WI_BINARY_RESULT (Ca, Cb) C;
1050 poly_int<N, C> r;
1051 for (unsigned int i = 0; i < N; i++)
1052 POLY_SET_COEFF (C, r, i, wi::mul (a.coeffs[i], b));
1053 return r;
1056 template<unsigned int N, typename Ca, typename Cb>
1057 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
1058 mul (const Ca &a, const poly_int<N, Cb> &b)
1060 typedef WI_BINARY_RESULT (Ca, Cb) C;
1061 poly_int<N, C> r;
1062 for (unsigned int i = 0; i < N; i++)
1063 POLY_SET_COEFF (C, r, i, wi::mul (a, b.coeffs[i]));
1064 return r;
1067 template<unsigned int N, typename Ca, typename Cb>
1068 inline poly_int<N, WI_BINARY_RESULT (Ca, Cb)>
1069 mul (const poly_int<N, Ca> &a, const Cb &b,
1070 signop sgn, wi::overflow_type *overflow)
1072 typedef WI_BINARY_RESULT (Ca, Cb) C;
1073 poly_int<N, C> r;
1074 POLY_SET_COEFF (C, r, 0, wi::mul (a.coeffs[0], b, sgn, overflow));
1075 for (unsigned int i = 1; i < N; i++)
1077 wi::overflow_type suboverflow;
1078 POLY_SET_COEFF (C, r, i, wi::mul (a.coeffs[i], b, sgn, &suboverflow));
1079 wi::accumulate_overflow (*overflow, suboverflow);
1081 return r;
1085 template<unsigned int N, typename Ca, typename Cb>
1086 inline POLY_POLY_RESULT (N, Ca, Ca)
1087 operator << (const poly_int<N, Ca> &a, const Cb &b)
1089 typedef POLY_CAST (Ca, Ca) NCa;
1090 typedef POLY_POLY_COEFF (Ca, Ca) C;
1091 poly_int<N, C> r;
1092 for (unsigned int i = 0; i < N; i++)
1093 POLY_SET_COEFF (C, r, i, NCa (a.coeffs[i]) << b);
1094 return r;
1097 namespace wi {
1098 /* Poly version of wi::lshift, with the same interface. */
1100 template<unsigned int N, typename Ca, typename Cb>
1101 inline poly_int<N, WI_BINARY_RESULT (Ca, Ca)>
1102 lshift (const poly_int<N, Ca> &a, const Cb &b)
1104 typedef WI_BINARY_RESULT (Ca, Ca) C;
1105 poly_int<N, C> r;
1106 for (unsigned int i = 0; i < N; i++)
1107 POLY_SET_COEFF (C, r, i, wi::lshift (a.coeffs[i], b));
1108 return r;
1112 /* Poly version of sext_hwi, with the same interface. */
1114 template<unsigned int N, typename C>
1115 inline poly_int<N, HOST_WIDE_INT>
1116 sext_hwi (const poly_int<N, C> &a, unsigned int precision)
1118 poly_int<N, HOST_WIDE_INT> r;
1119 for (unsigned int i = 0; i < N; i++)
1120 r.coeffs[i] = sext_hwi (a.coeffs[i], precision);
1121 return r;
1125 /* Return true if a0 + a1 * x might equal b0 + b1 * x for some nonnegative
1126 integer x. */
1128 template<typename Ca, typename Cb>
1129 inline bool
1130 maybe_eq_2 (const Ca &a0, const Ca &a1, const Cb &b0, const Cb &b1)
1132 if (a1 != b1)
1133 /* a0 + a1 * x == b0 + b1 * x
1134 ==> (a1 - b1) * x == b0 - a0
1135 ==> x == (b0 - a0) / (a1 - b1)
1137 We need to test whether that's a valid value of x.
1138 (b0 - a0) and (a1 - b1) must not have opposite signs
1139 and the result must be integral. */
1140 return (a1 < b1
1141 ? b0 <= a0 && (a0 - b0) % (b1 - a1) == 0
1142 : b0 >= a0 && (b0 - a0) % (a1 - b1) == 0);
1143 return a0 == b0;
1146 /* Return true if a0 + a1 * x might equal b for some nonnegative
1147 integer x. */
1149 template<typename Ca, typename Cb>
1150 inline bool
1151 maybe_eq_2 (const Ca &a0, const Ca &a1, const Cb &b)
1153 if (a1 != 0)
1154 /* a0 + a1 * x == b
1155 ==> x == (b - a0) / a1
1157 We need to test whether that's a valid value of x.
1158 (b - a0) and a1 must not have opposite signs and the
1159 result must be integral. */
1160 return (a1 < 0
1161 ? b <= a0 && (a0 - b) % a1 == 0
1162 : b >= a0 && (b - a0) % a1 == 0);
1163 return a0 == b;
1166 /* Return true if A might equal B for some indeterminate values. */
1168 template<unsigned int N, typename Ca, typename Cb>
1169 inline bool
1170 maybe_eq (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
1172 STATIC_ASSERT (N <= 2);
1173 if (N == 2)
1174 return maybe_eq_2 (a.coeffs[0], a.coeffs[1], b.coeffs[0], b.coeffs[1]);
1175 return a.coeffs[0] == b.coeffs[0];
1178 template<unsigned int N, typename Ca, typename Cb>
1179 inline typename if_nonpoly<Cb, bool>::type
1180 maybe_eq (const poly_int<N, Ca> &a, const Cb &b)
1182 STATIC_ASSERT (N <= 2);
1183 if (N == 2)
1184 return maybe_eq_2 (a.coeffs[0], a.coeffs[1], b);
1185 return a.coeffs[0] == b;
1188 template<unsigned int N, typename Ca, typename Cb>
1189 inline typename if_nonpoly<Ca, bool>::type
1190 maybe_eq (const Ca &a, const poly_int<N, Cb> &b)
1192 STATIC_ASSERT (N <= 2);
1193 if (N == 2)
1194 return maybe_eq_2 (b.coeffs[0], b.coeffs[1], a);
1195 return a == b.coeffs[0];
1198 template<typename Ca, typename Cb>
1199 inline typename if_nonpoly2<Ca, Cb, bool>::type
1200 maybe_eq (const Ca &a, const Cb &b)
1202 return a == b;
1205 /* Return true if A might not equal B for some indeterminate values. */
1207 template<unsigned int N, typename Ca, typename Cb>
1208 inline bool
1209 maybe_ne (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
1211 if (N >= 2)
1212 for (unsigned int i = 1; i < N; i++)
1213 if (a.coeffs[i] != b.coeffs[i])
1214 return true;
1215 return a.coeffs[0] != b.coeffs[0];
1218 template<unsigned int N, typename Ca, typename Cb>
1219 inline typename if_nonpoly<Cb, bool>::type
1220 maybe_ne (const poly_int<N, Ca> &a, const Cb &b)
1222 if (N >= 2)
1223 for (unsigned int i = 1; i < N; i++)
1224 if (a.coeffs[i] != 0)
1225 return true;
1226 return a.coeffs[0] != b;
1229 template<unsigned int N, typename Ca, typename Cb>
1230 inline typename if_nonpoly<Ca, bool>::type
1231 maybe_ne (const Ca &a, const poly_int<N, Cb> &b)
1233 if (N >= 2)
1234 for (unsigned int i = 1; i < N; i++)
1235 if (b.coeffs[i] != 0)
1236 return true;
1237 return a != b.coeffs[0];
1240 template<typename Ca, typename Cb>
1241 inline typename if_nonpoly2<Ca, Cb, bool>::type
1242 maybe_ne (const Ca &a, const Cb &b)
1244 return a != b;
1247 /* Return true if A is known to be equal to B. */
1248 #define known_eq(A, B) (!maybe_ne (A, B))
1250 /* Return true if A is known to be unequal to B. */
1251 #define known_ne(A, B) (!maybe_eq (A, B))
1253 /* Return true if A might be less than or equal to B for some
1254 indeterminate values. */
1256 template<unsigned int N, typename Ca, typename Cb>
1257 inline bool
1258 maybe_le (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
1260 if (N >= 2)
1261 for (unsigned int i = 1; i < N; i++)
1262 if (a.coeffs[i] < b.coeffs[i])
1263 return true;
1264 return a.coeffs[0] <= b.coeffs[0];
1267 template<unsigned int N, typename Ca, typename Cb>
1268 inline typename if_nonpoly<Cb, bool>::type
1269 maybe_le (const poly_int<N, Ca> &a, const Cb &b)
1271 if (N >= 2)
1272 for (unsigned int i = 1; i < N; i++)
1273 if (a.coeffs[i] < 0)
1274 return true;
1275 return a.coeffs[0] <= b;
1278 template<unsigned int N, typename Ca, typename Cb>
1279 inline typename if_nonpoly<Ca, bool>::type
1280 maybe_le (const Ca &a, const poly_int<N, Cb> &b)
1282 if (N >= 2)
1283 for (unsigned int i = 1; i < N; i++)
1284 if (b.coeffs[i] > 0)
1285 return true;
1286 return a <= b.coeffs[0];
1289 template<typename Ca, typename Cb>
1290 inline typename if_nonpoly2<Ca, Cb, bool>::type
1291 maybe_le (const Ca &a, const Cb &b)
1293 return a <= b;
1296 /* Return true if A might be less than B for some indeterminate values. */
1298 template<unsigned int N, typename Ca, typename Cb>
1299 inline bool
1300 maybe_lt (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
1302 if (N >= 2)
1303 for (unsigned int i = 1; i < N; i++)
1304 if (a.coeffs[i] < b.coeffs[i])
1305 return true;
1306 return a.coeffs[0] < b.coeffs[0];
1309 template<unsigned int N, typename Ca, typename Cb>
1310 inline typename if_nonpoly<Cb, bool>::type
1311 maybe_lt (const poly_int<N, Ca> &a, const Cb &b)
1313 if (N >= 2)
1314 for (unsigned int i = 1; i < N; i++)
1315 if (a.coeffs[i] < 0)
1316 return true;
1317 return a.coeffs[0] < b;
1320 template<unsigned int N, typename Ca, typename Cb>
1321 inline typename if_nonpoly<Ca, bool>::type
1322 maybe_lt (const Ca &a, const poly_int<N, Cb> &b)
1324 if (N >= 2)
1325 for (unsigned int i = 1; i < N; i++)
1326 if (b.coeffs[i] > 0)
1327 return true;
1328 return a < b.coeffs[0];
1331 template<typename Ca, typename Cb>
1332 inline typename if_nonpoly2<Ca, Cb, bool>::type
1333 maybe_lt (const Ca &a, const Cb &b)
1335 return a < b;
1338 /* Return true if A may be greater than or equal to B. */
1339 #define maybe_ge(A, B) maybe_le (B, A)
1341 /* Return true if A may be greater than B. */
1342 #define maybe_gt(A, B) maybe_lt (B, A)
1344 /* Return true if A is known to be less than or equal to B. */
1345 #define known_le(A, B) (!maybe_gt (A, B))
1347 /* Return true if A is known to be less than B. */
1348 #define known_lt(A, B) (!maybe_ge (A, B))
1350 /* Return true if A is known to be greater than B. */
1351 #define known_gt(A, B) (!maybe_le (A, B))
1353 /* Return true if A is known to be greater than or equal to B. */
1354 #define known_ge(A, B) (!maybe_lt (A, B))
1356 /* Return true if A and B are ordered by the partial ordering known_le. */
1358 template<typename T1, typename T2>
1359 inline bool
1360 ordered_p (const T1 &a, const T2 &b)
1362 return ((poly_int_traits<T1>::num_coeffs == 1
1363 && poly_int_traits<T2>::num_coeffs == 1)
1364 || known_le (a, b)
1365 || known_le (b, a));
1368 /* Assert that A and B are known to be ordered and return the minimum
1369 of the two.
1371 NOTE: When using this function, please add a comment above the call
1372 explaining why we know the values are ordered in that context. */
1374 template<unsigned int N, typename Ca, typename Cb>
1375 inline POLY_POLY_RESULT (N, Ca, Cb)
1376 ordered_min (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
1378 if (known_le (a, b))
1379 return a;
1380 else
1382 if (N > 1)
1383 gcc_checking_assert (known_le (b, a));
1384 return b;
1388 template<unsigned int N, typename Ca, typename Cb>
1389 inline CONST_POLY_RESULT (N, Ca, Cb)
1390 ordered_min (const Ca &a, const poly_int<N, Cb> &b)
1392 if (known_le (a, b))
1393 return a;
1394 else
1396 if (N > 1)
1397 gcc_checking_assert (known_le (b, a));
1398 return b;
1402 template<unsigned int N, typename Ca, typename Cb>
1403 inline POLY_CONST_RESULT (N, Ca, Cb)
1404 ordered_min (const poly_int<N, Ca> &a, const Cb &b)
1406 if (known_le (a, b))
1407 return a;
1408 else
1410 if (N > 1)
1411 gcc_checking_assert (known_le (b, a));
1412 return b;
1416 /* Assert that A and B are known to be ordered and return the maximum
1417 of the two.
1419 NOTE: When using this function, please add a comment above the call
1420 explaining why we know the values are ordered in that context. */
1422 template<unsigned int N, typename Ca, typename Cb>
1423 inline POLY_POLY_RESULT (N, Ca, Cb)
1424 ordered_max (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
1426 if (known_le (a, b))
1427 return b;
1428 else
1430 if (N > 1)
1431 gcc_checking_assert (known_le (b, a));
1432 return a;
1436 template<unsigned int N, typename Ca, typename Cb>
1437 inline CONST_POLY_RESULT (N, Ca, Cb)
1438 ordered_max (const Ca &a, const poly_int<N, Cb> &b)
1440 if (known_le (a, b))
1441 return b;
1442 else
1444 if (N > 1)
1445 gcc_checking_assert (known_le (b, a));
1446 return a;
1450 template<unsigned int N, typename Ca, typename Cb>
1451 inline POLY_CONST_RESULT (N, Ca, Cb)
1452 ordered_max (const poly_int<N, Ca> &a, const Cb &b)
1454 if (known_le (a, b))
1455 return b;
1456 else
1458 if (N > 1)
1459 gcc_checking_assert (known_le (b, a));
1460 return a;
1464 /* Return a constant lower bound on the value of A, which is known
1465 to be nonnegative. */
1467 template<unsigned int N, typename Ca>
1468 inline Ca
1469 constant_lower_bound (const poly_int<N, Ca> &a)
1471 gcc_checking_assert (known_ge (a, POLY_INT_TYPE (Ca) (0)));
1472 return a.coeffs[0];
1475 /* Return the constant lower bound of A, given that it is no less than B. */
1477 template<unsigned int N, typename Ca, typename Cb>
1478 inline POLY_CONST_COEFF (Ca, Cb)
1479 constant_lower_bound_with_limit (const poly_int<N, Ca> &a, const Cb &b)
1481 if (known_ge (a, b))
1482 return a.coeffs[0];
1483 return b;
1486 /* Return the constant upper bound of A, given that it is no greater
1487 than B. */
1489 template<unsigned int N, typename Ca, typename Cb>
1490 inline POLY_CONST_COEFF (Ca, Cb)
1491 constant_upper_bound_with_limit (const poly_int<N, Ca> &a, const Cb &b)
1493 if (known_le (a, b))
1494 return a.coeffs[0];
1495 return b;
1498 /* Return a value that is known to be no greater than A and B. This
1499 will be the greatest lower bound for some indeterminate values but
1500 not necessarily for all. */
1502 template<unsigned int N, typename Ca, typename Cb>
1503 inline POLY_CONST_RESULT (N, Ca, Cb)
1504 lower_bound (const poly_int<N, Ca> &a, const Cb &b)
1506 typedef POLY_CAST (Ca, Cb) NCa;
1507 typedef POLY_CAST (Cb, Ca) NCb;
1508 typedef POLY_INT_TYPE (Cb) ICb;
1509 typedef POLY_CONST_COEFF (Ca, Cb) C;
1511 poly_int<N, C> r;
1512 POLY_SET_COEFF (C, r, 0, MIN (NCa (a.coeffs[0]), NCb (b)));
1513 if (N >= 2)
1514 for (unsigned int i = 1; i < N; i++)
1515 POLY_SET_COEFF (C, r, i, MIN (NCa (a.coeffs[i]), ICb (0)));
1516 return r;
1519 template<unsigned int N, typename Ca, typename Cb>
1520 inline CONST_POLY_RESULT (N, Ca, Cb)
1521 lower_bound (const Ca &a, const poly_int<N, Cb> &b)
1523 return lower_bound (b, a);
1526 template<unsigned int N, typename Ca, typename Cb>
1527 inline POLY_POLY_RESULT (N, Ca, Cb)
1528 lower_bound (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
1530 typedef POLY_CAST (Ca, Cb) NCa;
1531 typedef POLY_CAST (Cb, Ca) NCb;
1532 typedef POLY_POLY_COEFF (Ca, Cb) C;
1534 poly_int<N, C> r;
1535 for (unsigned int i = 0; i < N; i++)
1536 POLY_SET_COEFF (C, r, i, MIN (NCa (a.coeffs[i]), NCb (b.coeffs[i])));
1537 return r;
1540 template<typename Ca, typename Cb>
1541 inline CONST_CONST_RESULT (N, Ca, Cb)
1542 lower_bound (const Ca &a, const Cb &b)
1544 return a < b ? a : b;
1547 /* Return a value that is known to be no less than A and B. This will
1548 be the least upper bound for some indeterminate values but not
1549 necessarily for all. */
1551 template<unsigned int N, typename Ca, typename Cb>
1552 inline POLY_CONST_RESULT (N, Ca, Cb)
1553 upper_bound (const poly_int<N, Ca> &a, const Cb &b)
1555 typedef POLY_CAST (Ca, Cb) NCa;
1556 typedef POLY_CAST (Cb, Ca) NCb;
1557 typedef POLY_INT_TYPE (Cb) ICb;
1558 typedef POLY_CONST_COEFF (Ca, Cb) C;
1560 poly_int<N, C> r;
1561 POLY_SET_COEFF (C, r, 0, MAX (NCa (a.coeffs[0]), NCb (b)));
1562 if (N >= 2)
1563 for (unsigned int i = 1; i < N; i++)
1564 POLY_SET_COEFF (C, r, i, MAX (NCa (a.coeffs[i]), ICb (0)));
1565 return r;
1568 template<unsigned int N, typename Ca, typename Cb>
1569 inline CONST_POLY_RESULT (N, Ca, Cb)
1570 upper_bound (const Ca &a, const poly_int<N, Cb> &b)
1572 return upper_bound (b, a);
1575 template<unsigned int N, typename Ca, typename Cb>
1576 inline POLY_POLY_RESULT (N, Ca, Cb)
1577 upper_bound (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
1579 typedef POLY_CAST (Ca, Cb) NCa;
1580 typedef POLY_CAST (Cb, Ca) NCb;
1581 typedef POLY_POLY_COEFF (Ca, Cb) C;
1583 poly_int<N, C> r;
1584 for (unsigned int i = 0; i < N; i++)
1585 POLY_SET_COEFF (C, r, i, MAX (NCa (a.coeffs[i]), NCb (b.coeffs[i])));
1586 return r;
1589 /* Return the greatest common divisor of all nonzero coefficients, or zero
1590 if all coefficients are zero. */
1592 template<unsigned int N, typename Ca>
1593 inline POLY_BINARY_COEFF (Ca, Ca)
1594 coeff_gcd (const poly_int<N, Ca> &a)
1596 /* Find the first nonzero coefficient, stopping at 0 whatever happens. */
1597 unsigned int i;
1598 for (i = N - 1; i > 0; --i)
1599 if (a.coeffs[i] != 0)
1600 break;
1601 typedef POLY_BINARY_COEFF (Ca, Ca) C;
1602 C r = a.coeffs[i];
1603 for (unsigned int j = 0; j < i; ++j)
1604 if (a.coeffs[j] != 0)
1605 r = gcd (r, C (a.coeffs[j]));
1606 return r;
1609 /* Return a value that is a multiple of both A and B. This will be the
1610 least common multiple for some indeterminate values but necessarily
1611 for all. */
1613 template<unsigned int N, typename Ca, typename Cb>
1614 POLY_CONST_RESULT (N, Ca, Cb)
1615 common_multiple (const poly_int<N, Ca> &a, Cb b)
1617 POLY_BINARY_COEFF (Ca, Ca) xgcd = coeff_gcd (a);
1618 return a * (least_common_multiple (xgcd, b) / xgcd);
1621 template<unsigned int N, typename Ca, typename Cb>
1622 inline CONST_POLY_RESULT (N, Ca, Cb)
1623 common_multiple (const Ca &a, const poly_int<N, Cb> &b)
1625 return common_multiple (b, a);
1628 /* Return a value that is a multiple of both A and B, asserting that
1629 such a value exists. The result will be the least common multiple
1630 for some indeterminate values but necessarily for all.
1632 NOTE: When using this function, please add a comment above the call
1633 explaining why we know the values have a common multiple (which might
1634 for example be because we know A / B is rational). */
1636 template<unsigned int N, typename Ca, typename Cb>
1637 POLY_POLY_RESULT (N, Ca, Cb)
1638 force_common_multiple (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
1640 if (b.is_constant ())
1641 return common_multiple (a, b.coeffs[0]);
1642 if (a.is_constant ())
1643 return common_multiple (a.coeffs[0], b);
1645 typedef POLY_CAST (Ca, Cb) NCa;
1646 typedef POLY_CAST (Cb, Ca) NCb;
1647 typedef POLY_BINARY_COEFF (Ca, Cb) C;
1648 typedef POLY_INT_TYPE (Ca) ICa;
1650 for (unsigned int i = 1; i < N; ++i)
1651 if (a.coeffs[i] != ICa (0))
1653 C lcm = least_common_multiple (NCa (a.coeffs[i]), NCb (b.coeffs[i]));
1654 C amul = lcm / a.coeffs[i];
1655 C bmul = lcm / b.coeffs[i];
1656 for (unsigned int j = 0; j < N; ++j)
1657 gcc_checking_assert (a.coeffs[j] * amul == b.coeffs[j] * bmul);
1658 return a * amul;
1660 gcc_unreachable ();
1663 /* Compare A and B for sorting purposes, returning -1 if A should come
1664 before B, 0 if A and B are identical, and 1 if A should come after B.
1665 This is a lexicographical compare of the coefficients in reverse order.
1667 A consequence of this is that all constant sizes come before all
1668 non-constant ones, regardless of magnitude (since a size is never
1669 negative). This is what most callers want. For example, when laying
1670 data out on the stack, it's better to keep all the constant-sized
1671 data together so that it can be accessed as a constant offset from a
1672 single base. */
1674 template<unsigned int N, typename Ca, typename Cb>
1675 inline int
1676 compare_sizes_for_sort (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
1678 for (unsigned int i = N; i-- > 0; )
1679 if (a.coeffs[i] != b.coeffs[i])
1680 return a.coeffs[i] < b.coeffs[i] ? -1 : 1;
1681 return 0;
1684 /* Return true if we can calculate VALUE & (ALIGN - 1) at compile time. */
1686 template<unsigned int N, typename Ca, typename Cb>
1687 inline bool
1688 can_align_p (const poly_int<N, Ca> &value, Cb align)
1690 for (unsigned int i = 1; i < N; i++)
1691 if ((value.coeffs[i] & (align - 1)) != 0)
1692 return false;
1693 return true;
1696 /* Return true if we can align VALUE up to the smallest multiple of
1697 ALIGN that is >= VALUE. Store the aligned value in *ALIGNED if so. */
1699 template<unsigned int N, typename Ca, typename Cb>
1700 inline bool
1701 can_align_up (const poly_int<N, Ca> &value, Cb align,
1702 poly_int<N, Ca> *aligned)
1704 if (!can_align_p (value, align))
1705 return false;
1706 *aligned = value + (-value.coeffs[0] & (align - 1));
1707 return true;
1710 /* Return true if we can align VALUE down to the largest multiple of
1711 ALIGN that is <= VALUE. Store the aligned value in *ALIGNED if so. */
1713 template<unsigned int N, typename Ca, typename Cb>
1714 inline bool
1715 can_align_down (const poly_int<N, Ca> &value, Cb align,
1716 poly_int<N, Ca> *aligned)
1718 if (!can_align_p (value, align))
1719 return false;
1720 *aligned = value - (value.coeffs[0] & (align - 1));
1721 return true;
1724 /* Return true if we can align A and B up to the smallest multiples of
1725 ALIGN that are >= A and B respectively, and if doing so gives the
1726 same value. */
1728 template<unsigned int N, typename Ca, typename Cb, typename Cc>
1729 inline bool
1730 known_equal_after_align_up (const poly_int<N, Ca> &a,
1731 const poly_int<N, Cb> &b,
1732 Cc align)
1734 poly_int<N, Ca> aligned_a;
1735 poly_int<N, Cb> aligned_b;
1736 return (can_align_up (a, align, &aligned_a)
1737 && can_align_up (b, align, &aligned_b)
1738 && known_eq (aligned_a, aligned_b));
1741 /* Return true if we can align A and B down to the largest multiples of
1742 ALIGN that are <= A and B respectively, and if doing so gives the
1743 same value. */
1745 template<unsigned int N, typename Ca, typename Cb, typename Cc>
1746 inline bool
1747 known_equal_after_align_down (const poly_int<N, Ca> &a,
1748 const poly_int<N, Cb> &b,
1749 Cc align)
1751 poly_int<N, Ca> aligned_a;
1752 poly_int<N, Cb> aligned_b;
1753 return (can_align_down (a, align, &aligned_a)
1754 && can_align_down (b, align, &aligned_b)
1755 && known_eq (aligned_a, aligned_b));
1758 /* Assert that we can align VALUE to ALIGN at compile time and return
1759 the smallest multiple of ALIGN that is >= VALUE.
1761 NOTE: When using this function, please add a comment above the call
1762 explaining why we know the non-constant coefficients must already
1763 be a multiple of ALIGN. */
1765 template<unsigned int N, typename Ca, typename Cb>
1766 inline poly_int<N, Ca>
1767 force_align_up (const poly_int<N, Ca> &value, Cb align)
1769 gcc_checking_assert (can_align_p (value, align));
1770 return value + (-value.coeffs[0] & (align - 1));
1773 /* Assert that we can align VALUE to ALIGN at compile time and return
1774 the largest multiple of ALIGN that is <= VALUE.
1776 NOTE: When using this function, please add a comment above the call
1777 explaining why we know the non-constant coefficients must already
1778 be a multiple of ALIGN. */
1780 template<unsigned int N, typename Ca, typename Cb>
1781 inline poly_int<N, Ca>
1782 force_align_down (const poly_int<N, Ca> &value, Cb align)
1784 gcc_checking_assert (can_align_p (value, align));
1785 return value - (value.coeffs[0] & (align - 1));
1788 /* Return a value <= VALUE that is a multiple of ALIGN. It will be the
1789 greatest such value for some indeterminate values but not necessarily
1790 for all. */
1792 template<unsigned int N, typename Ca, typename Cb>
1793 inline poly_int<N, Ca>
1794 aligned_lower_bound (const poly_int<N, Ca> &value, Cb align)
1796 poly_int<N, Ca> r;
1797 for (unsigned int i = 0; i < N; i++)
1798 /* This form copes correctly with more type combinations than
1799 value.coeffs[i] & -align would. */
1800 POLY_SET_COEFF (Ca, r, i, (value.coeffs[i]
1801 - (value.coeffs[i] & (align - 1))));
1802 return r;
1805 /* Return a value >= VALUE that is a multiple of ALIGN. It will be the
1806 least such value for some indeterminate values but not necessarily
1807 for all. */
1809 template<unsigned int N, typename Ca, typename Cb>
1810 inline poly_int<N, Ca>
1811 aligned_upper_bound (const poly_int<N, Ca> &value, Cb align)
1813 poly_int<N, Ca> r;
1814 for (unsigned int i = 0; i < N; i++)
1815 POLY_SET_COEFF (Ca, r, i, (value.coeffs[i]
1816 + (-value.coeffs[i] & (align - 1))));
1817 return r;
1820 /* Assert that we can align VALUE to ALIGN at compile time. Align VALUE
1821 down to the largest multiple of ALIGN that is <= VALUE, then divide by
1822 ALIGN.
1824 NOTE: When using this function, please add a comment above the call
1825 explaining why we know the non-constant coefficients must already
1826 be a multiple of ALIGN. */
1828 template<unsigned int N, typename Ca, typename Cb>
1829 inline poly_int<N, Ca>
1830 force_align_down_and_div (const poly_int<N, Ca> &value, Cb align)
1832 gcc_checking_assert (can_align_p (value, align));
1834 poly_int<N, Ca> r;
1835 POLY_SET_COEFF (Ca, r, 0, ((value.coeffs[0]
1836 - (value.coeffs[0] & (align - 1)))
1837 / align));
1838 if (N >= 2)
1839 for (unsigned int i = 1; i < N; i++)
1840 POLY_SET_COEFF (Ca, r, i, value.coeffs[i] / align);
1841 return r;
1844 /* Assert that we can align VALUE to ALIGN at compile time. Align VALUE
1845 up to the smallest multiple of ALIGN that is >= VALUE, then divide by
1846 ALIGN.
1848 NOTE: When using this function, please add a comment above the call
1849 explaining why we know the non-constant coefficients must already
1850 be a multiple of ALIGN. */
1852 template<unsigned int N, typename Ca, typename Cb>
1853 inline poly_int<N, Ca>
1854 force_align_up_and_div (const poly_int<N, Ca> &value, Cb align)
1856 gcc_checking_assert (can_align_p (value, align));
1858 poly_int<N, Ca> r;
1859 POLY_SET_COEFF (Ca, r, 0, ((value.coeffs[0]
1860 + (-value.coeffs[0] & (align - 1)))
1861 / align));
1862 if (N >= 2)
1863 for (unsigned int i = 1; i < N; i++)
1864 POLY_SET_COEFF (Ca, r, i, value.coeffs[i] / align);
1865 return r;
1868 /* Return true if we know at compile time the difference between VALUE
1869 and the equal or preceding multiple of ALIGN. Store the value in
1870 *MISALIGN if so. */
1872 template<unsigned int N, typename Ca, typename Cb, typename Cm>
1873 inline bool
1874 known_misalignment (const poly_int<N, Ca> &value, Cb align, Cm *misalign)
1876 gcc_checking_assert (align != 0);
1877 if (!can_align_p (value, align))
1878 return false;
1879 *misalign = value.coeffs[0] & (align - 1);
1880 return true;
1883 /* Return X & (Y - 1), asserting that this value is known. Please add
1884 an a comment above callers to this function to explain why the condition
1885 is known to hold. */
1887 template<unsigned int N, typename Ca, typename Cb>
1888 inline POLY_BINARY_COEFF (Ca, Ca)
1889 force_get_misalignment (const poly_int<N, Ca> &a, Cb align)
1891 gcc_checking_assert (can_align_p (a, align));
1892 return a.coeffs[0] & (align - 1);
1895 /* Return the maximum alignment that A is known to have. Return 0
1896 if A is known to be zero. */
1898 template<unsigned int N, typename Ca>
1899 inline POLY_BINARY_COEFF (Ca, Ca)
1900 known_alignment (const poly_int<N, Ca> &a)
1902 typedef POLY_BINARY_COEFF (Ca, Ca) C;
1903 C r = a.coeffs[0];
1904 for (unsigned int i = 1; i < N; ++i)
1905 r |= a.coeffs[i];
1906 return r & -r;
1909 /* Return true if we can compute A | B at compile time, storing the
1910 result in RES if so. */
1912 template<unsigned int N, typename Ca, typename Cb, typename Cr>
1913 inline typename if_nonpoly<Cb, bool>::type
1914 can_ior_p (const poly_int<N, Ca> &a, Cb b, Cr *result)
1916 /* Coefficients 1 and above must be a multiple of something greater
1917 than B. */
1918 typedef POLY_INT_TYPE (Ca) int_type;
1919 if (N >= 2)
1920 for (unsigned int i = 1; i < N; i++)
1921 if ((-(a.coeffs[i] & -a.coeffs[i]) & b) != int_type (0))
1922 return false;
1923 *result = a;
1924 result->coeffs[0] |= b;
1925 return true;
1928 /* Return true if A is a constant multiple of B, storing the
1929 multiple in *MULTIPLE if so. */
1931 template<unsigned int N, typename Ca, typename Cb, typename Cm>
1932 inline typename if_nonpoly<Cb, bool>::type
1933 constant_multiple_p (const poly_int<N, Ca> &a, Cb b, Cm *multiple)
1935 typedef POLY_CAST (Ca, Cb) NCa;
1936 typedef POLY_CAST (Cb, Ca) NCb;
1938 /* Do the modulus before the constant check, to catch divide by
1939 zero errors. */
1940 if (NCa (a.coeffs[0]) % NCb (b) != 0 || !a.is_constant ())
1941 return false;
1942 *multiple = NCa (a.coeffs[0]) / NCb (b);
1943 return true;
1946 template<unsigned int N, typename Ca, typename Cb, typename Cm>
1947 inline typename if_nonpoly<Ca, bool>::type
1948 constant_multiple_p (Ca a, const poly_int<N, Cb> &b, Cm *multiple)
1950 typedef POLY_CAST (Ca, Cb) NCa;
1951 typedef POLY_CAST (Cb, Ca) NCb;
1952 typedef POLY_INT_TYPE (Ca) int_type;
1954 /* Do the modulus before the constant check, to catch divide by
1955 zero errors. */
1956 if (NCa (a) % NCb (b.coeffs[0]) != 0
1957 || (a != int_type (0) && !b.is_constant ()))
1958 return false;
1959 *multiple = NCa (a) / NCb (b.coeffs[0]);
1960 return true;
1963 template<unsigned int N, typename Ca, typename Cb, typename Cm>
1964 inline bool
1965 constant_multiple_p (const poly_int<N, Ca> &a,
1966 const poly_int<N, Cb> &b, Cm *multiple)
1968 typedef POLY_CAST (Ca, Cb) NCa;
1969 typedef POLY_CAST (Cb, Ca) NCb;
1970 typedef POLY_INT_TYPE (Ca) ICa;
1971 typedef POLY_INT_TYPE (Cb) ICb;
1972 typedef POLY_BINARY_COEFF (Ca, Cb) C;
1974 if (NCa (a.coeffs[0]) % NCb (b.coeffs[0]) != 0)
1975 return false;
1977 C r = NCa (a.coeffs[0]) / NCb (b.coeffs[0]);
1978 for (unsigned int i = 1; i < N; ++i)
1979 if (b.coeffs[i] == ICb (0)
1980 ? a.coeffs[i] != ICa (0)
1981 : (NCa (a.coeffs[i]) % NCb (b.coeffs[i]) != 0
1982 || NCa (a.coeffs[i]) / NCb (b.coeffs[i]) != r))
1983 return false;
1985 *multiple = r;
1986 return true;
1989 /* Return true if A is a constant multiple of B. */
1991 template<unsigned int N, typename Ca, typename Cb>
1992 inline typename if_nonpoly<Cb, bool>::type
1993 constant_multiple_p (const poly_int<N, Ca> &a, Cb b)
1995 typedef POLY_CAST (Ca, Cb) NCa;
1996 typedef POLY_CAST (Cb, Ca) NCb;
1998 /* Do the modulus before the constant check, to catch divide by
1999 zero errors. */
2000 if (NCa (a.coeffs[0]) % NCb (b) != 0 || !a.is_constant ())
2001 return false;
2002 return true;
2005 template<unsigned int N, typename Ca, typename Cb>
2006 inline typename if_nonpoly<Ca, bool>::type
2007 constant_multiple_p (Ca a, const poly_int<N, Cb> &b)
2009 typedef POLY_CAST (Ca, Cb) NCa;
2010 typedef POLY_CAST (Cb, Ca) NCb;
2011 typedef POLY_INT_TYPE (Ca) int_type;
2013 /* Do the modulus before the constant check, to catch divide by
2014 zero errors. */
2015 if (NCa (a) % NCb (b.coeffs[0]) != 0
2016 || (a != int_type (0) && !b.is_constant ()))
2017 return false;
2018 return true;
2021 template<unsigned int N, typename Ca, typename Cb>
2022 inline bool
2023 constant_multiple_p (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
2025 typedef POLY_CAST (Ca, Cb) NCa;
2026 typedef POLY_CAST (Cb, Ca) NCb;
2027 typedef POLY_INT_TYPE (Ca) ICa;
2028 typedef POLY_INT_TYPE (Cb) ICb;
2029 typedef POLY_BINARY_COEFF (Ca, Cb) C;
2031 if (NCa (a.coeffs[0]) % NCb (b.coeffs[0]) != 0)
2032 return false;
2034 C r = NCa (a.coeffs[0]) / NCb (b.coeffs[0]);
2035 for (unsigned int i = 1; i < N; ++i)
2036 if (b.coeffs[i] == ICb (0)
2037 ? a.coeffs[i] != ICa (0)
2038 : (NCa (a.coeffs[i]) % NCb (b.coeffs[i]) != 0
2039 || NCa (a.coeffs[i]) / NCb (b.coeffs[i]) != r))
2040 return false;
2041 return true;
2045 /* Return true if A is a multiple of B. */
2047 template<typename Ca, typename Cb>
2048 inline typename if_nonpoly2<Ca, Cb, bool>::type
2049 multiple_p (Ca a, Cb b)
2051 return a % b == 0;
2054 /* Return true if A is a (polynomial) multiple of B. */
2056 template<unsigned int N, typename Ca, typename Cb>
2057 inline typename if_nonpoly<Cb, bool>::type
2058 multiple_p (const poly_int<N, Ca> &a, Cb b)
2060 for (unsigned int i = 0; i < N; ++i)
2061 if (a.coeffs[i] % b != 0)
2062 return false;
2063 return true;
2066 /* Return true if A is a (constant) multiple of B. */
2068 template<unsigned int N, typename Ca, typename Cb>
2069 inline typename if_nonpoly<Ca, bool>::type
2070 multiple_p (Ca a, const poly_int<N, Cb> &b)
2072 typedef POLY_INT_TYPE (Ca) int_type;
2074 /* Do the modulus before the constant check, to catch divide by
2075 potential zeros. */
2076 return a % b.coeffs[0] == 0 && (a == int_type (0) || b.is_constant ());
2079 /* Return true if A is a (polynomial) multiple of B. This handles cases
2080 where either B is constant or the multiple is constant. */
2082 template<unsigned int N, typename Ca, typename Cb>
2083 inline bool
2084 multiple_p (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
2086 if (b.is_constant ())
2087 return multiple_p (a, b.coeffs[0]);
2088 POLY_BINARY_COEFF (Ca, Ca) tmp;
2089 return constant_multiple_p (a, b, &tmp);
2092 /* Return true if A is a (constant) multiple of B, storing the
2093 multiple in *MULTIPLE if so. */
2095 template<typename Ca, typename Cb, typename Cm>
2096 inline typename if_nonpoly2<Ca, Cb, bool>::type
2097 multiple_p (Ca a, Cb b, Cm *multiple)
2099 if (a % b != 0)
2100 return false;
2101 *multiple = a / b;
2102 return true;
2105 /* Return true if A is a (polynomial) multiple of B, storing the
2106 multiple in *MULTIPLE if so. */
2108 template<unsigned int N, typename Ca, typename Cb, typename Cm>
2109 inline typename if_nonpoly<Cb, bool>::type
2110 multiple_p (const poly_int<N, Ca> &a, Cb b, poly_int<N, Cm> *multiple)
2112 if (!multiple_p (a, b))
2113 return false;
2114 for (unsigned int i = 0; i < N; ++i)
2115 multiple->coeffs[i] = a.coeffs[i] / b;
2116 return true;
2119 /* Return true if B is a constant and A is a (constant) multiple of B,
2120 storing the multiple in *MULTIPLE if so. */
2122 template<unsigned int N, typename Ca, typename Cb, typename Cm>
2123 inline typename if_nonpoly<Ca, bool>::type
2124 multiple_p (Ca a, const poly_int<N, Cb> &b, Cm *multiple)
2126 typedef POLY_CAST (Ca, Cb) NCa;
2128 /* Do the modulus before the constant check, to catch divide by
2129 potential zeros. */
2130 if (a % b.coeffs[0] != 0 || (NCa (a) != 0 && !b.is_constant ()))
2131 return false;
2132 *multiple = a / b.coeffs[0];
2133 return true;
2136 /* Return true if A is a (polynomial) multiple of B, storing the
2137 multiple in *MULTIPLE if so. This handles cases where either
2138 B is constant or the multiple is constant. */
2140 template<unsigned int N, typename Ca, typename Cb, typename Cm>
2141 inline bool
2142 multiple_p (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b,
2143 poly_int<N, Cm> *multiple)
2145 if (b.is_constant ())
2146 return multiple_p (a, b.coeffs[0], multiple);
2147 return constant_multiple_p (a, b, multiple);
2150 /* Return A / B, given that A is known to be a multiple of B. */
2152 template<unsigned int N, typename Ca, typename Cb>
2153 inline POLY_CONST_RESULT (N, Ca, Cb)
2154 exact_div (const poly_int<N, Ca> &a, Cb b)
2156 typedef POLY_CONST_COEFF (Ca, Cb) C;
2157 poly_int<N, C> r;
2158 for (unsigned int i = 0; i < N; i++)
2160 gcc_checking_assert (a.coeffs[i] % b == 0);
2161 POLY_SET_COEFF (C, r, i, a.coeffs[i] / b);
2163 return r;
2166 /* Return A / B, given that A is known to be a multiple of B. */
2168 template<unsigned int N, typename Ca, typename Cb>
2169 inline POLY_POLY_RESULT (N, Ca, Cb)
2170 exact_div (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b)
2172 if (b.is_constant ())
2173 return exact_div (a, b.coeffs[0]);
2175 typedef POLY_CAST (Ca, Cb) NCa;
2176 typedef POLY_CAST (Cb, Ca) NCb;
2177 typedef POLY_BINARY_COEFF (Ca, Cb) C;
2178 typedef POLY_INT_TYPE (Cb) int_type;
2180 gcc_checking_assert (a.coeffs[0] % b.coeffs[0] == 0);
2181 C r = NCa (a.coeffs[0]) / NCb (b.coeffs[0]);
2182 for (unsigned int i = 1; i < N; ++i)
2183 gcc_checking_assert (b.coeffs[i] == int_type (0)
2184 ? a.coeffs[i] == int_type (0)
2185 : (a.coeffs[i] % b.coeffs[i] == 0
2186 && NCa (a.coeffs[i]) / NCb (b.coeffs[i]) == r));
2188 return r;
2191 /* Return true if there is some constant Q and polynomial r such that:
2193 (1) a = b * Q + r
2194 (2) |b * Q| <= |a|
2195 (3) |r| < |b|
2197 Store the value Q in *QUOTIENT if so. */
2199 template<unsigned int N, typename Ca, typename Cb, typename Cq>
2200 inline typename if_nonpoly2<Cb, Cq, bool>::type
2201 can_div_trunc_p (const poly_int<N, Ca> &a, Cb b, Cq *quotient)
2203 typedef POLY_CAST (Ca, Cb) NCa;
2204 typedef POLY_CAST (Cb, Ca) NCb;
2206 /* Do the division before the constant check, to catch divide by
2207 zero errors. */
2208 Cq q = NCa (a.coeffs[0]) / NCb (b);
2209 if (!a.is_constant ())
2210 return false;
2211 *quotient = q;
2212 return true;
2215 template<unsigned int N, typename Ca, typename Cb, typename Cq>
2216 inline typename if_nonpoly<Cq, bool>::type
2217 can_div_trunc_p (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b,
2218 Cq *quotient)
2220 /* We can calculate Q from the case in which the indeterminates
2221 are zero. */
2222 typedef POLY_CAST (Ca, Cb) NCa;
2223 typedef POLY_CAST (Cb, Ca) NCb;
2224 typedef POLY_INT_TYPE (Ca) ICa;
2225 typedef POLY_INT_TYPE (Cb) ICb;
2226 typedef POLY_BINARY_COEFF (Ca, Cb) C;
2227 C q = NCa (a.coeffs[0]) / NCb (b.coeffs[0]);
2229 /* Check the other coefficients and record whether the division is exact.
2230 The only difficult case is when it isn't. If we require a and b to
2231 ordered wrt zero, there can be no two coefficients of the same value
2232 that have opposite signs. This means that:
2234 |a| = |a0| + |a1 * x1| + |a2 * x2| + ...
2235 |b| = |b0| + |b1 * x1| + |b2 * x2| + ...
2237 The Q we've just calculated guarantees:
2239 |b0 * Q| <= |a0|
2240 |a0 - b0 * Q| < |b0|
2242 and so:
2244 (2) |b * Q| <= |a|
2246 is satisfied if:
2248 |bi * xi * Q| <= |ai * xi|
2250 for each i in [1, N]. This is trivially true when xi is zero.
2251 When it isn't we need:
2253 (2') |bi * Q| <= |ai|
2255 r is calculated as:
2257 r = r0 + r1 * x1 + r2 * x2 + ...
2258 where ri = ai - bi * Q
2260 Restricting to ordered a and b also guarantees that no two ris
2261 have opposite signs, so we have:
2263 |r| = |r0| + |r1 * x1| + |r2 * x2| + ...
2265 We know from the calculation of Q that |r0| < |b0|, so:
2267 (3) |r| < |b|
2269 is satisfied if:
2271 (3') |ai - bi * Q| <= |bi|
2273 for each i in [1, N]. */
2274 bool rem_p = NCa (a.coeffs[0]) % NCb (b.coeffs[0]) != 0;
2275 for (unsigned int i = 1; i < N; ++i)
2277 if (b.coeffs[i] == ICb (0))
2279 /* For bi == 0 we simply need: (3') |ai| == 0. */
2280 if (a.coeffs[i] != ICa (0))
2281 return false;
2283 else
2285 /* The only unconditional arithmetic that we can do on ai,
2286 bi and Q is ai / bi and ai % bi. (ai == minimum int and
2287 bi == -1 would be UB in the caller.) Anything else runs
2288 the risk of overflow. */
2289 auto qi = NCa (a.coeffs[i]) / NCb (b.coeffs[i]);
2290 auto ri = NCa (a.coeffs[i]) % NCb (b.coeffs[i]);
2291 /* (2') and (3') are satisfied when ai /[trunc] bi == q.
2292 So is the stricter condition |ai - bi * Q| < |bi|. */
2293 if (qi == q)
2294 rem_p |= (ri != 0);
2295 /* The only other case is when:
2297 |bi * Q| + |bi| = |ai| (for (2'))
2298 and |ai - bi * Q| = |bi| (for (3'))
2300 The first is equivalent to |bi|(|Q| + 1) == |ai|.
2301 The second requires ai == bi * (Q + 1) or ai == bi * (Q - 1). */
2302 else if (ri != 0)
2303 return false;
2304 else if (q <= 0 && qi < q && qi + 1 == q)
2306 else if (q >= 0 && qi > q && qi - 1 == q)
2308 else
2309 return false;
2313 /* If the division isn't exact, require both values to be ordered wrt 0,
2314 so that we can guarantee conditions (2) and (3) for all indeterminate
2315 values. */
2316 if (rem_p && (!ordered_p (a, ICa (0)) || !ordered_p (b, ICb (0))))
2317 return false;
2319 *quotient = q;
2320 return true;
2323 /* Likewise, but also store r in *REMAINDER. */
2325 template<unsigned int N, typename Ca, typename Cb, typename Cq, typename Cr>
2326 inline typename if_nonpoly<Cq, bool>::type
2327 can_div_trunc_p (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b,
2328 Cq *quotient, Cr *remainder)
2330 if (!can_div_trunc_p (a, b, quotient))
2331 return false;
2332 *remainder = a - *quotient * b;
2333 return true;
2336 /* Return true if there is some polynomial q and constant R such that:
2338 (1) a = B * q + R
2339 (2) |B * q| <= |a|
2340 (3) |R| < |B|
2342 Store the value q in *QUOTIENT if so. */
2344 template<unsigned int N, typename Ca, typename Cb, typename Cq>
2345 inline typename if_nonpoly<Cb, bool>::type
2346 can_div_trunc_p (const poly_int<N, Ca> &a, Cb b,
2347 poly_int<N, Cq> *quotient)
2349 /* The remainder must be constant. */
2350 for (unsigned int i = 1; i < N; ++i)
2351 if (a.coeffs[i] % b != 0)
2352 return false;
2353 for (unsigned int i = 0; i < N; ++i)
2354 quotient->coeffs[i] = a.coeffs[i] / b;
2355 return true;
2358 /* Likewise, but also store R in *REMAINDER. */
2360 template<unsigned int N, typename Ca, typename Cb, typename Cq, typename Cr>
2361 inline typename if_nonpoly<Cb, bool>::type
2362 can_div_trunc_p (const poly_int<N, Ca> &a, Cb b,
2363 poly_int<N, Cq> *quotient, Cr *remainder)
2365 if (!can_div_trunc_p (a, b, quotient))
2366 return false;
2367 *remainder = a.coeffs[0] % b;
2368 return true;
2371 /* Return true if we can compute A / B at compile time, rounding towards zero.
2372 Store the result in QUOTIENT if so.
2374 This handles cases in which either B is constant or the result is
2375 constant. */
2377 template<unsigned int N, typename Ca, typename Cb, typename Cq>
2378 inline bool
2379 can_div_trunc_p (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b,
2380 poly_int<N, Cq> *quotient)
2382 if (b.is_constant ())
2383 return can_div_trunc_p (a, b.coeffs[0], quotient);
2384 if (!can_div_trunc_p (a, b, &quotient->coeffs[0]))
2385 return false;
2386 for (unsigned int i = 1; i < N; ++i)
2387 quotient->coeffs[i] = 0;
2388 return true;
2391 /* Return true if there is some constant Q and polynomial r such that:
2393 (1) a = b * Q + r
2394 (2) |a| <= |b * Q|
2395 (3) |r| < |b|
2397 Store the value Q in *QUOTIENT if so. */
2399 template<unsigned int N, typename Ca, typename Cb, typename Cq>
2400 inline typename if_nonpoly<Cq, bool>::type
2401 can_div_away_from_zero_p (const poly_int<N, Ca> &a, const poly_int<N, Cb> &b,
2402 Cq *quotient)
2404 if (!can_div_trunc_p (a, b, quotient))
2405 return false;
2406 if (maybe_ne (*quotient * b, a))
2407 *quotient += (*quotient < 0 ? -1 : 1);
2408 return true;
2411 /* Use print_dec to print VALUE to FILE, where SGN is the sign
2412 of the values. */
2414 template<unsigned int N, typename C>
2415 void
2416 print_dec (const poly_int<N, C> &value, FILE *file, signop sgn)
2418 if (value.is_constant ())
2419 print_dec (value.coeffs[0], file, sgn);
2420 else
2422 fprintf (file, "[");
2423 for (unsigned int i = 0; i < N; ++i)
2425 print_dec (value.coeffs[i], file, sgn);
2426 fputc (i == N - 1 ? ']' : ',', file);
2431 /* Likewise without the signop argument, for coefficients that have an
2432 inherent signedness. */
2434 template<unsigned int N, typename C>
2435 void
2436 print_dec (const poly_int<N, C> &value, FILE *file)
2438 STATIC_ASSERT (poly_coeff_traits<C>::signedness >= 0);
2439 print_dec (value, file,
2440 poly_coeff_traits<C>::signedness ? SIGNED : UNSIGNED);
2443 /* Use print_hex to print VALUE to FILE. */
2445 template<unsigned int N, typename C>
2446 void
2447 print_hex (const poly_int<N, C> &value, FILE *file)
2449 if (value.is_constant ())
2450 print_hex (value.coeffs[0], file);
2451 else
2453 fprintf (file, "[");
2454 for (unsigned int i = 0; i < N; ++i)
2456 print_hex (value.coeffs[i], file);
2457 fputc (i == N - 1 ? ']' : ',', file);
2462 /* Helper for calculating the distance between two points P1 and P2,
2463 in cases where known_le (P1, P2). T1 and T2 are the types of the
2464 two positions, in either order. The coefficients of P2 - P1 have
2465 type unsigned HOST_WIDE_INT if the coefficients of both T1 and T2
2466 have C++ primitive type, otherwise P2 - P1 has its usual
2467 wide-int-based type.
2469 The actual subtraction should look something like this:
2471 typedef poly_span_traits<T1, T2> span_traits;
2472 span_traits::cast (P2) - span_traits::cast (P1)
2474 Applying the cast before the subtraction avoids undefined overflow
2475 for signed T1 and T2.
2477 The implementation of the cast tries to avoid unnecessary arithmetic
2478 or copying. */
2479 template<typename T1, typename T2,
2480 typename Res = POLY_BINARY_COEFF (POLY_BINARY_COEFF (T1, T2),
2481 unsigned HOST_WIDE_INT)>
2482 struct poly_span_traits
2484 template<typename T>
2485 static const T &cast (const T &x) { return x; }
2488 template<typename T1, typename T2>
2489 struct poly_span_traits<T1, T2, unsigned HOST_WIDE_INT>
2491 template<typename T>
2492 static typename if_nonpoly<T, unsigned HOST_WIDE_INT>::type
2493 cast (const T &x) { return x; }
2495 template<unsigned int N, typename T>
2496 static poly_int<N, unsigned HOST_WIDE_INT>
2497 cast (const poly_int<N, T> &x) { return x; }
2500 /* Return true if SIZE represents a known size, assuming that all-ones
2501 indicates an unknown size. */
2503 template<typename T>
2504 inline bool
2505 known_size_p (const T &a)
2507 return maybe_ne (a, POLY_INT_TYPE (T) (-1));
2510 /* Return true if range [POS, POS + SIZE) might include VAL.
2511 SIZE can be the special value -1, in which case the range is
2512 open-ended. */
2514 template<typename T1, typename T2, typename T3>
2515 inline bool
2516 maybe_in_range_p (const T1 &val, const T2 &pos, const T3 &size)
2518 typedef poly_span_traits<T1, T2> start_span;
2519 typedef poly_span_traits<T3, T3> size_span;
2520 if (known_lt (val, pos))
2521 return false;
2522 if (!known_size_p (size))
2523 return true;
2524 if ((poly_int_traits<T1>::num_coeffs > 1
2525 || poly_int_traits<T2>::num_coeffs > 1)
2526 && maybe_lt (val, pos))
2527 /* In this case we don't know whether VAL >= POS is true at compile
2528 time, so we can't prove that VAL >= POS + SIZE. */
2529 return true;
2530 return maybe_lt (start_span::cast (val) - start_span::cast (pos),
2531 size_span::cast (size));
2534 /* Return true if range [POS, POS + SIZE) is known to include VAL.
2535 SIZE can be the special value -1, in which case the range is
2536 open-ended. */
2538 template<typename T1, typename T2, typename T3>
2539 inline bool
2540 known_in_range_p (const T1 &val, const T2 &pos, const T3 &size)
2542 typedef poly_span_traits<T1, T2> start_span;
2543 typedef poly_span_traits<T3, T3> size_span;
2544 return (known_size_p (size)
2545 && known_ge (val, pos)
2546 && known_lt (start_span::cast (val) - start_span::cast (pos),
2547 size_span::cast (size)));
2550 /* Return true if the two ranges [POS1, POS1 + SIZE1) and [POS2, POS2 + SIZE2)
2551 might overlap. SIZE1 and/or SIZE2 can be the special value -1, in which
2552 case the range is open-ended. */
2554 template<typename T1, typename T2, typename T3, typename T4>
2555 inline bool
2556 ranges_maybe_overlap_p (const T1 &pos1, const T2 &size1,
2557 const T3 &pos2, const T4 &size2)
2559 if (maybe_in_range_p (pos2, pos1, size1))
2560 return maybe_ne (size2, POLY_INT_TYPE (T4) (0));
2561 if (maybe_in_range_p (pos1, pos2, size2))
2562 return maybe_ne (size1, POLY_INT_TYPE (T2) (0));
2563 return false;
2566 /* Return true if the two ranges [POS1, POS1 + SIZE1) and [POS2, POS2 + SIZE2)
2567 are known to overlap. SIZE1 and/or SIZE2 can be the special value -1,
2568 in which case the range is open-ended. */
2570 template<typename T1, typename T2, typename T3, typename T4>
2571 inline bool
2572 ranges_known_overlap_p (const T1 &pos1, const T2 &size1,
2573 const T3 &pos2, const T4 &size2)
2575 typedef poly_span_traits<T1, T3> start_span;
2576 typedef poly_span_traits<T2, T2> size1_span;
2577 typedef poly_span_traits<T4, T4> size2_span;
2578 /* known_gt (POS1 + SIZE1, POS2) [infinite precision]
2579 --> known_gt (SIZE1, POS2 - POS1) [infinite precision]
2580 --> known_gt (SIZE1, POS2 - lower_bound (POS1, POS2)) [infinite precision]
2581 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ always nonnegative
2582 --> known_gt (SIZE1, span1::cast (POS2 - lower_bound (POS1, POS2))).
2584 Using the saturating subtraction enforces that SIZE1 must be
2585 nonzero, since known_gt (0, x) is false for all nonnegative x.
2586 If POS2.coeff[I] < POS1.coeff[I] for some I > 0, increasing
2587 indeterminate number I makes the unsaturated condition easier to
2588 satisfy, so using a saturated coefficient of zero tests the case in
2589 which the indeterminate is zero (the minimum value). */
2590 return (known_size_p (size1)
2591 && known_size_p (size2)
2592 && known_lt (start_span::cast (pos2)
2593 - start_span::cast (lower_bound (pos1, pos2)),
2594 size1_span::cast (size1))
2595 && known_lt (start_span::cast (pos1)
2596 - start_span::cast (lower_bound (pos1, pos2)),
2597 size2_span::cast (size2)));
2600 /* Return true if range [POS1, POS1 + SIZE1) is known to be a subrange of
2601 [POS2, POS2 + SIZE2). SIZE1 and/or SIZE2 can be the special value -1,
2602 in which case the range is open-ended. */
2604 template<typename T1, typename T2, typename T3, typename T4>
2605 inline bool
2606 known_subrange_p (const T1 &pos1, const T2 &size1,
2607 const T3 &pos2, const T4 &size2)
2609 typedef typename poly_int_traits<T2>::coeff_type C2;
2610 typedef poly_span_traits<T1, T3> start_span;
2611 typedef poly_span_traits<T2, T4> size_span;
2612 return (known_gt (size1, POLY_INT_TYPE (T2) (0))
2613 && (poly_coeff_traits<C2>::signedness > 0
2614 || known_size_p (size1))
2615 && known_size_p (size2)
2616 && known_ge (pos1, pos2)
2617 && known_le (size1, size2)
2618 && known_le (start_span::cast (pos1) - start_span::cast (pos2),
2619 size_span::cast (size2) - size_span::cast (size1)));
2622 /* Return true if the endpoint of the range [POS, POS + SIZE) can be
2623 stored in a T, or if SIZE is the special value -1, which makes the
2624 range open-ended. */
2626 template<typename T>
2627 inline typename if_nonpoly<T, bool>::type
2628 endpoint_representable_p (const T &pos, const T &size)
2630 return (!known_size_p (size)
2631 || pos <= poly_coeff_traits<T>::max_value - size);
2634 template<unsigned int N, typename C>
2635 inline bool
2636 endpoint_representable_p (const poly_int<N, C> &pos,
2637 const poly_int<N, C> &size)
2639 if (known_size_p (size))
2640 for (unsigned int i = 0; i < N; ++i)
2641 if (pos.coeffs[i] > poly_coeff_traits<C>::max_value - size.coeffs[i])
2642 return false;
2643 return true;
2646 template<unsigned int N, typename C>
2647 void
2648 gt_ggc_mx (poly_int<N, C> *)
2652 template<unsigned int N, typename C>
2653 void
2654 gt_pch_nx (poly_int<N, C> *)
2658 template<unsigned int N, typename C>
2659 void
2660 gt_pch_nx (poly_int<N, C> *, gt_pointer_operator, void *)
2664 #undef POLY_SET_COEFF
2665 #undef POLY_INT_TYPE
2666 #undef POLY_BINARY_COEFF
2667 #undef CONST_CONST_RESULT
2668 #undef POLY_CONST_RESULT
2669 #undef CONST_POLY_RESULT
2670 #undef POLY_POLY_RESULT
2671 #undef POLY_CONST_COEFF
2672 #undef CONST_POLY_COEFF
2673 #undef POLY_POLY_COEFF
2675 #endif