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
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
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
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:
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
;
69 struct poly_coeff_traits
<T
, wi::FLEXIBLE_PRECISION
>
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))
79 static const int rank
= sizeof (T
) * 2 + !signedness
;
81 template<typename Arg
>
82 struct init_cast
{ using type
= T
; };
86 struct poly_coeff_traits
<T
, wi::VAR_PRECISION
>
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
&; };
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
&; };
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.
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
))
167 /* SFINAE class that makes T3 available as "type" if T2 can represent all the
169 template<typename T1
, typename T2
, typename T3
,
170 bool lossless_p
= poly_coeff_pair_traits
<T1
, T2
>::lossless_p
>
172 template<typename T1
, typename T2
, typename T3
>
173 struct if_lossless
<T1
, T2
, T3
, true>
178 /* poly_int_traits<T> describes an integer type T that might be polynomial
181 - poly_int_traits<T>::is_poly is true if T is a poly_int-based type
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. */
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
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>
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>
232 /* SFINAE class that makes T2 available as "type" if T1 is a polynomial
234 template<typename T1
, typename T2
= T1
,
235 bool is_poly
= poly_int_traits
<T1
>::is_poly
>
237 template<typename T1
, typename T2
>
238 struct if_poly
<T1
, T2
, true>
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
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
>
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
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
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
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
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
>
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;
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,
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
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
>
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
>
455 poly_int
<N
, C
>::poly_int (const Cs
&... cs
)
456 : poly_int (typename poly_int_fullness
<sizeof... (Cs
) >= N
>::type (),
459 /* Initialize with c0, cs..., and some trailing zeros. */
460 template<unsigned int N
, typename C
>
461 template<typename C0
, typename
...Cs
>
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
>
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
]);
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
);
491 for (unsigned int i
= 1; i
< N
; i
++)
492 POLY_SET_COEFF (C
, *this, i
, wi::ints_for
<C
>::zero (this->coeffs
[0]));
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
];
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
;
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
];
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
;
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
;
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
;
553 /* Return true if the polynomial value is a compile-time constant. */
555 template<unsigned int N
, typename C
>
557 poly_int
<N
, C
>::is_constant () const
560 for (unsigned int i
= 1; i
< N
; i
++)
561 if (this->coeffs
[i
] != 0)
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
>
571 inline typename if_lossless
<T
, C
, bool>::type
572 poly_int
<N
, C
>::is_constant (T
*const_value
) const
576 *const_value
= this->coeffs
[0];
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
>
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
,
607 for (unsigned int i
= 0; i
< N
; i
++)
608 POLY_SET_COEFF (C
, r
, i
, C::from (a
.coeffs
[i
], bitsize
, sgn
));
612 /* Convert X to a fixed_wide_int-based polynomial, extending according
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
)
621 for (unsigned int i
= 0; i
< N
; i
++)
622 POLY_SET_COEFF (C
, r
, i
, C::from (a
.coeffs
[i
], sgn
));
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
>
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
]))
637 for (unsigned int i
= 0; i
< N
; i
++)
638 r
->coeffs
[i
] = this->coeffs
[i
].to_shwi ();
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
647 template<unsigned int N
, typename C
>
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
]))
654 for (unsigned int i
= 0; i
< N
; i
++)
655 r
->coeffs
[i
] = this->coeffs
[i
].to_uhwi ();
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 ();
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 ();
685 #if POLY_INT_CONVERSION
686 /* Provide a conversion operator to constants. */
688 template<unsigned int N
, typename C
>
690 poly_int
<N
, C
>::operator C () const
692 gcc_checking_assert (this->is_constant ());
693 return this->coeffs
[0];
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
)
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
));
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
));
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
;
749 for (unsigned int i
= 0; i
< N
; i
++)
750 POLY_SET_COEFF (C
, r
, i
, wi::sext (a
.coeffs
[i
], precision
));
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
;
762 for (unsigned int i
= 0; i
< N
; i
++)
763 POLY_SET_COEFF (C
, r
, i
, wi::zext (a
.coeffs
[i
], precision
));
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
;
775 for (unsigned int i
= 0; i
< N
; i
++)
776 POLY_SET_COEFF (C
, r
, i
, NCa (a
.coeffs
[i
]) + b
.coeffs
[i
]);
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
;
787 POLY_SET_COEFF (C
, r
, 0, NCa (a
.coeffs
[0]) + b
);
789 for (unsigned int i
= 1; i
< N
; i
++)
790 POLY_SET_COEFF (C
, r
, i
, NCa (a
.coeffs
[i
]));
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
;
801 POLY_SET_COEFF (C
, r
, 0, a
+ NCb (b
.coeffs
[0]));
803 for (unsigned int i
= 1; i
< N
; i
++)
804 POLY_SET_COEFF (C
, r
, i
, NCb (b
.coeffs
[i
]));
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
;
817 for (unsigned int i
= 0; i
< N
; i
++)
818 POLY_SET_COEFF (C
, r
, i
, wi::add (a
.coeffs
[i
], b
.coeffs
[i
]));
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
;
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
)));
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
;
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
),
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
;
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
,
861 wi::accumulate_overflow (*overflow
, suboverflow
);
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
;
874 for (unsigned int i
= 0; i
< N
; i
++)
875 POLY_SET_COEFF (C
, r
, i
, NCa (a
.coeffs
[i
]) - b
.coeffs
[i
]);
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
;
886 POLY_SET_COEFF (C
, r
, 0, NCa (a
.coeffs
[0]) - b
);
888 for (unsigned int i
= 1; i
< N
; i
++)
889 POLY_SET_COEFF (C
, r
, i
, NCa (a
.coeffs
[i
]));
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
;
900 POLY_SET_COEFF (C
, r
, 0, a
- NCb (b
.coeffs
[0]));
902 for (unsigned int i
= 1; i
< N
; i
++)
903 POLY_SET_COEFF (C
, r
, i
, -NCb (b
.coeffs
[i
]));
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
;
916 for (unsigned int i
= 0; i
< N
; i
++)
917 POLY_SET_COEFF (C
, r
, i
, wi::sub (a
.coeffs
[i
], b
.coeffs
[i
]));
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
;
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
)));
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
;
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
),
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
;
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
,
960 wi::accumulate_overflow (*overflow
, suboverflow
);
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
;
973 for (unsigned int i
= 0; i
< N
; i
++)
974 POLY_SET_COEFF (C
, r
, i
, -NCa (a
.coeffs
[i
]));
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
;
987 for (unsigned int i
= 0; i
< N
; i
++)
988 POLY_SET_COEFF (C
, r
, i
, wi::neg (a
.coeffs
[i
]));
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
;
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
);
1009 template<unsigned int N
, typename Ca
>
1010 inline POLY_POLY_RESULT (N
, Ca
, Ca
)
1011 operator ~ (const poly_int
<N
, Ca
> &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
;
1025 for (unsigned int i
= 0; i
< N
; i
++)
1026 POLY_SET_COEFF (C
, r
, i
, NCa (a
.coeffs
[i
]) * b
);
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
;
1037 for (unsigned int i
= 0; i
< N
; i
++)
1038 POLY_SET_COEFF (C
, r
, i
, NCa (a
) * b
.coeffs
[i
]);
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
;
1051 for (unsigned int i
= 0; i
< N
; i
++)
1052 POLY_SET_COEFF (C
, r
, i
, wi::mul (a
.coeffs
[i
], b
));
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
;
1062 for (unsigned int i
= 0; i
< N
; i
++)
1063 POLY_SET_COEFF (C
, r
, i
, wi::mul (a
, b
.coeffs
[i
]));
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
;
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
);
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
;
1092 for (unsigned int i
= 0; i
< N
; i
++)
1093 POLY_SET_COEFF (C
, r
, i
, NCa (a
.coeffs
[i
]) << b
);
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
;
1106 for (unsigned int i
= 0; i
< N
; i
++)
1107 POLY_SET_COEFF (C
, r
, i
, wi::lshift (a
.coeffs
[i
], b
));
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
);
1125 /* Return true if a0 + a1 * x might equal b0 + b1 * x for some nonnegative
1128 template<typename Ca
, typename Cb
>
1130 maybe_eq_2 (const Ca
&a0
, const Ca
&a1
, const Cb
&b0
, const Cb
&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. */
1141 ? b0
<= a0
&& (a0
- b0
) % (b1
- a1
) == 0
1142 : b0
>= a0
&& (b0
- a0
) % (a1
- b1
) == 0);
1146 /* Return true if a0 + a1 * x might equal b for some nonnegative
1149 template<typename Ca
, typename Cb
>
1151 maybe_eq_2 (const Ca
&a0
, const Ca
&a1
, const Cb
&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. */
1161 ? b
<= a0
&& (a0
- b
) % a1
== 0
1162 : b
>= a0
&& (b
- a0
) % a1
== 0);
1166 /* Return true if A might equal B for some indeterminate values. */
1168 template<unsigned int N
, typename Ca
, typename Cb
>
1170 maybe_eq (const poly_int
<N
, Ca
> &a
, const poly_int
<N
, Cb
> &b
)
1172 STATIC_ASSERT (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);
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);
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
)
1205 /* Return true if A might not equal B for some indeterminate values. */
1207 template<unsigned int N
, typename Ca
, typename Cb
>
1209 maybe_ne (const poly_int
<N
, Ca
> &a
, const poly_int
<N
, Cb
> &b
)
1212 for (unsigned int i
= 1; i
< N
; i
++)
1213 if (a
.coeffs
[i
] != b
.coeffs
[i
])
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
)
1223 for (unsigned int i
= 1; i
< N
; i
++)
1224 if (a
.coeffs
[i
] != 0)
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
)
1234 for (unsigned int i
= 1; i
< N
; i
++)
1235 if (b
.coeffs
[i
] != 0)
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
)
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
>
1258 maybe_le (const poly_int
<N
, Ca
> &a
, const poly_int
<N
, Cb
> &b
)
1261 for (unsigned int i
= 1; i
< N
; i
++)
1262 if (a
.coeffs
[i
] < b
.coeffs
[i
])
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
)
1272 for (unsigned int i
= 1; i
< N
; i
++)
1273 if (a
.coeffs
[i
] < 0)
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
)
1283 for (unsigned int i
= 1; i
< N
; i
++)
1284 if (b
.coeffs
[i
] > 0)
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
)
1296 /* Return true if A might be less than B for some indeterminate values. */
1298 template<unsigned int N
, typename Ca
, typename Cb
>
1300 maybe_lt (const poly_int
<N
, Ca
> &a
, const poly_int
<N
, Cb
> &b
)
1303 for (unsigned int i
= 1; i
< N
; i
++)
1304 if (a
.coeffs
[i
] < b
.coeffs
[i
])
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
)
1314 for (unsigned int i
= 1; i
< N
; i
++)
1315 if (a
.coeffs
[i
] < 0)
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
)
1325 for (unsigned int i
= 1; i
< N
; i
++)
1326 if (b
.coeffs
[i
] > 0)
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
)
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
>
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)
1365 || known_le (b
, a
));
1368 /* Assert that A and B are known to be ordered and return the minimum
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
))
1383 gcc_checking_assert (known_le (b
, a
));
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
))
1397 gcc_checking_assert (known_le (b
, a
));
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
))
1411 gcc_checking_assert (known_le (b
, a
));
1416 /* Assert that A and B are known to be ordered and return the maximum
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
))
1431 gcc_checking_assert (known_le (b
, 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
))
1445 gcc_checking_assert (known_le (b
, 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
))
1459 gcc_checking_assert (known_le (b
, 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
>
1469 constant_lower_bound (const poly_int
<N
, Ca
> &a
)
1471 gcc_checking_assert (known_ge (a
, POLY_INT_TYPE (Ca
) (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
))
1486 /* Return the constant upper bound of A, given that it is no greater
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
))
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
;
1512 POLY_SET_COEFF (C
, r
, 0, MIN (NCa (a
.coeffs
[0]), NCb (b
)));
1514 for (unsigned int i
= 1; i
< N
; i
++)
1515 POLY_SET_COEFF (C
, r
, i
, MIN (NCa (a
.coeffs
[i
]), ICb (0)));
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
;
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
])));
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
;
1561 POLY_SET_COEFF (C
, r
, 0, MAX (NCa (a
.coeffs
[0]), NCb (b
)));
1563 for (unsigned int i
= 1; i
< N
; i
++)
1564 POLY_SET_COEFF (C
, r
, i
, MAX (NCa (a
.coeffs
[i
]), ICb (0)));
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
;
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
])));
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. */
1598 for (i
= N
- 1; i
> 0; --i
)
1599 if (a
.coeffs
[i
] != 0)
1601 typedef POLY_BINARY_COEFF (Ca
, Ca
) C
;
1603 for (unsigned int j
= 0; j
< i
; ++j
)
1604 if (a
.coeffs
[j
] != 0)
1605 r
= gcd (r
, C (a
.coeffs
[j
]));
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
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
);
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
1674 template<unsigned int N
, typename Ca
, typename Cb
>
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;
1684 /* Return true if we can calculate VALUE & (ALIGN - 1) at compile time. */
1686 template<unsigned int N
, typename Ca
, typename Cb
>
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)
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
>
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
))
1706 *aligned
= value
+ (-value
.coeffs
[0] & (align
- 1));
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
>
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
))
1720 *aligned
= value
- (value
.coeffs
[0] & (align
- 1));
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
1728 template<unsigned int N
, typename Ca
, typename Cb
, typename Cc
>
1730 known_equal_after_align_up (const poly_int
<N
, Ca
> &a
,
1731 const poly_int
<N
, Cb
> &b
,
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
1745 template<unsigned int N
, typename Ca
, typename Cb
, typename Cc
>
1747 known_equal_after_align_down (const poly_int
<N
, Ca
> &a
,
1748 const poly_int
<N
, Cb
> &b
,
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
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
)
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))));
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
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
)
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))));
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
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
));
1835 POLY_SET_COEFF (Ca
, r
, 0, ((value
.coeffs
[0]
1836 - (value
.coeffs
[0] & (align
- 1)))
1839 for (unsigned int i
= 1; i
< N
; i
++)
1840 POLY_SET_COEFF (Ca
, r
, i
, value
.coeffs
[i
] / align
);
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
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
));
1859 POLY_SET_COEFF (Ca
, r
, 0, ((value
.coeffs
[0]
1860 + (-value
.coeffs
[0] & (align
- 1)))
1863 for (unsigned int i
= 1; i
< N
; i
++)
1864 POLY_SET_COEFF (Ca
, r
, i
, value
.coeffs
[i
] / align
);
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
1872 template<unsigned int N
, typename Ca
, typename Cb
, typename Cm
>
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
))
1879 *misalign
= value
.coeffs
[0] & (align
- 1);
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
;
1904 for (unsigned int i
= 1; i
< N
; ++i
)
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
1918 typedef POLY_INT_TYPE (Ca
) int_type
;
1920 for (unsigned int i
= 1; i
< N
; i
++)
1921 if ((-(a
.coeffs
[i
] & -a
.coeffs
[i
]) & b
) != int_type (0))
1924 result
->coeffs
[0] |= b
;
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
1940 if (NCa (a
.coeffs
[0]) % NCb (b
) != 0 || !a
.is_constant ())
1942 *multiple
= NCa (a
.coeffs
[0]) / NCb (b
);
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
1956 if (NCa (a
) % NCb (b
.coeffs
[0]) != 0
1957 || (a
!= int_type (0) && !b
.is_constant ()))
1959 *multiple
= NCa (a
) / NCb (b
.coeffs
[0]);
1963 template<unsigned int N
, typename Ca
, typename Cb
, typename Cm
>
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)
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
))
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
2000 if (NCa (a
.coeffs
[0]) % NCb (b
) != 0 || !a
.is_constant ())
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
2015 if (NCa (a
) % NCb (b
.coeffs
[0]) != 0
2016 || (a
!= int_type (0) && !b
.is_constant ()))
2021 template<unsigned int N
, typename Ca
, typename Cb
>
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)
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
))
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
)
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)
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
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
>
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
)
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
))
2114 for (unsigned int i
= 0; i
< N
; ++i
)
2115 multiple
->coeffs
[i
] = a
.coeffs
[i
] / b
;
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
2130 if (a
% b
.coeffs
[0] != 0 || (NCa (a
) != 0 && !b
.is_constant ()))
2132 *multiple
= a
/ b
.coeffs
[0];
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
>
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
;
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
);
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
));
2191 /* Return true if there is some constant Q and polynomial r such that:
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
2208 Cq q
= NCa (a
.coeffs
[0]) / NCb (b
);
2209 if (!a
.is_constant ())
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
,
2220 /* We can calculate Q from the case in which the indeterminates
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:
2240 |a0 - b0 * Q| < |b0|
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|
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:
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))
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|. */
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). */
2304 else if (q
<= 0 && qi
< q
&& qi
+ 1 == q
)
2306 else if (q
>= 0 && qi
> q
&& qi
- 1 == q
)
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
2316 if (rem_p
&& (!ordered_p (a
, ICa (0)) || !ordered_p (b
, ICb (0))))
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
))
2332 *remainder
= a
- *quotient
* b
;
2336 /* Return true if there is some polynomial q and constant R such that:
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)
2353 for (unsigned int i
= 0; i
< N
; ++i
)
2354 quotient
->coeffs
[i
] = a
.coeffs
[i
] / b
;
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
))
2367 *remainder
= a
.coeffs
[0] % b
;
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
2377 template<unsigned int N
, typename Ca
, typename Cb
, typename Cq
>
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
, "ient
->coeffs
[0]))
2386 for (unsigned int i
= 1; i
< N
; ++i
)
2387 quotient
->coeffs
[i
] = 0;
2391 /* Return true if there is some constant Q and polynomial r such that:
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
,
2404 if (!can_div_trunc_p (a
, b
, quotient
))
2406 if (maybe_ne (*quotient
* b
, a
))
2407 *quotient
+= (*quotient
< 0 ? -1 : 1);
2411 /* Use print_dec to print VALUE to FILE, where SGN is the sign
2414 template<unsigned int N
, typename C
>
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
);
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
>
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
>
2447 print_hex (const poly_int
<N
, C
> &value
, FILE *file
)
2449 if (value
.is_constant ())
2450 print_hex (value
.coeffs
[0], file
);
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
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
>
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
2514 template<typename T1
, typename T2
, typename T3
>
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
))
2522 if (!known_size_p (size
))
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. */
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
2538 template<typename T1
, typename T2
, typename T3
>
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
>
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));
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
>
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
>
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
>
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
])
2646 template<unsigned int N
, typename C
>
2648 gt_ggc_mx (poly_int
<N
, C
> *)
2652 template<unsigned int N
, typename C
>
2654 gt_pch_nx (poly_int
<N
, C
> *)
2658 template<unsigned int N
, typename C
>
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