LCOV - code coverage report
Current view: top level - gcc - sparseset.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 58.0 % 88 51
Test Date: 2026-02-28 14:20:25 Functions: 75.0 % 8 6
Legend: Lines:     hit not hit

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

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.