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