]> git.saurik.com Git - bison.git/blob - lib/bitset_stats.c
ChangeLog (2006-09-15): add Odd Arild Olsen's role for push.c.
[bison.git] / lib / bitset_stats.c
1 /* Bitset statistics.
2 Copyright (C) 2002-2006, 2009-2010 Free Software Foundation, Inc.
3 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18 /* This file is a wrapper bitset implementation for the other bitset
19 implementations. It provides bitset compatibility checking and
20 statistics gathering without having to instrument the bitset
21 implementations. When statistics gathering is enabled, the bitset
22 operations get vectored through here and we then call the appropriate
23 routines. */
24
25 #include <config.h>
26
27 #include "bitset_stats.h"
28
29 #include "bbitset.h"
30 #include "abitset.h"
31 #include "ebitset.h"
32 #include "lbitset.h"
33 #include "vbitset.h"
34 #include <stdlib.h>
35 #include <string.h>
36 #include <stdio.h>
37
38 #include "gettext.h"
39 #define _(Msgid) gettext (Msgid)
40
41 /* Configuration macros. */
42 #define BITSET_STATS_FILE "bitset.dat"
43 #define BITSET_LOG_COUNT_BINS 10
44 #define BITSET_LOG_SIZE_BINS 16
45 #define BITSET_DENSITY_BINS 20
46
47
48 /* Accessor macros. */
49 #define BITSET_STATS_ALLOCS_INC(TYPE) \
50 bitset_stats_info->types[(TYPE)].allocs++
51 #define BITSET_STATS_FREES_INC(BSET) \
52 bitset_stats_info->types[BITSET_TYPE_ (BSET)].frees++
53 #define BITSET_STATS_SETS_INC(BSET) \
54 bitset_stats_info->types[BITSET_TYPE_ (BSET)].sets++
55 #define BITSET_STATS_CACHE_SETS_INC(BSET) \
56 bitset_stats_info->types[BITSET_TYPE_ (BSET)].cache_sets++
57 #define BITSET_STATS_RESETS_INC(BSET) \
58 bitset_stats_info->types[BITSET_TYPE_ (BSET)].resets++
59 #define BITSET_STATS_CACHE_RESETS_INC(BSET) \
60 bitset_stats_info->types[BITSET_TYPE_ (BSET)].cache_resets++
61 #define BITSET_STATS_TESTS_INC(BSET) \
62 bitset_stats_info->types[BITSET_TYPE_ (BSET)].tests++
63 #define BITSET_STATS_CACHE_TESTS_INC(BSET) \
64 bitset_stats_info->types[BITSET_TYPE_ (BSET)].cache_tests++
65 #define BITSET_STATS_LISTS_INC(BSET) \
66 bitset_stats_info->types[BITSET_TYPE_ (BSET)].lists++
67 #define BITSET_STATS_LIST_COUNTS_INC(BSET, I) \
68 bitset_stats_info->types[BITSET_TYPE_ (BSET)].list_counts[(I)]++
69 #define BITSET_STATS_LIST_SIZES_INC(BSET, I) \
70 bitset_stats_info->types[BITSET_TYPE_ (BSET)].list_sizes[(I)]++
71 #define BITSET_STATS_LIST_DENSITY_INC(BSET, I) \
72 bitset_stats_info->types[BITSET_TYPE_ (BSET)].list_density[(I)]++
73
74
75 struct bitset_type_info_struct
76 {
77 unsigned int allocs;
78 unsigned int frees;
79 unsigned int lists;
80 unsigned int sets;
81 unsigned int cache_sets;
82 unsigned int resets;
83 unsigned int cache_resets;
84 unsigned int tests;
85 unsigned int cache_tests;
86 unsigned int list_counts[BITSET_LOG_COUNT_BINS];
87 unsigned int list_sizes[BITSET_LOG_SIZE_BINS];
88 unsigned int list_density[BITSET_DENSITY_BINS];
89 };
90
91 struct bitset_stats_info_struct
92 {
93 unsigned int runs;
94 struct bitset_type_info_struct types[BITSET_TYPE_NUM];
95 };
96
97
98 struct bitset_stats_info_struct bitset_stats_info_data;
99 struct bitset_stats_info_struct *bitset_stats_info;
100 bool bitset_stats_enabled = false;
101
102
103 /* Print a percentage histogram with message MSG to FILE. */
104 static void
105 bitset_percent_histogram_print (FILE *file, const char *name, const char *msg,
106 unsigned int n_bins, unsigned int *bins)
107 {
108 unsigned int i;
109 unsigned int total;
110
111 total = 0;
112 for (i = 0; i < n_bins; i++)
113 total += bins[i];
114
115 if (!total)
116 return;
117
118 fprintf (file, "%s %s", name, msg);
119 for (i = 0; i < n_bins; i++)
120 fprintf (file, "%.0f-%.0f%%\t%8u (%5.1f%%)\n",
121 i * 100.0 / n_bins,
122 (i + 1) * 100.0 / n_bins, bins[i],
123 (100.0 * bins[i]) / total);
124 }
125
126
127 /* Print a log histogram with message MSG to FILE. */
128 static void
129 bitset_log_histogram_print (FILE *file, const char *name, const char *msg,
130 unsigned int n_bins, unsigned int *bins)
131 {
132 unsigned int i;
133 unsigned int total;
134 unsigned int max_width;
135
136 total = 0;
137 for (i = 0; i < n_bins; i++)
138 total += bins[i];
139
140 if (!total)
141 return;
142
143 /* Determine number of useful bins. */
144 for (i = n_bins; i > 3 && ! bins[i - 1]; i--)
145 continue;
146 n_bins = i;
147
148 /* 2 * ceil (log10 (2) * (N - 1)) + 1. */
149 max_width = 2 * (unsigned int) (0.30103 * (n_bins - 1) + 0.9999) + 1;
150
151 fprintf (file, "%s %s", name, msg);
152 for (i = 0; i < 2; i++)
153 fprintf (file, "%*d\t%8u (%5.1f%%)\n",
154 max_width, i, bins[i], 100.0 * bins[i] / total);
155
156 for (; i < n_bins; i++)
157 fprintf (file, "%*lu-%lu\t%8u (%5.1f%%)\n",
158 max_width - ((unsigned int) (0.30103 * (i) + 0.9999) + 1),
159 1UL << (i - 1),
160 (1UL << i) - 1,
161 bins[i],
162 (100.0 * bins[i]) / total);
163 }
164
165
166 /* Print bitset statistics to FILE. */
167 static void
168 bitset_stats_print_1 (FILE *file, const char *name,
169 struct bitset_type_info_struct *stats)
170 {
171 if (!stats)
172 return;
173
174 fprintf (file, "%s:\n", name);
175 fprintf (file, _("%u bitset_allocs, %u freed (%.2f%%).\n"),
176 stats->allocs, stats->frees,
177 stats->allocs ? 100.0 * stats->frees / stats->allocs : 0);
178 fprintf (file, _("%u bitset_sets, %u cached (%.2f%%)\n"),
179 stats->sets, stats->cache_sets,
180 stats->sets ? 100.0 * stats->cache_sets / stats->sets : 0);
181 fprintf (file, _("%u bitset_resets, %u cached (%.2f%%)\n"),
182 stats->resets, stats->cache_resets,
183 stats->resets ? 100.0 * stats->cache_resets / stats->resets : 0);
184 fprintf (file, _("%u bitset_tests, %u cached (%.2f%%)\n"),
185 stats->tests, stats->cache_tests,
186 stats->tests ? 100.0 * stats->cache_tests / stats->tests : 0);
187
188 fprintf (file, _("%u bitset_lists\n"), stats->lists);
189
190 bitset_log_histogram_print (file, name, _("count log histogram\n"),
191 BITSET_LOG_COUNT_BINS, stats->list_counts);
192
193 bitset_log_histogram_print (file, name, _("size log histogram\n"),
194 BITSET_LOG_SIZE_BINS, stats->list_sizes);
195
196 bitset_percent_histogram_print (file, name, _("density histogram\n"),
197 BITSET_DENSITY_BINS, stats->list_density);
198 }
199
200
201 /* Print all bitset statistics to FILE. */
202 static void
203 bitset_stats_print (FILE *file, bool verbose ATTRIBUTE_UNUSED)
204 {
205 int i;
206
207 if (!bitset_stats_info)
208 return;
209
210 fprintf (file, _("Bitset statistics:\n\n"));
211
212 if (bitset_stats_info->runs > 1)
213 fprintf (file, _("Accumulated runs = %u\n"), bitset_stats_info->runs);
214
215 for (i = 0; i < BITSET_TYPE_NUM; i++)
216 bitset_stats_print_1 (file, bitset_type_names[i],
217 &bitset_stats_info->types[i]);
218 }
219
220
221 /* Initialise bitset statistics logging. */
222 void
223 bitset_stats_enable (void)
224 {
225 if (!bitset_stats_info)
226 bitset_stats_info = &bitset_stats_info_data;
227 bitset_stats_enabled = true;
228 }
229
230
231 void
232 bitset_stats_disable (void)
233 {
234 bitset_stats_enabled = false;
235 }
236
237
238 /* Read bitset statistics file. */
239 void
240 bitset_stats_read (const char *file_name)
241 {
242 FILE *file;
243
244 if (!bitset_stats_info)
245 return;
246
247 if (!file_name)
248 file_name = BITSET_STATS_FILE;
249
250 file = fopen (file_name, "r");
251 if (file)
252 {
253 if (fread (&bitset_stats_info_data, sizeof (bitset_stats_info_data),
254 1, file) != 1)
255 {
256 if (ferror (file))
257 perror (_("Could not read stats file."));
258 else
259 fprintf (stderr, _("Bad stats file size.\n"));
260 }
261 if (fclose (file) != 0)
262 perror (_("Could not read stats file."));
263 }
264 bitset_stats_info_data.runs++;
265 }
266
267
268 /* Write bitset statistics file. */
269 void
270 bitset_stats_write (const char *file_name)
271 {
272 FILE *file;
273
274 if (!bitset_stats_info)
275 return;
276
277 if (!file_name)
278 file_name = BITSET_STATS_FILE;
279
280 file = fopen (file_name, "w");
281 if (file)
282 {
283 if (fwrite (&bitset_stats_info_data, sizeof (bitset_stats_info_data),
284 1, file) != 1)
285 perror (_("Could not write stats file."));
286 if (fclose (file) != 0)
287 perror (_("Could not write stats file."));
288 }
289 else
290 perror (_("Could not open stats file for writing."));
291 }
292
293
294 /* Dump bitset statistics to FILE. */
295 void
296 bitset_stats_dump (FILE *file)
297 {
298 bitset_stats_print (file, false);
299 }
300
301
302 /* Function to be called from debugger to print bitset stats. */
303 void
304 debug_bitset_stats (void)
305 {
306 bitset_stats_print (stderr, true);
307 }
308
309
310 static void
311 bitset_stats_set (bitset dst, bitset_bindex bitno)
312 {
313 bitset bset = dst->s.bset;
314 bitset_windex wordno = bitno / BITSET_WORD_BITS;
315 bitset_windex offset = wordno - bset->b.cindex;
316
317 BITSET_STATS_SETS_INC (bset);
318
319 if (offset < bset->b.csize)
320 {
321 bset->b.cdata[offset] |= (bitset_word) 1 << (bitno % BITSET_WORD_BITS);
322 BITSET_STATS_CACHE_SETS_INC (bset);
323 }
324 else
325 BITSET_SET_ (bset, bitno);
326 }
327
328
329 static void
330 bitset_stats_reset (bitset dst, bitset_bindex bitno)
331 {
332 bitset bset = dst->s.bset;
333 bitset_windex wordno = bitno / BITSET_WORD_BITS;
334 bitset_windex offset = wordno - bset->b.cindex;
335
336 BITSET_STATS_RESETS_INC (bset);
337
338 if (offset < bset->b.csize)
339 {
340 bset->b.cdata[offset] &=
341 ~((bitset_word) 1 << (bitno % BITSET_WORD_BITS));
342 BITSET_STATS_CACHE_RESETS_INC (bset);
343 }
344 else
345 BITSET_RESET_ (bset, bitno);
346 }
347
348
349 static bool
350 bitset_stats_toggle (bitset src, bitset_bindex bitno)
351 {
352 return BITSET_TOGGLE_ (src->s.bset, bitno);
353 }
354
355
356 static bool
357 bitset_stats_test (bitset src, bitset_bindex bitno)
358 {
359 bitset bset = src->s.bset;
360 bitset_windex wordno = bitno / BITSET_WORD_BITS;
361 bitset_windex offset = wordno - bset->b.cindex;
362
363 BITSET_STATS_TESTS_INC (bset);
364
365 if (offset < bset->b.csize)
366 {
367 BITSET_STATS_CACHE_TESTS_INC (bset);
368 return (bset->b.cdata[offset] >> (bitno % BITSET_WORD_BITS)) & 1;
369 }
370 else
371 return BITSET_TEST_ (bset, bitno);
372 }
373
374
375 static bitset_bindex
376 bitset_stats_resize (bitset src, bitset_bindex size)
377 {
378 return BITSET_RESIZE_ (src->s.bset, size);
379 }
380
381
382 static bitset_bindex
383 bitset_stats_size (bitset src)
384 {
385 return BITSET_SIZE_ (src->s.bset);
386 }
387
388
389 static bitset_bindex
390 bitset_stats_count (bitset src)
391 {
392 return BITSET_COUNT_ (src->s.bset);
393 }
394
395
396 static bool
397 bitset_stats_empty_p (bitset dst)
398 {
399 return BITSET_EMPTY_P_ (dst->s.bset);
400 }
401
402
403 static void
404 bitset_stats_ones (bitset dst)
405 {
406 BITSET_ONES_ (dst->s.bset);
407 }
408
409
410 static void
411 bitset_stats_zero (bitset dst)
412 {
413 BITSET_ZERO_ (dst->s.bset);
414 }
415
416
417 static void
418 bitset_stats_copy (bitset dst, bitset src)
419 {
420 BITSET_CHECK2_ (dst, src);
421 BITSET_COPY_ (dst->s.bset, src->s.bset);
422 }
423
424
425 static bool
426 bitset_stats_disjoint_p (bitset dst, bitset src)
427 {
428 BITSET_CHECK2_ (dst, src);
429 return BITSET_DISJOINT_P_ (dst->s.bset, src->s.bset);
430 }
431
432
433 static bool
434 bitset_stats_equal_p (bitset dst, bitset src)
435 {
436 BITSET_CHECK2_ (dst, src);
437 return BITSET_EQUAL_P_ (dst->s.bset, src->s.bset);
438 }
439
440
441 static void
442 bitset_stats_not (bitset dst, bitset src)
443 {
444 BITSET_CHECK2_ (dst, src);
445 BITSET_NOT_ (dst->s.bset, src->s.bset);
446 }
447
448
449 static bool
450 bitset_stats_subset_p (bitset dst, bitset src)
451 {
452 BITSET_CHECK2_ (dst, src);
453 return BITSET_SUBSET_P_ (dst->s.bset, src->s.bset);
454 }
455
456
457 static void
458 bitset_stats_and (bitset dst, bitset src1, bitset src2)
459 {
460 BITSET_CHECK3_ (dst, src1, src2);
461 BITSET_AND_ (dst->s.bset, src1->s.bset, src2->s.bset);
462 }
463
464
465 static bool
466 bitset_stats_and_cmp (bitset dst, bitset src1, bitset src2)
467 {
468 BITSET_CHECK3_ (dst, src1, src2);
469 return BITSET_AND_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset);
470 }
471
472
473 static void
474 bitset_stats_andn (bitset dst, bitset src1, bitset src2)
475 {
476 BITSET_CHECK3_ (dst, src1, src2);
477 BITSET_ANDN_ (dst->s.bset, src1->s.bset, src2->s.bset);
478 }
479
480
481 static bool
482 bitset_stats_andn_cmp (bitset dst, bitset src1, bitset src2)
483 {
484 BITSET_CHECK3_ (dst, src1, src2);
485 return BITSET_ANDN_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset);
486 }
487
488
489 static void
490 bitset_stats_or (bitset dst, bitset src1, bitset src2)
491 {
492 BITSET_CHECK3_ (dst, src1, src2);
493 BITSET_OR_ (dst->s.bset, src1->s.bset, src2->s.bset);
494 }
495
496
497 static bool
498 bitset_stats_or_cmp (bitset dst, bitset src1, bitset src2)
499 {
500 BITSET_CHECK3_ (dst, src1, src2);
501 return BITSET_OR_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset);
502 }
503
504
505 static void
506 bitset_stats_xor (bitset dst, bitset src1, bitset src2)
507 {
508 BITSET_CHECK3_ (dst, src1, src2);
509 BITSET_XOR_ (dst->s.bset, src1->s.bset, src2->s.bset);
510 }
511
512
513 static bool
514 bitset_stats_xor_cmp (bitset dst, bitset src1, bitset src2)
515 {
516 BITSET_CHECK3_ (dst, src1, src2);
517 return BITSET_XOR_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset);
518 }
519
520
521 static void
522 bitset_stats_and_or (bitset dst, bitset src1, bitset src2, bitset src3)
523 {
524 BITSET_CHECK4_ (dst, src1, src2, src3);
525 BITSET_AND_OR_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset);
526 }
527
528
529 static bool
530 bitset_stats_and_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
531 {
532 BITSET_CHECK4_ (dst, src1, src2, src3);
533 return BITSET_AND_OR_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset);
534 }
535
536
537 static void
538 bitset_stats_andn_or (bitset dst, bitset src1, bitset src2, bitset src3)
539 {
540 BITSET_CHECK4_ (dst, src1, src2, src3);
541 BITSET_ANDN_OR_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset);
542 }
543
544
545 static bool
546 bitset_stats_andn_or_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
547 {
548 BITSET_CHECK4_ (dst, src1, src2, src3);
549 return BITSET_ANDN_OR_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset);
550 }
551
552
553 static void
554 bitset_stats_or_and (bitset dst, bitset src1, bitset src2, bitset src3)
555 {
556 BITSET_CHECK4_ (dst, src1, src2, src3);
557 BITSET_OR_AND_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset);
558 }
559
560
561 static bool
562 bitset_stats_or_and_cmp (bitset dst, bitset src1, bitset src2, bitset src3)
563 {
564 BITSET_CHECK4_ (dst, src1, src2, src3);
565 return BITSET_OR_AND_CMP_ (dst->s.bset, src1->s.bset, src2->s.bset, src3->s.bset);
566 }
567
568
569 static bitset_bindex
570 bitset_stats_list (bitset bset, bitset_bindex *list,
571 bitset_bindex num, bitset_bindex *next)
572 {
573 bitset_bindex count;
574 bitset_bindex tmp;
575 bitset_bindex size;
576 bitset_bindex i;
577 enum bitset_type type;
578
579 count = BITSET_LIST_ (bset->s.bset, list, num, next);
580
581 type = BITSET_TYPE_ (bset->s.bset);
582 BITSET_STATS_LISTS_INC (bset->s.bset);
583
584 /* Log histogram of number of set bits. */
585 for (i = 0, tmp = count; tmp; tmp >>= 1, i++)
586 continue;
587 if (i >= BITSET_LOG_COUNT_BINS)
588 i = BITSET_LOG_COUNT_BINS - 1;
589 BITSET_STATS_LIST_COUNTS_INC (bset->s.bset, i);
590
591 /* Log histogram of number of bits in set. */
592 size = BITSET_SIZE_ (bset->s.bset);
593 for (i = 0, tmp = size; tmp; tmp >>= 1, i++)
594 continue;
595 if (i >= BITSET_LOG_SIZE_BINS)
596 i = BITSET_LOG_SIZE_BINS - 1;
597 BITSET_STATS_LIST_SIZES_INC (bset->s.bset, i);
598
599 /* Histogram of fraction of bits set. */
600 i = size ? (count * BITSET_DENSITY_BINS) / size : 0;
601 if (i >= BITSET_DENSITY_BINS)
602 i = BITSET_DENSITY_BINS - 1;
603 BITSET_STATS_LIST_DENSITY_INC (bset->s.bset, i);
604 return count;
605 }
606
607
608 static bitset_bindex
609 bitset_stats_list_reverse (bitset bset, bitset_bindex *list,
610 bitset_bindex num, bitset_bindex *next)
611 {
612 return BITSET_LIST_REVERSE_ (bset->s.bset, list, num, next);
613 }
614
615
616 static void
617 bitset_stats_free (bitset bset)
618 {
619 BITSET_STATS_FREES_INC (bset->s.bset);
620 BITSET_FREE_ (bset->s.bset);
621 }
622
623
624 struct bitset_vtable bitset_stats_vtable = {
625 bitset_stats_set,
626 bitset_stats_reset,
627 bitset_stats_toggle,
628 bitset_stats_test,
629 bitset_stats_resize,
630 bitset_stats_size,
631 bitset_stats_count,
632 bitset_stats_empty_p,
633 bitset_stats_ones,
634 bitset_stats_zero,
635 bitset_stats_copy,
636 bitset_stats_disjoint_p,
637 bitset_stats_equal_p,
638 bitset_stats_not,
639 bitset_stats_subset_p,
640 bitset_stats_and,
641 bitset_stats_and_cmp,
642 bitset_stats_andn,
643 bitset_stats_andn_cmp,
644 bitset_stats_or,
645 bitset_stats_or_cmp,
646 bitset_stats_xor,
647 bitset_stats_xor_cmp,
648 bitset_stats_and_or,
649 bitset_stats_and_or_cmp,
650 bitset_stats_andn_or,
651 bitset_stats_andn_or_cmp,
652 bitset_stats_or_and,
653 bitset_stats_or_and_cmp,
654 bitset_stats_list,
655 bitset_stats_list_reverse,
656 bitset_stats_free,
657 BITSET_STATS
658 };
659
660
661 /* Return enclosed bitset type. */
662 enum bitset_type
663 bitset_stats_type_get (bitset bset)
664 {
665 return BITSET_TYPE_ (bset->s.bset);
666 }
667
668
669 size_t
670 bitset_stats_bytes (void)
671 {
672 return sizeof (struct bitset_stats_struct);
673 }
674
675
676 bitset
677 bitset_stats_init (bitset bset, bitset_bindex n_bits, enum bitset_type type)
678 {
679 size_t bytes;
680 bitset sbset;
681
682 bset->b.vtable = &bitset_stats_vtable;
683
684 /* Disable cache. */
685 bset->b.cindex = 0;
686 bset->b.csize = 0;
687 bset->b.cdata = 0;
688
689 BITSET_NBITS_ (bset) = n_bits;
690
691 /* Set up the actual bitset implementation that
692 we are a wrapper over. */
693 switch (type)
694 {
695 default:
696 abort ();
697
698 case BITSET_ARRAY:
699 bytes = abitset_bytes (n_bits);
700 sbset = xcalloc (1, bytes);
701 abitset_init (sbset, n_bits);
702 break;
703
704 case BITSET_LIST:
705 bytes = lbitset_bytes (n_bits);
706 sbset = xcalloc (1, bytes);
707 lbitset_init (sbset, n_bits);
708 break;
709
710 case BITSET_TABLE:
711 bytes = ebitset_bytes (n_bits);
712 sbset = xcalloc (1, bytes);
713 ebitset_init (sbset, n_bits);
714 break;
715
716 case BITSET_VARRAY:
717 bytes = vbitset_bytes (n_bits);
718 sbset = xcalloc (1, bytes);
719 vbitset_init (sbset, n_bits);
720 break;
721 }
722
723 bset->s.bset = sbset;
724
725 BITSET_STATS_ALLOCS_INC (type);
726
727 return bset;
728 }