1*e4b17023SJohn Marino /* SparseSet implementation.
2*e4b17023SJohn Marino Copyright (C) 2007, 2008 Free Software Foundation, Inc.
3*e4b17023SJohn Marino Contributed by Peter Bergner <bergner@vnet.ibm.com>
4*e4b17023SJohn Marino
5*e4b17023SJohn Marino This file is part of GCC.
6*e4b17023SJohn Marino
7*e4b17023SJohn Marino GCC is free software; you can redistribute it and/or modify it under
8*e4b17023SJohn Marino the terms of the GNU General Public License as published by the Free
9*e4b17023SJohn Marino Software Foundation; either version 3, or (at your option) any later
10*e4b17023SJohn Marino version.
11*e4b17023SJohn Marino
12*e4b17023SJohn Marino GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*e4b17023SJohn Marino WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*e4b17023SJohn Marino FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15*e4b17023SJohn Marino for more details.
16*e4b17023SJohn Marino
17*e4b17023SJohn Marino You should have received a copy of the GNU General Public License
18*e4b17023SJohn Marino along with GCC; see the file COPYING3. If not see
19*e4b17023SJohn Marino <http://www.gnu.org/licenses/>. */
20*e4b17023SJohn Marino
21*e4b17023SJohn Marino #include "config.h"
22*e4b17023SJohn Marino #include "system.h"
23*e4b17023SJohn Marino #include "sparseset.h"
24*e4b17023SJohn Marino
25*e4b17023SJohn Marino /* Allocate and clear a n_elms SparseSet. */
26*e4b17023SJohn Marino
27*e4b17023SJohn Marino sparseset
sparseset_alloc(SPARSESET_ELT_TYPE n_elms)28*e4b17023SJohn Marino sparseset_alloc (SPARSESET_ELT_TYPE n_elms)
29*e4b17023SJohn Marino {
30*e4b17023SJohn Marino unsigned int n_bytes = sizeof (struct sparseset_def)
31*e4b17023SJohn Marino + ((n_elms - 1) * 2 * sizeof (SPARSESET_ELT_TYPE));
32*e4b17023SJohn Marino
33*e4b17023SJohn Marino /* We use xcalloc rather than xmalloc to silence some valgrind uninitialized
34*e4b17023SJohn Marino read errors when accessing set->sparse[n] when "n" is not, and never has
35*e4b17023SJohn Marino been, in the set. These uninitialized reads are expected, by design and
36*e4b17023SJohn Marino harmless. If this turns into a performance problem due to some future
37*e4b17023SJohn Marino additional users of sparseset, we can revisit this decision. */
38*e4b17023SJohn Marino sparseset set = (sparseset) xcalloc (1, n_bytes);
39*e4b17023SJohn Marino set->dense = &(set->elms[0]);
40*e4b17023SJohn Marino set->sparse = &(set->elms[n_elms]);
41*e4b17023SJohn Marino set->size = n_elms;
42*e4b17023SJohn Marino sparseset_clear (set);
43*e4b17023SJohn Marino return set;
44*e4b17023SJohn Marino }
45*e4b17023SJohn Marino
46*e4b17023SJohn Marino /* Low level routine not meant for use outside of sparseset.[ch].
47*e4b17023SJohn Marino Assumes idx1 < s->members and idx2 < s->members. */
48*e4b17023SJohn Marino
49*e4b17023SJohn Marino static inline void
sparseset_swap(sparseset s,SPARSESET_ELT_TYPE idx1,SPARSESET_ELT_TYPE idx2)50*e4b17023SJohn Marino sparseset_swap (sparseset s, SPARSESET_ELT_TYPE idx1, SPARSESET_ELT_TYPE idx2)
51*e4b17023SJohn Marino {
52*e4b17023SJohn Marino SPARSESET_ELT_TYPE tmp = s->dense[idx2];
53*e4b17023SJohn Marino sparseset_insert_bit (s, s->dense[idx1], idx2);
54*e4b17023SJohn Marino sparseset_insert_bit (s, tmp, idx1);
55*e4b17023SJohn Marino }
56*e4b17023SJohn Marino
57*e4b17023SJohn Marino /* Operation: S = S - {e}
58*e4b17023SJohn Marino Delete e from the set S if it is a member of S. */
59*e4b17023SJohn Marino
60*e4b17023SJohn Marino void
sparseset_clear_bit(sparseset s,SPARSESET_ELT_TYPE e)61*e4b17023SJohn Marino sparseset_clear_bit (sparseset s, SPARSESET_ELT_TYPE e)
62*e4b17023SJohn Marino {
63*e4b17023SJohn Marino if (sparseset_bit_p (s, e))
64*e4b17023SJohn Marino {
65*e4b17023SJohn Marino SPARSESET_ELT_TYPE idx = s->sparse[e];
66*e4b17023SJohn Marino SPARSESET_ELT_TYPE iter = s->iter;
67*e4b17023SJohn Marino SPARSESET_ELT_TYPE mem = s->members - 1;
68*e4b17023SJohn Marino
69*e4b17023SJohn Marino /* If we are iterating over this set and we want to delete a
70*e4b17023SJohn Marino member we've already visited, then we swap the element we
71*e4b17023SJohn Marino want to delete with the element at the current iteration
72*e4b17023SJohn Marino index so that it plays well together with the code below
73*e4b17023SJohn Marino that actually removes the element. */
74*e4b17023SJohn Marino if (s->iterating && idx <= iter)
75*e4b17023SJohn Marino {
76*e4b17023SJohn Marino if (idx < iter)
77*e4b17023SJohn Marino {
78*e4b17023SJohn Marino sparseset_swap (s, idx, iter);
79*e4b17023SJohn Marino idx = iter;
80*e4b17023SJohn Marino }
81*e4b17023SJohn Marino s->iter_inc = 0;
82*e4b17023SJohn Marino }
83*e4b17023SJohn Marino
84*e4b17023SJohn Marino /* Replace the element we want to delete with the last element
85*e4b17023SJohn Marino in the dense array and then decrement s->members, effectively
86*e4b17023SJohn Marino removing the element we want to delete. */
87*e4b17023SJohn Marino sparseset_insert_bit (s, s->dense[mem], idx);
88*e4b17023SJohn Marino s->members = mem;
89*e4b17023SJohn Marino }
90*e4b17023SJohn Marino }
91*e4b17023SJohn Marino
92*e4b17023SJohn Marino /* Operation: D = S
93*e4b17023SJohn Marino Restrictions: none. */
94*e4b17023SJohn Marino
95*e4b17023SJohn Marino void
sparseset_copy(sparseset d,sparseset s)96*e4b17023SJohn Marino sparseset_copy (sparseset d, sparseset s)
97*e4b17023SJohn Marino {
98*e4b17023SJohn Marino SPARSESET_ELT_TYPE i;
99*e4b17023SJohn Marino
100*e4b17023SJohn Marino if (d == s)
101*e4b17023SJohn Marino return;
102*e4b17023SJohn Marino
103*e4b17023SJohn Marino sparseset_clear (d);
104*e4b17023SJohn Marino for (i = 0; i < s->members; i++)
105*e4b17023SJohn Marino sparseset_insert_bit (d, s->dense[i], i);
106*e4b17023SJohn Marino d->members = s->members;
107*e4b17023SJohn Marino }
108*e4b17023SJohn Marino
109*e4b17023SJohn Marino /* Operation: D = A & B.
110*e4b17023SJohn Marino Restrictions: none. */
111*e4b17023SJohn Marino
112*e4b17023SJohn Marino void
sparseset_and(sparseset d,sparseset a,sparseset b)113*e4b17023SJohn Marino sparseset_and (sparseset d, sparseset a, sparseset b)
114*e4b17023SJohn Marino {
115*e4b17023SJohn Marino SPARSESET_ELT_TYPE e;
116*e4b17023SJohn Marino
117*e4b17023SJohn Marino if (a == b)
118*e4b17023SJohn Marino {
119*e4b17023SJohn Marino if (d != a)
120*e4b17023SJohn Marino sparseset_copy (d, a);
121*e4b17023SJohn Marino return;
122*e4b17023SJohn Marino }
123*e4b17023SJohn Marino
124*e4b17023SJohn Marino if (d == a || d == b)
125*e4b17023SJohn Marino {
126*e4b17023SJohn Marino sparseset s = (d == a) ? b : a;
127*e4b17023SJohn Marino
128*e4b17023SJohn Marino EXECUTE_IF_SET_IN_SPARSESET (d, e)
129*e4b17023SJohn Marino if (!sparseset_bit_p (s, e))
130*e4b17023SJohn Marino sparseset_clear_bit (d, e);
131*e4b17023SJohn Marino }
132*e4b17023SJohn Marino else
133*e4b17023SJohn Marino {
134*e4b17023SJohn Marino sparseset sml, lrg;
135*e4b17023SJohn Marino
136*e4b17023SJohn Marino if (sparseset_cardinality (a) < sparseset_cardinality (b))
137*e4b17023SJohn Marino {
138*e4b17023SJohn Marino sml = a;
139*e4b17023SJohn Marino lrg = b;
140*e4b17023SJohn Marino }
141*e4b17023SJohn Marino else
142*e4b17023SJohn Marino {
143*e4b17023SJohn Marino sml = b;
144*e4b17023SJohn Marino lrg = a;
145*e4b17023SJohn Marino }
146*e4b17023SJohn Marino
147*e4b17023SJohn Marino sparseset_clear (d);
148*e4b17023SJohn Marino EXECUTE_IF_SET_IN_SPARSESET (sml, e)
149*e4b17023SJohn Marino if (sparseset_bit_p (lrg, e))
150*e4b17023SJohn Marino sparseset_set_bit (d, e);
151*e4b17023SJohn Marino }
152*e4b17023SJohn Marino }
153*e4b17023SJohn Marino
154*e4b17023SJohn Marino /* Operation: D = A & ~B.
155*e4b17023SJohn Marino Restrictions: D != B, unless D == A == B. */
156*e4b17023SJohn Marino
157*e4b17023SJohn Marino void
sparseset_and_compl(sparseset d,sparseset a,sparseset b)158*e4b17023SJohn Marino sparseset_and_compl (sparseset d, sparseset a, sparseset b)
159*e4b17023SJohn Marino {
160*e4b17023SJohn Marino SPARSESET_ELT_TYPE e;
161*e4b17023SJohn Marino
162*e4b17023SJohn Marino if (a == b)
163*e4b17023SJohn Marino {
164*e4b17023SJohn Marino sparseset_clear (d);
165*e4b17023SJohn Marino return;
166*e4b17023SJohn Marino }
167*e4b17023SJohn Marino
168*e4b17023SJohn Marino gcc_assert (d != b);
169*e4b17023SJohn Marino
170*e4b17023SJohn Marino if (d == a)
171*e4b17023SJohn Marino {
172*e4b17023SJohn Marino if (sparseset_cardinality (d) < sparseset_cardinality (b))
173*e4b17023SJohn Marino {
174*e4b17023SJohn Marino EXECUTE_IF_SET_IN_SPARSESET (d, e)
175*e4b17023SJohn Marino if (sparseset_bit_p (b, e))
176*e4b17023SJohn Marino sparseset_clear_bit (d, e);
177*e4b17023SJohn Marino }
178*e4b17023SJohn Marino else
179*e4b17023SJohn Marino {
180*e4b17023SJohn Marino EXECUTE_IF_SET_IN_SPARSESET (b, e)
181*e4b17023SJohn Marino sparseset_clear_bit (d, e);
182*e4b17023SJohn Marino }
183*e4b17023SJohn Marino }
184*e4b17023SJohn Marino else
185*e4b17023SJohn Marino {
186*e4b17023SJohn Marino sparseset_clear (d);
187*e4b17023SJohn Marino EXECUTE_IF_SET_IN_SPARSESET (a, e)
188*e4b17023SJohn Marino if (!sparseset_bit_p (b, e))
189*e4b17023SJohn Marino sparseset_set_bit (d, e);
190*e4b17023SJohn Marino }
191*e4b17023SJohn Marino }
192*e4b17023SJohn Marino
193*e4b17023SJohn Marino /* Operation: D = A | B.
194*e4b17023SJohn Marino Restrictions: none. */
195*e4b17023SJohn Marino
196*e4b17023SJohn Marino void
sparseset_ior(sparseset d,sparseset a,sparseset b)197*e4b17023SJohn Marino sparseset_ior (sparseset d, sparseset a, sparseset b)
198*e4b17023SJohn Marino {
199*e4b17023SJohn Marino SPARSESET_ELT_TYPE e;
200*e4b17023SJohn Marino
201*e4b17023SJohn Marino if (a == b)
202*e4b17023SJohn Marino sparseset_copy (d, a);
203*e4b17023SJohn Marino else if (d == b)
204*e4b17023SJohn Marino {
205*e4b17023SJohn Marino EXECUTE_IF_SET_IN_SPARSESET (a, e)
206*e4b17023SJohn Marino sparseset_set_bit (d, e);
207*e4b17023SJohn Marino }
208*e4b17023SJohn Marino else
209*e4b17023SJohn Marino {
210*e4b17023SJohn Marino if (d != a)
211*e4b17023SJohn Marino sparseset_copy (d, a);
212*e4b17023SJohn Marino EXECUTE_IF_SET_IN_SPARSESET (b, e)
213*e4b17023SJohn Marino sparseset_set_bit (d, e);
214*e4b17023SJohn Marino }
215*e4b17023SJohn Marino }
216*e4b17023SJohn Marino
217*e4b17023SJohn Marino /* Operation: A == B
218*e4b17023SJohn Marino Restrictions: none. */
219*e4b17023SJohn Marino
220*e4b17023SJohn Marino bool
sparseset_equal_p(sparseset a,sparseset b)221*e4b17023SJohn Marino sparseset_equal_p (sparseset a, sparseset b)
222*e4b17023SJohn Marino {
223*e4b17023SJohn Marino SPARSESET_ELT_TYPE e;
224*e4b17023SJohn Marino
225*e4b17023SJohn Marino if (a == b)
226*e4b17023SJohn Marino return true;
227*e4b17023SJohn Marino
228*e4b17023SJohn Marino if (sparseset_cardinality (a) != sparseset_cardinality (b))
229*e4b17023SJohn Marino return false;
230*e4b17023SJohn Marino
231*e4b17023SJohn Marino EXECUTE_IF_SET_IN_SPARSESET (a, e)
232*e4b17023SJohn Marino if (!sparseset_bit_p (b, e))
233*e4b17023SJohn Marino return false;
234*e4b17023SJohn Marino
235*e4b17023SJohn Marino return true;
236*e4b17023SJohn Marino }
237*e4b17023SJohn Marino
238