Line data Source code
1 : /* Support routines for vrange storage.
2 : Copyright (C) 2022-2026 Free Software Foundation, Inc.
3 : Contributed by Aldy Hernandez <aldyh@redhat.com>.
4 :
5 : This file is part of GCC.
6 :
7 : GCC is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3, or (at your option)
10 : any later version.
11 :
12 : GCC is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #include "config.h"
22 : #include "system.h"
23 : #include "coretypes.h"
24 : #include "backend.h"
25 : #include "tree.h"
26 : #include "gimple.h"
27 : #include "ssa.h"
28 : #include "tree-pretty-print.h"
29 : #include "fold-const.h"
30 : #include "gimple-range.h"
31 : #include "value-range-storage.h"
32 :
33 : // Generic memory allocator to share one interface between GC and
34 : // obstack allocators.
35 :
36 : class vrange_internal_alloc
37 : {
38 : public:
39 112861961 : vrange_internal_alloc () { }
40 112861949 : virtual ~vrange_internal_alloc () { }
41 : virtual void *alloc (size_t size) = 0;
42 : virtual void free (void *) = 0;
43 : private:
44 : DISABLE_COPY_AND_ASSIGN (vrange_internal_alloc);
45 : };
46 :
47 : class vrange_obstack_alloc final: public vrange_internal_alloc
48 : {
49 : public:
50 112575220 : vrange_obstack_alloc ()
51 112575220 : {
52 112575220 : obstack_init (&m_obstack);
53 112575220 : }
54 112575208 : virtual ~vrange_obstack_alloc () final override
55 112575208 : {
56 112575208 : obstack_free (&m_obstack, NULL);
57 112575208 : }
58 394659090 : virtual void *alloc (size_t size) final override
59 : {
60 394659090 : return obstack_alloc (&m_obstack, size);
61 : }
62 0 : virtual void free (void *) final override { }
63 : private:
64 : obstack m_obstack;
65 : };
66 :
67 : class vrange_ggc_alloc final: public vrange_internal_alloc
68 : {
69 : public:
70 286741 : vrange_ggc_alloc () { }
71 286741 : virtual ~vrange_ggc_alloc () final override { }
72 18168556 : virtual void *alloc (size_t size) final override
73 : {
74 18168556 : return ggc_internal_alloc (size);
75 : }
76 0 : virtual void free (void *p) final override
77 : {
78 0 : return ggc_free (p);
79 : }
80 : };
81 :
82 112861961 : vrange_allocator::vrange_allocator (bool gc)
83 : {
84 112861961 : if (gc)
85 286741 : m_alloc = new vrange_ggc_alloc;
86 : else
87 112575220 : m_alloc = new vrange_obstack_alloc;
88 112861961 : }
89 :
90 112861949 : vrange_allocator::~vrange_allocator ()
91 : {
92 112861949 : delete m_alloc;
93 112861949 : }
94 :
95 : void *
96 56646332 : vrange_allocator::alloc (size_t size)
97 : {
98 56646332 : return m_alloc->alloc (size);
99 : }
100 :
101 : void
102 0 : vrange_allocator::free (void *p)
103 : {
104 0 : m_alloc->free (p);
105 0 : }
106 :
107 : // Allocate a new vrange_storage object initialized to R and return
108 : // it.
109 :
110 : vrange_storage *
111 299545027 : vrange_allocator::clone (const vrange &r)
112 : {
113 299545027 : return vrange_storage::alloc (*m_alloc, r);
114 : }
115 :
116 : vrange_storage *
117 28361267 : vrange_allocator::clone_varying (tree type)
118 : {
119 28361267 : if (irange::supports_p (type))
120 18217722 : return irange_storage::alloc (*m_alloc, int_range <1> (type));
121 10143545 : if (prange::supports_p (type))
122 9686914 : return prange_storage::alloc (*m_alloc, prange (type));
123 456631 : if (frange::supports_p (type))
124 456631 : return frange_storage::alloc (*m_alloc, frange (type));
125 : return NULL;
126 : }
127 :
128 : vrange_storage *
129 28275020 : vrange_allocator::clone_undefined (tree type)
130 : {
131 28275020 : if (irange::supports_p (type))
132 18136827 : return irange_storage::alloc (*m_alloc, int_range<1> ());
133 10138193 : if (prange::supports_p (type))
134 9685726 : return prange_storage::alloc (*m_alloc, prange ());
135 452467 : if (frange::supports_p (type))
136 452467 : return frange_storage::alloc (*m_alloc, frange ());
137 : return NULL;
138 : }
139 :
140 : // Allocate a new vrange_storage object initialized to R and return
141 : // it. Return NULL if R is unsupported.
142 :
143 : vrange_storage *
144 299545027 : vrange_storage::alloc (vrange_internal_alloc &allocator, const vrange &r)
145 : {
146 299545027 : if (is_a <irange> (r))
147 213333913 : return irange_storage::alloc (allocator, as_a <irange> (r));
148 86211114 : if (is_a <prange> (r))
149 74725581 : return prange_storage::alloc (allocator, as_a <prange> (r));
150 11485533 : if (is_a <frange> (r))
151 11485533 : return frange_storage::alloc (allocator, as_a <frange> (r));
152 : return NULL;
153 : }
154 :
155 : // Set storage to R.
156 :
157 : void
158 27545197 : vrange_storage::set_vrange (const vrange &r)
159 : {
160 27545197 : if (is_a <irange> (r))
161 : {
162 23276339 : irange_storage *s = static_cast <irange_storage *> (this);
163 23276339 : gcc_checking_assert (s->fits_p (as_a <irange> (r)));
164 23276339 : s->set_irange (as_a <irange> (r));
165 : }
166 4268858 : else if (is_a <prange> (r))
167 : {
168 3590297 : prange_storage *s = static_cast <prange_storage *> (this);
169 3590297 : gcc_checking_assert (s->fits_p (as_a <prange> (r)));
170 3590297 : s->set_prange (as_a <prange> (r));
171 : }
172 678561 : else if (is_a <frange> (r))
173 : {
174 678561 : frange_storage *s = static_cast <frange_storage *> (this);
175 678561 : gcc_checking_assert (s->fits_p (as_a <frange> (r)));
176 678561 : s->set_frange (as_a <frange> (r));
177 : }
178 : else
179 0 : gcc_unreachable ();
180 :
181 : // Verify that reading back from the cache didn't drop bits.
182 27545197 : if (flag_checking
183 : // FIXME: Avoid checking frange, as it currently pessimizes some ranges:
184 : //
185 : // gfortran.dg/pr49472.f90 pessimizes [0.0, 1.0] into [-0.0, 1.0].
186 27545107 : && !is_a <frange> (r)
187 54411743 : && !r.undefined_p ())
188 : {
189 26742467 : value_range tmp (r);
190 26742467 : get_vrange (tmp, r.type ());
191 26742467 : gcc_checking_assert (tmp == r);
192 26742467 : }
193 27545197 : }
194 :
195 : // Restore R from storage.
196 :
197 : void
198 1720677320 : vrange_storage::get_vrange (vrange &r, tree type) const
199 : {
200 1720677320 : if (is_a <irange> (r))
201 : {
202 1329125382 : const irange_storage *s = static_cast <const irange_storage *> (this);
203 1329125382 : s->get_irange (as_a <irange> (r), type);
204 : }
205 391551938 : else if (is_a <prange> (r))
206 : {
207 345239575 : const prange_storage *s = static_cast <const prange_storage *> (this);
208 345239575 : s->get_prange (as_a <prange> (r), type);
209 : }
210 46312363 : else if (is_a <frange> (r))
211 : {
212 46312363 : const frange_storage *s = static_cast <const frange_storage *> (this);
213 46312363 : s->get_frange (as_a <frange> (r), type);
214 : }
215 : else
216 0 : gcc_unreachable ();
217 1720677320 : }
218 :
219 : // Return TRUE if storage can fit R.
220 :
221 : bool
222 32272320 : vrange_storage::fits_p (const vrange &r) const
223 : {
224 32272320 : if (is_a <irange> (r))
225 : {
226 28198872 : const irange_storage *s = static_cast <const irange_storage *> (this);
227 28198872 : return s->fits_p (as_a <irange> (r));
228 : }
229 4073448 : if (is_a <prange> (r))
230 : {
231 3395306 : const prange_storage *s = static_cast <const prange_storage *> (this);
232 3395306 : return s->fits_p (as_a <prange> (r));
233 : }
234 678142 : if (is_a <frange> (r))
235 : {
236 678142 : const frange_storage *s = static_cast <const frange_storage *> (this);
237 678142 : return s->fits_p (as_a <frange> (r));
238 : }
239 0 : gcc_unreachable ();
240 : return false;
241 : }
242 :
243 : // Return TRUE if the range in storage is equal to R. It is the
244 : // caller's responsibility to verify that the type of the range in
245 : // storage matches that of R.
246 :
247 : bool
248 9637853 : vrange_storage::equal_p (const vrange &r) const
249 : {
250 9637853 : if (is_a <irange> (r))
251 : {
252 4541433 : const irange_storage *s = static_cast <const irange_storage *> (this);
253 4541433 : return s->equal_p (as_a <irange> (r));
254 : }
255 5096420 : if (is_a <prange> (r))
256 : {
257 5077402 : const prange_storage *s = static_cast <const prange_storage *> (this);
258 5077402 : return s->equal_p (as_a <prange> (r));
259 : }
260 19018 : if (is_a <frange> (r))
261 : {
262 19018 : const frange_storage *s = static_cast <const frange_storage *> (this);
263 19018 : return s->equal_p (as_a <frange> (r));
264 : }
265 0 : gcc_unreachable ();
266 : }
267 :
268 : //============================================================================
269 : // irange_storage implementation
270 : //============================================================================
271 :
272 : unsigned short *
273 1063577272 : irange_storage::write_lengths_address ()
274 : {
275 1063577272 : return (unsigned short *)&m_val[(m_num_ranges * 2 + 2)
276 1063577272 : * WIDE_INT_MAX_HWIS (m_precision)];
277 : }
278 :
279 : const unsigned short *
280 922982972 : irange_storage::lengths_address () const
281 : {
282 922982972 : return const_cast <irange_storage *> (this)->write_lengths_address ();
283 : }
284 :
285 : // Allocate a new irange_storage object initialized to R.
286 :
287 : irange_storage *
288 249688462 : irange_storage::alloc (vrange_internal_alloc &allocator, const irange &r)
289 : {
290 249688462 : size_t size = irange_storage::size (r);
291 249688462 : irange_storage *p = static_cast <irange_storage *> (allocator.alloc (size));
292 249688462 : new (p) irange_storage (r);
293 249688462 : return p;
294 : }
295 :
296 : // Initialize the storage with R.
297 :
298 249688462 : irange_storage::irange_storage (const irange &r)
299 249688462 : : m_max_ranges (r.num_pairs ())
300 : {
301 249688462 : m_num_ranges = m_max_ranges;
302 249688462 : set_irange (r);
303 249688462 : }
304 :
305 : static inline void
306 677982776 : write_wide_int (HOST_WIDE_INT *&val, unsigned short *&len, const wide_int &w)
307 : {
308 677982776 : *len = w.get_len ();
309 1357027419 : for (unsigned i = 0; i < *len; ++i)
310 679044643 : *val++ = w.elt (i);
311 677982776 : ++len;
312 677982776 : }
313 :
314 : // Store R into the current storage.
315 :
316 : void
317 272964801 : irange_storage::set_irange (const irange &r)
318 : {
319 272964801 : gcc_checking_assert (fits_p (r));
320 :
321 272964801 : if (r.undefined_p ())
322 : {
323 18521242 : m_kind = VR_UNDEFINED;
324 132370501 : return;
325 : }
326 254443559 : if (r.varying_p ())
327 : {
328 113849259 : m_kind = VR_VARYING;
329 113849259 : return;
330 : }
331 :
332 140594300 : m_precision = TYPE_PRECISION (r.type ());
333 140594300 : m_num_ranges = r.num_pairs ();
334 140594300 : m_kind = VR_RANGE;
335 :
336 140594300 : HOST_WIDE_INT *val = &m_val[0];
337 140594300 : unsigned short *len = write_lengths_address ();
338 :
339 338991388 : for (unsigned i = 0; i < r.num_pairs (); ++i)
340 : {
341 198397088 : write_wide_int (val, len, r.lower_bound (i));
342 198399377 : write_wide_int (val, len, r.upper_bound (i));
343 : }
344 :
345 : // TODO: We could avoid streaming out the value if the mask is -1.
346 140594300 : irange_bitmask bm = r.m_bitmask;
347 140594300 : write_wide_int (val, len, bm.value ());
348 140594300 : write_wide_int (val, len, bm.mask ());
349 140594300 : }
350 :
351 : static inline void
352 4461050608 : read_wide_int (wide_int &w,
353 : const HOST_WIDE_INT *val, unsigned short len, unsigned prec)
354 : {
355 4461050608 : trailing_wide_int_storage stow (prec, &len,
356 1112599064 : const_cast <HOST_WIDE_INT *> (val));
357 3348451544 : w = trailing_wide_int (stow);
358 : }
359 :
360 : // Restore a range of TYPE from storage into R.
361 :
362 : void
363 1333251510 : irange_storage::get_irange (irange &r, tree type) const
364 : {
365 1333251510 : if (m_kind == VR_UNDEFINED)
366 : {
367 10504097 : r.set_undefined ();
368 420772635 : return;
369 : }
370 1322747413 : if (m_kind == VR_VARYING)
371 : {
372 399764441 : r.set_varying (type);
373 399764441 : return;
374 : }
375 :
376 922982972 : gcc_checking_assert (TYPE_PRECISION (type) == m_precision);
377 922982972 : const HOST_WIDE_INT *val = &m_val[0];
378 922982972 : const unsigned short *len = lengths_address ();
379 :
380 : // Handle the common case where R can fit the new range.
381 922982972 : if (r.m_max_ranges >= m_num_ranges)
382 : {
383 890336209 : r.m_kind = VR_RANGE;
384 890336209 : r.m_num_ranges = m_num_ranges;
385 890336209 : r.m_type = type;
386 3126188689 : for (unsigned i = 0; i < m_num_ranges * 2; ++i)
387 : {
388 2235852480 : read_wide_int (r.m_base[i], val, *len, m_precision);
389 2235852480 : val += *len++;
390 : }
391 : }
392 : // Otherwise build the range piecewise.
393 : else
394 : {
395 32646763 : r.set_undefined ();
396 222262855 : for (unsigned i = 0; i < m_num_ranges; ++i)
397 : {
398 189616092 : wide_int lb, ub;
399 189616092 : read_wide_int (lb, val, *len, m_precision);
400 189616092 : val += *len++;
401 189616092 : read_wide_int (ub, val, *len, m_precision);
402 189616092 : val += *len++;
403 189616092 : int_range<1> tmp (type, lb, ub);
404 189616092 : r.union_ (tmp);
405 189616092 : }
406 : }
407 :
408 922982972 : wide_int bits_value, bits_mask;
409 922982972 : read_wide_int (bits_value, val, *len, m_precision);
410 922982972 : val += *len++;
411 922982972 : read_wide_int (bits_mask, val, *len, m_precision);
412 922982972 : r.m_bitmask = irange_bitmask (bits_value, bits_mask);
413 922982972 : if (r.m_kind == VR_VARYING)
414 0 : r.m_kind = VR_RANGE;
415 :
416 922982972 : if (flag_checking)
417 922979258 : r.verify_range ();
418 922989645 : }
419 :
420 : bool
421 4541433 : irange_storage::equal_p (const irange &r) const
422 : {
423 4541433 : if (m_kind == VR_UNDEFINED || r.undefined_p ())
424 0 : return m_kind == r.m_kind;
425 4541433 : if (m_kind == VR_VARYING || r.varying_p ())
426 415305 : return m_kind == r.m_kind;
427 :
428 : // ?? We could make this faster by doing the comparison in place,
429 : // without going through get_irange.
430 4126128 : int_range_max tmp;
431 4126128 : get_irange (tmp, r.type ());
432 4126128 : return tmp == r;
433 4126128 : }
434 :
435 : // Return the size in bytes to allocate storage that can hold R.
436 :
437 : size_t
438 249688462 : irange_storage::size (const irange &r)
439 : {
440 249688462 : if (r.undefined_p ())
441 : return sizeof (irange_storage);
442 :
443 231285028 : unsigned prec = TYPE_PRECISION (r.type ());
444 231285028 : unsigned n = r.num_pairs () * 2 + 2;
445 231285028 : unsigned hwi_size = ((n * WIDE_INT_MAX_HWIS (prec) - 1)
446 : * sizeof (HOST_WIDE_INT));
447 231285028 : unsigned len_size = n * sizeof (unsigned short);
448 231285028 : return sizeof (irange_storage) + hwi_size + len_size;
449 : }
450 :
451 : // Return TRUE if R fits in the current storage.
452 :
453 : bool
454 324440012 : irange_storage::fits_p (const irange &r) const
455 : {
456 324440012 : return m_max_ranges >= r.num_pairs ();
457 : }
458 :
459 : void
460 0 : irange_storage::dump () const
461 : {
462 0 : fprintf (stderr, "irange_storage (prec=%d, ranges=%d):\n",
463 0 : m_precision, m_num_ranges);
464 :
465 0 : if (m_num_ranges == 0)
466 : return;
467 :
468 0 : const HOST_WIDE_INT *val = &m_val[0];
469 0 : const unsigned short *len = lengths_address ();
470 0 : int i, j;
471 :
472 0 : fprintf (stderr, " lengths = [ ");
473 0 : for (i = 0; i < m_num_ranges * 2 + 2; ++i)
474 0 : fprintf (stderr, "%d ", len[i]);
475 0 : fprintf (stderr, "]\n");
476 :
477 0 : for (i = 0; i < m_num_ranges; ++i)
478 : {
479 0 : for (j = 0; j < *len; ++j)
480 0 : fprintf (stderr, " [PAIR %d] LB " HOST_WIDE_INT_PRINT_DEC "\n", i,
481 0 : *val++);
482 0 : ++len;
483 0 : for (j = 0; j < *len; ++j)
484 0 : fprintf (stderr, " [PAIR %d] UB " HOST_WIDE_INT_PRINT_DEC "\n", i,
485 0 : *val++);
486 0 : ++len;
487 : }
488 :
489 : // Dump value/mask pair.
490 0 : for (j = 0; j < *len; ++j)
491 0 : fprintf (stderr, " [VALUE] " HOST_WIDE_INT_PRINT_DEC "\n", *val++);
492 0 : ++len;
493 0 : for (j = 0; j < *len; ++j)
494 0 : fprintf (stderr, " [MASK] " HOST_WIDE_INT_PRINT_DEC "\n", *val++);
495 : }
496 :
497 : DEBUG_FUNCTION void
498 0 : debug (const irange_storage &storage)
499 : {
500 0 : storage.dump ();
501 0 : fprintf (stderr, "\n");
502 0 : }
503 :
504 : //============================================================================
505 : // frange_storage implementation
506 : //============================================================================
507 :
508 : // Allocate a new frange_storage object initialized to R.
509 :
510 : frange_storage *
511 12394631 : frange_storage::alloc (vrange_internal_alloc &allocator, const frange &r)
512 : {
513 12394631 : size_t size = sizeof (frange_storage);
514 12394631 : frange_storage *p = static_cast <frange_storage *> (allocator.alloc (size));
515 12394631 : new (p) frange_storage (r);
516 12394631 : return p;
517 : }
518 :
519 : void
520 13073192 : frange_storage::set_frange (const frange &r)
521 : {
522 13073192 : gcc_checking_assert (fits_p (r));
523 :
524 13073192 : m_kind = r.m_kind;
525 13073192 : m_min = r.m_min;
526 13073192 : m_max = r.m_max;
527 13073192 : m_pos_nan = r.m_pos_nan;
528 13073192 : m_neg_nan = r.m_neg_nan;
529 13073192 : }
530 :
531 : void
532 46331381 : frange_storage::get_frange (frange &r, tree type) const
533 : {
534 46331381 : gcc_checking_assert (r.supports_type_p (type));
535 :
536 : // Handle explicit NANs.
537 46331381 : if (m_kind == VR_NAN)
538 : {
539 104771 : if (HONOR_NANS (type))
540 : {
541 104771 : if (m_pos_nan && m_neg_nan)
542 99281 : r.set_nan (type);
543 : else
544 5490 : r.set_nan (type, m_neg_nan);
545 : }
546 : else
547 0 : r.set_undefined ();
548 104771 : return;
549 : }
550 46226610 : if (m_kind == VR_UNDEFINED)
551 : {
552 67156 : r.set_undefined ();
553 67156 : return;
554 : }
555 :
556 : // We use the constructor to create the new range instead of writing
557 : // out the bits into the frange directly, because the global range
558 : // being read may be being inlined into a function with different
559 : // restrictions as when it was originally written. We want to make
560 : // sure the resulting range is canonicalized correctly for the new
561 : // consumer.
562 46159454 : r = frange (type, m_min, m_max, m_kind);
563 :
564 : // The constructor will set the NAN bits for HONOR_NANS, but we must
565 : // make sure to set the NAN sign if known.
566 46159454 : if (HONOR_NANS (type) && (m_pos_nan ^ m_neg_nan) == 1)
567 1288264 : r.update_nan (m_neg_nan);
568 44871190 : else if (!m_pos_nan && !m_neg_nan)
569 12267899 : r.clear_nan ();
570 : }
571 :
572 : bool
573 19018 : frange_storage::equal_p (const frange &r) const
574 : {
575 19018 : if (r.undefined_p ())
576 0 : return m_kind == VR_UNDEFINED;
577 :
578 19018 : frange tmp;
579 19018 : get_frange (tmp, r.type ());
580 19018 : return tmp == r;
581 19018 : }
582 :
583 : bool
584 14429895 : frange_storage::fits_p (const frange &) const
585 : {
586 14429895 : return true;
587 : }
588 :
589 : //============================================================================
590 : // prange_storage implementation
591 : //============================================================================
592 :
593 : prange_storage *
594 94098221 : prange_storage::alloc (vrange_internal_alloc &allocator, const prange &r)
595 : {
596 94098221 : size_t size = sizeof (prange_storage);
597 94098221 : if (!r.undefined_p ())
598 : {
599 84378663 : unsigned prec = TYPE_PRECISION (r.type ());
600 84378663 : size += trailing_wide_ints<NINTS>::extra_size (prec);
601 : }
602 94098221 : prange_storage *p = static_cast <prange_storage *> (allocator.alloc (size));
603 94098221 : new (p) prange_storage (r);
604 94098221 : return p;
605 : }
606 :
607 : // Initialize the storage with R.
608 :
609 94098221 : prange_storage::prange_storage (const prange &r)
610 : {
611 : // It is the caller's responsibility to allocate enough space such
612 : // that the precision fits.
613 94098221 : if (r.undefined_p ())
614 : // Undefined ranges do not require any extra space for trailing
615 : // wide ints.
616 9719558 : m_trailing_ints.set_precision (0);
617 : else
618 84378663 : m_trailing_ints.set_precision (TYPE_PRECISION (r.type ()));
619 :
620 94098221 : set_prange (r);
621 94098221 : }
622 :
623 : void
624 97688518 : prange_storage::set_prange (const prange &r)
625 : {
626 97688518 : if (r.undefined_p ())
627 9725846 : m_kind = VR_UNDEFINED;
628 87962672 : else if (r.varying_p ())
629 47346948 : m_kind = VR_VARYING;
630 : else
631 : {
632 40615724 : m_kind = VR_RANGE;
633 40615724 : set_low (r.lower_bound ());
634 40615724 : set_high (r.upper_bound ());
635 40615724 : irange_bitmask bm = r.m_bitmask;
636 40615724 : set_value (bm.value ());
637 40615724 : set_mask (bm.mask ());
638 40615724 : }
639 97688518 : }
640 :
641 : void
642 350316977 : prange_storage::get_prange (prange &r, tree type) const
643 : {
644 350316977 : gcc_checking_assert (r.supports_type_p (type));
645 :
646 350316977 : if (m_kind == VR_UNDEFINED)
647 959790 : r.set_undefined ();
648 349357187 : else if (m_kind == VR_VARYING)
649 196143632 : r.set_varying (type);
650 : else
651 : {
652 153213555 : gcc_checking_assert (m_kind == VR_RANGE);
653 153213555 : gcc_checking_assert (TYPE_PRECISION (type) == m_trailing_ints.get_precision ());
654 153213555 : r.m_kind = VR_RANGE;
655 153213555 : r.m_type = type;
656 153213555 : r.m_min = get_low ();
657 153213555 : r.m_max = get_high ();
658 153213555 : r.m_bitmask = irange_bitmask (get_value (), get_mask ());
659 153213555 : if (flag_checking)
660 153213417 : r.verify_range ();
661 : }
662 350316977 : }
663 :
664 : bool
665 5077402 : prange_storage::equal_p (const prange &r) const
666 : {
667 5077402 : if (r.undefined_p ())
668 0 : return m_kind == VR_UNDEFINED;
669 :
670 5077402 : prange tmp;
671 5077402 : get_prange (tmp, r.type ());
672 5077402 : return tmp == r;
673 5077402 : }
674 :
675 : bool
676 6985603 : prange_storage::fits_p (const prange &r) const
677 : {
678 : // Undefined ranges always fit, because they don't store anything in
679 : // the trailing wide ints.
680 6985603 : if (r.undefined_p ())
681 : return true;
682 :
683 6973027 : return TYPE_PRECISION (r.type ()) <= m_trailing_ints.get_precision ();
684 : }
685 :
686 :
687 : static vrange_allocator ggc_vrange_allocator (true);
688 :
689 0 : vrange_storage *ggc_alloc_vrange_storage (tree type)
690 : {
691 0 : return ggc_vrange_allocator.clone_varying (type);
692 : }
693 :
694 18168556 : vrange_storage *ggc_alloc_vrange_storage (const vrange &r)
695 : {
696 18168556 : return ggc_vrange_allocator.clone (r);
697 : }
|