diff options
Diffstat (limited to 'src/depmap.c')
-rw-r--r-- | src/depmap.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/depmap.c b/src/depmap.c new file mode 100644 index 0000000..340d41f --- /dev/null +++ b/src/depmap.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* This file is part of GNU cflow. | ||
2 | Copyright (C) 2008, 2009 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 | 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 | rowsize = WORDSIZE (n) * sizeof (unsigned); | ||
44 | relend = (unsigned *) ((char *) R + (n * rowsize)); | ||
45 | |||
46 | cword = R; | ||
47 | mask = 1; | ||
48 | rowi = R; | ||
49 | while (rowi < relend) { | ||
50 | ccol = cword; | ||
51 | rowj = R; | ||
52 | |||
53 | while (rowj < relend) { | ||
54 | if (*ccol & mask) { | ||
55 | rp = rowi; | ||
56 | rend = (unsigned *) ((char *) rowj + rowsize); | ||
57 | |||
58 | while (rowj < rend) | ||
59 | *rowj++ |= *rp++; | ||
60 | } else { | ||
61 | rowj = (unsigned *) ((char *) rowj + rowsize); | ||
62 | } | ||
63 | |||
64 | ccol = (unsigned *) ((char *) ccol + rowsize); | ||
65 | } | ||
66 | |||
67 | mask <<= 1; | ||
68 | if (mask == 0) { | ||
69 | mask = 1; | ||
70 | cword++; | ||
71 | } | ||
72 | rowi = (unsigned *) ((char *) rowi + rowsize); | ||
73 | } | ||
74 | } | ||
75 | |||
76 | struct cflow_depmap { | ||
77 | size_t nrows; | ||
78 | size_t rowlen; | ||
79 | unsigned r[1]; | ||
80 | }; | ||
81 | |||
82 | cflow_depmap_t | ||
83 | depmap_alloc(size_t count) | ||
84 | { | ||
85 | size_t size = (count + BITS_PER_WORD - 1) / BITS_PER_WORD; | ||
86 | cflow_depmap_t dmap = xzalloc(sizeof(*dmap) - 1 | ||
87 | + count * size * sizeof(unsigned)); | ||
88 | dmap->nrows = count; | ||
89 | dmap->rowlen = size; | ||
90 | return dmap; | ||
91 | } | ||
92 | |||
93 | static unsigned * | ||
94 | depmap_rowptr(cflow_depmap_t dmap, size_t row) | ||
95 | { | ||
96 | return dmap->r + dmap->rowlen * row; | ||
97 | } | ||
98 | |||
99 | void | ||
100 | depmap_set(cflow_depmap_t dmap, size_t row, size_t col) | ||
101 | { | ||
102 | unsigned *rptr = depmap_rowptr(dmap, row); | ||
103 | SETBIT(rptr, col); | ||
104 | } | ||
105 | |||
106 | int | ||
107 | depmap_isset(cflow_depmap_t dmap, size_t row, size_t col) | ||
108 | { | ||
109 | unsigned *rptr = depmap_rowptr(dmap, row); | ||
110 | return BITISSET(rptr, col); | ||
111 | } | ||
112 | |||
113 | void | ||
114 | depmap_tc(cflow_depmap_t dmap) | ||
115 | { | ||
116 | transitive_closure(dmap->r, dmap->nrows); | ||
117 | } | ||
118 | |||