Bastoul branch to OpenScop
[openscop.git] / source / statement.c
blob226cf3297b09bd47c0cce1bb16deed4b965761e7
2 /*+------- <| --------------------------------------------------------**
3 ** A Clan/Scop **
4 **--- /.\ -----------------------------------------------------**
5 ** <| [""M# statement.c **
6 **- A | # -----------------------------------------------------**
7 ** /.\ [""M# First version: 30/04/2008 **
8 **- [""M# | # U"U#U -----------------------------------------------**
9 | # | # \ .:/
10 | # | #___| #
11 ****** | "--' .-" ******************************************************
12 * |"-"-"-"-"-#-#-## Clan : the Chunky Loop Analyzer (experimental) *
13 **** | # ## ###### *****************************************************
14 * \ .::::'/ *
15 * \ ::::'/ Copyright (C) 2008 Cedric Bastoul *
16 * :8a| # # ## *
17 * ::88a ### This is free software; you can redistribute it *
18 * ::::888a 8a ##::. and/or modify it under the terms of the GNU Lesser *
19 * ::::::::888a88a[]::: General Public License as published by the Free *
20 *::8:::::::::SUNDOGa8a::. Software Foundation, either version 2.1 of the *
21 *::::::::8::::888:Y8888:: License, or (at your option) any later version. *
22 *::::':::88::::888::Y88a::::::::::::... *
23 *::'::.. . ..... .. ... . *
24 * This software is distributed in the hope that it will be useful, but *
25 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
26 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
27 * for more details. *
28 * *
29 * You should have received a copy of the GNU Lesser General Public License *
30 * along with software; if not, write to the Free Software Foundation, Inc., *
31 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
32 * *
33 * Clan, the Chunky Loop Analyzer *
34 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
35 * *
36 ******************************************************************************/
39 # include <stdlib.h>
40 # include <stdio.h>
41 # include <string.h>
42 # include <ctype.h>
43 # include <scoplib/statement.h>
46 /*+****************************************************************************
47 * Structure display functions *
48 ******************************************************************************/
51 /**
52 * scoplib_statement_print_structure function:
53 * Displays a scoplib_statement_t structure (*statement) into a file (file,
54 * possibly stdout) in a way that trends to be understandable without falling
55 * in a deep depression or, for the lucky ones, getting a headache... It
56 * includes an indentation level (level) in order to work with others
57 * print_structure functions.
58 * \param file File where informations are printed.
59 * \param statement The statement whose information have to be printed.
60 * \param level Number of spaces before printing, for each line.
62 * - 30/04/2008: first version.
64 void
65 scoplib_statement_print_structure(FILE * file, scoplib_statement_p statement,
66 int level)
68 int i, j, first = 1, number = 1;
70 /* Go to the right level. */
71 for (j = 0; j < level; j++)
72 fprintf(file,"|\t");
74 if (statement != NULL)
75 fprintf(file,"+-- scoplib_statement_t (S%d)\n",number);
76 else
77 fprintf(file,"+-- NULL statement\n");
79 while (statement != NULL)
80 { if (!first)
82 /* Go to the right level. */
83 for (j = 0; j < level; j++)
84 fprintf(file,"|\t");
85 fprintf(file,"| scoplib_statement_t (S%d)\n",number);
87 else
88 first = 0;
90 /* A blank line. */
91 for (j = 0; j <= level+1; j++)
92 fprintf(file,"|\t");
93 fprintf(file,"\n");
95 /* Print the domain of the statement. */
96 scoplib_matrix_list_print_structure(file,statement->domain,level+1);
98 /* Print the schedule of the statement. */
99 scoplib_matrix_print_structure(file,statement->schedule,level+1);
101 /* Print the array read access informations of the statement. */
102 scoplib_matrix_print_structure(file,statement->read,level+1);
104 /* Print the array write access informations of the statement. */
105 scoplib_matrix_print_structure(file,statement->write,level+1);
107 /* Print the original iterator names. */
108 for (i=0; i<=level; i++)
109 fprintf(file,"|\t");
110 if (statement->nb_iterators > 0)
112 fprintf(file,"+-- Original iterator strings:");
113 for (i = 0; i < statement->nb_iterators; i++)
114 fprintf(file," %s",statement->iterators[i]);
115 fprintf(file,"\n");
117 else
118 fprintf(file,"+-- No original iterator string\n");
120 /* A blank line. */
121 for (i = 0; i <= level+1; i++)
122 fprintf(file,"|\t");
123 fprintf(file,"\n");
125 /* Print the original statement body. */
126 for (i = 0; i <= level; i++)
127 fprintf(file,"|\t");
128 if (statement->body != NULL)
129 fprintf(file,"+-- Original body: %s\n",statement->body);
130 else
131 fprintf(file,"+-- No original body\n");
133 /* Print the control and exit predicates associated to the statement. */
134 /** @FIXME: do it! */
136 /* A blank line. */
137 for (i = 0; i <= level+1; i++)
138 fprintf(file,"|\t");
139 fprintf(file,"\n");
141 statement = statement->next;
142 number++;
144 /* Next line. */
145 if (statement != NULL)
147 for (j = 0; j <= level; j++)
148 fprintf(file,"|\t");
149 fprintf(file,"V\n");
153 /* The last line. */
154 for (j = 0; j <= level; j++)
155 fprintf(file,"|\t");
156 fprintf(file,"\n");
161 * scoplib_statement_print function:
162 * This function prints the content of a scoplib_statement_t structure
163 * (*statement) into a file (file, possibly stdout).
164 * \param file File where informations are printed.
165 * \param statement The statement whose information have to be printed.
167 * - 30/04/2008: first version.
169 void
170 scoplib_statement_print(FILE * file, scoplib_statement_p statement)
172 scoplib_statement_print_structure(file, statement, 0);
177 * scoplib_statement_print_dot_scop function:
178 * This function prints the content of a scoplib_statement_t structure
179 * (*statement) into a file (file, possibly stdout) for the .scop format.
180 * \param file File where informations are printed.
181 * \param statement The statement whose information have to be printed.
182 * \param nb_parameters The number of parameters in the SCoP.
183 * \param parameters An array containing all parameters names.
184 * \param nb_arrays The number of arrays accessed in the SCoP.
185 * \param arrays An array containing all accessed array names.
187 * - 02/05/2008: first version.
189 void
190 scoplib_statement_print_dot_scop(FILE * file, scoplib_statement_p statement,
191 int nb_parameters, char ** parameters,
192 int nb_arrays, char ** arrays)
194 int i, number = 1;
196 while (statement != NULL)
198 fprintf(file,"# =============================================== ");
199 fprintf(file,"Statement %d\n",number);
201 fprintf(file,"# ---------------------------------------------- ");
202 fprintf(file,"%2d.1 Domain\n",number);
203 fprintf(file,"# Iteration domain\n");
204 scoplib_matrix_list_print_dot_scop(file, statement->domain,
205 SCOPLIB_TYPE_DOMAIN,
206 statement->nb_iterators,
207 statement->iterators,
208 nb_parameters,parameters,
209 nb_arrays,arrays);
210 fprintf(file,"\n");
212 fprintf(file,"# ---------------------------------------------- ");
213 fprintf(file,"%2d.2 Scattering\n",number);
214 fprintf(file,"# Scattering function is provided\n");
215 fprintf(file,"1\n");
216 fprintf(file,"# Scattering function\n");
217 scoplib_matrix_print_dot_scop(file,statement->schedule,
218 SCOPLIB_TYPE_SCATTERING,
219 statement->nb_iterators,statement->iterators,
220 nb_parameters,parameters,
221 nb_arrays,arrays);
222 fprintf(file,"\n");
224 fprintf(file,"# ---------------------------------------------- ");
225 fprintf(file,"%2d.3 Access\n",number);
226 fprintf(file,"# Access informations are provided\n");
227 fprintf(file,"1\n");
228 fprintf(file,"# Read access informations\n");
229 scoplib_matrix_print_dot_scop(file,statement->read,SCOPLIB_TYPE_ACCESS,
230 statement->nb_iterators,statement->iterators,
231 nb_parameters,parameters,
232 nb_arrays,arrays);
233 fprintf(file,"# Write access informations\n");
234 scoplib_matrix_print_dot_scop(file,statement->write,SCOPLIB_TYPE_ACCESS,
235 statement->nb_iterators,statement->iterators,
236 nb_parameters,parameters,
237 nb_arrays,arrays);
238 fprintf(file,"\n");
240 fprintf(file,"# ---------------------------------------------- ");
241 fprintf(file,"%2d.4 Body\n",number);
242 fprintf(file,"# Statement body is provided\n");
243 fprintf(file,"1\n");
244 if (statement->nb_iterators > 0)
246 fprintf(file,"# Original iterator names\n");
247 for (i = 0; i < statement->nb_iterators; i++)
248 fprintf(file,"%s ",statement->iterators[i]);
249 fprintf(file,"\n");
251 else
252 fprintf(file,"# No original iterator names\n");
253 fprintf(file,"# Statement body\n");
254 fprintf(file,"%s\n",statement->body);
255 fprintf(file,"\n\n");
257 statement = statement->next;
258 number++;
264 /******************************************************************************
265 * Reading function *
266 ******************************************************************************/
269 * Internal function. Read 'nb_strings' strings on the input 'file'.
271 * \FIXME should be placed somewhere else, it's duplicated in scop.c.
273 static
274 char**
275 scoplib_statement_read_strings(FILE* file, int nb_strings)
277 char str[SCOPLIB_MAX_STRING];
278 char tmp[SCOPLIB_MAX_STRING];
279 char* s;
280 char** res = NULL;
281 int i;
282 int count;
284 /* Skip blank/commented lines. */
285 while (fgets(str, SCOPLIB_MAX_STRING, file) == 0 || str[0] == '#' ||
286 isspace(str[0]))
288 s = str;
290 /* Allocate the array of string. Make it NULL-terminated. */
291 res = (char**) malloc(sizeof(char*) * (nb_strings + 1));
292 res[nb_strings] = NULL;
294 /* Read the desired number of strings. */
295 for (i = 0; i < nb_strings; ++i)
297 for (count = 0; *s && ! isspace(*s) && *s != '#'; ++count)
298 tmp[count] = *(s++);
299 tmp[count] = '\0';
300 res[i] = strdup(tmp);
301 if (*s != '#')
302 ++s;
305 return res;
309 * Internal function. Read an int on the input 'file'.
311 * \FIXME should be placed somewhere else, it's duplicated in scop.c.
313 static
315 scoplib_statement_read_int(FILE* file)
317 char s[SCOPLIB_MAX_STRING];
318 int res;
320 /* Skip blank/commented lines. */
321 while (fgets(s, SCOPLIB_MAX_STRING, file) == 0 || s[0] == '#' ||
322 isspace(s[0]))
324 sscanf(s, "%d", &res);
326 return res;
329 char** scoplib_scop_generate_names(char*, int);
332 * scoplib_statement_read function:
333 * This function reads a scoplib_statement_t structure from an input stream
334 * (possibly stdin).
335 * \param file The input stream
336 * \param nb_parameters The number of global parameters for the program
337 * \param arrays The array containing names of arrays of the
338 * input program
339 * \param nb_arr The size of the array parameter
341 scoplib_statement_p
342 scoplib_statement_read (FILE* file, int nb_parameters, char*** arrays,
343 int* nb_arr)
345 scoplib_statement_p stmt = scoplib_statement_malloc();
346 char** tmp;
348 if (file)
350 /* Read the domain matrices. */
351 stmt->domain = scoplib_matrix_list_read(file);
353 /* Read the scattering, if any. */
354 if (scoplib_statement_read_int(file) > 0)
355 stmt->schedule = scoplib_matrix_read(file);
357 /* Read the access functions, if any. */
358 if (scoplib_statement_read_int(file) > 0)
360 stmt->read = scoplib_matrix_read_arrays(file, arrays, nb_arr);
361 stmt->write = scoplib_matrix_read_arrays(file, arrays, nb_arr);
364 stmt->nb_iterators = stmt->domain->elt->NbColumns - 2 - nb_parameters;
365 /* Read the body information, if any. */
366 if (scoplib_statement_read_int(file) > 0)
368 if (stmt->nb_iterators > 0)
369 stmt->iterators = scoplib_statement_read_strings(file,
370 stmt->nb_iterators);
371 tmp = scoplib_statement_read_strings(file, 1);
372 stmt->body = tmp[0];
373 free(tmp);
375 else
377 stmt->iterators = scoplib_scop_generate_names("i",
378 stmt->nb_iterators);
379 stmt->body = strdup("[undefined]");
383 return stmt;
387 /*+****************************************************************************
388 * Memory allocation/deallocation functions *
389 ******************************************************************************/
393 * scoplib_statement_malloc function:
394 * This function allocates the memory space for a scoplib_statement_t structure
395 * and sets its fields with default values. Then it returns a pointer to the
396 * allocated space.
398 * - 30/04/2008: first version.
400 scoplib_statement_p
401 scoplib_statement_malloc()
403 scoplib_statement_p statement;
405 statement = (scoplib_statement_p)malloc(sizeof(scoplib_statement_t));
406 if (statement == NULL)
408 fprintf(stderr, "[Scoplib] Memory Overflow.\n");
409 exit(1);
412 statement->domain = NULL;
413 statement->schedule = NULL;
414 statement->read = NULL;
415 statement->write = NULL;
416 statement->nb_iterators = 0;
417 statement->iterators = NULL;
418 statement->body = NULL;
419 statement->next = NULL;
422 /* Non-static code support specifics. */
423 statement->exit_predicates = NULL;
424 statement->nb_exit_predicates = 0;
425 statement->control_predicates = NULL;
426 statement->nb_control_predicates = 0;
428 return statement;
433 * scoplib_statement_free function:
434 * This function frees the allocated memory for a scoplib_statement_t structure.
435 * \param statement The pointer to the statement we want to free.
437 * - 30/04/2008: first version.
439 void
440 scoplib_statement_free(scoplib_statement_p statement)
442 int i;
443 scoplib_statement_p next;
445 while (statement != NULL)
447 next = statement->next;
448 scoplib_matrix_list_free(statement->domain);
449 scoplib_matrix_free(statement->schedule);
450 scoplib_matrix_free(statement->read);
451 scoplib_matrix_free(statement->write);
452 if (statement->iterators != NULL)
454 for (i = 0; i < statement->nb_iterators; i++)
455 free(statement->iterators[i]);
456 free(statement->iterators);
458 if (statement->body != NULL)
459 free(statement->body);
461 /* Non-static code support specifics. */
462 if (statement->exit_predicates != NULL)
463 free(statement->exit_predicates);
464 if (statement->control_predicates != NULL)
465 free(statement->control_predicates);
467 free(statement);
468 statement = next;
473 /*+****************************************************************************
474 * Processing functions *
475 ******************************************************************************/
479 * scoplib_statement_add function:
480 * This function adds a statement "statement" at the end of the statement
481 * list pointed by "location".
482 * \param location Address of the first element of the statement list.
483 * \param statement The statement to add to the list.
485 * - 30/04/2008: first version.
487 void
488 scoplib_statement_add(scoplib_statement_p * location,
489 scoplib_statement_p statement)
491 while (*location != NULL)
492 location = &((*location)->next);
494 *location = statement;
500 * scoplib_statement_number function:
501 * This function returns the number of statements in the statement list
502 * provided as parameter.
503 * \param statement The first element of the statement list.
505 * - 03/05/2008: first version.
508 scoplib_statement_number(scoplib_statement_p statement)
510 int number = 0;
512 while (statement != NULL)
514 number++;
515 statement = statement->next;
517 return number;