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 */