cloog_domain_simple_convex: always compute simple hull
[cloog.git] / source / union_domain.c
blob32b00876efdaad9f50bdd7579e5743908827b335
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 free(ud->name[type][index]);
140 ud->name[type][index] = strdup(name);
141 if (!ud->name[type][index])
142 cloog_die("memory overflow.\n");
144 return ud;
147 static char *next_line(FILE *input, char *line, unsigned len)
149 char *p;
151 do {
152 if (!(p = fgets(line, len, input)))
153 return NULL;
154 while (isspace(*p) && *p != '\n')
155 ++p;
156 } while (*p == '#' || *p == '\n');
158 return p;
162 * cloog_scattering_list_read
163 * Read in a list of scattering functions for the nb_statements
164 * domains in loop.
166 static CloogScatteringList *cloog_scattering_list_read(FILE * foo,
167 CloogDomain **domain, int nb_statements, int nb_parameters)
169 int nb_scat = 0;
170 char s[MAX_STRING];
171 CloogScatteringList *list = NULL, **next = &list;
173 /* We read first the number of scattering functions in the list. */
174 do {
175 if (!fgets(s, MAX_STRING, foo))
176 break;
177 } while ((*s=='#' || *s=='\n') || (sscanf(s, " %d", &nb_scat) < 1));
179 if (nb_scat == 0)
180 return NULL;
182 if (nb_scat != nb_statements)
183 cloog_die("wrong number of scattering functions.\n");
185 while (nb_scat--) {
186 *next = (CloogScatteringList *)malloc(sizeof(CloogScatteringList));
187 (*next)->scatt = cloog_domain_read_scattering(*domain, foo);
188 (*next)->next = NULL;
190 next = &(*next)->next;
191 domain++;
193 return list;
196 static CloogUnionDomain *set_names_from_list(CloogUnionDomain *ud,
197 enum cloog_dim_type type, int n, char **names)
199 int i;
201 if (!names)
202 return ud;
204 for (i = 0; i < n; ++i) {
205 ud = cloog_union_domain_set_name(ud, type, i, names[i]);
206 free(names[i]);
208 free(names);
210 return ud;
214 * Fill up a CloogUnionDomain from information in a CLooG input file.
215 * The language and the context are assumed to have been read from
216 * the input file already.
218 CloogUnionDomain *cloog_union_domain_read(FILE *file, int nb_par,
219 CloogOptions *options)
221 int op1, op2, op3;
222 char line[MAX_STRING];
223 CloogDomain **domain;
224 CloogUnionDomain *ud;
225 CloogScatteringList *scatteringl;
226 int i;
227 int n_iter = -1;
228 int n_dom;
229 char **names;
231 ud = cloog_union_domain_alloc(nb_par);
233 names = cloog_names_read_strings(file, nb_par);
234 ud = set_names_from_list(ud, CLOOG_PARAM, nb_par, names);
236 /* We read the number of statements. */
237 if (!next_line(file, line, sizeof(line)))
238 cloog_die("Input error.\n");
239 if (sscanf(line, "%d", &n_dom) != 1)
240 cloog_die("Input error.\n");
242 domain = ALLOCN(CloogDomain *, n_dom);
243 if (!domain)
244 cloog_die("memory overflow.\n");
246 for (i = 0; i < n_dom; ++i) {
247 int dim;
249 domain[i] = cloog_domain_union_read(options->state, file,
250 nb_par);
251 dim = cloog_domain_dimension(domain[i]);
252 if (dim > n_iter)
253 n_iter = dim;
255 /* To read that stupid "0 0 0" line. */
256 if (!next_line(file, line, sizeof(line)))
257 cloog_die("Input error.\n");
258 if (sscanf(line, " %d %d %d", &op1, &op2, &op3) != 3)
259 cloog_die("Input error.\n");
262 /* Reading of the iterator names. */
263 names = cloog_names_read_strings(file, n_iter);
265 /* Reading and putting the scattering data in program structure. */
266 scatteringl = cloog_scattering_list_read(file, domain, n_dom, nb_par);
268 if (scatteringl) {
269 CloogScatteringList *is, *next;
271 if (cloog_scattering_list_lazy_same(scatteringl))
272 cloog_msg(options, CLOOG_WARNING,
273 "some scattering functions are similar.\n");
275 for (i = 0, is = scatteringl; i < n_dom; ++i, is = next) {
276 next = is->next;
277 ud = cloog_union_domain_add_domain(ud, NULL, domain[i],
278 is->scatt, NULL);
279 free(is);
281 } else {
282 for (i = 0; i < n_dom; ++i)
283 ud = cloog_union_domain_add_domain(ud, NULL, domain[i],
284 NULL, NULL);
287 ud = set_names_from_list(ud, CLOOG_ITER, n_iter, names);
289 if (scatteringl) {
290 int n_scat = ud->n_name[CLOOG_SCAT];
291 names = cloog_names_read_strings(file, n_scat);
292 ud = set_names_from_list(ud, CLOOG_SCAT, n_scat, names);
295 free(domain);
297 return ud;