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