CLooG 0.18.4
[cloog.git] / source / union_domain.c
blobed9c91a166ef0bed76a17793561549b3ea28c3a7
1 #include <ctype.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "../include/cloog/cloog.h"
6 #ifdef OSL_SUPPORT
7 #include <osl/strings.h>
8 #include <osl/extensions/scatnames.h>
9 #include <osl/statement.h>
10 #include <osl/scop.h>
11 #endif
13 #define ALLOC(type) (type*)malloc(sizeof(type))
14 #define ALLOCN(type,n) (type*)malloc((n)*sizeof(type))
16 void cloog_named_domain_list_free(CloogNamedDomainList *list)
18 while (list != NULL) {
19 CloogNamedDomainList *temp = list->next;
20 cloog_domain_free(list->domain);
21 cloog_scattering_free(list->scattering);
22 free(list->name);
23 free(list);
24 list = temp;
28 CloogUnionDomain *cloog_union_domain_alloc(int nb_par)
30 CloogUnionDomain *ud;
32 ud = ALLOC(CloogUnionDomain);
33 if (!ud)
34 cloog_die("memory overflow.\n");
36 ud->domain = NULL;
37 ud->next_domain = &ud->domain;
39 ud->n_name[CLOOG_PARAM] = nb_par;
40 ud->n_name[CLOOG_ITER] = 0;
41 ud->n_name[CLOOG_SCAT] = 0;
43 ud->name[CLOOG_PARAM] = NULL;
44 ud->name[CLOOG_ITER] = NULL;
45 ud->name[CLOOG_SCAT] = NULL;
47 return ud;
50 void cloog_union_domain_free(CloogUnionDomain *ud)
52 int i;
53 int j;
55 if (!ud)
56 return;
58 for (i = 0; i < 3; ++i) {
59 if (!ud->name[i])
60 continue;
61 for (j = 0; j < ud->n_name[i]; ++j)
62 free(ud->name[i][j]);
63 free(ud->name[i]);
66 cloog_named_domain_list_free(ud->domain);
68 free(ud);
71 /**
72 * Add a domain with scattering function to the union of domains.
73 * name may be NULL and is duplicated if it is not.
74 * domain and scattering are taken over by the CloogUnionDomain.
75 * scattering may be NULL.
77 CloogUnionDomain *cloog_union_domain_add_domain(CloogUnionDomain *ud,
78 const char *name, CloogDomain *domain, CloogScattering *scattering,
79 void *usr)
81 CloogNamedDomainList *named;
82 int n;
84 if (!ud)
85 return NULL;
87 named = ALLOC(CloogNamedDomainList);
88 if (!named)
89 cloog_die("memory overflow.\n");
91 if (ud->name[CLOOG_ITER])
92 cloog_die("iterator names must be set after adding domains.\n");
93 if (ud->name[CLOOG_SCAT])
94 cloog_die("scattering names must be set after adding domains.\n");
96 n = cloog_domain_dimension(domain);
97 if (n > ud->n_name[CLOOG_ITER])
98 ud->n_name[CLOOG_ITER] = n;
100 if (scattering) {
101 n = cloog_scattering_dimension(scattering, domain);
102 if (n > ud->n_name[CLOOG_SCAT])
103 ud->n_name[CLOOG_SCAT] = n;
106 named->domain = domain;
107 named->scattering = scattering;
108 named->name = name ? strdup(name) : NULL;
109 named->usr = usr;
110 named->next = NULL;
112 *ud->next_domain = named;
113 ud->next_domain = &named->next;
115 return ud;
119 * Set the name of parameter, iterator or scattering dimension
120 * at the specified position. The name is duplicated.
122 CloogUnionDomain *cloog_union_domain_set_name(CloogUnionDomain *ud,
123 enum cloog_dim_type type, int index, const char *name)
125 int i;
127 if (!ud)
128 return ud;
130 if (type != CLOOG_PARAM &&
131 type != CLOOG_ITER &&
132 type != CLOOG_SCAT)
133 cloog_die("invalid dim type\n");
135 if (index < 0 || index >= ud->n_name[type])
136 cloog_die("index out of range\n");
138 if (!ud->name[type]) {
139 ud->name[type] = ALLOCN(char *, ud->n_name[type]);
140 if (!ud->name[type])
141 cloog_die("memory overflow.\n");
142 for (i = 0; i < ud->n_name[type]; ++i)
143 ud->name[type][i] = NULL;
146 free(ud->name[type][index]);
147 ud->name[type][index] = strdup(name);
148 if (!ud->name[type][index])
149 cloog_die("memory overflow.\n");
151 return ud;
154 static char *next_line(FILE *input, char *line, unsigned len)
156 char *p;
158 do {
159 if (!(p = fgets(line, len, input)))
160 return NULL;
161 while (isspace(*p) && *p != '\n')
162 ++p;
163 } while (*p == '#' || *p == '\n');
165 return p;
169 * cloog_scattering_list_read
170 * Read in a list of scattering functions for the nb_statements
171 * domains in loop.
173 static CloogScatteringList *cloog_scattering_list_read(FILE * foo,
174 CloogDomain **domain, int nb_statements, int nb_parameters)
176 int nb_scat = 0;
177 char s[MAX_STRING];
178 CloogScatteringList *list = NULL, **next = &list;
180 /* We read first the number of scattering functions in the list. */
181 do {
182 if (!fgets(s, MAX_STRING, foo))
183 break;
184 } while ((*s=='#' || *s=='\n') || (sscanf(s, " %d", &nb_scat) < 1));
186 if (nb_scat == 0)
187 return NULL;
189 if (nb_scat != nb_statements)
190 cloog_die("wrong number of scattering functions.\n");
192 while (nb_scat--) {
193 *next = (CloogScatteringList *)malloc(sizeof(CloogScatteringList));
194 (*next)->scatt = cloog_domain_read_scattering(*domain, foo);
195 (*next)->next = NULL;
197 next = &(*next)->next;
198 domain++;
200 return list;
203 static CloogUnionDomain *set_names_from_list(CloogUnionDomain *ud,
204 enum cloog_dim_type type, int n, char **names)
206 int i;
208 if (!names)
209 return ud;
211 for (i = 0; i < n; ++i) {
212 ud = cloog_union_domain_set_name(ud, type, i, names[i]);
213 free(names[i]);
215 free(names);
217 return ud;
221 * Fill up a CloogUnionDomain from information in a CLooG input file.
222 * The language and the context are assumed to have been read from
223 * the input file already.
225 CloogUnionDomain *cloog_union_domain_read(FILE *file, int nb_par,
226 CloogOptions *options)
228 int op1, op2, op3;
229 char line[MAX_STRING];
230 CloogDomain **domain;
231 CloogUnionDomain *ud;
232 CloogScatteringList *scatteringl;
233 int i;
234 int n_iter = -1;
235 int n_dom;
236 char **names;
238 ud = cloog_union_domain_alloc(nb_par);
240 names = cloog_names_read_strings(file, nb_par);
241 ud = set_names_from_list(ud, CLOOG_PARAM, nb_par, names);
243 /* We read the number of statements. */
244 if (!next_line(file, line, sizeof(line)))
245 cloog_die("Input error.\n");
246 if (sscanf(line, "%d", &n_dom) != 1)
247 cloog_die("Input error.\n");
249 domain = ALLOCN(CloogDomain *, n_dom);
250 if (!domain)
251 cloog_die("memory overflow.\n");
253 for (i = 0; i < n_dom; ++i) {
254 int dim;
256 domain[i] = cloog_domain_union_read(options->state, file,
257 nb_par);
258 dim = cloog_domain_dimension(domain[i]);
259 if (dim > n_iter)
260 n_iter = dim;
262 /* To read that stupid "0 0 0" line. */
263 if (!next_line(file, line, sizeof(line)))
264 cloog_die("Input error.\n");
265 if (sscanf(line, " %d %d %d", &op1, &op2, &op3) != 3)
266 cloog_die("Input error.\n");
269 /* Reading of the iterator names. */
270 names = cloog_names_read_strings(file, n_iter);
272 /* Reading and putting the scattering data in program structure. */
273 scatteringl = cloog_scattering_list_read(file, domain, n_dom, nb_par);
275 if (scatteringl) {
276 CloogScatteringList *is, *next;
278 if (cloog_scattering_list_lazy_same(scatteringl))
279 cloog_msg(options, CLOOG_WARNING,
280 "some scattering functions are similar.\n");
282 for (i = 0, is = scatteringl; i < n_dom; ++i, is = next) {
283 next = is->next;
284 ud = cloog_union_domain_add_domain(ud, NULL, domain[i],
285 is->scatt, NULL);
286 free(is);
288 } else {
289 for (i = 0; i < n_dom; ++i)
290 ud = cloog_union_domain_add_domain(ud, NULL, domain[i],
291 NULL, NULL);
294 ud = set_names_from_list(ud, CLOOG_ITER, n_iter, names);
296 if (scatteringl) {
297 int n_scat = ud->n_name[CLOOG_SCAT];
298 names = cloog_names_read_strings(file, n_scat);
299 ud = set_names_from_list(ud, CLOOG_SCAT, n_scat, names);
302 free(domain);
304 return ud;
308 #ifdef OSL_SUPPORT
310 * Extracts a CloogUnionDomain from an openscop scop (the CloogUnionDomain
311 * corresponds more or less to the openscop statement).
312 * \param[in,out] state CLooG state.
313 * \param[in] scop OpenScop scop to convert.
314 * \return A new CloogUnionDomain corresponding the input OpenScop scop.
316 CloogUnionDomain *cloog_union_domain_from_osl_scop(CloogState *state,
317 osl_scop_p scop) {
318 int i, nb_parameters;
319 CloogDomain *domain = NULL;
320 CloogScattering *scattering = NULL;
321 CloogUnionDomain *ud = NULL;
322 osl_scop_p normalized;
323 osl_statement_p statement;
324 osl_scatnames_p scatnames;
326 /* Set the union of domains. */
327 nb_parameters = (scop->context == NULL) ? 0 : scop->context->nb_parameters;
328 ud = cloog_union_domain_alloc(nb_parameters);
330 /* - Set the parameter names. */
331 if (osl_generic_has_URI(scop->parameters, OSL_URI_STRINGS)) {
332 for (i = 0; i < osl_strings_size(scop->parameters->data); i++) {
333 ud = cloog_union_domain_set_name(ud, CLOOG_PARAM, i,
334 ((osl_strings_p)(scop->parameters->data))->string[i]);
338 /* - Set each statement (domain/scattering).
339 * Since CLooG requires all number of scattering dimensions to be
340 * equal, we normalize them first.
342 normalized = osl_scop_clone(scop);
343 osl_scop_normalize_scattering(normalized);
344 statement = normalized->statement;
345 while(statement != NULL) {
346 domain = cloog_domain_from_osl_relation(state, statement->domain);
347 scattering = cloog_scattering_from_osl_relation(state,
348 statement->scattering);
349 ud = cloog_union_domain_add_domain(ud, NULL, domain, scattering, NULL);
350 statement = statement->next;
352 osl_scop_free(normalized);
354 /* - Set the scattering dimension names. */
355 scatnames = osl_generic_lookup(scop->extension, OSL_URI_SCATNAMES);
356 if ((scatnames != NULL) && (scatnames->names != NULL)) {
357 for (i = 0; (i < osl_strings_size(scatnames->names)) &&
358 (i < ud->n_name[CLOOG_SCAT]); i++) {
359 ud = cloog_union_domain_set_name(ud, CLOOG_SCAT, i,
360 scatnames->names->string[i]);
364 return ud;
366 #endif