Add OpenScop support
[cloog.git] / source / union_domain.c
blobab9f2dab558c47a874bc43527e0b1839ffc2d7b1
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/statement.h>
8 #include <osl/scop.h>
9 #endif
11 #define ALLOC(type) (type*)malloc(sizeof(type))
12 #define ALLOCN(type,n) (type*)malloc((n)*sizeof(type))
14 void cloog_named_domain_list_free(CloogNamedDomainList *list)
16 while (list != NULL) {
17 CloogNamedDomainList *temp = list->next;
18 cloog_domain_free(list->domain);
19 cloog_scattering_free(list->scattering);
20 free(list->name);
21 free(list);
22 list = temp;
26 CloogUnionDomain *cloog_union_domain_alloc(int nb_par)
28 CloogUnionDomain *ud;
30 ud = ALLOC(CloogUnionDomain);
31 if (!ud)
32 cloog_die("memory overflow.\n");
34 ud->domain = NULL;
35 ud->next_domain = &ud->domain;
37 ud->n_name[CLOOG_PARAM] = nb_par;
38 ud->n_name[CLOOG_ITER] = 0;
39 ud->n_name[CLOOG_SCAT] = 0;
41 ud->name[CLOOG_PARAM] = NULL;
42 ud->name[CLOOG_ITER] = NULL;
43 ud->name[CLOOG_SCAT] = NULL;
45 return ud;
48 void cloog_union_domain_free(CloogUnionDomain *ud)
50 int i;
51 int j;
53 if (!ud)
54 return;
56 for (i = 0; i < 3; ++i) {
57 if (!ud->name[i])
58 continue;
59 for (j = 0; j < ud->n_name[i]; ++i)
60 free(ud->name[i][j]);
61 free(ud->name[i]);
64 cloog_named_domain_list_free(ud->domain);
66 free(ud);
69 /**
70 * Add a domain with scattering function to the union of domains.
71 * name may be NULL and is duplicated if it is not.
72 * domain and scattering are taken over by the CloogUnionDomain.
73 * scattering may be NULL.
75 CloogUnionDomain *cloog_union_domain_add_domain(CloogUnionDomain *ud,
76 const char *name, CloogDomain *domain, CloogScattering *scattering,
77 void *usr)
79 CloogNamedDomainList *named;
80 int n;
82 if (!ud)
83 return NULL;
85 named = ALLOC(CloogNamedDomainList);
86 if (!named)
87 cloog_die("memory overflow.\n");
89 if (ud->name[CLOOG_ITER])
90 cloog_die("iterator names must be set after adding domains.\n");
91 if (ud->name[CLOOG_SCAT])
92 cloog_die("scattering names must be set after adding domains.\n");
94 n = cloog_domain_dimension(domain);
95 if (n > ud->n_name[CLOOG_ITER])
96 ud->n_name[CLOOG_ITER] = n;
98 if (scattering) {
99 n = cloog_scattering_dimension(scattering, domain);
100 if (n > ud->n_name[CLOOG_SCAT])
101 ud->n_name[CLOOG_SCAT] = n;
104 named->domain = domain;
105 named->scattering = scattering;
106 named->name = name ? strdup(name) : NULL;
107 named->usr = usr;
108 named->next = NULL;
110 *ud->next_domain = named;
111 ud->next_domain = &named->next;
113 return ud;
117 * Set the name of parameter, iterator or scattering dimension
118 * at the specified position. The name is duplicated.
120 CloogUnionDomain *cloog_union_domain_set_name(CloogUnionDomain *ud,
121 enum cloog_dim_type type, int index, const char *name)
123 int i;
125 if (!ud)
126 return ud;
128 if (type != CLOOG_PARAM &&
129 type != CLOOG_ITER &&
130 type != CLOOG_SCAT)
131 cloog_die("invalid dim type\n");
133 if (index < 0 || index >= ud->n_name[type])
134 cloog_die("index out of range\n");
136 if (!ud->name[type]) {
137 ud->name[type] = ALLOCN(char *, ud->n_name[type]);
138 if (!ud->name[type])
139 cloog_die("memory overflow.\n");
140 for (i = 0; i < ud->n_name[type]; ++i)
141 ud->name[type][i] = NULL;
144 free(ud->name[type][index]);
145 ud->name[type][index] = strdup(name);
146 if (!ud->name[type][index])
147 cloog_die("memory overflow.\n");
149 return ud;
152 static char *next_line(FILE *input, char *line, unsigned len)
154 char *p;
156 do {
157 if (!(p = fgets(line, len, input)))
158 return NULL;
159 while (isspace(*p) && *p != '\n')
160 ++p;
161 } while (*p == '#' || *p == '\n');
163 return p;
167 * cloog_scattering_list_read
168 * Read in a list of scattering functions for the nb_statements
169 * domains in loop.
171 static CloogScatteringList *cloog_scattering_list_read(FILE * foo,
172 CloogDomain **domain, int nb_statements, int nb_parameters)
174 int nb_scat = 0;
175 char s[MAX_STRING];
176 CloogScatteringList *list = NULL, **next = &list;
178 /* We read first the number of scattering functions in the list. */
179 do {
180 if (!fgets(s, MAX_STRING, foo))
181 break;
182 } while ((*s=='#' || *s=='\n') || (sscanf(s, " %d", &nb_scat) < 1));
184 if (nb_scat == 0)
185 return NULL;
187 if (nb_scat != nb_statements)
188 cloog_die("wrong number of scattering functions.\n");
190 while (nb_scat--) {
191 *next = (CloogScatteringList *)malloc(sizeof(CloogScatteringList));
192 (*next)->scatt = cloog_domain_read_scattering(*domain, foo);
193 (*next)->next = NULL;
195 next = &(*next)->next;
196 domain++;
198 return list;
201 static CloogUnionDomain *set_names_from_list(CloogUnionDomain *ud,
202 enum cloog_dim_type type, int n, char **names)
204 int i;
206 if (!names)
207 return ud;
209 for (i = 0; i < n; ++i) {
210 ud = cloog_union_domain_set_name(ud, type, i, names[i]);
211 free(names[i]);
213 free(names);
215 return ud;
219 * Fill up a CloogUnionDomain from information in a CLooG input file.
220 * The language and the context are assumed to have been read from
221 * the input file already.
223 CloogUnionDomain *cloog_union_domain_read(FILE *file, int nb_par,
224 CloogOptions *options)
226 int op1, op2, op3;
227 char line[MAX_STRING];
228 CloogDomain **domain;
229 CloogUnionDomain *ud;
230 CloogScatteringList *scatteringl;
231 int i;
232 int n_iter = -1;
233 int n_dom;
234 char **names;
236 ud = cloog_union_domain_alloc(nb_par);
238 names = cloog_names_read_strings(file, nb_par);
239 ud = set_names_from_list(ud, CLOOG_PARAM, nb_par, names);
241 /* We read the number of statements. */
242 if (!next_line(file, line, sizeof(line)))
243 cloog_die("Input error.\n");
244 if (sscanf(line, "%d", &n_dom) != 1)
245 cloog_die("Input error.\n");
247 domain = ALLOCN(CloogDomain *, n_dom);
248 if (!domain)
249 cloog_die("memory overflow.\n");
251 for (i = 0; i < n_dom; ++i) {
252 int dim;
254 domain[i] = cloog_domain_union_read(options->state, file,
255 nb_par);
256 dim = cloog_domain_dimension(domain[i]);
257 if (dim > n_iter)
258 n_iter = dim;
260 /* To read that stupid "0 0 0" line. */
261 if (!next_line(file, line, sizeof(line)))
262 cloog_die("Input error.\n");
263 if (sscanf(line, " %d %d %d", &op1, &op2, &op3) != 3)
264 cloog_die("Input error.\n");
267 /* Reading of the iterator names. */
268 names = cloog_names_read_strings(file, n_iter);
270 /* Reading and putting the scattering data in program structure. */
271 scatteringl = cloog_scattering_list_read(file, domain, n_dom, nb_par);
273 if (scatteringl) {
274 CloogScatteringList *is, *next;
276 if (cloog_scattering_list_lazy_same(scatteringl))
277 cloog_msg(options, CLOOG_WARNING,
278 "some scattering functions are similar.\n");
280 for (i = 0, is = scatteringl; i < n_dom; ++i, is = next) {
281 next = is->next;
282 ud = cloog_union_domain_add_domain(ud, NULL, domain[i],
283 is->scatt, NULL);
284 free(is);
286 } else {
287 for (i = 0; i < n_dom; ++i)
288 ud = cloog_union_domain_add_domain(ud, NULL, domain[i],
289 NULL, NULL);
292 ud = set_names_from_list(ud, CLOOG_ITER, n_iter, names);
294 if (scatteringl) {
295 int n_scat = ud->n_name[CLOOG_SCAT];
296 names = cloog_names_read_strings(file, n_scat);
297 ud = set_names_from_list(ud, CLOOG_SCAT, n_scat, names);
300 free(domain);
302 return ud;
306 #ifdef OSL_SUPPORT
308 * Extracts a CloogUnionDomain from an openscop scop (the CloogUnionDomain
309 * corresponds more or less to the openscop statement).
310 * \param[in,out] state CLooG state.
311 * \param[in] scop OpenScop scop to convert.
312 * \return A new CloogUnionDomain corresponding the input OpenScop scop.
314 CloogUnionDomain *cloog_union_domain_from_osl_scop(CloogState *state,
315 osl_scop_p scop) {
316 int i, nb_parameters;
317 CloogDomain *domain = NULL;
318 CloogScattering *scattering = NULL;
319 CloogUnionDomain *ud = NULL;
320 osl_scop_p normalized;
321 osl_statement_p statement;
323 /* Set the union of domains. */
324 nb_parameters = (scop->context == NULL) ? 0 : scop->context->nb_parameters;
325 ud = cloog_union_domain_alloc(nb_parameters);
327 /* - Set the parameter names. */
328 if (osl_generic_has_URI(scop->parameters, OSL_URI_STRINGS)) {
329 for (i = 0; i < osl_strings_size(scop->parameters->data); i++) {
330 ud = cloog_union_domain_set_name(ud, CLOOG_PARAM, i,
331 ((osl_strings_p)(scop->parameters->data))->string[i]);
335 /* - Set each statement (domain/scattering).
336 * Since CLooG requires all number of scattering dimensions to be
337 * equal, we normalize them first.
339 normalized = osl_scop_clone(scop);
340 osl_scop_normalize_scattering(normalized);
341 statement = normalized->statement;
342 while(statement != NULL) {
343 domain = cloog_domain_from_osl_relation(state, statement->domain);
344 scattering = cloog_scattering_from_osl_relation(state,
345 statement->scattering);
346 ud = cloog_union_domain_add_domain(ud, NULL, domain, scattering, NULL);
347 statement = statement->next;
349 osl_scop_free(normalized);
351 return ud;
353 #endif