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 */
cloog_names_print_structure(FILE * file,CloogNames * names,int level)60 void 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 */
cloog_names_print(FILE * file,CloogNames * names)193 void 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 */
cloog_names_free(CloogNames * names)209 void 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 */
cloog_names_copy(CloogNames * names)246 CloogNames *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 */
cloog_names_read_strings(FILE * file,int nb_items)267 char ** 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 if (fgets(s, MAX_STRING, file))
275 continue;
276
277 /* If there is no item to read, then return NULL. */
278 if (nb_items == 0)
279 return NULL ;
280
281 /* If option is to read them in the file, then we do it and put them into
282 * the array.
283 */
284 if (option)
285 { /* Memory allocation. */
286 names = (char **)malloc(nb_items*sizeof(char *)) ;
287 if (names == NULL)
288 cloog_die("memory overflow.\n");
289 for (i=0;i<nb_items;i++)
290 { names[i] = (char *)malloc(MAX_NAME*sizeof(char)) ;
291 if (names[i] == NULL)
292 cloog_die("memory overflow.\n");
293 }
294
295 do /* Skip the comments, spaces and empty lines... */
296 { c = fgets(s,MAX_STRING,file) ;
297 while ((c != NULL) && isspace(*c) && (*c != '\n'))
298 c++ ;
299 }
300 while (c != NULL && (*c == '#' || *c == '\n'));
301
302 if (c == NULL)
303 cloog_die("no names in input file.\n");
304 for (i=0;i<nb_items;i++)
305 { /* All names must be on the same line. */
306 while (isspace(*c))
307 c++ ;
308 if (!*c || *c == '#' || *c == '\n')
309 cloog_die("not enough names in input file.\n");
310 /* n is strlen(str). */
311 if (sscanf(c,"%s%n",str,&n) == 0)
312 cloog_die("no names in input file.\n");
313 sscanf(str,"%s",names[i]) ;
314 c += n ;
315 }
316 }
317
318 return names ;
319 }
320
321
322 /******************************************************************************
323 * Processing functions *
324 ******************************************************************************/
325
326
327 /**
328 * cloog_names_malloc function:
329 * This function allocates the memory space for a CloogNames structure and
330 * sets its fields with default values. Then it returns a pointer to the
331 * allocated space.
332 * - November 21th 2005: first version.
333 */
cloog_names_malloc()334 CloogNames * cloog_names_malloc()
335 { CloogNames * names ;
336
337 /* Memory allocation for the CloogNames structure. */
338 names = (CloogNames *)malloc(sizeof(CloogNames)) ;
339 if (names == NULL)
340 cloog_die("memory overflow.\n");
341
342 /* We set the various fields with default values. */
343 names->nb_scalars = 0 ;
344 names->nb_scattering = 0 ;
345 names->nb_iterators = 0 ;
346 names->nb_parameters = 0 ;
347 names->scalars = NULL ;
348 names->scattering = NULL ;
349 names->iterators = NULL ;
350 names->parameters = NULL ;
351 names->references = 1;
352
353 return names ;
354 }
355
356
357 /**
358 * cloog_names_alloc function:
359 * This function allocates the memory space for a CloogNames structure and
360 * sets its fields with those given as input. Then it returns a pointer to the
361 * allocated space.
362 * - July 7th 2005: first version.
363 * - September 11th 2005: addition of both scalar and scattering informations.
364 * - November 21th 2005: use of cloog_names_malloc.
365 */
cloog_names_alloc()366 CloogNames * cloog_names_alloc()
367 { CloogNames * names ;
368
369 /* Memory allocation for the CloogNames structure. */
370 names = cloog_names_malloc() ;
371
372 names->nb_scalars = 0;
373 names->nb_scattering = 0;
374 names->nb_iterators = 0;
375 names->nb_parameters = 0;
376 names->scalars = NULL;
377 names->scattering = NULL;
378 names->iterators = NULL;
379 names->parameters = NULL;
380
381 return names ;
382 }
383
384
385 /**
386 * cloog_names_generate_items function:
387 * This function returns a pointer to an array of strings with entries set
388 * based on the function's parameters.
389 * - nb_items will be the number of entries in the string array.
390 * - prefix is the name prefix of each item or NULL.
391 * If not NULL, then the remainder of the name will be an integer
392 * in the range [0, nb_items-1].
393 * - first_item is the name of the first item (if prefix == NULL),
394 * the nb_items-1 following items will be the nb_items-1
395 * following letters in ASCII code.
396 **
397 * - September 9th 2002 : first version, extracted from cloog_names_generate.
398 */
cloog_names_generate_items(int nb_items,char * prefix,char first_item)399 char ** cloog_names_generate_items(int nb_items, char * prefix, char first_item)
400 { int i ;
401 char ** names ;
402
403 if (nb_items == 0)
404 return NULL ;
405
406 names = (char **)malloc(nb_items*sizeof(char *)) ;
407 if (names == NULL)
408 cloog_die("memory overflow.\n");
409 for (i=0;i<nb_items;i++)
410 { names[i] = (char *)malloc(MAX_NAME*sizeof(char)) ;
411 if (names[i] == NULL)
412 cloog_die("memory overflow.\n");
413 if (prefix == NULL)
414 sprintf(names[i],"%c",first_item+i) ;
415 else
416 sprintf(names[i], "%s%d", prefix, 1+i);
417 }
418
419 return names ;
420 }
421
422
423 /**
424 * cloog_names_generate function:
425 * This function returns a pointer to a CloogNames structure with fields set
426 * thanks to the function's parameters.
427 * - nb_scalars will be the number of scalar dimensions in the structure.
428 * - nb_scattering will be the number of scattering dimensions in the structure.
429 * - nb_iterators will be the number of iterators in the CloogNames structure.
430 * - nb_parameters will be the number of parameters in the CloogNames structure.
431 * - first_s is the name of the first scalar iterator, the nb_scalars-1
432 * following iterators will be the nb_scalars-1 following letters in ASCII.
433 * - first_t is the name of the first scattering iterator, the nb_scattering-1
434 * following iterators will be the nb_scattering-1 following letters in ASCII.
435 * - first_i is the name of the first iterator, the nb_iterators-1 following
436 * iterators will be the nb_iterators-1 following letters in ASCII code.
437 * - first_i is the name of the first iterator, the nb_iterators-1 following
438 * iterators will be the nb_iterators-1 following letters in ASCII code.
439 * - first_p is the name of the first parameter, the nb_parameters-1 following
440 * parameters will be the nb_parameters-1 following letters in ASCII code.
441 **
442 * - July 1st 2002 : first version.
443 * - September 9th 2002 : use of cloog_names_generate_items.
444 * - September 11th 2005 : addition of both scalar and scattering informations.
445 */
cloog_names_generate(int nb_scalars,int nb_scattering,int nb_iterators,int nb_parameters,char first_s,char first_t,char first_i,char first_p)446 CloogNames * cloog_names_generate(
447 int nb_scalars, int nb_scattering, int nb_iterators, int nb_parameters,
448 char first_s, char first_t, char first_i, char first_p)
449 { CloogNames * names ;
450
451 names = (CloogNames *)malloc(sizeof(CloogNames)) ;
452 if (names == NULL)
453 cloog_die("memory overflow.\n");
454
455 names->nb_scalars = nb_scalars ;
456 names->nb_scattering = nb_scattering ;
457 names->nb_parameters = nb_parameters ;
458 names->nb_iterators = nb_iterators ;
459 names->scalars = cloog_names_generate_items(nb_scalars, NULL,first_s);
460 names->scattering = cloog_names_generate_items(nb_scattering,NULL,first_t);
461 names->parameters = cloog_names_generate_items(nb_parameters,NULL,first_p);
462 names->iterators = cloog_names_generate_items(nb_iterators, NULL,first_i);
463
464 return names ;
465 }
466
467
468 /* Lastly we update the CLoogNames structure: the iterators corresponding to
469 * scalar dimensions have to be removed since these dimensions have been
470 * erased and do not need to be print. We copy all the iterator names except
471 * the scalar ones in a new string array.
472 * - September 12th 2005: first version.
473 */
cloog_names_scalarize(CloogNames * names,int nb_scattdims,int * scaldims)474 void cloog_names_scalarize(CloogNames * names, int nb_scattdims, int * scaldims)
475 { int nb_scalars, nb_scattering, i, current_scalar, current_scattering ;
476 char ** scalars, ** scattering ;
477
478 if (!nb_scattdims || (scaldims == NULL))
479 return ;
480
481 nb_scalars = 0 ;
482 for (i=0;i<nb_scattdims;i++)
483 if (scaldims[i])
484 nb_scalars ++ ;
485
486 if (!nb_scalars)
487 return ;
488
489 nb_scattering = names->nb_scattering - nb_scalars ;
490 scattering = (char **)malloc(nb_scattering * sizeof(char *)) ;
491 if (scattering == NULL)
492 cloog_die("memory overflow.\n");
493 scalars = (char **)malloc(nb_scalars * sizeof(char *)) ;
494 if (scalars == NULL)
495 cloog_die("memory overflow.\n");
496
497 current_scalar = 0 ;
498 current_scattering = 0 ;
499 for (i=0;i<nb_scattdims;i++)
500 { if (!scaldims[i])
501 { scattering[current_scattering] = names->scattering[i] ;
502 current_scattering ++ ;
503 }
504 else
505 { scalars[current_scalar] = names->scattering[i] ;
506 current_scalar ++ ;
507 }
508 }
509
510 free(names->scattering) ;
511 names->scattering = scattering ;
512 names->scalars = scalars ;
513 names->nb_scattering = nb_scattering ;
514 names->nb_scalars = nb_scalars ;
515 }
516
517 /**
518 * Return the name at a given level (starting at one).
519 * May be a scattering dimension or an iterator of the original domain.
520 */
cloog_names_name_at_level(CloogNames * names,int level)521 const char *cloog_names_name_at_level(CloogNames *names, int level)
522 {
523 if (level <= names->nb_scattering)
524 return names->scattering[level - 1];
525 else
526 return names->iterators[level - names->nb_scattering - 1];
527 }
528