]> git.saurik.com Git - bison.git/blame - lib/bitset.c
maint: get fdl.texi from gnulib
[bison.git] / lib / bitset.c
CommitLineData
7086e707 1/* General bitsets.
6e30ede8 2
c932d613 3 Copyright (C) 2002-2006, 2009-2012 Free Software Foundation, Inc.
6e30ede8 4
7086e707
AD
5 Contributed by Michael Hayes (m.hayes@elec.canterbury.ac.nz).
6
f16b0819 7 This program is free software: you can redistribute it and/or modify
ef017502 8 it under the terms of the GNU General Public License as published by
f16b0819 9 the Free Software Foundation, either version 3 of the License, or
ef017502 10 (at your option) any later version.
7086e707 11
ef017502
AD
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
7086e707 16
ef017502 17 You should have received a copy of the GNU General Public License
f16b0819 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
7086e707 19
231ed89a
PE
20#include <config.h>
21
22#include "bitset.h"
7086e707
AD
23
24#include <stdlib.h>
eaef5507 25#include <string.h>
613f5e1a 26#include "abitset.h"
ef017502
AD
27#include "lbitset.h"
28#include "ebitset.h"
eaef5507 29#include "vbitset.h"
613f5e1a 30#include "bitset_stats.h"
7086e707
AD
31#include "obstack.h"
32
6aa452a6
AD
33const char * const bitset_type_names[] = BITSET_TYPE_NAMES;
34
7086e707 35
7086e707
AD
36/* Return number of bytes required to create a N_BIT bitset
37 of TYPE. The bitset may grow to require more bytes than this. */
d32fe6f6 38size_t
447e90bc 39bitset_bytes (enum bitset_type type, bitset_bindex n_bits)
7086e707 40{
d32fe6f6 41 size_t bytes;
7086e707 42
613f5e1a
AD
43 if (bitset_stats_enabled)
44 return bitset_stats_bytes ();
45
7086e707
AD
46 switch (type)
47 {
68cae94e
PE
48 default:
49 abort ();
50
7086e707 51 case BITSET_ARRAY:
613f5e1a 52 bytes = abitset_bytes (n_bits);
7086e707
AD
53 break;
54
55 case BITSET_LIST:
56 bytes = lbitset_bytes (n_bits);
57 break;
58
59 case BITSET_TABLE:
60 bytes = ebitset_bytes (n_bits);
61 break;
62
eaef5507
PE
63 case BITSET_VARRAY:
64 bytes = vbitset_bytes (n_bits);
65 break;
7086e707
AD
66 }
67
68 return bytes;
69}
70
71
72/* Initialise bitset BSET of TYPE for N_BITS. */
73bitset
447e90bc 74bitset_init (bitset bset, bitset_bindex n_bits, enum bitset_type type)
7086e707 75{
613f5e1a
AD
76 if (bitset_stats_enabled)
77 return bitset_stats_init (bset, n_bits, type);
447e90bc 78
7086e707
AD
79 switch (type)
80 {
68cae94e
PE
81 default:
82 abort ();
83
7086e707 84 case BITSET_ARRAY:
613f5e1a 85 return abitset_init (bset, n_bits);
7086e707
AD
86
87 case BITSET_LIST:
88 return lbitset_init (bset, n_bits);
89
90 case BITSET_TABLE:
91 return ebitset_init (bset, n_bits);
92
eaef5507
PE
93 case BITSET_VARRAY:
94 return vbitset_init (bset, n_bits);
7086e707
AD
95 }
96}
97
98
99/* Select a bitset type for a set of N_BITS and with attribute hints
100 specified by ATTR. For variable size bitsets, N_BITS is only a
101 hint and may be zero. */
102enum bitset_type
447e90bc 103bitset_type_choose (bitset_bindex n_bits ATTRIBUTE_UNUSED, unsigned int attr)
7086e707 104{
7086e707
AD
105 /* Check attributes. */
106 if (attr & BITSET_FIXED && attr & BITSET_VARIABLE)
107 abort ();
108 if (attr & BITSET_SPARSE && attr & BITSET_DENSE)
109 abort ();
110
eaef5507 111 /* Choose the type of bitset. Note that sometimes we will be asked
6aa452a6 112 for a zero length fixed size bitset. */
7086e707 113
4d1801f1 114
eaef5507
PE
115 /* If no attributes selected, choose a good compromise. */
116 if (!attr)
117 return BITSET_VARRAY;
118
119 if (attr & BITSET_SPARSE)
120 return BITSET_LIST;
121
122 if (attr & BITSET_FIXED)
123 return BITSET_ARRAY;
7086e707 124
eaef5507
PE
125 if (attr & BITSET_GREEDY)
126 return BITSET_TABLE;
127
128 return BITSET_VARRAY;
7086e707
AD
129}
130
131
132/* Create a bitset of N_BITS of type TYPE. */
133bitset
447e90bc 134bitset_alloc (bitset_bindex n_bits, enum bitset_type type)
7086e707 135{
d32fe6f6 136 size_t bytes;
7086e707
AD
137 bitset bset;
138
7086e707
AD
139 bytes = bitset_bytes (type, n_bits);
140
89519adf 141 bset = xcalloc (1, bytes);
ef017502
AD
142
143 /* The cache is disabled until some elements are allocated. If we
613f5e1a 144 have variable length arrays, then we may need to allocate a dummy
ef017502 145 element. */
7086e707
AD
146
147 return bitset_init (bset, n_bits, type);
148}
149
150
151/* Create a bitset of N_BITS of type TYPE. */
152bitset
447e90bc
PE
153bitset_obstack_alloc (struct obstack *bobstack,
154 bitset_bindex n_bits, enum bitset_type type)
7086e707 155{
d32fe6f6 156 size_t bytes;
ef017502 157 bitset bset;
7086e707 158
7086e707
AD
159 bytes = bitset_bytes (type, n_bits);
160
ef017502
AD
161 bset = obstack_alloc (bobstack, bytes);
162 memset (bset, 0, bytes);
163
164 return bitset_init (bset, n_bits, type);
7086e707
AD
165}
166
167
168/* Create a bitset of N_BITS and with attribute hints specified by
169 ATTR. */
170bitset
447e90bc 171bitset_create (bitset_bindex n_bits, unsigned int attr)
7086e707
AD
172{
173 enum bitset_type type;
174
175 type = bitset_type_choose (n_bits, attr);
176
177 return bitset_alloc (n_bits, type);
178}
179
180
181/* Free bitset BSET. */
182void
447e90bc 183bitset_free (bitset bset)
7086e707 184{
ef017502 185 BITSET_FREE_ (bset);
7086e707
AD
186 free (bset);
187}
188
189
190/* Free bitset BSET allocated on obstack. */
191void
447e90bc 192bitset_obstack_free (bitset bset)
7086e707 193{
ef017502 194 BITSET_FREE_ (bset);
7086e707
AD
195}
196
197
613f5e1a
AD
198/* Return bitset type. */
199enum bitset_type
447e90bc 200bitset_type_get (bitset bset)
613f5e1a
AD
201{
202 enum bitset_type type;
203
204 type = BITSET_TYPE_ (bset);
205 if (type != BITSET_STATS)
206 return type;
447e90bc 207
613f5e1a
AD
208 return bitset_stats_type_get (bset);
209}
210
211
6aa452a6
AD
212/* Return name of bitset type. */
213const char *
447e90bc 214bitset_type_name_get (bitset bset)
6aa452a6
AD
215{
216 enum bitset_type type;
217
218 type = bitset_type_get (bset);
219
220 return bitset_type_names[type];
221}
222
223
7086e707 224/* Find next bit set in SRC starting from and including BITNO.
d32fe6f6
PE
225 Return BITSET_BINDEX_MAX if SRC empty. */
226bitset_bindex
447e90bc 227bitset_next (bitset src, bitset_bindex bitno)
7086e707
AD
228{
229 bitset_bindex val;
230 bitset_bindex next = bitno;
231
232 if (!bitset_list (src, &val, 1, &next))
d32fe6f6 233 return BITSET_BINDEX_MAX;
7086e707
AD
234 return val;
235}
236
237
eaef5507
PE
238/* Return true if both bitsets are of the same type and size. */
239extern bool
240bitset_compatible_p (bitset bset1, bitset bset2)
241{
242 return BITSET_COMPATIBLE_ (bset1, bset2);
243}
244
245
7086e707 246/* Find previous bit set in SRC starting from and including BITNO.
d32fe6f6
PE
247 Return BITSET_BINDEX_MAX if SRC empty. */
248bitset_bindex
447e90bc 249bitset_prev (bitset src, bitset_bindex bitno)
7086e707
AD
250{
251 bitset_bindex val;
252 bitset_bindex next = bitno;
253
6aa452a6 254 if (!bitset_list_reverse (src, &val, 1, &next))
d32fe6f6 255 return BITSET_BINDEX_MAX;
7086e707
AD
256 return val;
257}
258
259
260/* Find first set bit. */
d32fe6f6 261bitset_bindex
447e90bc 262bitset_first (bitset src)
7086e707
AD
263{
264 return bitset_next (src, 0);
265}
266
267
268/* Find last set bit. */
d32fe6f6 269bitset_bindex
447e90bc 270bitset_last (bitset src)
7086e707
AD
271{
272 return bitset_prev (src, 0);
273}
274
275
d0829076
PE
276/* Is BITNO in SRC the only set bit? */
277bool
447e90bc 278bitset_only_set_p (bitset src, bitset_bindex bitno)
345cea78
AD
279{
280 bitset_bindex val[2];
281 bitset_bindex next = 0;
282
283 if (bitset_list (src, val, 2, &next) != 1)
d0829076 284 return false;
345cea78
AD
285 return val[0] == bitno;
286}
287
288
ef017502 289/* Print contents of bitset BSET to FILE. */
7086e707 290static void
d0829076 291bitset_print (FILE *file, bitset bset, bool verbose)
7086e707 292{
6aa452a6
AD
293 unsigned int pos;
294 bitset_bindex i;
613f5e1a 295 bitset_iterator iter;
7086e707
AD
296
297 if (verbose)
d32fe6f6 298 fprintf (file, "n_bits = %lu, set = {",
779e7ceb 299 (unsigned long int) bitset_size (bset));
7086e707
AD
300
301 pos = 30;
613f5e1a 302 BITSET_FOR_EACH (iter, bset, i, 0)
7086e707
AD
303 {
304 if (pos > 70)
305 {
2f4f028d 306 fprintf (file, "\n");
7086e707
AD
307 pos = 0;
308 }
309
4d1801f1 310 fprintf (file, "%lu ", (unsigned long int) i);
7086e707 311 pos += 1 + (i >= 10) + (i >= 100);
613f5e1a 312 };
7086e707
AD
313
314 if (verbose)
2f4f028d 315 fprintf (file, "}\n");
7086e707
AD
316}
317
318
6aa452a6
AD
319/* Dump bitset BSET to FILE. */
320void
447e90bc 321bitset_dump (FILE *file, bitset bset)
7086e707 322{
d0829076 323 bitset_print (file, bset, false);
6aa452a6 324}
7086e707 325
7086e707 326
6aa452a6
AD
327/* Release memory associated with bitsets. */
328void
447e90bc 329bitset_release_memory (void)
6aa452a6
AD
330{
331 lbitset_release_memory ();
332 ebitset_release_memory ();
7086e707
AD
333}
334
335
d0829076
PE
336/* Toggle bit BITNO in bitset BSET and the new value of the bit. */
337bool
447e90bc 338bitset_toggle_ (bitset bset, bitset_bindex bitno)
ef017502 339{
6aa452a6
AD
340 /* This routine is for completeness. It could be optimized if
341 required. */
342 if (bitset_test (bset, bitno))
343 {
344 bitset_reset (bset, bitno);
d0829076 345 return false;
6aa452a6
AD
346 }
347 else
348 {
349 bitset_set (bset, bitno);
d0829076 350 return true;
6aa452a6 351 }
ef017502
AD
352}
353
354
eaef5507
PE
355/* Return number of bits in bitset SRC. */
356bitset_bindex
357bitset_size_ (bitset src)
358{
359 return BITSET_NBITS_ (src);
360}
361
362
ef017502 363/* Return number of bits set in bitset SRC. */
d32fe6f6 364bitset_bindex
447e90bc 365bitset_count_ (bitset src)
7086e707 366{
ef017502
AD
367 bitset_bindex list[BITSET_LIST_SIZE];
368 bitset_bindex next;
d32fe6f6
PE
369 bitset_bindex num;
370 bitset_bindex count;
447e90bc 371
613f5e1a
AD
372 /* This could be greatly sped up by adding a count method for each
373 bitset implementation that uses a direct technique (based on
374 masks) for counting the number of bits set in a word. */
375
ef017502
AD
376 next = 0;
377 for (count = 0; (num = bitset_list (src, list, BITSET_LIST_SIZE, &next));
378 count += num)
379 continue;
447e90bc 380
ef017502 381 return count;
7086e707
AD
382}
383
384
d0829076 385/* DST = SRC. Return true if DST != SRC.
6aa452a6
AD
386 This is a fallback for the case where SRC and DST are different
387 bitset types. */
d0829076 388bool
447e90bc 389bitset_copy_ (bitset dst, bitset src)
ef017502 390{
6aa452a6
AD
391 bitset_bindex i;
392 bitset_iterator iter;
7086e707 393
6aa452a6
AD
394 /* Convert bitset types. We assume that the DST bitset
395 is large enough to hold the SRC bitset. */
396 bitset_zero (dst);
397 BITSET_FOR_EACH (iter, src, i, 0)
398 {
399 bitset_set (dst, i);
400 };
7086e707 401
d0829076 402 return true;
7086e707
AD
403}
404
405
613f5e1a
AD
406/* This is a fallback for implementations that do not support
407 four operand operations. */
d0829076 408static inline bool
447e90bc
PE
409bitset_op4_cmp (bitset dst, bitset src1, bitset src2, bitset src3,
410 enum bitset_ops op)
ef017502 411{
d0829076
PE
412 bool changed = false;
413 bool stats_enabled_save;
ef017502
AD
414 bitset tmp;
415
416 /* Create temporary bitset. */
6aa452a6 417 stats_enabled_save = bitset_stats_enabled;
d0829076 418 bitset_stats_enabled = false;
613f5e1a 419 tmp = bitset_alloc (0, bitset_type_get (dst));
6aa452a6 420 bitset_stats_enabled = stats_enabled_save;
ef017502
AD
421
422 switch (op)
423 {
68cae94e
PE
424 default:
425 abort ();
426
ef017502 427 case BITSET_OP_OR_AND:
6aa452a6
AD
428 bitset_or (tmp, src1, src2);
429 changed = bitset_and_cmp (dst, src3, tmp);
ef017502
AD
430 break;
431
432 case BITSET_OP_AND_OR:
6aa452a6
AD
433 bitset_and (tmp, src1, src2);
434 changed = bitset_or_cmp (dst, src3, tmp);
ef017502
AD
435 break;
436
437 case BITSET_OP_ANDN_OR:
6aa452a6
AD
438 bitset_andn (tmp, src1, src2);
439 changed = bitset_or_cmp (dst, src3, tmp);
ef017502 440 break;
ef017502
AD
441 }
442
443 bitset_free (tmp);
444 return changed;
7086e707
AD
445}
446
447
d5c559cd
PE
448/* DST = (SRC1 & SRC2) | SRC3. */
449void
447e90bc 450bitset_and_or_ (bitset dst, bitset src1, bitset src2, bitset src3)
d5c559cd
PE
451{
452 bitset_and_or_cmp_ (dst, src1, src2, src3);
453}
454
455
6aa452a6
AD
456/* DST = (SRC1 & SRC2) | SRC3. Return non-zero if
457 DST != (SRC1 & SRC2) | SRC3. */
d0829076 458bool
447e90bc 459bitset_and_or_cmp_ (bitset dst, bitset src1, bitset src2, bitset src3)
7086e707 460{
6aa452a6 461 return bitset_op4_cmp (dst, src1, src2, src3, BITSET_OP_AND_OR);
7086e707
AD
462}
463
464
d5c559cd
PE
465/* DST = (SRC1 & ~SRC2) | SRC3. */
466void
447e90bc 467bitset_andn_or_ (bitset dst, bitset src1, bitset src2, bitset src3)
d5c559cd
PE
468{
469 bitset_andn_or_cmp_ (dst, src1, src2, src3);
470}
471
472
6aa452a6
AD
473/* DST = (SRC1 & ~SRC2) | SRC3. Return non-zero if
474 DST != (SRC1 & ~SRC2) | SRC3. */
d0829076 475bool
447e90bc 476bitset_andn_or_cmp_ (bitset dst, bitset src1, bitset src2, bitset src3)
ef017502 477{
6aa452a6 478 return bitset_op4_cmp (dst, src1, src2, src3, BITSET_OP_ANDN_OR);
ef017502
AD
479}
480
481
d5c559cd
PE
482/* DST = (SRC1 | SRC2) & SRC3. */
483void
447e90bc 484bitset_or_and_ (bitset dst, bitset src1, bitset src2, bitset src3)
d5c559cd
PE
485{
486 bitset_or_and_cmp_ (dst, src1, src2, src3);
487}
488
489
6aa452a6
AD
490/* DST = (SRC1 | SRC2) & SRC3. Return non-zero if
491 DST != (SRC1 | SRC2) & SRC3. */
d0829076 492bool
447e90bc 493bitset_or_and_cmp_ (bitset dst, bitset src1, bitset src2, bitset src3)
7086e707 494{
6aa452a6 495 return bitset_op4_cmp (dst, src1, src2, src3, BITSET_OP_OR_AND);
7086e707
AD
496}
497
498
499/* Function to be called from debugger to print bitset. */
500void
447e90bc 501debug_bitset (bitset bset)
7086e707 502{
ef017502 503 if (bset)
d0829076 504 bitset_print (stderr, bset, true);
7086e707 505}