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