Mercurial > hg > CbC > CbC_gcc
comparison gcc/vec.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Vector API for GNU compiler. | 1 /* Vector API for GNU compiler. |
2 Copyright (C) 2004-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2004-2018 Free Software Foundation, Inc. |
3 Contributed by Nathan Sidwell <nathan@codesourcery.com> | 3 Contributed by Nathan Sidwell <nathan@codesourcery.com> |
4 Re-implemented in C++ by Diego Novillo <dnovillo@google.com> | 4 Re-implemented in C++ by Diego Novillo <dnovillo@google.com> |
5 | 5 |
6 This file is part of GCC. | 6 This file is part of GCC. |
7 | 7 |
58 vec_usage (size_t allocated, size_t times, size_t peak, | 58 vec_usage (size_t allocated, size_t times, size_t peak, |
59 size_t items, size_t items_peak) | 59 size_t items, size_t items_peak) |
60 : mem_usage (allocated, times, peak), | 60 : mem_usage (allocated, times, peak), |
61 m_items (items), m_items_peak (items_peak) {} | 61 m_items (items), m_items_peak (items_peak) {} |
62 | 62 |
63 /* Comparison operator. */ | |
64 inline bool | |
65 operator< (const vec_usage &second) const | |
66 { | |
67 return (m_allocated == second.m_allocated ? | |
68 (m_peak == second.m_peak ? m_times < second.m_times | |
69 : m_peak < second.m_peak) : m_allocated < second.m_allocated); | |
70 } | |
71 | |
72 /* Sum the usage with SECOND usage. */ | 63 /* Sum the usage with SECOND usage. */ |
73 vec_usage | 64 vec_usage |
74 operator+ (const vec_usage &second) | 65 operator+ (const vec_usage &second) |
75 { | 66 { |
76 return vec_usage (m_allocated + second.m_allocated, | 67 return vec_usage (m_allocated + second.m_allocated, |
111 dump_header (const char *name) | 102 dump_header (const char *name) |
112 { | 103 { |
113 fprintf (stderr, "%-48s %11s%15s%10s%17s%11s\n", name, "Leak", "Peak", | 104 fprintf (stderr, "%-48s %11s%15s%10s%17s%11s\n", name, "Leak", "Peak", |
114 "Times", "Leak items", "Peak items"); | 105 "Times", "Leak items", "Peak items"); |
115 print_dash_line (); | 106 print_dash_line (); |
116 } | |
117 | |
118 /* Compare wrapper used by qsort method. */ | |
119 static int | |
120 compare (const void *first, const void *second) | |
121 { | |
122 typedef std::pair<mem_location *, vec_usage *> mem_pair_t; | |
123 | |
124 const mem_pair_t f = *(const mem_pair_t *)first; | |
125 const mem_pair_t s = *(const mem_pair_t *)second; | |
126 | |
127 return (*f.second) < (*s.second); | |
128 } | 107 } |
129 | 108 |
130 /* Current number of items allocated. */ | 109 /* Current number of items allocated. */ |
131 size_t m_items; | 110 size_t m_items; |
132 /* Peak value of number of allocated items. */ | 111 /* Peak value of number of allocated items. */ |
220 error ("qsort comparator not transitive: %d, %d, %d", r1, r2, r3); | 199 error ("qsort comparator not transitive: %d, %d, %d", r1, r2, r3); |
221 } | 200 } |
222 internal_error ("qsort checking failed"); | 201 internal_error ("qsort checking failed"); |
223 } | 202 } |
224 | 203 |
225 /* Wrapper around qsort with checking that CMP is consistent on given input. | 204 /* Verify anti-symmetry and transitivity for comparator CMP on sorted array |
226 | 205 of N SIZE-sized elements pointed to by BASE. */ |
227 Strictly speaking, passing invalid (non-transitive, non-anti-commutative) | |
228 comparators to libc qsort can result in undefined behavior. Therefore we | |
229 should ideally perform consistency checks prior to invoking qsort, but in | |
230 order to do that optimally we'd need to sort the array ourselves beforehand | |
231 with a sorting routine known to be "safe". Instead, we expect that most | |
232 implementations in practice will still produce some permutation of input | |
233 array even for invalid comparators, which enables us to perform checks on | |
234 the output array. */ | |
235 void | 206 void |
236 qsort_chk (void *base, size_t n, size_t size, | 207 qsort_chk (void *base, size_t n, size_t size, |
237 int (*cmp)(const void *, const void *)) | 208 int (*cmp)(const void *, const void *)) |
238 { | 209 { |
239 (qsort) (base, n, size, cmp); | |
240 #if 0 | 210 #if 0 |
241 #define LIM(n) (n) | 211 #define LIM(n) (n) |
242 #else | 212 #else |
243 /* Limit overall time complexity to O(n log n). */ | 213 /* Limit overall time complexity to O(n log n). */ |
244 #define LIM(n) ((n) <= 16 ? (n) : 12 + floor_log2 (n)) | 214 #define LIM(n) ((n) <= 16 ? (n) : 12 + floor_log2 (n)) |
401 ASSERT_EQ (4, v[4]); | 371 ASSERT_EQ (4, v[4]); |
402 ASSERT_EQ (6, v[5]); | 372 ASSERT_EQ (6, v[5]); |
403 ASSERT_EQ (9, v.length ()); | 373 ASSERT_EQ (9, v.length ()); |
404 } | 374 } |
405 | 375 |
376 /* Verify that vec::ordered_remove_if works correctly. */ | |
377 | |
378 static void | |
379 test_ordered_remove_if (void) | |
380 { | |
381 auto_vec <int> v; | |
382 safe_push_range (v, 0, 10); | |
383 unsigned ix, ix2; | |
384 int *elem_ptr; | |
385 VEC_ORDERED_REMOVE_IF (v, ix, ix2, elem_ptr, | |
386 *elem_ptr == 5 || *elem_ptr == 7); | |
387 ASSERT_EQ (4, v[4]); | |
388 ASSERT_EQ (6, v[5]); | |
389 ASSERT_EQ (8, v[6]); | |
390 ASSERT_EQ (8, v.length ()); | |
391 | |
392 v.truncate (0); | |
393 safe_push_range (v, 0, 10); | |
394 VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 0, 6, | |
395 *elem_ptr == 5 || *elem_ptr == 7); | |
396 ASSERT_EQ (4, v[4]); | |
397 ASSERT_EQ (6, v[5]); | |
398 ASSERT_EQ (7, v[6]); | |
399 ASSERT_EQ (9, v.length ()); | |
400 | |
401 v.truncate (0); | |
402 safe_push_range (v, 0, 10); | |
403 VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 0, 5, | |
404 *elem_ptr == 5 || *elem_ptr == 7); | |
405 VEC_ORDERED_REMOVE_IF_FROM_TO (v, ix, ix2, elem_ptr, 8, 10, | |
406 *elem_ptr == 5 || *elem_ptr == 7); | |
407 ASSERT_EQ (4, v[4]); | |
408 ASSERT_EQ (5, v[5]); | |
409 ASSERT_EQ (6, v[6]); | |
410 ASSERT_EQ (10, v.length ()); | |
411 | |
412 v.truncate (0); | |
413 safe_push_range (v, 0, 10); | |
414 VEC_ORDERED_REMOVE_IF (v, ix, ix2, elem_ptr, *elem_ptr == 5); | |
415 ASSERT_EQ (4, v[4]); | |
416 ASSERT_EQ (6, v[5]); | |
417 ASSERT_EQ (7, v[6]); | |
418 ASSERT_EQ (9, v.length ()); | |
419 } | |
420 | |
406 /* Verify that vec::unordered_remove works correctly. */ | 421 /* Verify that vec::unordered_remove works correctly. */ |
407 | 422 |
408 static void | 423 static void |
409 test_unordered_remove () | 424 test_unordered_remove () |
410 { | 425 { |
448 ASSERT_EQ (9, v[0]); | 463 ASSERT_EQ (9, v[0]); |
449 ASSERT_EQ (8, v[1]); | 464 ASSERT_EQ (8, v[1]); |
450 ASSERT_EQ (1, v[8]); | 465 ASSERT_EQ (1, v[8]); |
451 ASSERT_EQ (0, v[9]); | 466 ASSERT_EQ (0, v[9]); |
452 ASSERT_EQ (10, v.length ()); | 467 ASSERT_EQ (10, v.length ()); |
468 } | |
469 | |
470 /* Verify that vec::reverse works correctly. */ | |
471 | |
472 static void | |
473 test_reverse () | |
474 { | |
475 /* Reversing an empty vec ought to be a no-op. */ | |
476 { | |
477 auto_vec <int> v; | |
478 ASSERT_EQ (0, v.length ()); | |
479 v.reverse (); | |
480 ASSERT_EQ (0, v.length ()); | |
481 } | |
482 | |
483 /* Verify reversing a vec with even length. */ | |
484 { | |
485 auto_vec <int> v; | |
486 safe_push_range (v, 0, 4); | |
487 v.reverse (); | |
488 ASSERT_EQ (3, v[0]); | |
489 ASSERT_EQ (2, v[1]); | |
490 ASSERT_EQ (1, v[2]); | |
491 ASSERT_EQ (0, v[3]); | |
492 ASSERT_EQ (4, v.length ()); | |
493 } | |
494 | |
495 /* Verify reversing a vec with odd length. */ | |
496 { | |
497 auto_vec <int> v; | |
498 safe_push_range (v, 0, 3); | |
499 v.reverse (); | |
500 ASSERT_EQ (2, v[0]); | |
501 ASSERT_EQ (1, v[1]); | |
502 ASSERT_EQ (0, v[2]); | |
503 ASSERT_EQ (3, v.length ()); | |
504 } | |
453 } | 505 } |
454 | 506 |
455 /* Run all of the selftests within this file. */ | 507 /* Run all of the selftests within this file. */ |
456 | 508 |
457 void | 509 void |
462 test_truncate (); | 514 test_truncate (); |
463 test_safe_grow_cleared (); | 515 test_safe_grow_cleared (); |
464 test_pop (); | 516 test_pop (); |
465 test_safe_insert (); | 517 test_safe_insert (); |
466 test_ordered_remove (); | 518 test_ordered_remove (); |
519 test_ordered_remove_if (); | |
467 test_unordered_remove (); | 520 test_unordered_remove (); |
468 test_block_remove (); | 521 test_block_remove (); |
469 test_qsort (); | 522 test_qsort (); |
523 test_reverse (); | |
470 } | 524 } |
471 | 525 |
472 } // namespace selftest | 526 } // namespace selftest |
473 | 527 |
474 #endif /* #if CHECKING_P */ | 528 #endif /* #if CHECKING_P */ |