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