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 fgets(s
,MAX_STRING
,file
) ;
276 /* If there is no item to read, then return NULL. */
280 /* If option is to read them in the file, then we do it and put them into
284 { /* Memory allocation. */
285 names
= (char **)malloc(nb_items
*sizeof(char *)) ;
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");
294 do /* Skip the comments, spaces and empty lines... */
295 { c
= fgets(s
,MAX_STRING
,file
) ;
296 while ((c
!= NULL
) && isspace(*c
) && (*c
!= '\n'))
299 while (c
!= NULL
&& (*c
== '#' || *c
== '\n'));
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. */
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
]) ;
321 /******************************************************************************
322 * Processing functions *
323 ******************************************************************************/
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
331 * - November 21th 2005: first version.
333 CloogNames
* cloog_names_malloc()
334 { CloogNames
* names
;
336 /* Memory allocation for the CloogNames structure. */
337 names
= (CloogNames
*)malloc(sizeof(CloogNames
)) ;
339 cloog_die("memory overflow.\n");
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;
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
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.
365 CloogNames
* cloog_names_alloc()
366 { CloogNames
* names
;
368 /* Memory allocation for the CloogNames structure. */
369 names
= cloog_names_malloc() ;
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
;
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.
396 * - September 9th 2002 : first version, extracted from cloog_names_generate.
398 char ** cloog_names_generate_items(int nb_items
, char * prefix
, char first_item
)
405 names
= (char **)malloc(nb_items
*sizeof(char *)) ;
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");
413 sprintf(names
[i
],"%c",first_item
+i
) ;
415 sprintf(names
[i
], "%s%d", prefix
, 1+i
);
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.
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.
445 CloogNames
* 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
;
450 names
= (CloogNames
*)malloc(sizeof(CloogNames
)) ;
452 cloog_die("memory overflow.\n");
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
);
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.
473 void 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
;
477 if (!nb_scattdims
|| (scaldims
== NULL
))
481 for (i
=0;i
<nb_scattdims
;i
++)
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 *)) ;
494 cloog_die("memory overflow.\n");
497 current_scattering
= 0 ;
498 for (i
=0;i
<nb_scattdims
;i
++)
500 { scattering
[current_scattering
] = names
->scattering
[i
] ;
501 current_scattering
++ ;
504 { scalars
[current_scalar
] = names
->scattering
[i
] ;
509 free(names
->scattering
) ;
510 names
->scattering
= scattering
;
511 names
->scalars
= scalars
;
512 names
->nb_scattering
= nb_scattering
;
513 names
->nb_scalars
= nb_scalars
;
517 * Return the name at a given level (starting at one).
518 * May be a scattering dimension or an iterator of the original domain.
520 const char *cloog_names_name_at_level(CloogNames
*names
, int level
)
522 if (level
<= names
->nb_scattering
)
523 return names
->scattering
[level
- 1];
525 return names
->iterators
[level
- names
->nb_scattering
- 1];