2 /**-------------------------------------------------------------------**
4 **-------------------------------------------------------------------**
6 **-------------------------------------------------------------------**
7 ** First version: august 1st 2002 **
8 **-------------------------------------------------------------------**/
11 /******************************************************************************
12 * CLooG : the Chunky Loop Generator (experimental) *
13 ******************************************************************************
15 * Copyright (C) 2002-2005 Cedric Bastoul *
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. *
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. *
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 *
32 * CLooG, the Chunky Loop Generator *
33 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
35 ******************************************************************************/
36 /* CAUTION: the english used for comments is probably the worst you ever read,
37 * please feel free to correct and improve it !
44 # include "../include/cloog/cloog.h"
47 /******************************************************************************
48 * Structure display function *
49 ******************************************************************************/
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 !
60 void cloog_names_print_structure(FILE * file
, CloogNames
* names
, int level
)
63 /* Go to the right level. */
64 for (i
=0; i
<level
; i
++)
68 { fprintf(file
,"+-- CloogNames\n") ;
71 for (i
=0; i
<=level
+1; i
++)
75 /* Print the scalar dimension number. */
76 for (i
=0; i
<=level
; i
++)
78 fprintf(file
,"Scalar dimension number ---: %d\n",names
->nb_scalars
) ;
81 for (i
=0; i
<=level
+1; i
++)
85 /* Print the scalar iterators. */
86 for (i
=0; i
<=level
; i
++)
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
]) ;
95 fprintf(file
,"+-- No scalar string\n") ;
98 for (i
=0; i
<=level
+1; i
++)
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
) ;
108 for (i
=0; i
<=level
+1; i
++)
109 fprintf(file
,"|\t") ;
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
]) ;
122 fprintf(file
,"+-- No scattering string\n") ;
125 for (i
=0; i
<=level
+1; i
++)
126 fprintf(file
,"|\t") ;
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
) ;
135 for (i
=0; i
<=level
+1; i
++)
136 fprintf(file
,"|\t") ;
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
]) ;
149 fprintf(file
,"+-- No iterators\n") ;
152 for (i
=0; i
<=level
+1; i
++)
153 fprintf(file
,"|\t") ;
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
) ;
162 for (i
=0; i
<=level
+1; i
++)
163 fprintf(file
,"|\t") ;
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
]) ;
176 fprintf(file
,"No parameters\n") ;
180 fprintf(file
,"+-- No CloogNames\n") ;
181 fprintf(file
, "Number of active references: %d\n", names
->references
);
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.
193 void cloog_names_print(FILE * file
, CloogNames
* names
)
194 { cloog_names_print_structure(file
,names
,0) ;
198 /******************************************************************************
199 * Memory deallocation function *
200 ******************************************************************************/
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.
209 void cloog_names_free(CloogNames
* names
)
212 if (--names
->references
)
215 if (names
->scalars
!= NULL
)
216 { for (i
=0;i
<names
->nb_scalars
;i
++)
217 free(names
->scalars
[i
]) ;
218 free(names
->scalars
) ;
221 if (names
->scattering
!= NULL
)
222 { for (i
=0;i
<names
->nb_scattering
;i
++)
223 free(names
->scattering
[i
]) ;
224 free(names
->scattering
) ;
227 if (names
->iterators
!= NULL
)
228 { for (i
=0;i
<names
->nb_iterators
;i
++)
229 free(names
->iterators
[i
]) ;
230 free(names
->iterators
) ;
233 if (names
->parameters
!= NULL
)
234 { for (i
=0;i
<names
->nb_parameters
;i
++)
235 free(names
->parameters
[i
]) ;
236 free(names
->parameters
) ;
243 * cloog_names_copy function:
244 * As usual in CLooG, "copy" means incrementing the reference count.
246 CloogNames
*cloog_names_copy(CloogNames
*names
)
253 /******************************************************************************
254 * Reading functions *
255 ******************************************************************************/
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.
267 char ** cloog_names_read_strings(FILE *file
, int nb_items
)
269 char s
[MAX_STRING
], str
[MAX_STRING
], * c
, **names
= NULL
;
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
))
277 /* If there is no item to read, then return NULL. */
281 /* If option is to read them in the file, then we do it and put them into
285 { /* Memory allocation. */
286 names
= (char **)malloc(nb_items
*sizeof(char *)) ;
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");
295 do /* Skip the comments, spaces and empty lines... */
296 { c
= fgets(s
,MAX_STRING
,file
) ;
297 while ((c
!= NULL
) && isspace(*c
) && (*c
!= '\n'))
300 while (c
!= NULL
&& (*c
== '#' || *c
== '\n'));
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. */
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
]) ;
322 /******************************************************************************
323 * Processing functions *
324 ******************************************************************************/
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
332 * - November 21th 2005: first version.
334 CloogNames
* cloog_names_malloc()
335 { CloogNames
* names
;
337 /* Memory allocation for the CloogNames structure. */
338 names
= (CloogNames
*)malloc(sizeof(CloogNames
)) ;
340 cloog_die("memory overflow.\n");
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;
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
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.
366 CloogNames
* cloog_names_alloc()
367 { CloogNames
* names
;
369 /* Memory allocation for the CloogNames structure. */
370 names
= cloog_names_malloc() ;
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
;
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.
397 * - September 9th 2002 : first version, extracted from cloog_names_generate.
399 char ** cloog_names_generate_items(int nb_items
, char * prefix
, char first_item
)
406 names
= (char **)malloc(nb_items
*sizeof(char *)) ;
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");
414 sprintf(names
[i
],"%c",first_item
+i
) ;
416 sprintf(names
[i
], "%s%d", prefix
, 1+i
);
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.
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.
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
;
451 names
= (CloogNames
*)malloc(sizeof(CloogNames
)) ;
453 cloog_die("memory overflow.\n");
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
);
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.
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
;
478 if (!nb_scattdims
|| (scaldims
== NULL
))
482 for (i
=0;i
<nb_scattdims
;i
++)
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 *)) ;
495 cloog_die("memory overflow.\n");
498 current_scattering
= 0 ;
499 for (i
=0;i
<nb_scattdims
;i
++)
501 { scattering
[current_scattering
] = names
->scattering
[i
] ;
502 current_scattering
++ ;
505 { scalars
[current_scalar
] = names
->scattering
[i
] ;
510 free(names
->scattering
) ;
511 names
->scattering
= scattering
;
512 names
->scalars
= scalars
;
513 names
->nb_scattering
= nb_scattering
;
514 names
->nb_scalars
= nb_scalars
;
518 * Return the name at a given level (starting at one).
519 * May be a scattering dimension or an iterator of the original domain.
521 const char *cloog_names_name_at_level(CloogNames
*names
, int level
)
523 if (level
<= names
->nb_scattering
)
524 return names
->scattering
[level
- 1];
526 return names
->iterators
[level
- names
->nb_scattering
- 1];