xref: /dflybsd-src/contrib/gcc-4.7/gcc/sparseset.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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