1#include <ctype.h> 2#include <stdio.h> 3#include <stdlib.h> 4#include "../include/cloog/cloog.h" 5 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 12 13#define ALLOC(type) (type*)malloc(sizeof(type)) 14#define ALLOCN(type,n) (type*)malloc((n)*sizeof(type)) 15 16void cloog_named_domain_list_free(CloogNamedDomainList *list) 17{ 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; 25 } 26} 27 28CloogUnionDomain *cloog_union_domain_alloc(int nb_par) 29{ 30 CloogUnionDomain *ud; 31 32 ud = ALLOC(CloogUnionDomain); 33 if (!ud) 34 cloog_die("memory overflow.\n"); 35 36 ud->domain = NULL; 37 ud->next_domain = &ud->domain; 38 39 ud->n_name[CLOOG_PARAM] = nb_par; 40 ud->n_name[CLOOG_ITER] = 0; 41 ud->n_name[CLOOG_SCAT] = 0; 42 43 ud->name[CLOOG_PARAM] = NULL; 44 ud->name[CLOOG_ITER] = NULL; 45 ud->name[CLOOG_SCAT] = NULL; 46 47 return ud; 48} 49 50void cloog_union_domain_free(CloogUnionDomain *ud) 51{ 52 int i; 53 int j; 54 55 if (!ud) 56 return; 57 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]); 64 } 65 66 cloog_named_domain_list_free(ud->domain); 67 68 free(ud); 69} 70 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. 76 */ 77CloogUnionDomain *cloog_union_domain_add_domain(CloogUnionDomain *ud, 78 const char *name, CloogDomain *domain, CloogScattering *scattering, 79 void *usr) 80{ 81 CloogNamedDomainList *named; 82 int n; 83 84 if (!ud) 85 return NULL; 86 87 named = ALLOC(CloogNamedDomainList); 88 if (!named) 89 cloog_die("memory overflow.\n"); 90 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"); 95 96 n = cloog_domain_dimension(domain); 97 if (n > ud->n_name[CLOOG_ITER]) 98 ud->n_name[CLOOG_ITER] = n; 99 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; 104 } 105 106 named->domain = domain; 107 named->scattering = scattering; 108 named->name = name ? strdup(name) : NULL; 109 named->usr = usr; 110 named->next = NULL; 111 112 *ud->next_domain = named; 113 ud->next_domain = &named->next; 114 115 return ud; 116} 117 118/** 119 * Set the name of parameter, iterator or scattering dimension 120 * at the specified position. The name is duplicated. 121 */ 122CloogUnionDomain *cloog_union_domain_set_name(CloogUnionDomain *ud, 123 enum cloog_dim_type type, int index, const char *name) 124{ 125 int i; 126 127 if (!ud) 128 return ud; 129 130 if (type != CLOOG_PARAM && 131 type != CLOOG_ITER && 132 type != CLOOG_SCAT) 133 cloog_die("invalid dim type\n"); 134 135 if (index < 0 || index >= ud->n_name[type]) 136 cloog_die("index out of range\n"); 137 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; 144 } 145 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"); 150 151 return ud; 152} 153 154static char *next_line(FILE *input, char *line, unsigned len) 155{ 156 char *p; 157 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'); 164 165 return p; 166} 167 168/** 169 * cloog_scattering_list_read 170 * Read in a list of scattering functions for the nb_statements 171 * domains in loop. 172 */ 173static CloogScatteringList *cloog_scattering_list_read(FILE * foo, 174 CloogDomain **domain, int nb_statements, int nb_parameters) 175{ 176 int nb_scat = 0; 177 char s[MAX_STRING]; 178 CloogScatteringList *list = NULL, **next = &list; 179 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)); 185 186 if (nb_scat == 0) 187 return NULL; 188 189 if (nb_scat != nb_statements) 190 cloog_die("wrong number of scattering functions.\n"); 191 192 while (nb_scat--) { 193 *next = (CloogScatteringList *)malloc(sizeof(CloogScatteringList)); 194 (*next)->scatt = cloog_domain_read_scattering(*domain, foo); 195 (*next)->next = NULL; 196 197 next = &(*next)->next; 198 domain++; 199 } 200 return list; 201} 202 203static CloogUnionDomain *set_names_from_list(CloogUnionDomain *ud, 204 enum cloog_dim_type type, int n, char **names) 205{ 206 int i; 207 208 if (!names) 209 return ud; 210 211 for (i = 0; i < n; ++i) { 212 ud = cloog_union_domain_set_name(ud, type, i, names[i]); 213 free(names[i]); 214 } 215 free(names); 216 217 return ud; 218} 219 220/** 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. 224 */ 225CloogUnionDomain *cloog_union_domain_read(FILE *file, int nb_par, 226 CloogOptions *options) 227{ 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; 237 238 ud = cloog_union_domain_alloc(nb_par); 239 240 names = cloog_names_read_strings(file, nb_par); 241 ud = set_names_from_list(ud, CLOOG_PARAM, nb_par, names); 242 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"); 248 249 domain = ALLOCN(CloogDomain *, n_dom); 250 if (!domain) 251 cloog_die("memory overflow.\n"); 252 253 for (i = 0; i < n_dom; ++i) { 254 int dim; 255 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; 261 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"); 267 } 268 269 /* Reading of the iterator names. */ 270 names = cloog_names_read_strings(file, n_iter); 271 272 /* Reading and putting the scattering data in program structure. */ 273 scatteringl = cloog_scattering_list_read(file, domain, n_dom, nb_par); 274 275 if (scatteringl) { 276 CloogScatteringList *is, *next; 277 278 if (cloog_scattering_list_lazy_same(scatteringl)) 279 cloog_msg(options, CLOOG_WARNING, 280 "some scattering functions are similar.\n"); 281 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); 287 } 288 } else { 289 for (i = 0; i < n_dom; ++i) 290 ud = cloog_union_domain_add_domain(ud, NULL, domain[i], 291 NULL, NULL); 292 } 293 294 ud = set_names_from_list(ud, CLOOG_ITER, n_iter, names); 295 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); 300 } 301 302 free(domain); 303 304 return ud; 305} 306 307 308#ifdef OSL_SUPPORT 309/** 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. 315 */ 316CloogUnionDomain *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; 325 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); 329 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]); 335 } 336 } 337 338 /* - Set each statement (domain/scattering). 339 * Since CLooG requires all number of scattering dimensions to be 340 * equal, we normalize them first. 341 */ 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; 351 } 352 osl_scop_free(normalized); 353 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]); 361 } 362 } 363 364 return ud; 365} 366#endif 367