Optionally store domains of scattering dimensions in clast for
[cloog.git] / source / union_domain.c
blobb8576259bafc9ddcd9af88cc60ae5f57d6f32cb3
1 #include <ctype.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "../include/cloog/cloog.h"
6 #define ALLOC(type) (type*)malloc(sizeof(type))
7 #define ALLOCN(type,n) (type*)malloc((n)*sizeof(type))
9 void cloog_named_domain_list_free(CloogNamedDomainList *list)
11 while (list != NULL) {
12 CloogNamedDomainList *temp = list->next;
13 cloog_domain_free(list->domain);
14 cloog_scattering_free(list->scattering);
15 free(list->name);
16 free(list);
17 list = temp;
21 CloogUnionDomain *cloog_union_domain_alloc(int nb_par)
23 CloogUnionDomain *ud;
25 ud = ALLOC(CloogUnionDomain);
26 if (!ud)
27 cloog_die("memory overflow.\n");
29 ud->domain = NULL;
30 ud->next_domain = &ud->domain;
32 ud->n_name[CLOOG_PARAM] = nb_par;
33 ud->n_name[CLOOG_ITER] = 0;
34 ud->n_name[CLOOG_SCAT] = 0;
36 ud->name[CLOOG_PARAM] = NULL;
37 ud->name[CLOOG_ITER] = NULL;
38 ud->name[CLOOG_SCAT] = NULL;
40 return ud;
43 void cloog_union_domain_free(CloogUnionDomain *ud)
45 int i;
46 int j;
48 if (!ud)
49 return;
51 for (i = 0; i < 3; ++i) {
52 if (!ud->name[i])
53 continue;
54 for (j = 0; j < ud->n_name[i]; ++i)
55 free(ud->name[i][j]);
56 free(ud->name[i]);
59 cloog_named_domain_list_free(ud->domain);
61 free(ud);
64 /**
65 * Add a domain with scattering function to the union of domains.
66 * name may be NULL and is duplicated if it is not.
67 * domain and scattering are taken over by the CloogUnionDomain.
68 * scattering may be NULL.
70 CloogUnionDomain *cloog_union_domain_add_domain(CloogUnionDomain *ud,
71 const char *name, CloogDomain *domain, CloogScattering *scattering,
72 void *usr)
74 CloogNamedDomainList *named;
75 int n;
77 if (!ud)
78 return NULL;
80 named = ALLOC(CloogNamedDomainList);
81 if (!named)
82 cloog_die("memory overflow.\n");
84 if (ud->name[CLOOG_ITER])
85 cloog_die("iterator names must be set after adding domains.\n");
86 if (ud->name[CLOOG_SCAT])
87 cloog_die("scattering names must be set after adding domains.\n");
89 n = cloog_domain_dimension(domain);
90 if (n > ud->n_name[CLOOG_ITER])
91 ud->n_name[CLOOG_ITER] = n;
93 if (scattering) {
94 n = cloog_scattering_dimension(scattering, domain);
95 if (n > ud->n_name[CLOOG_SCAT])
96 ud->n_name[CLOOG_SCAT] = n;
99 named->domain = domain;
100 named->scattering = scattering;
101 named->name = name ? strdup(name) : NULL;
102 named->usr = usr;
103 named->next = NULL;
105 *ud->next_domain = named;
106 ud->next_domain = &named->next;
108 return ud;
112 * Set the name of parameter, iterator or scattering dimension
113 * at the specified position. The name is duplicated.
115 CloogUnionDomain *cloog_union_domain_set_name(CloogUnionDomain *ud,
116 enum cloog_dim_type type, int index, const char *name)
118 int i;
120 if (!ud)
121 return ud;
123 if (type != CLOOG_PARAM &&
124 type != CLOOG_ITER &&
125 type != CLOOG_SCAT)
126 cloog_die("invalid dim type\n");
128 if (index < 0 || index >= ud->n_name[type])
129 cloog_die("index out of range\n");
131 if (!ud->name[type]) {
132 ud->name[type] = ALLOCN(char *, ud->n_name[type]);
133 if (!ud->name[type])
134 cloog_die("memory overflow.\n");
135 for (i = 0; i < ud->n_name[type]; ++i)
136 ud->name[type][i] = NULL;
139 ud->name[type][index] = strdup(name);
140 if (!ud->name[type][index])
141 cloog_die("memory overflow.\n");
143 return ud;
146 static char *next_line(FILE *input, char *line, unsigned len)
148 char *p;
150 do {
151 if (!(p = fgets(line, len, input)))
152 return NULL;
153 while (isspace(*p) && *p != '\n')
154 ++p;
155 } while (*p == '#' || *p == '\n');
157 return p;
161 * cloog_scattering_list_read
162 * Read in a list of scattering functions for the nb_statements
163 * domains in loop.
165 static CloogScatteringList *cloog_scattering_list_read(FILE * foo,
166 CloogDomain **domain, int nb_statements, int nb_parameters)
168 int nb_scat = 0;
169 char s[MAX_STRING];
170 CloogScatteringList *list = NULL, **next = &list;
172 /* We read first the number of scattering functions in the list. */
173 do {
174 if (!fgets(s, MAX_STRING, foo))
175 break;
176 } while ((*s=='#' || *s=='\n') || (sscanf(s, " %d", &nb_scat) < 1));
178 if (nb_scat == 0)
179 return NULL;
181 if (nb_scat != nb_statements)
182 cloog_die("wrong number of scattering functions.\n");
184 while (nb_scat--) {
185 *next = (CloogScatteringList *)malloc(sizeof(CloogScatteringList));
186 (*next)->scatt = cloog_domain_read_scattering(*domain, foo);
187 (*next)->next = NULL;
189 next = &(*next)->next;
190 domain++;
192 return list;
195 static CloogUnionDomain *set_names_from_list(CloogUnionDomain *ud,
196 enum cloog_dim_type type, int n, char **names)
198 int i;
200 if (!names)
201 return ud;
203 for (i = 0; i < n; ++i) {
204 ud = cloog_union_domain_set_name(ud, type, i, names[i]);
205 free(names[i]);
207 free(names);
209 return ud;
213 * Fill up a CloogUnionDomain from information in a CLooG input file.
214 * The language and the context are assumed to have been read from
215 * the input file already.
217 CloogUnionDomain *cloog_union_domain_read(FILE *file, int nb_par,
218 CloogOptions *options)
220 int op1, op2, op3;
221 char line[MAX_STRING];
222 CloogDomain **domain;
223 CloogUnionDomain *ud;
224 CloogScatteringList *scatteringl;
225 int i;
226 int n_iter = -1;
227 int n_dom;
228 char **names;
230 ud = cloog_union_domain_alloc(nb_par);
232 names = cloog_names_read_strings(file, nb_par);
233 ud = set_names_from_list(ud, CLOOG_PARAM, nb_par, names);
235 /* We read the number of statements. */
236 if (!next_line(file, line, sizeof(line)))
237 cloog_die("Input error.\n");
238 if (sscanf(line, "%d", &n_dom) != 1)
239 cloog_die("Input error.\n");
241 domain = ALLOCN(CloogDomain *, n_dom);
242 if (!domain)
243 cloog_die("memory overflow.\n");
245 for (i = 0; i < n_dom; ++i) {
246 int dim;
248 domain[i] = cloog_domain_union_read(options->state, file,
249 nb_par);
250 dim = cloog_domain_dimension(domain[i]);
251 if (dim > n_iter)
252 n_iter = dim;
254 /* To read that stupid "0 0 0" line. */
255 if (!next_line(file, line, sizeof(line)))
256 cloog_die("Input error.\n");
257 if (sscanf(line, " %d %d %d", &op1, &op2, &op3) != 3)
258 cloog_die("Input error.\n");
261 /* Reading of the iterator names. */
262 names = cloog_names_read_strings(file, n_iter);
264 /* Reading and putting the scattering data in program structure. */
265 scatteringl = cloog_scattering_list_read(file, domain, n_dom, nb_par);
267 if (scatteringl) {
268 CloogScatteringList *is, *next;
270 if (cloog_scattering_list_lazy_same(scatteringl))
271 cloog_msg(options, CLOOG_WARNING,
272 "some scattering functions are similar.\n");
274 for (i = 0, is = scatteringl; i < n_dom; ++i, is = next) {
275 next = is->next;
276 ud = cloog_union_domain_add_domain(ud, NULL, domain[i],
277 is->scatt, NULL);
278 free(is);
280 } else {
281 for (i = 0; i < n_dom; ++i)
282 ud = cloog_union_domain_add_domain(ud, NULL, domain[i],
283 NULL, NULL);
286 ud = set_names_from_list(ud, CLOOG_ITER, n_iter, names);
288 if (scatteringl) {
289 int n_scat = ud->n_name[CLOOG_SCAT];
290 names = cloog_names_read_strings(file, n_scat);
291 ud = set_names_from_list(ud, CLOOG_SCAT, n_scat, names);
294 free(domain);
296 return ud;