1 2 /**-------------------------------------------------------------------** 3 ** CLooG ** 4 **-------------------------------------------------------------------** 5 ** names.c ** 6 **-------------------------------------------------------------------** 7 ** First version: august 1st 2002 ** 8 **-------------------------------------------------------------------**/ 9 10 11/****************************************************************************** 12 * CLooG : the Chunky Loop Generator (experimental) * 13 ****************************************************************************** 14 * * 15 * Copyright (C) 2002-2005 Cedric Bastoul * 16 * * 17 * This library is free software; you can redistribute it and/or * 18 * modify it under the terms of the GNU Lesser General Public * 19 * License as published by the Free Software Foundation; either * 20 * version 2.1 of the License, or (at your option) any later version. * 21 * * 22 * This library is distributed in the hope that it will be useful, * 23 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 25 * Lesser General Public License for more details. * 26 * * 27 * You should have received a copy of the GNU Lesser General Public * 28 * License along with this library; if not, write to the Free Software * 29 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 30 * Boston, MA 02110-1301 USA * 31 * * 32 * CLooG, the Chunky Loop Generator * 33 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr * 34 * * 35 ******************************************************************************/ 36/* CAUTION: the english used for comments is probably the worst you ever read, 37 * please feel free to correct and improve it ! 38 */ 39 40 41# include <stdlib.h> 42# include <stdio.h> 43# include <ctype.h> 44# include "../include/cloog/cloog.h" 45 46 47/****************************************************************************** 48 * Structure display function * 49 ******************************************************************************/ 50 51 52/** 53 * cloog_names_print function: 54 * this function is a human-friendly way to display the CloogNames data 55 * structure, it shows all the different fields and includes an indentation 56 * level (level) in order to work with others print_structure functions. 57 * - July 1st 2005: first version based on the old cloog_names_print function, 58 * it was the first modification in this file since two years ! 59 */ 60void cloog_names_print_structure(FILE * file, CloogNames * names, int level) 61{ int i ; 62 63 /* Go to the right level. */ 64 for (i=0; i<level; i++) 65 fprintf(file,"|\t") ; 66 67 if (names != NULL) 68 { fprintf(file,"+-- CloogNames\n") ; 69 70 /* A blank line. */ 71 for (i=0; i<=level+1; i++) 72 fprintf(file,"|\t") ; 73 fprintf(file,"\n") ; 74 75 /* Print the scalar dimension number. */ 76 for (i=0; i<=level; i++) 77 fprintf(file,"|\t") ; 78 fprintf(file,"Scalar dimension number ---: %d\n",names->nb_scalars) ; 79 80 /* A blank line. */ 81 for (i=0; i<=level+1; i++) 82 fprintf(file,"|\t") ; 83 fprintf(file,"\n") ; 84 85 /* Print the scalar iterators. */ 86 for (i=0; i<=level; i++) 87 fprintf(file,"|\t") ; 88 if (names->nb_scalars > 0) 89 { fprintf(file,"+-- Scalar iterator strings:") ; 90 for (i=0;i<names->nb_scalars;i++) 91 fprintf(file," %s",names->scalars[i]) ; 92 fprintf(file,"\n") ; 93 } 94 else 95 fprintf(file,"+-- No scalar string\n") ; 96 97 /* A blank line. */ 98 for (i=0; i<=level+1; i++) 99 fprintf(file,"|\t") ; 100 fprintf(file,"\n") ; 101 102 /* Print the scattering dimension number. */ 103 for (i=0; i<=level; i++) 104 fprintf(file,"|\t") ; 105 fprintf(file,"Scattering dimension number: %d\n",names->nb_scattering) ; 106 107 /* A blank line. */ 108 for (i=0; i<=level+1; i++) 109 fprintf(file,"|\t") ; 110 fprintf(file,"\n") ; 111 112 /* Print the scattering iterators. */ 113 for (i=0; i<=level; i++) 114 fprintf(file,"|\t") ; 115 if (names->nb_scattering > 0) 116 { fprintf(file,"+-- Scattering strings ----:") ; 117 for (i=0;i<names->nb_scattering;i++) 118 fprintf(file," %s",names->scattering[i]) ; 119 fprintf(file,"\n") ; 120 } 121 else 122 fprintf(file,"+-- No scattering string\n") ; 123 124 /* A blank line. */ 125 for (i=0; i<=level+1; i++) 126 fprintf(file,"|\t") ; 127 fprintf(file,"\n") ; 128 129 /* Print the iterator number. */ 130 for (i=0; i<=level; i++) 131 fprintf(file,"|\t") ; 132 fprintf(file,"Iterator number -----------: %d\n",names->nb_iterators) ; 133 134 /* A blank line. */ 135 for (i=0; i<=level+1; i++) 136 fprintf(file,"|\t") ; 137 fprintf(file,"\n") ; 138 139 /* Print the iterators. */ 140 for (i=0; i<=level; i++) 141 fprintf(file,"|\t") ; 142 if (names->nb_iterators > 0) 143 { fprintf(file,"+-- Iterator strings ------:") ; 144 for (i=0;i<names->nb_iterators;i++) 145 fprintf(file," %s",names->iterators[i]) ; 146 fprintf(file,"\n") ; 147 } 148 else 149 fprintf(file,"+-- No iterators\n") ; 150 151 /* A blank line. */ 152 for (i=0; i<=level+1; i++) 153 fprintf(file,"|\t") ; 154 fprintf(file,"\n") ; 155 156 /* Print the parameter number. */ 157 for (i=0; i<=level; i++) 158 fprintf(file,"|\t") ; 159 fprintf(file,"Parameter number ----------: %d\n",names->nb_parameters) ; 160 161 /* A blank line. */ 162 for (i=0; i<=level+1; i++) 163 fprintf(file,"|\t") ; 164 fprintf(file,"\n") ; 165 166 /* Print the parameters. */ 167 for (i=0; i<=level; i++) 168 fprintf(file,"|\t") ; 169 if (names->nb_parameters > 0) 170 { fprintf(file,"+-- Parameter strings -----:") ; 171 for (i=0;i<names->nb_parameters;i++) 172 fprintf(file," %s",names->parameters[i]) ; 173 fprintf(file,"\n") ; 174 } 175 else 176 fprintf(file,"No parameters\n") ; 177 178 } 179 else 180 fprintf(file,"+-- No CloogNames\n") ; 181 fprintf(file, "Number of active references: %d\n", names->references); 182} 183 184 185/** 186 * cloog_names_print function: 187 * This function prints the content of a CloogNames structure (names) into a 188 * file (file, possibly stdout). 189 * - July 1st 2005: Now this function is only a frontend to 190 * cloog_program_print_structure, with a quite better 191 * human-readable representation. 192 */ 193void cloog_names_print(FILE * file, CloogNames * names) 194{ cloog_names_print_structure(file,names,0) ; 195} 196 197 198/****************************************************************************** 199 * Memory deallocation function * 200 ******************************************************************************/ 201 202 203/** 204 * cloog_names_free function: 205 * This function decrements the number of active references to 206 * a CloogNames structure and frees the allocated memory for this structure 207 * if the count drops to zero. 208 */ 209void cloog_names_free(CloogNames * names) 210{ int i ; 211 212 if (--names->references) 213 return; 214 215 if (names->scalars != NULL) 216 { for (i=0;i<names->nb_scalars;i++) 217 free(names->scalars[i]) ; 218 free(names->scalars) ; 219 } 220 221 if (names->scattering != NULL) 222 { for (i=0;i<names->nb_scattering;i++) 223 free(names->scattering[i]) ; 224 free(names->scattering) ; 225 } 226 227 if (names->iterators != NULL) 228 { for (i=0;i<names->nb_iterators;i++) 229 free(names->iterators[i]) ; 230 free(names->iterators) ; 231 } 232 233 if (names->parameters != NULL) 234 { for (i=0;i<names->nb_parameters;i++) 235 free(names->parameters[i]) ; 236 free(names->parameters) ; 237 } 238 free(names) ; 239} 240 241 242/** 243 * cloog_names_copy function: 244 * As usual in CLooG, "copy" means incrementing the reference count. 245 */ 246CloogNames *cloog_names_copy(CloogNames *names) 247{ 248 names->references++; 249 return names; 250} 251 252 253/****************************************************************************** 254 * Reading functions * 255 ******************************************************************************/ 256 257 258/** 259 * cloog_names_read_strings function: 260 * This function reads names data from a file (file, possibly stdin). It first 261 * reads the naming option to know if whether it can read the names from the 262 * file. If not, NULL is returned. Otherwise, the names are stored 263 * into an array of strings, and a pointer to this array is returned. 264 * - nb_items is the number of names the function will have to read if the 265 * naming option is set to read. 266 */ 267char ** cloog_names_read_strings(FILE *file, int nb_items) 268{ int i, option, n ; 269 char s[MAX_STRING], str[MAX_STRING], * c, **names = NULL; 270 271 /* We first read name option. */ 272 while (fgets(s,MAX_STRING,file) == 0) ; 273 while ((*s=='#' || *s=='\n') || (sscanf(s," %d",&option)<1)) 274 fgets(s,MAX_STRING,file) ; 275 276 /* If there is no item to read, then return NULL. */ 277 if (nb_items == 0) 278 return NULL ; 279 280 /* If option is to read them in the file, then we do it and put them into 281 * the array. 282 */ 283 if (option) 284 { /* Memory allocation. */ 285 names = (char **)malloc(nb_items*sizeof(char *)) ; 286 if (names == NULL) 287 cloog_die("memory overflow.\n"); 288 for (i=0;i<nb_items;i++) 289 { names[i] = (char *)malloc(MAX_NAME*sizeof(char)) ; 290 if (names[i] == NULL) 291 cloog_die("memory overflow.\n"); 292 } 293 294 do /* Skip the comments, spaces and empty lines... */ 295 { c = fgets(s,MAX_STRING,file) ; 296 while ((c != NULL) && isspace(*c) && (*c != '\n')) 297 c++ ; 298 } 299 while (c != NULL && (*c == '#' || *c == '\n')); 300 301 if (c == NULL) 302 cloog_die("no names in input file.\n"); 303 for (i=0;i<nb_items;i++) 304 { /* All names must be on the same line. */ 305 while (isspace(*c)) 306 c++ ; 307 if (!*c || *c == '#' || *c == '\n') 308 cloog_die("not enough names in input file.\n"); 309 /* n is strlen(str). */ 310 if (sscanf(c,"%s%n",str,&n) == 0) 311 cloog_die("no names in input file.\n"); 312 sscanf(str,"%s",names[i]) ; 313 c += n ; 314 } 315 } 316 317 return names ; 318} 319 320 321/****************************************************************************** 322 * Processing functions * 323 ******************************************************************************/ 324 325 326/** 327 * cloog_names_malloc function: 328 * This function allocates the memory space for a CloogNames structure and 329 * sets its fields with default values. Then it returns a pointer to the 330 * allocated space. 331 * - November 21th 2005: first version. 332 */ 333CloogNames * cloog_names_malloc() 334{ CloogNames * names ; 335 336 /* Memory allocation for the CloogNames structure. */ 337 names = (CloogNames *)malloc(sizeof(CloogNames)) ; 338 if (names == NULL) 339 cloog_die("memory overflow.\n"); 340 341 /* We set the various fields with default values. */ 342 names->nb_scalars = 0 ; 343 names->nb_scattering = 0 ; 344 names->nb_iterators = 0 ; 345 names->nb_parameters = 0 ; 346 names->scalars = NULL ; 347 names->scattering = NULL ; 348 names->iterators = NULL ; 349 names->parameters = NULL ; 350 names->references = 1; 351 352 return names ; 353} 354 355 356/** 357 * cloog_names_alloc function: 358 * This function allocates the memory space for a CloogNames structure and 359 * sets its fields with those given as input. Then it returns a pointer to the 360 * allocated space. 361 * - July 7th 2005: first version. 362 * - September 11th 2005: addition of both scalar and scattering informations. 363 * - November 21th 2005: use of cloog_names_malloc. 364 */ 365CloogNames * cloog_names_alloc() 366{ CloogNames * names ; 367 368 /* Memory allocation for the CloogNames structure. */ 369 names = cloog_names_malloc() ; 370 371 names->nb_scalars = 0; 372 names->nb_scattering = 0; 373 names->nb_iterators = 0; 374 names->nb_parameters = 0; 375 names->scalars = NULL; 376 names->scattering = NULL; 377 names->iterators = NULL; 378 names->parameters = NULL; 379 380 return names ; 381} 382 383 384/** 385 * cloog_names_generate_items function: 386 * This function returns a pointer to an array of strings with entries set 387 * based on the function's parameters. 388 * - nb_items will be the number of entries in the string array. 389 * - prefix is the name prefix of each item or NULL. 390 * If not NULL, then the remainder of the name will be an integer 391 * in the range [0, nb_items-1]. 392 * - first_item is the name of the first item (if prefix == NULL), 393 * the nb_items-1 following items will be the nb_items-1 394 * following letters in ASCII code. 395 ** 396 * - September 9th 2002 : first version, extracted from cloog_names_generate. 397 */ 398char ** cloog_names_generate_items(int nb_items, char * prefix, char first_item) 399{ int i ; 400 char ** names ; 401 402 if (nb_items == 0) 403 return NULL ; 404 405 names = (char **)malloc(nb_items*sizeof(char *)) ; 406 if (names == NULL) 407 cloog_die("memory overflow.\n"); 408 for (i=0;i<nb_items;i++) 409 { names[i] = (char *)malloc(MAX_NAME*sizeof(char)) ; 410 if (names[i] == NULL) 411 cloog_die("memory overflow.\n"); 412 if (prefix == NULL) 413 sprintf(names[i],"%c",first_item+i) ; 414 else 415 sprintf(names[i], "%s%d", prefix, 1+i); 416 } 417 418 return names ; 419} 420 421 422/** 423 * cloog_names_generate function: 424 * This function returns a pointer to a CloogNames structure with fields set 425 * thanks to the function's parameters. 426 * - nb_scalars will be the number of scalar dimensions in the structure. 427 * - nb_scattering will be the number of scattering dimensions in the structure. 428 * - nb_iterators will be the number of iterators in the CloogNames structure. 429 * - nb_parameters will be the number of parameters in the CloogNames structure. 430 * - first_s is the name of the first scalar iterator, the nb_scalars-1 431 * following iterators will be the nb_scalars-1 following letters in ASCII. 432 * - first_t is the name of the first scattering iterator, the nb_scattering-1 433 * following iterators will be the nb_scattering-1 following letters in ASCII. 434 * - first_i is the name of the first iterator, the nb_iterators-1 following 435 * iterators will be the nb_iterators-1 following letters in ASCII code. 436 * - first_i is the name of the first iterator, the nb_iterators-1 following 437 * iterators will be the nb_iterators-1 following letters in ASCII code. 438 * - first_p is the name of the first parameter, the nb_parameters-1 following 439 * parameters will be the nb_parameters-1 following letters in ASCII code. 440 ** 441 * - July 1st 2002 : first version. 442 * - September 9th 2002 : use of cloog_names_generate_items. 443 * - September 11th 2005 : addition of both scalar and scattering informations. 444 */ 445CloogNames * cloog_names_generate( 446 int nb_scalars, int nb_scattering, int nb_iterators, int nb_parameters, 447 char first_s, char first_t, char first_i, char first_p) 448{ CloogNames * names ; 449 450 names = (CloogNames *)malloc(sizeof(CloogNames)) ; 451 if (names == NULL) 452 cloog_die("memory overflow.\n"); 453 454 names->nb_scalars = nb_scalars ; 455 names->nb_scattering = nb_scattering ; 456 names->nb_parameters = nb_parameters ; 457 names->nb_iterators = nb_iterators ; 458 names->scalars = cloog_names_generate_items(nb_scalars, NULL,first_s); 459 names->scattering = cloog_names_generate_items(nb_scattering,NULL,first_t); 460 names->parameters = cloog_names_generate_items(nb_parameters,NULL,first_p); 461 names->iterators = cloog_names_generate_items(nb_iterators, NULL,first_i); 462 463 return names ; 464} 465 466 467/* Lastly we update the CLoogNames structure: the iterators corresponding to 468 * scalar dimensions have to be removed since these dimensions have been 469 * erased and do not need to be print. We copy all the iterator names except 470 * the scalar ones in a new string array. 471 * - September 12th 2005: first version. 472 */ 473void cloog_names_scalarize(CloogNames * names, int nb_scattdims, int * scaldims) 474{ int nb_scalars, nb_scattering, i, current_scalar, current_scattering ; 475 char ** scalars, ** scattering ; 476 477 if (!nb_scattdims || (scaldims == NULL)) 478 return ; 479 480 nb_scalars = 0 ; 481 for (i=0;i<nb_scattdims;i++) 482 if (scaldims[i]) 483 nb_scalars ++ ; 484 485 if (!nb_scalars) 486 return ; 487 488 nb_scattering = names->nb_scattering - nb_scalars ; 489 scattering = (char **)malloc(nb_scattering * sizeof(char *)) ; 490 if (scattering == NULL) 491 cloog_die("memory overflow.\n"); 492 scalars = (char **)malloc(nb_scalars * sizeof(char *)) ; 493 if (scalars == NULL) 494 cloog_die("memory overflow.\n"); 495 496 current_scalar = 0 ; 497 current_scattering = 0 ; 498 for (i=0;i<nb_scattdims;i++) 499 { if (!scaldims[i]) 500 { scattering[current_scattering] = names->scattering[i] ; 501 current_scattering ++ ; 502 } 503 else 504 { scalars[current_scalar] = names->scattering[i] ; 505 current_scalar ++ ; 506 } 507 } 508 509 free(names->scattering) ; 510 names->scattering = scattering ; 511 names->scalars = scalars ; 512 names->nb_scattering = nb_scattering ; 513 names->nb_scalars = nb_scalars ; 514} 515 516/** 517 * Return the name at a given level (starting at one). 518 * May be a scattering dimension or an iterator of the original domain. 519 */ 520const char *cloog_names_name_at_level(CloogNames *names, int level) 521{ 522 if (level <= names->nb_scattering) 523 return names->scattering[level - 1]; 524 else 525 return names->iterators[level - names->nb_scattering - 1]; 526} 527