2 |
Copyright (C) 2002 Free Software Foundation, Inc. |
Copyright (C) 2002 Free Software Foundation, Inc. |
3 |
Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz). |
Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz). |
4 |
|
|
5 |
This program is free software; you can redistribute it and/or modify |
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 |
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 |
the Free Software Foundation; either version 2 of the License, or |
8 |
(at your option) any later version. |
(at your option) any later version. |
9 |
|
|
10 |
This program is distributed in the hope that it will be useful, |
This program is distributed in the hope that it will be useful, |
11 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 |
GNU General Public License for more details. |
GNU General Public License for more details. |
14 |
|
|
15 |
You should have received a copy of the GNU General Public License |
You should have received a copy of the GNU General Public License |
16 |
along with this program; if not, write to the Free Software |
along with this program; if not, write to the Free Software |
17 |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ |
18 |
|
|
19 |
#ifdef HAVE_CONFIG_H |
#ifdef HAVE_CONFIG_H |
20 |
#include "config.h" |
#include "config.h" |
22 |
|
|
23 |
#include <stdlib.h> |
#include <stdlib.h> |
24 |
#include "bitset.h" |
#include "bitset.h" |
25 |
|
#include "sbitset.h" |
26 |
|
#include "lbitset.h" |
27 |
|
#include "ebitset.h" |
28 |
#include "obstack.h" |
#include "obstack.h" |
29 |
|
|
30 |
static void bitset_print PARAMS ((FILE *, bitset, int)); |
static void bitset_print PARAMS ((FILE *, bitset, int)); |
31 |
|
|
|
#if BITSET_CHECK |
|
|
#define BITSET__CHECK2(DST, SRC) \ |
|
|
if ((DST)->OPS != (SRC)->OPS) abort (); |
|
|
|
|
|
#define BITSET__CHECK3(DST, SRC1, SRC2) \ |
|
|
if ((DST)->OPS != (SRC1)->OPS || (DST)->OPS != (SRC2)->OPS) abort (); |
|
|
|
|
|
#define BITSET__CHECK4(DST, SRC1, SRC2) \ |
|
|
if ((DST)->OPS != (SRC1)->OPS || (DST)->OPS != (SRC2)->OPS \ |
|
|
|| (DST)->OPS != (SRC3)->OPS) abort (); |
|
|
#else |
|
|
#define BITSET__CHECK2(DST, SRC) |
|
|
|
|
|
#define BITSET__CHECK3(DST, SRC1, SRC2) |
|
|
|
|
|
#define BITSET__CHECK4(DST, SRC1, SRC2, SRC3) |
|
|
#endif |
|
|
|
|
32 |
#if BITSET_STATS |
#if BITSET_STATS |
33 |
#define BITSET_STATS_FILE "bitset.dat" |
#define BITSET_STATS_FILE "bitset.dat" |
34 |
|
|
50 |
|
|
51 |
struct bitset_stats_struct |
struct bitset_stats_struct |
52 |
{ |
{ |
53 |
unsigned int runs; |
unsigned int runs; |
54 |
struct bitset_type_stats_struct types[BITSET_TYPE_NUM]; |
struct bitset_type_stats_struct types[BITSET_TYPE_NUM]; |
55 |
}; |
}; |
56 |
|
|
57 |
struct bitset_stats_struct bitset_stats_data; |
struct bitset_stats_struct bitset_stats_data; |
63 |
unsigned int *)); |
unsigned int *)); |
64 |
static void bitset_log_histogram_print PARAMS ((FILE *, const char *, |
static void bitset_log_histogram_print PARAMS ((FILE *, const char *, |
65 |
const char *, |
const char *, |
66 |
unsigned int, unsigned int *)); |
unsigned int, |
67 |
static void bitset_stats_print_1 PARAMS ((FILE *, const char *, |
unsigned int *)); |
68 |
struct bitset_type_stats_struct *)); |
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)); |
static void bitset_stats_print PARAMS ((FILE *, int)); |
71 |
static void bitset_stats_read PARAMS ((void)); |
static void bitset_stats_read PARAMS ((void)); |
72 |
static void bitset_stats_write PARAMS ((void)); |
static void bitset_stats_write PARAMS ((void)); |
77 |
|
|
78 |
#define BITSET_STATS_XFREES_INC(BSET) \ |
#define BITSET_STATS_XFREES_INC(BSET) \ |
79 |
if (bitset_stats) \ |
if (bitset_stats) \ |
80 |
bitset_stats->types[(BSET)->ops->type].xfrees++ |
bitset_stats->types[BITSET_TYPE_ (BSET)].xfrees++ |
81 |
|
|
82 |
#define BITSET_STATS_OBALLOCS_INC(TYPE) \ |
#define BITSET_STATS_OBALLOCS_INC(TYPE) \ |
83 |
if (bitset_stats) \ |
if (bitset_stats) \ |
84 |
bitset_stats->types[(TYPE)].oballocs++ |
bitset_stats->types[(TYPE)].oballocs++ |
85 |
|
|
86 |
#define BITSET_STATS_OBFREES_INC(BSET) \ |
#define BITSET_STATS_OBFREES_INC(BSET) \ |
87 |
if (bitset_stats) \ |
if (bitset_stats) \ |
88 |
bitset_stats->types[(BSET)->ops->type].obfrees++ |
bitset_stats->types[BITSET_TYPE_ (BSET)].obfrees++ |
89 |
|
|
90 |
#define BITSET_STATS_LISTS_INC(BSET) \ |
#define BITSET_STATS_LISTS_INC(BSET) \ |
91 |
if (bitset_stats) \ |
if (bitset_stats) \ |
92 |
bitset_stats->types[(BSET)->ops->type].lists++ |
bitset_stats->types[BITSET_TYPE_ (BSET)].lists++ |
93 |
|
|
94 |
#define BITSET_STATS_LIST_COUNTS_INC(BSET, I) \ |
#define BITSET_STATS_LIST_COUNTS_INC(BSET, I) \ |
95 |
if (bitset_stats) \ |
if (bitset_stats) \ |
96 |
bitset_stats->types[(BSET)->ops->type].list_counts[(I)]++ |
bitset_stats->types[BITSET_TYPE_ (BSET)].list_counts[(I)]++ |
97 |
|
|
98 |
#define BITSET_STATS_LIST_SIZES_INC(BSET, I) \ |
#define BITSET_STATS_LIST_SIZES_INC(BSET, I) \ |
99 |
if (bitset_stats) \ |
if (bitset_stats) \ |
100 |
bitset_stats->types[(BSET)->ops->type].list_sizes[(I)]++ |
bitset_stats->types[BITSET_TYPE_ (BSET)].list_sizes[(I)]++ |
101 |
|
|
102 |
#define BITSET_STATS_LIST_DENSITY_INC(BSET, I) \ |
#define BITSET_STATS_LIST_DENSITY_INC(BSET, I) \ |
103 |
if (bitset_stats) \ |
if (bitset_stats) \ |
104 |
bitset_stats->types[(BSET)->ops->type].list_density[(I)]++ |
bitset_stats->types[BITSET_TYPE_ (BSET)].list_density[(I)]++ |
105 |
|
|
106 |
#else |
#else |
107 |
#define BITSET_STATS_XMALLOCS_INC(TYPE) |
#define BITSET_STATS_XMALLOCS_INC(TYPE) |
122 |
#endif /* BITSET_STATS */ |
#endif /* BITSET_STATS */ |
123 |
|
|
124 |
|
|
|
|
|
125 |
/* Return number of bytes required to create a N_BIT bitset |
/* Return number of bytes required to create a N_BIT bitset |
126 |
of TYPE. The bitset may grow to require more bytes than this. */ |
of TYPE. The bitset may grow to require more bytes than this. */ |
127 |
int |
int |
187 |
{ |
{ |
188 |
enum bitset_type type; |
enum bitset_type type; |
189 |
|
|
190 |
#ifdef ENABLE_CHECKING |
#if BITSET_CHECK |
191 |
/* Check attributes. */ |
/* Check attributes. */ |
192 |
if (attr & BITSET_FIXED && attr & BITSET_VARIABLE) |
if (attr & BITSET_FIXED && attr & BITSET_VARIABLE) |
193 |
abort (); |
abort (); |
226 |
|
|
227 |
bytes = bitset_bytes (type, n_bits); |
bytes = bitset_bytes (type, n_bits); |
228 |
|
|
229 |
bset = (bitset) xmalloc (bytes); |
bset = (bitset) xcalloc (1, bytes); |
230 |
|
|
231 |
|
/* The cache is disabled until some elements are allocated. If we |
232 |
|
have variable length arrays, then we may need to allocate dummy |
233 |
|
element. */ |
234 |
|
|
235 |
return bitset_init (bset, n_bits, type); |
return bitset_init (bset, n_bits, type); |
236 |
} |
} |
239 |
/* Create a bitset of N_BITS of type TYPE. */ |
/* Create a bitset of N_BITS of type TYPE. */ |
240 |
bitset |
bitset |
241 |
bitset_obstack_alloc (bobstack, n_bits, type) |
bitset_obstack_alloc (bobstack, n_bits, type) |
242 |
struct obstack *bobstack; |
struct obstack *bobstack; |
243 |
bitset_bindex n_bits; |
bitset_bindex n_bits; |
244 |
enum bitset_type type; |
enum bitset_type type; |
245 |
{ |
{ |
246 |
unsigned int bytes; |
unsigned int bytes; |
247 |
|
bitset bset; |
248 |
|
|
249 |
BITSET_STATS_OBALLOCS_INC (type); |
BITSET_STATS_OBALLOCS_INC (type); |
250 |
|
|
251 |
bytes = bitset_bytes (type, n_bits); |
bytes = bitset_bytes (type, n_bits); |
252 |
|
|
253 |
return bitset_init (obstack_alloc (bobstack, bytes), n_bits, type); |
bset = obstack_alloc (bobstack, bytes); |
254 |
|
memset (bset, 0, bytes); |
255 |
|
|
256 |
|
return bitset_init (bset, n_bits, type); |
257 |
} |
} |
258 |
|
|
259 |
|
|
279 |
{ |
{ |
280 |
BITSET_STATS_XFREES_INC (bset); |
BITSET_STATS_XFREES_INC (bset); |
281 |
|
|
282 |
if (bset->ops->free) |
BITSET_FREE_ (bset); |
|
BITSET__FREE (bset); |
|
|
|
|
|
bset->ops = NULL; |
|
283 |
free (bset); |
free (bset); |
284 |
} |
} |
285 |
|
|
291 |
{ |
{ |
292 |
BITSET_STATS_OBFREES_INC (bset); |
BITSET_STATS_OBFREES_INC (bset); |
293 |
|
|
294 |
if (bset->ops->free) |
BITSET_FREE_ (bset); |
|
BITSET__FREE (bset); |
|
|
bset->ops = NULL; |
|
295 |
} |
} |
296 |
|
|
297 |
|
|
345 |
} |
} |
346 |
|
|
347 |
|
|
348 |
|
/* Print contents of bitset BSET to FILE. */ |
349 |
static void |
static void |
350 |
bitset_print (file, bset, verbose) |
bitset_print (file, bset, verbose) |
351 |
FILE *file; |
FILE *file; |
375 |
} |
} |
376 |
|
|
377 |
|
|
378 |
|
/* DST = SRC. Return non-zero if DST != SRC. */ |
379 |
int |
int |
380 |
bitset_copy (dst, src) |
bitset_copy (dst, src) |
381 |
bitset dst; |
bitset dst; |
382 |
bitset src; |
bitset src; |
383 |
{ |
{ |
384 |
unsigned int i; |
unsigned int i; |
385 |
|
|
386 |
if (dst->ops == src->ops) |
if (BITSET_COMPATIBLE_ (dst, src)) |
387 |
return BITSET__COPY (dst, src); |
return BITSET_COPY_ (dst, src); |
388 |
|
|
389 |
/* Convert bitset types. We assume that the DST bitset |
/* Convert bitset types. We assume that the DST bitset |
390 |
is large enough to hold the SRC bitset. */ |
is large enough to hold the SRC bitset. */ |
391 |
bitset_zero (dst); |
bitset_zero (dst); |
392 |
BITSET_EXECUTE (src, 0, i, |
BITSET_EXECUTE (src, 0, i, |
393 |
{ |
{ |
394 |
bitset_set (dst, i); |
bitset_set (dst, i); |
395 |
}); |
}); |
396 |
|
|
397 |
return 1; |
return 1; |
398 |
} |
} |
399 |
|
|
400 |
|
|
401 |
/* Return size in bits of bitset SRC. */ |
/* Return size in bits of bitset SRC. */ |
402 |
int |
int |
403 |
bitset_size (src) |
bitset_size (src) |
404 |
bitset src; |
bitset src; |
405 |
|
{ |
406 |
|
return BITSET_SIZE_ (src); |
407 |
|
} |
408 |
|
|
409 |
|
|
410 |
|
/* Return number of bits set in bitset SRC. */ |
411 |
|
int |
412 |
|
bitset_count (src) |
413 |
|
bitset src; |
414 |
{ |
{ |
415 |
return BITSET__SIZE (src); |
bitset_bindex list[BITSET_LIST_SIZE]; |
416 |
|
bitset_bindex next; |
417 |
|
int num; |
418 |
|
int count; |
419 |
|
|
420 |
|
next = 0; |
421 |
|
for (count = 0; (num = bitset_list (src, list, BITSET_LIST_SIZE, &next)); |
422 |
|
count += num) |
423 |
|
continue; |
424 |
|
|
425 |
|
return count; |
426 |
} |
} |
427 |
|
|
428 |
|
|
429 |
/* DST = 0. */ |
/* DST = 0. */ |
430 |
int |
int |
431 |
bitset_zero (dst) |
bitset_zero (dst) |
432 |
bitset dst; |
bitset dst; |
433 |
{ |
{ |
434 |
return BITSET__OP1 (dst, BITSET_ZERO); |
return BITSET_ZERO_ (dst); |
435 |
} |
} |
436 |
|
|
437 |
|
|
438 |
/* DST = ~0. */ |
/* DST = ~0. */ |
439 |
int |
int |
440 |
bitset_ones (dst) |
bitset_ones (dst) |
441 |
bitset dst; |
bitset dst; |
442 |
{ |
{ |
443 |
return BITSET__OP1 (dst, BITSET_ONES); |
return BITSET_ONES_ (dst); |
444 |
} |
} |
445 |
|
|
446 |
|
|
447 |
/* Return non-zero if all bits in bitset SRC are reset. */ |
/* Return SRC == 0. */ |
448 |
int |
int |
449 |
bitset_empty_p (src) |
bitset_empty_p (src) |
450 |
bitset src; |
bitset src; |
451 |
{ |
{ |
452 |
return BITSET__OP1 (src, BITSET_EMPTY_P); |
return BITSET_EMPTY_P_ (src); |
453 |
} |
} |
454 |
|
|
455 |
|
|
456 |
/* Return DST == DST | SRC. */ |
/* Return DST == DST | SRC. */ |
457 |
int |
int |
458 |
bitset_subset_p (dst, src) |
bitset_subset_p (dst, src) |
459 |
bitset dst; |
bitset dst; |
460 |
bitset src; |
bitset src; |
461 |
{ |
{ |
462 |
return BITSET__OP2 (dst, src, BITSET_SUBSET_P); |
BITSET_CHECK2_ (dst, src); |
463 |
|
return BITSET_SUBSET_P_ (dst, src); |
464 |
} |
} |
465 |
|
|
466 |
|
|
467 |
/* Return DST == SRC. */ |
/* Return DST == SRC. */ |
468 |
int |
int |
469 |
bitset_equal_p (dst, src) |
bitset_equal_p (dst, src) |
470 |
bitset dst; |
bitset dst; |
471 |
bitset src; |
bitset src; |
472 |
{ |
{ |
473 |
BITSET__CHECK2 (dst, src); |
BITSET_CHECK2_ (dst, src); |
474 |
return BITSET__OP2 (dst, src, BITSET_EQUAL_P); |
return BITSET_EQUAL_P_ (dst, src); |
475 |
|
} |
476 |
|
|
477 |
|
|
478 |
|
/* Return DST & SRC == 0. */ |
479 |
|
int |
480 |
|
bitset_disjoint_p (dst, src) |
481 |
|
bitset dst; |
482 |
|
bitset src; |
483 |
|
{ |
484 |
|
BITSET_CHECK2_ (dst, src); |
485 |
|
return BITSET_DISJOINT_P_ (dst, src); |
486 |
} |
} |
487 |
|
|
488 |
|
|
489 |
/* DST = ~SRC. */ |
/* DST = ~SRC. */ |
490 |
int |
int |
491 |
bitset_not (dst, src) |
bitset_not (dst, src) |
492 |
bitset dst; |
bitset dst; |
493 |
bitset src; |
bitset src; |
494 |
{ |
{ |
495 |
BITSET__CHECK2 (dst, src); |
BITSET_CHECK2_ (dst, src); |
496 |
return BITSET__OP2 (dst, src, BITSET_NOT); |
return BITSET_NOT_ (dst, src); |
497 |
} |
} |
498 |
|
|
499 |
|
|
500 |
/* DST = SRC1 | SRC2. Return non-zero if DST != SRC1 | SRC2. */ |
/* DST = SRC1 | SRC2. Return non-zero if DST != SRC1 | SRC2. */ |
501 |
int |
int |
502 |
bitset_or (dst, src1, src2) |
bitset_or (dst, src1, src2) |
503 |
bitset dst; |
bitset dst; |
504 |
bitset src1; |
bitset src1; |
505 |
bitset src2; |
bitset src2; |
506 |
{ |
{ |
507 |
BITSET__CHECK3 (dst, src1, src2); |
BITSET_CHECK3_ (dst, src1, src2); |
508 |
return BITSET__OP3 (dst, src1, src2, BITSET_OR); |
return BITSET_OR_ (dst, src1, src2); |
509 |
} |
} |
510 |
|
|
511 |
|
|
512 |
/* DST = SRC1 & SRC2. Return non-zero if DST != SRC1 & SRC2. */ |
/* DST = SRC1 & SRC2. Return non-zero if DST != SRC1 & SRC2. */ |
513 |
int |
int |
514 |
bitset_and (dst, src1, src2) |
bitset_and (dst, src1, src2) |
515 |
bitset dst; |
bitset dst; |
516 |
bitset src1; |
bitset src1; |
517 |
bitset src2; |
bitset src2; |
518 |
{ |
{ |
519 |
BITSET__CHECK3 (dst, src1, src2); |
BITSET_CHECK3_ (dst, src1, src2); |
520 |
return BITSET__OP3 (dst, src1, src2, BITSET_AND); |
return BITSET_AND_ (dst, src1, src2); |
521 |
} |
} |
522 |
|
|
523 |
|
|
524 |
/* DST = SRC1 ^ SRC2. Return non-zero if DST != SRC1 ^ SRC2. */ |
/* DST = SRC1 ^ SRC2. Return non-zero if DST != SRC1 ^ SRC2. */ |
525 |
int |
int |
526 |
bitset_xor (dst, src1, src2) |
bitset_xor (dst, src1, src2) |
527 |
bitset dst; |
bitset dst; |
528 |
bitset src1; |
bitset src1; |
529 |
bitset src2; |
bitset src2; |
530 |
{ |
{ |
531 |
BITSET__CHECK3 (dst, src1, src2); |
BITSET_CHECK3_ (dst, src1, src2); |
532 |
return BITSET__OP3 (dst, src1, src2, BITSET_XOR); |
return BITSET_XOR_ (dst, src1, src2); |
533 |
} |
} |
534 |
|
|
535 |
|
|
536 |
/* DST = SRC1 & ~SRC2. Return non-zero if DST != SRC1 & ~SRC2. */ |
/* DST = SRC1 & ~SRC2. Return non-zero if DST != SRC1 & ~SRC2. */ |
537 |
int |
int |
538 |
bitset_andn (dst, src1, src2) |
bitset_andn (dst, src1, src2) |
539 |
bitset dst; |
bitset dst; |
540 |
bitset src1; |
bitset src1; |
541 |
bitset src2; |
bitset src2; |
542 |
{ |
{ |
543 |
BITSET__CHECK3 (dst, src1, src2); |
BITSET_CHECK3_ (dst, src1, src2); |
544 |
return BITSET__OP3 (dst, src1, src2, BITSET_ANDN); |
return BITSET_ANDN_ (dst, src1, src2); |
545 |
} |
} |
546 |
|
|
547 |
|
|
548 |
/* DST = SRC1 | ~SRC2. Return non-zero if DST != SRC1 | ~SRC2. */ |
/* DST = SRC1 | ~SRC2. Return non-zero if DST != SRC1 | ~SRC2. */ |
549 |
int |
int |
550 |
bitset_orn (dst, src1, src2) |
bitset_orn (dst, src1, src2) |
551 |
bitset dst; |
bitset dst; |
552 |
bitset src1; |
bitset src1; |
553 |
bitset src2; |
bitset src2; |
554 |
{ |
{ |
555 |
BITSET__CHECK3 (dst, src1, src2); |
BITSET_CHECK3_ (dst, src1, src2); |
556 |
return BITSET__OP3 (dst, src1, src2, BITSET_ORN); |
return BITSET_ORN_ (dst, src1, src2); |
557 |
|
} |
558 |
|
|
559 |
|
|
560 |
|
int |
561 |
|
bitset_op4 (dst, src1, src2, src3, op) |
562 |
|
bitset dst; |
563 |
|
bitset src1; |
564 |
|
bitset src2; |
565 |
|
bitset src3; |
566 |
|
enum bitset_ops op; |
567 |
|
{ |
568 |
|
int changed = 0; |
569 |
|
bitset tmp; |
570 |
|
|
571 |
|
/* Create temporary bitset. */ |
572 |
|
tmp = bitset_alloc (BITSET_TYPE_ (dst), 0); |
573 |
|
|
574 |
|
switch (op) |
575 |
|
{ |
576 |
|
case BITSET_OP_OR_AND: |
577 |
|
BITSET_OR_ (tmp, src1, src2); |
578 |
|
changed = BITSET_AND_ (dst, src3, tmp); |
579 |
|
break; |
580 |
|
|
581 |
|
case BITSET_OP_AND_OR: |
582 |
|
BITSET_AND_ (tmp, src1, src2); |
583 |
|
changed = BITSET_OR_ (dst, src3, tmp); |
584 |
|
break; |
585 |
|
|
586 |
|
case BITSET_OP_ANDN_OR: |
587 |
|
BITSET_ANDN_ (tmp, src1, src2); |
588 |
|
changed = BITSET_OR_ (dst, src3, tmp); |
589 |
|
break; |
590 |
|
|
591 |
|
default: |
592 |
|
abort (); |
593 |
|
} |
594 |
|
|
595 |
|
bitset_free (tmp); |
596 |
|
return changed; |
597 |
} |
} |
598 |
|
|
599 |
|
|
601 |
DST != (SRC1 | SRC2) & SRC3. */ |
DST != (SRC1 | SRC2) & SRC3. */ |
602 |
int |
int |
603 |
bitset_or_and (dst, src1, src2, src3) |
bitset_or_and (dst, src1, src2, src3) |
604 |
bitset dst; |
bitset dst; |
605 |
bitset src1; |
bitset src1; |
606 |
bitset src2; |
bitset src2; |
607 |
bitset src3; |
bitset src3; |
608 |
{ |
{ |
609 |
BITSET__CHECK4 (dst, src1, src2, src3); |
BITSET_CHECK4_ (dst, src1, src2, src3); |
610 |
return BITSET__OP4 (dst, src1, src2, src3, BITSET_OR_AND); |
return BITSET_OR_AND_ (dst, src1, src2, src3); |
611 |
} |
} |
612 |
|
|
613 |
|
|
615 |
DST != (SRC1 & SRC2) | SRC3. */ |
DST != (SRC1 & SRC2) | SRC3. */ |
616 |
int |
int |
617 |
bitset_and_or (dst, src1, src2, src3) |
bitset_and_or (dst, src1, src2, src3) |
618 |
bitset dst; |
bitset dst; |
619 |
bitset src1; |
bitset src1; |
620 |
bitset src2; |
bitset src2; |
621 |
bitset src3; |
bitset src3; |
622 |
|
{ |
623 |
|
BITSET_CHECK4_ (dst, src1, src2, src3); |
624 |
|
return BITSET_AND_OR_ (dst, src1, src2, src3); |
625 |
|
} |
626 |
|
|
627 |
|
|
628 |
|
/* DST = (SRC1 & ~SRC2) | SRC3. Return non-zero if |
629 |
|
DST != (SRC1 & ~SRC2) | SRC3. */ |
630 |
|
int |
631 |
|
bitset_andn_or (dst, src1, src2, src3) |
632 |
|
bitset dst; |
633 |
|
bitset src1; |
634 |
|
bitset src2; |
635 |
|
bitset src3; |
636 |
{ |
{ |
637 |
BITSET__CHECK4 (dst, src1, src2, src3); |
BITSET_CHECK4_ (dst, src1, src2, src3); |
638 |
return BITSET__OP4 (dst, src1, src2, src3, BITSET_AND_OR); |
return BITSET_ANDN_OR_ (dst, src1, src2, src3); |
639 |
} |
} |
640 |
|
|
641 |
|
|
654 |
debug_bitset (bset) |
debug_bitset (bset) |
655 |
bitset bset; |
bitset bset; |
656 |
{ |
{ |
657 |
bitset_print (stderr, bset, 1); |
if (bset) |
658 |
|
bitset_print (stderr, bset, 1); |
659 |
} |
} |
660 |
|
|
661 |
|
|
671 |
#if BITSET_STATS |
#if BITSET_STATS |
672 |
int |
int |
673 |
bitset_list (bset, list, num, next) |
bitset_list (bset, list, num, next) |
674 |
bitset bset; |
bitset bset; |
675 |
bitset_bindex *list; |
bitset_bindex *list; |
676 |
bitset_bindex num; |
bitset_bindex num; |
677 |
bitset_bindex *next; |
bitset_bindex *next; |
678 |
{ |
{ |
679 |
bitset_bindex count; |
bitset_bindex count; |
680 |
|
|
681 |
count = BITSET__LIST (bset, list, num, next); |
count = BITSET_LIST_ (bset, list, num, next); |
682 |
|
|
683 |
if (bitset_stats) |
if (bitset_stats) |
684 |
{ |
{ |
685 |
bitset_bindex tmp; |
bitset_bindex tmp; |
686 |
bitset_bindex size; |
bitset_bindex size; |
687 |
bitset_bindex i; |
bitset_bindex i; |
688 |
enum bitset_type type; |
enum bitset_type type; |
689 |
|
|
690 |
type = bset->ops->type; |
type = BITSET_TYPE_ (bset); |
691 |
BITSET_STATS_LISTS_INC (bset); |
BITSET_STATS_LISTS_INC (bset); |
692 |
|
|
693 |
/* Log histogram of number of set bits. */ |
/* Log histogram of number of set bits. */ |
694 |
for (i = 0, tmp = count; tmp; tmp >>= 1, i++) |
for (i = 0, tmp = count; tmp; tmp >>= 1, i++) |
695 |
continue; |
continue; |
696 |
if (i >= BITSET_LOG_COUNT_BINS) |
if (i >= BITSET_LOG_COUNT_BINS) |
697 |
i = BITSET_LOG_COUNT_BINS - 1; |
i = BITSET_LOG_COUNT_BINS - 1; |
698 |
BITSET_STATS_LIST_COUNTS_INC (bset, i); |
BITSET_STATS_LIST_COUNTS_INC (bset, i); |
699 |
|
|
700 |
/* Log histogram of number of bits in set. */ |
/* Log histogram of number of bits in set. */ |
701 |
size = bitset_size (bset); |
size = bitset_size (bset); |
702 |
for (i = 0, tmp = size; tmp; tmp >>= 1, i++) |
for (i = 0, tmp = size; tmp; tmp >>= 1, i++) |
703 |
continue; |
continue; |
704 |
if (i >= BITSET_LOG_SIZE_BINS) |
if (i >= BITSET_LOG_SIZE_BINS) |
705 |
i = BITSET_LOG_SIZE_BINS - 1; |
i = BITSET_LOG_SIZE_BINS - 1; |
706 |
BITSET_STATS_LIST_SIZES_INC (bset, i); |
BITSET_STATS_LIST_SIZES_INC (bset, i); |
707 |
|
|
708 |
/* Histogram of fraction of bits set. */ |
/* Histogram of fraction of bits set. */ |
709 |
i = size ? (count * BITSET_DENSITY_BINS) / size : 0; |
i = size ? (count * BITSET_DENSITY_BINS) / size : 0; |
710 |
if (i >= BITSET_DENSITY_BINS) |
if (i >= BITSET_DENSITY_BINS) |
711 |
i = BITSET_DENSITY_BINS - 1; |
i = BITSET_DENSITY_BINS - 1; |
712 |
BITSET_STATS_LIST_DENSITY_INC (bset, i); |
BITSET_STATS_LIST_DENSITY_INC (bset, i); |
713 |
} |
} |
714 |
return count; |
return count; |
715 |
} |
} |
716 |
|
|
717 |
|
|
732 |
total += bins[i]; |
total += bins[i]; |
733 |
|
|
734 |
if (!total) |
if (!total) |
735 |
return; |
return; |
736 |
|
|
737 |
fprintf (file, "%s %s", name, msg); |
fprintf (file, "%s %s", name, msg); |
738 |
for (i = 0; i < n_bins; i++) |
for (i = 0; i < n_bins; i++) |
739 |
fprintf (file, "%.0f-%.0f%%\t%8d (%5.1f%%)\n", |
fprintf (file, "%.0f-%.0f%%\t%8d (%5.1f%%)\n", |
740 |
i * 100.0 / n_bins, |
i * 100.0 / n_bins, |
741 |
(i + 1) * 100.0 / n_bins, |
(i + 1) * 100.0 / n_bins, bins[i], |
742 |
bins[i], (100.0 * bins[i]) / total); |
(100.0 * bins[i]) / total); |
743 |
} |
} |
744 |
|
|
745 |
|
|
761 |
total += bins[i]; |
total += bins[i]; |
762 |
|
|
763 |
if (!total) |
if (!total) |
764 |
return; |
return; |
765 |
|
|
766 |
/* 2 * ceil (log10(2) * (N - 1)) + 1 */ |
/* 2 * ceil (log10(2) * (N - 1)) + 1 */ |
767 |
max_width = 2 * (unsigned int)(0.30103 * (n_bins - 1) + 0.9999) + 1; |
max_width = 2 * (unsigned int) (0.30103 * (n_bins - 1) + 0.9999) + 1; |
768 |
|
|
769 |
fprintf (file, "%s %s", name, msg); |
fprintf (file, "%s %s", name, msg); |
770 |
for (i = 0; i < 2; i++) |
for (i = 0; i < 2; i++) |
775 |
for (; i < n_bins; i++) |
for (; i < n_bins; i++) |
776 |
fprintf (file, "%*d-%d\t%8d (%5.1f%%)\n", |
fprintf (file, "%*d-%d\t%8d (%5.1f%%)\n", |
777 |
max_width - ((unsigned int) (0.30103 * (i) + 0.9999) + 1), |
max_width - ((unsigned int) (0.30103 * (i) + 0.9999) + 1), |
778 |
1 << (i - 1), (1 << i) - 1, bins[i], (100.0 * bins[i]) / total); |
1 << (i - 1), (1 << i) - 1, bins[i], |
779 |
|
(100.0 * bins[i]) / total); |
780 |
} |
} |
781 |
|
|
782 |
|
|
798 |
fprintf (file, "%d bitset_lists\n", stats->lists); |
fprintf (file, "%d bitset_lists\n", stats->lists); |
799 |
|
|
800 |
bitset_log_histogram_print (file, name, "count log histogram\n", |
bitset_log_histogram_print (file, name, "count log histogram\n", |
801 |
BITSET_LOG_COUNT_BINS, stats->list_counts); |
BITSET_LOG_COUNT_BINS, stats->list_counts); |
802 |
|
|
803 |
bitset_log_histogram_print (file, name, "size log histogram\n", |
bitset_log_histogram_print (file, name, "size log histogram\n", |
804 |
BITSET_LOG_SIZE_BINS, stats->list_sizes); |
BITSET_LOG_SIZE_BINS, stats->list_sizes); |
805 |
|
|
806 |
bitset_percent_histogram_print (file, name, "density histogram\n", |
bitset_percent_histogram_print (file, name, "density histogram\n", |
807 |
BITSET_DENSITY_BINS, stats->list_density); |
BITSET_DENSITY_BINS, stats->list_density); |
815 |
int verbose ATTRIBUTE_UNUSED; |
int verbose ATTRIBUTE_UNUSED; |
816 |
{ |
{ |
817 |
int i; |
int i; |
818 |
static const char *names[] = BITSET__TYPE_NAMES; |
static const char *names[] = BITSET_TYPE_NAMES; |
819 |
|
|
820 |
if (!bitset_stats) |
if (!bitset_stats) |
821 |
return; |
return; |
826 |
fprintf (file, "Accumulated runs = %d\n", bitset_stats->runs); |
fprintf (file, "Accumulated runs = %d\n", bitset_stats->runs); |
827 |
|
|
828 |
for (i = 0; i < BITSET_TYPE_NUM; i++) |
for (i = 0; i < BITSET_TYPE_NUM; i++) |
829 |
bitset_stats_print_1 (file, names[i], &bitset_stats->types[i]); |
bitset_stats_print_1 (file, names[i], &bitset_stats->types[i]); |
830 |
} |
} |
831 |
#endif /* BITSET_STATS */ |
#endif /* BITSET_STATS */ |
832 |
|
|
836 |
bitset_stats_init () |
bitset_stats_init () |
837 |
{ |
{ |
838 |
#if BITSET_STATS |
#if BITSET_STATS |
839 |
bitset_stats = &bitset_stats_data; |
bitset_stats = &bitset_stats_data; |
840 |
bitset_stats_read (); |
bitset_stats_read (); |
841 |
#endif /* BITSET_STATS */ |
#endif /* BITSET_STATS */ |
842 |
} |
} |
843 |
|
|
844 |
|
|
846 |
static void |
static void |
847 |
bitset_stats_read () |
bitset_stats_read () |
848 |
{ |
{ |
849 |
FILE *file; |
FILE *file; |
850 |
|
|
851 |
if (!bitset_stats) |
if (!bitset_stats) |
852 |
return; |
return; |
853 |
|
|
854 |
file = fopen (BITSET_STATS_FILE, "r"); |
file = fopen (BITSET_STATS_FILE, "r"); |
855 |
if (file) |
if (file) |
856 |
{ |
{ |
857 |
if (fread (&bitset_stats_data, sizeof (bitset_stats_data), |
if (fread (&bitset_stats_data, sizeof (bitset_stats_data), |
858 |
1, file) != 1) |
1, file) != 1) |
859 |
{ |
{ |
860 |
if (ferror (file)) |
if (ferror (file)) |
861 |
perror ("Could not read stats file"); |
perror ("Could not read stats file."); |
862 |
else |
else |
863 |
fprintf (stderr, "Bad stats file size\n"); |
fprintf (stderr, "Bad stats file size.\n"); |
864 |
} |
} |
865 |
fclose (file); |
fclose (file); |
866 |
} |
} |
867 |
bitset_stats_data.runs++; |
bitset_stats_data.runs++; |
868 |
} |
} |
869 |
|
|
870 |
|
|
872 |
static void |
static void |
873 |
bitset_stats_write () |
bitset_stats_write () |
874 |
{ |
{ |
875 |
FILE *file; |
FILE *file; |
876 |
|
|
877 |
if (!bitset_stats) |
if (!bitset_stats) |
878 |
return; |
return; |
879 |
|
|
880 |
file = fopen (BITSET_STATS_FILE, "w"); |
file = fopen (BITSET_STATS_FILE, "w"); |
881 |
if (file) |
if (file) |
882 |
{ |
{ |
883 |
if (fwrite (&bitset_stats_data, sizeof (bitset_stats_data), |
if (fwrite (&bitset_stats_data, sizeof (bitset_stats_data), |
884 |
1, file) != 1) |
1, file) != 1) |
885 |
perror ("Could not write stats file"); |
perror ("Could not write stats file."); |
886 |
fclose (file); |
fclose (file); |
887 |
} |
} |
888 |
else |
else |
889 |
perror ("Could not open stats file for writing"); |
perror ("Could not open stats file for writing."); |
890 |
} |
} |
891 |
|
|
892 |
|
|