2 Copyright (C) 2002 Free Software Foundation, Inc.
3 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
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 2 of the License, or
8 (at your option) any later version.
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.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
30 static void bitset_print
PARAMS ((FILE *, bitset
, int));
33 #define BITSET_STATS_FILE "bitset.dat"
35 #define BITSET_LOG_COUNT_BINS 10
36 #define BITSET_LOG_SIZE_BINS 16
37 #define BITSET_DENSITY_BINS 20
39 struct bitset_type_stats_struct
41 unsigned int xmallocs
;
43 unsigned int oballocs
;
46 unsigned int list_counts
[BITSET_LOG_COUNT_BINS
];
47 unsigned int list_sizes
[BITSET_LOG_SIZE_BINS
];
48 unsigned int list_density
[BITSET_DENSITY_BINS
];
51 struct bitset_stats_struct
54 struct bitset_type_stats_struct types
[BITSET_TYPE_NUM
];
57 struct bitset_stats_struct bitset_stats_data
;
58 struct bitset_stats_struct
*bitset_stats
;
60 static void bitset_percent_histogram_print
PARAMS ((FILE *, const char *,
64 static void bitset_log_histogram_print
PARAMS ((FILE *, const char *,
68 static void bitset_stats_print_1
69 PARAMS ((FILE *, const char *, struct bitset_type_stats_struct
*));
70 static void bitset_stats_print
PARAMS ((FILE *, int));
71 static void bitset_stats_read
PARAMS ((void));
72 static void bitset_stats_write
PARAMS ((void));
74 #define BITSET_STATS_XMALLOCS_INC(TYPE) \
76 bitset_stats->types[(TYPE)].xmallocs++
78 #define BITSET_STATS_XFREES_INC(BSET) \
80 bitset_stats->types[BITSET_TYPE_ (BSET)].xfrees++
82 #define BITSET_STATS_OBALLOCS_INC(TYPE) \
84 bitset_stats->types[(TYPE)].oballocs++
86 #define BITSET_STATS_OBFREES_INC(BSET) \
88 bitset_stats->types[BITSET_TYPE_ (BSET)].obfrees++
90 #define BITSET_STATS_LISTS_INC(BSET) \
92 bitset_stats->types[BITSET_TYPE_ (BSET)].lists++
94 #define BITSET_STATS_LIST_COUNTS_INC(BSET, I) \
96 bitset_stats->types[BITSET_TYPE_ (BSET)].list_counts[(I)]++
98 #define BITSET_STATS_LIST_SIZES_INC(BSET, I) \
100 bitset_stats->types[BITSET_TYPE_ (BSET)].list_sizes[(I)]++
102 #define BITSET_STATS_LIST_DENSITY_INC(BSET, I) \
104 bitset_stats->types[BITSET_TYPE_ (BSET)].list_density[(I)]++
107 #define BITSET_STATS_XMALLOCS_INC(TYPE)
109 #define BITSET_STATS_XFREES_INC(BSET)
111 #define BITSET_STATS_OBALLOCS_INC(TYPE)
113 #define BITSET_STATS_OBFREES_INC(BSET)
115 #define BITSET_STATS_LISTS_INC(BSET)
117 #define BITSET_STATS_LIST_COUNTS_INC(BSET, I)
119 #define BITSET_STATS_LIST_SIZES_INC(BSET, I)
121 #define BITSET_STATS_LIST_DENSITY_INC(BSET, I)
122 #endif /* BITSET_STATS */
125 /* Return number of bytes required to create a N_BIT bitset
126 of TYPE. The bitset may grow to require more bytes than this. */
128 bitset_bytes (type
, n_bits
)
129 enum bitset_type type
;
130 bitset_bindex n_bits
;
137 bytes
= sbitset_bytes (n_bits
);
141 bytes
= lbitset_bytes (n_bits
);
145 bytes
= ebitset_bytes (n_bits
);
156 /* Initialise bitset BSET of TYPE for N_BITS. */
158 bitset_init (bset
, n_bits
, type
)
160 bitset_bindex n_bits
;
161 enum bitset_type type
;
166 return sbitset_init (bset
, n_bits
);
169 return lbitset_init (bset
, n_bits
);
172 return ebitset_init (bset
, n_bits
);
180 /* Select a bitset type for a set of N_BITS and with attribute hints
181 specified by ATTR. For variable size bitsets, N_BITS is only a
182 hint and may be zero. */
184 bitset_type_choose (n_bits
, attr
)
185 bitset_bindex n_bits ATTRIBUTE_UNUSED
;
188 enum bitset_type type
;
191 /* Check attributes. */
192 if (attr
& BITSET_FIXED
&& attr
& BITSET_VARIABLE
)
194 if (attr
& BITSET_SPARSE
&& attr
& BITSET_DENSE
)
197 /* Note that sometimes we will be asked for a zero length
198 fixed size bitset. */
201 /* Choose the type of bitset. */
204 /* Currently, the simple bitsets do not support a variable size. */
205 if (attr
& BITSET_VARIABLE
|| attr
& BITSET_SPARSE
)
208 if (attr
& BITSET_DENSE
|| attr
& BITSET_GREEDY
)
216 /* Create a bitset of N_BITS of type TYPE. */
218 bitset_alloc (n_bits
, type
)
219 bitset_bindex n_bits
;
220 enum bitset_type type
;
225 BITSET_STATS_XMALLOCS_INC (type
);
227 bytes
= bitset_bytes (type
, n_bits
);
229 bset
= (bitset
) xcalloc (1, bytes
);
231 /* The cache is disabled until some elements are allocated. If we
232 have variable length arrays, then we may need to allocate dummy
235 return bitset_init (bset
, n_bits
, type
);
239 /* Create a bitset of N_BITS of type TYPE. */
241 bitset_obstack_alloc (bobstack
, n_bits
, type
)
242 struct obstack
*bobstack
;
243 bitset_bindex n_bits
;
244 enum bitset_type type
;
249 BITSET_STATS_OBALLOCS_INC (type
);
251 bytes
= bitset_bytes (type
, n_bits
);
253 bset
= obstack_alloc (bobstack
, bytes
);
254 memset (bset
, 0, bytes
);
256 return bitset_init (bset
, n_bits
, type
);
260 /* Create a bitset of N_BITS and with attribute hints specified by
263 bitset_create (n_bits
, attr
)
264 bitset_bindex n_bits
;
267 enum bitset_type type
;
269 type
= bitset_type_choose (n_bits
, attr
);
271 return bitset_alloc (n_bits
, type
);
275 /* Free bitset BSET. */
280 BITSET_STATS_XFREES_INC (bset
);
287 /* Free bitset BSET allocated on obstack. */
289 bitset_obstack_free (bset
)
292 BITSET_STATS_OBFREES_INC (bset
);
298 /* Find next bit set in SRC starting from and including BITNO.
299 Return -1 if SRC empty. */
301 bitset_next (src
, bitno
)
306 bitset_bindex next
= bitno
;
308 if (!bitset_list (src
, &val
, 1, &next
))
314 /* Find previous bit set in SRC starting from and including BITNO.
315 Return -1 if SRC empty. */
317 bitset_prev (src
, bitno
)
322 bitset_bindex next
= bitno
;
324 if (!bitset_reverse_list (src
, &val
, 1, &next
))
330 /* Find first set bit. */
335 return bitset_next (src
, 0);
339 /* Find last set bit. */
344 return bitset_prev (src
, 0);
348 /* Print contents of bitset BSET to FILE. */
350 bitset_print (file
, bset
, verbose
)
358 fprintf (file
, "n_bits = %d, set = {", bitset_size (bset
));
361 BITSET_EXECUTE (bset
, 0, i
,
365 fprintf (file
, "\n");
369 fprintf (file
, "%d ", i
);
370 pos
+= 1 + (i
>= 10) + (i
>= 100);
374 fprintf (file
, "}\n");
378 /* DST = SRC. Return non-zero if DST != SRC. */
380 bitset_copy (dst
, src
)
386 if (BITSET_COMPATIBLE_ (dst
, src
))
387 return BITSET_COPY_ (dst
, src
);
389 /* Convert bitset types. We assume that the DST bitset
390 is large enough to hold the SRC bitset. */
392 BITSET_EXECUTE (src
, 0, i
,
401 /* Return size in bits of bitset SRC. */
406 return BITSET_SIZE_ (src
);
410 /* Return number of bits set in bitset SRC. */
415 bitset_bindex list
[BITSET_LIST_SIZE
];
421 for (count
= 0; (num
= bitset_list (src
, list
, BITSET_LIST_SIZE
, &next
));
434 return BITSET_ZERO_ (dst
);
443 return BITSET_ONES_ (dst
);
447 /* Return SRC == 0. */
452 return BITSET_EMPTY_P_ (src
);
456 /* Return DST == DST | SRC. */
458 bitset_subset_p (dst
, src
)
462 BITSET_CHECK2_ (dst
, src
);
463 return BITSET_SUBSET_P_ (dst
, src
);
467 /* Return DST == SRC. */
469 bitset_equal_p (dst
, src
)
473 BITSET_CHECK2_ (dst
, src
);
474 return BITSET_EQUAL_P_ (dst
, src
);
478 /* Return DST & SRC == 0. */
480 bitset_disjoint_p (dst
, src
)
484 BITSET_CHECK2_ (dst
, src
);
485 return BITSET_DISJOINT_P_ (dst
, src
);
491 bitset_not (dst
, src
)
495 BITSET_CHECK2_ (dst
, src
);
496 return BITSET_NOT_ (dst
, src
);
500 /* DST = SRC1 | SRC2. Return non-zero if DST != SRC1 | SRC2. */
502 bitset_or (dst
, src1
, src2
)
507 BITSET_CHECK3_ (dst
, src1
, src2
);
508 return BITSET_OR_ (dst
, src1
, src2
);
512 /* DST = SRC1 & SRC2. Return non-zero if DST != SRC1 & SRC2. */
514 bitset_and (dst
, src1
, src2
)
519 BITSET_CHECK3_ (dst
, src1
, src2
);
520 return BITSET_AND_ (dst
, src1
, src2
);
524 /* DST = SRC1 ^ SRC2. Return non-zero if DST != SRC1 ^ SRC2. */
526 bitset_xor (dst
, src1
, src2
)
531 BITSET_CHECK3_ (dst
, src1
, src2
);
532 return BITSET_XOR_ (dst
, src1
, src2
);
536 /* DST = SRC1 & ~SRC2. Return non-zero if DST != SRC1 & ~SRC2. */
538 bitset_andn (dst
, src1
, src2
)
543 BITSET_CHECK3_ (dst
, src1
, src2
);
544 return BITSET_ANDN_ (dst
, src1
, src2
);
548 /* DST = SRC1 | ~SRC2. Return non-zero if DST != SRC1 | ~SRC2. */
550 bitset_orn (dst
, src1
, src2
)
555 BITSET_CHECK3_ (dst
, src1
, src2
);
556 return BITSET_ORN_ (dst
, src1
, src2
);
561 bitset_op4 (dst
, src1
, src2
, src3
, op
)
571 /* Create temporary bitset. */
572 tmp
= bitset_alloc (BITSET_TYPE_ (dst
), 0);
576 case BITSET_OP_OR_AND
:
577 BITSET_OR_ (tmp
, src1
, src2
);
578 changed
= BITSET_AND_ (dst
, src3
, tmp
);
581 case BITSET_OP_AND_OR
:
582 BITSET_AND_ (tmp
, src1
, src2
);
583 changed
= BITSET_OR_ (dst
, src3
, tmp
);
586 case BITSET_OP_ANDN_OR
:
587 BITSET_ANDN_ (tmp
, src1
, src2
);
588 changed
= BITSET_OR_ (dst
, src3
, tmp
);
600 /* DST = (SRC1 | SRC2) & SRC3. Return non-zero if
601 DST != (SRC1 | SRC2) & SRC3. */
603 bitset_or_and (dst
, src1
, src2
, src3
)
609 BITSET_CHECK4_ (dst
, src1
, src2
, src3
);
610 return BITSET_OR_AND_ (dst
, src1
, src2
, src3
);
614 /* DST = (SRC1 & SRC2) | SRC3. Return non-zero if
615 DST != (SRC1 & SRC2) | SRC3. */
617 bitset_and_or (dst
, src1
, src2
, src3
)
623 BITSET_CHECK4_ (dst
, src1
, src2
, src3
);
624 return BITSET_AND_OR_ (dst
, src1
, src2
, src3
);
628 /* DST = (SRC1 & ~SRC2) | SRC3. Return non-zero if
629 DST != (SRC1 & ~SRC2) | SRC3. */
631 bitset_andn_or (dst
, src1
, src2
, src3
)
637 BITSET_CHECK4_ (dst
, src1
, src2
, src3
);
638 return BITSET_ANDN_OR_ (dst
, src1
, src2
, src3
);
642 /* Dump bitset BSET to FILE. */
644 bitset_dump (file
, bset
)
648 bitset_print (file
, bset
, 0);
652 /* Function to be called from debugger to print bitset. */
658 bitset_print (stderr
, bset
, 1);
662 /* Release memory associated with bitsets. */
664 bitset_release_memory ()
666 lbitset_release_memory ();
667 ebitset_release_memory ();
673 bitset_list (bset
, list
, num
, next
)
681 count
= BITSET_LIST_ (bset
, list
, num
, next
);
688 enum bitset_type type
;
690 type
= BITSET_TYPE_ (bset
);
691 BITSET_STATS_LISTS_INC (bset
);
693 /* Log histogram of number of set bits. */
694 for (i
= 0, tmp
= count
; tmp
; tmp
>>= 1, i
++)
696 if (i
>= BITSET_LOG_COUNT_BINS
)
697 i
= BITSET_LOG_COUNT_BINS
- 1;
698 BITSET_STATS_LIST_COUNTS_INC (bset
, i
);
700 /* Log histogram of number of bits in set. */
701 size
= bitset_size (bset
);
702 for (i
= 0, tmp
= size
; tmp
; tmp
>>= 1, i
++)
704 if (i
>= BITSET_LOG_SIZE_BINS
)
705 i
= BITSET_LOG_SIZE_BINS
- 1;
706 BITSET_STATS_LIST_SIZES_INC (bset
, i
);
708 /* Histogram of fraction of bits set. */
709 i
= size
? (count
* BITSET_DENSITY_BINS
) / size
: 0;
710 if (i
>= BITSET_DENSITY_BINS
)
711 i
= BITSET_DENSITY_BINS
- 1;
712 BITSET_STATS_LIST_DENSITY_INC (bset
, i
);
718 /* Print a percentage histogram with message MSG to FILE. */
720 bitset_percent_histogram_print (file
, name
, msg
, n_bins
, bins
)
731 for (i
= 0; i
< n_bins
; i
++)
737 fprintf (file
, "%s %s", name
, msg
);
738 for (i
= 0; i
< n_bins
; i
++)
739 fprintf (file
, "%.0f-%.0f%%\t%8d (%5.1f%%)\n",
741 (i
+ 1) * 100.0 / n_bins
, bins
[i
],
742 (100.0 * bins
[i
]) / total
);
746 /* Print a log histogram with message MSG to FILE. */
748 bitset_log_histogram_print (file
, name
, msg
, n_bins
, bins
)
757 unsigned int max_width
;
760 for (i
= 0; i
< n_bins
; i
++)
766 /* 2 * ceil (log10(2) * (N - 1)) + 1 */
767 max_width
= 2 * (unsigned int) (0.30103 * (n_bins
- 1) + 0.9999) + 1;
769 fprintf (file
, "%s %s", name
, msg
);
770 for (i
= 0; i
< 2; i
++)
771 fprintf (file
, "%*d\t%8d (%5.1f%%)\n",
772 max_width
, i
, bins
[i
], 100.0 * bins
[i
] / total
);
774 /* Perhaps we should bail out once the histogram goes to zero. */
775 for (; i
< n_bins
; i
++)
776 fprintf (file
, "%*d-%d\t%8d (%5.1f%%)\n",
777 max_width
- ((unsigned int) (0.30103 * (i
) + 0.9999) + 1),
778 1 << (i
- 1), (1 << i
) - 1, bins
[i
],
779 (100.0 * bins
[i
]) / total
);
783 /* Print bitset statistics to FILE. */
785 bitset_stats_print_1 (file
, name
, stats
)
788 struct bitset_type_stats_struct
*stats
;
793 fprintf (file
, "%d %ss xmalloced, %d freed.\n",
794 stats
->xmallocs
, name
, stats
->xfrees
);
795 fprintf (file
, "%d %ss oballoced, %d freed.\n",
796 stats
->oballocs
, name
, stats
->obfrees
);
798 fprintf (file
, "%d bitset_lists\n", stats
->lists
);
800 bitset_log_histogram_print (file
, name
, "count log histogram\n",
801 BITSET_LOG_COUNT_BINS
, stats
->list_counts
);
803 bitset_log_histogram_print (file
, name
, "size log histogram\n",
804 BITSET_LOG_SIZE_BINS
, stats
->list_sizes
);
806 bitset_percent_histogram_print (file
, name
, "density histogram\n",
807 BITSET_DENSITY_BINS
, stats
->list_density
);
811 /* Print all bitset statistics to FILE. */
813 bitset_stats_print (file
, verbose
)
815 int verbose ATTRIBUTE_UNUSED
;
818 static const char *names
[] = BITSET_TYPE_NAMES
;
823 fprintf (file
, "Bitset statistics:\n\n");
825 if (bitset_stats
->runs
> 1)
826 fprintf (file
, "Accumulated runs = %d\n", bitset_stats
->runs
);
828 for (i
= 0; i
< BITSET_TYPE_NUM
; i
++)
829 bitset_stats_print_1 (file
, names
[i
], &bitset_stats
->types
[i
]);
831 #endif /* BITSET_STATS */
834 /* Initialise bitset statistics logging. */
839 bitset_stats
= &bitset_stats_data
;
840 bitset_stats_read ();
841 #endif /* BITSET_STATS */
845 /* Read bitset statistics file. */
854 file
= fopen (BITSET_STATS_FILE
, "r");
857 if (fread (&bitset_stats_data
, sizeof (bitset_stats_data
),
861 perror ("Could not read stats file.");
863 fprintf (stderr
, "Bad stats file size.\n");
867 bitset_stats_data
.runs
++;
871 /* Write bitset statistics file. */
873 bitset_stats_write ()
880 file
= fopen (BITSET_STATS_FILE
, "w");
883 if (fwrite (&bitset_stats_data
, sizeof (bitset_stats_data
),
885 perror ("Could not write stats file.");
889 perror ("Could not open stats file for writing.");
893 /* Dump bitset statistics to FILE. */
895 bitset_stats_dump (file
)
899 bitset_stats_print (file
, 0);
900 bitset_stats_write ();
901 #endif /* BITSET_STATS */
905 /* Function to be called from debugger to print bitset stats. */
907 debug_bitset_stats (void)
910 bitset_stats_print (stderr
, 1);
911 #endif /* BITSET_STATS */