Line data Source code
1 : /* This file is part of GNU cflow.
2 : Copyright (C) 2008, 2009, 2010 Sergey Poznyakoff
3 :
4 : GNU cflow is free software; you can redistribute it and/or modify
5 : it under the terms of the GNU General Public License as published by
6 : the Free Software Foundation; either version 3, or (at your option)
7 : any later version.
8 :
9 : GNU cflow is distributed in the hope that it will be useful,
10 : but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : GNU General Public License for more details.
13 :
14 : You should have received a copy of the GNU General Public License
15 : along with GNU cflow. If not, see <http://www.gnu.org/licenses/>. */
16 :
17 : #include <cflow.h>
18 :
19 : #ifndef CHAR_BIT
20 : # define CHAR_BIT 8
21 : #endif
22 : #define BITS_PER_WORD (sizeof(unsigned)*CHAR_BIT)
23 :
24 : #define WORDSIZE(n) (((n) + BITS_PER_WORD - 1) / BITS_PER_WORD)
25 : #define SETBIT(x, i) ((x)[(i)/BITS_PER_WORD] |= (1<<((i) % BITS_PER_WORD)))
26 : #define RESETBIT(x, i) ((x)[(i)/BITS_PER_WORD] &= ~(1<<((i) % BITS_PER_WORD)))
27 : #define BITISSET(x, i) (((x)[(i)/BITS_PER_WORD] & (1<<((i) % BITS_PER_WORD))) != 0)
28 :
29 : static void
30 14 : transitive_closure(unsigned *R, int n)
31 : {
32 : register size_t rowsize;
33 : register unsigned mask;
34 : register unsigned *rowj;
35 : register unsigned *rp;
36 : register unsigned *rend;
37 : register unsigned *ccol;
38 :
39 : unsigned *relend;
40 : unsigned *cword;
41 : unsigned *rowi;
42 :
43 14 : rowsize = WORDSIZE (n) * sizeof (unsigned);
44 14 : relend = (unsigned *) ((char *) R + (n * rowsize));
45 :
46 14 : cword = R;
47 14 : mask = 1;
48 14 : rowi = R;
49 2967 : while (rowi < relend) {
50 2939 : ccol = cword;
51 2939 : rowj = R;
52 :
53 778013 : while (rowj < relend) {
54 772135 : if (*ccol & mask) {
55 11468 : rp = rowi;
56 11468 : rend = (unsigned *) ((char *) rowj + rowsize);
57 :
58 125908 : while (rowj < rend)
59 102972 : *rowj++ |= *rp++;
60 : } else {
61 760667 : rowj = (unsigned *) ((char *) rowj + rowsize);
62 : }
63 :
64 772135 : ccol = (unsigned *) ((char *) ccol + rowsize);
65 : }
66 :
67 2939 : mask <<= 1;
68 2939 : if (mask == 0) {
69 88 : mask = 1;
70 88 : cword++;
71 : }
72 2939 : rowi = (unsigned *) ((char *) rowi + rowsize);
73 : }
74 14 : }
75 :
76 : struct cflow_depmap {
77 : size_t nrows;
78 : size_t rowlen;
79 : unsigned r[1];
80 : };
81 :
82 : cflow_depmap_t
83 14 : depmap_alloc(size_t count)
84 : {
85 14 : size_t size = (count + BITS_PER_WORD - 1) / BITS_PER_WORD;
86 14 : cflow_depmap_t dmap = xzalloc(sizeof(*dmap) - 1
87 14 : + count * size * sizeof(unsigned));
88 14 : dmap->nrows = count;
89 14 : dmap->rowlen = size;
90 14 : return dmap;
91 : }
92 :
93 : static unsigned *
94 8514 : depmap_rowptr(cflow_depmap_t dmap, size_t row)
95 : {
96 8514 : return dmap->r + dmap->rowlen * row;
97 : }
98 :
99 : void
100 5575 : depmap_set(cflow_depmap_t dmap, size_t row, size_t col)
101 : {
102 5575 : unsigned *rptr = depmap_rowptr(dmap, row);
103 5575 : SETBIT(rptr, col);
104 5575 : }
105 :
106 : int
107 2939 : depmap_isset(cflow_depmap_t dmap, size_t row, size_t col)
108 : {
109 2939 : unsigned *rptr = depmap_rowptr(dmap, row);
110 2939 : return BITISSET(rptr, col);
111 : }
112 :
113 : void
114 14 : depmap_tc(cflow_depmap_t dmap)
115 : {
116 14 : transitive_closure(dmap->r, dmap->nrows);
117 14 : }
118 :
|