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