Remove some files left in builddir after make clean
[cloog-ppl.git] / source / program.c
blob7814fa1b72f89528cb7d64bb09c0a39722de90cf
2 /**-------------------------------------------------------------------**
3 ** CLooG **
4 **-------------------------------------------------------------------**
5 ** program.c **
6 **-------------------------------------------------------------------**
7 ** First version: october 25th 2001 **
8 **-------------------------------------------------------------------**/
11 /******************************************************************************
12 * CLooG : the Chunky Loop Generator (experimental) *
13 ******************************************************************************
14 * *
15 * Copyright (C) 2001-2005 Cedric Bastoul *
16 * *
17 * This is free software; you can redistribute it and/or modify it under the *
18 * terms of the GNU General Public License as published by the Free Software *
19 * Foundation; either version 2 of the License, or (at your option) any later *
20 * version. *
21 * *
22 * This software is distributed in the hope that it will be useful, but *
23 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
24 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
25 * for more details. *
26 * *
27 * You should have received a copy of the GNU General Public License along *
28 * with software; if not, write to the Free Software Foundation, Inc., *
29 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
30 * *
31 * CLooG, the Chunky Loop Generator *
32 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
33 * *
34 ******************************************************************************/
35 /* CAUTION: the english used for comments is probably the worst you ever read,
36 * please feel free to correct and improve it !
40 # include <sys/types.h>
41 # include <sys/time.h>
42 # include <sys/resource.h>
43 #include <stdarg.h>
44 # include <stdlib.h>
45 # include <stdio.h>
46 # include <string.h>
47 # include <ctype.h>
48 # include <unistd.h>
49 # include "../include/cloog/cloog.h"
52 /******************************************************************************
53 * Memory leaks hunting *
54 ******************************************************************************/
57 /**
58 * These global variables are devoted to memory leaks hunting: we
59 * want to know at each moment how many Value variables have been allocated
60 * since in GMP mode they have to be freed (see domain.c for the declaration).
61 * - July 3rd->11th 2003: first version (memory leaks hunt and correction).
64 extern int cloog_value_allocated ;
65 extern int cloog_value_freed ;
66 extern int cloog_value_max ;
69 /******************************************************************************
70 * Structure display function *
71 ******************************************************************************/
74 /**
75 * cloog_program_print function:
76 * this function is a human-friendly way to display the CloogProgram data
77 * structure, it shows all the different fields and includes an indentation
78 * level (level) in order to work with others print_structure functions.
79 * - July 1st 2005: first version based on the old cloog_program_print function.
81 void cloog_program_print_structure(FILE *file, CloogProgram *program, int level)
82 { int i, j ;
84 /* Go to the right level. */
85 for (i=0; i<level; i++)
86 fprintf(file,"|\t") ;
88 fprintf(file,"+-- CloogProgram\n") ;
90 /* A blank line. */
91 for (i=0; i<=level+1; i++)
92 fprintf(file,"|\t") ;
93 fprintf(file,"\n") ;
95 /* Print the language. */
96 for (i=0; i<=level; i++)
97 fprintf(file,"|\t") ;
98 fprintf(file, "Language: %c\n",cloog_program_language (program)) ;
100 /* A blank line. */
101 for (i=0; i<=level+1; i++)
102 fprintf(file,"|\t") ;
103 fprintf(file,"\n") ;
105 /* Print the scattering dimension number. */
106 for (i=0; i<=level; i++)
107 fprintf(file,"|\t") ;
108 fprintf(file,"Scattering dimension number: %d\n",
109 cloog_program_nb_scattdims (program)) ;
111 /* A blank line. */
112 for (i=0; i<=level+1; i++)
113 fprintf(file,"|\t") ;
114 fprintf(file,"\n") ;
116 /* Print the scalar scattering dimension informations. */
117 for (i=0; i<=level; i++)
118 fprintf(file,"|\t") ;
119 if (cloog_program_scaldims (program))
121 fprintf (file,"Scalar dimensions:");
122 for (i = 0; i < cloog_program_nb_scattdims (program); i++)
123 fprintf (file," %d:%d ", i, cloog_program_scaldim (program, i));
124 fprintf (file,"\n");
126 else
127 fprintf (file, "No scalar scattering dimensions\n");
129 /* A blank line. */
130 for (i=0; i<=level+1; i++)
131 fprintf(file,"|\t") ;
132 fprintf(file,"\n") ;
134 /* Print the parameter and the iterator names. */
135 cloog_names_print_structure (file, cloog_program_names (program), level + 1);
137 /* A blank line. */
138 for (i=0; i<=level+1; i++)
139 fprintf(file,"|\t") ;
140 fprintf(file,"\n") ;
142 /* Print the context. */
143 cloog_domain_print_structure(file, cloog_program_context (program), level+1);
145 /* Print the loop. */
146 cloog_loop_print_structure (file,cloog_program_loop (program), level + 1);
148 /* One more time something that is here only for a better look. */
149 for (j=0; j<2; j++)
150 { for (i=0; i<=level; i++)
151 fprintf(file,"|\t") ;
153 fprintf(file,"\n") ;
159 * cloog_program_dump_cloog function:
160 * This function dumps a CloogProgram structure supposed to be completely
161 * filled in a CLooG input file (foo possibly stdout) such as CLooG can
162 * rebuild almost exactly the data structure from the input file (the number
163 * of scattering functions is lost since they are included inside the
164 * iteration domains, this can only lead to a less beautiful pretty printing).
165 * WARNING: this function do not respect CloogDomain as an object.
166 * - June 27th 2003: first version.
167 * - May 15th 2005: (debug) several patches by Kristof Beyls.
168 * - November 16th 2005: adaptation for CLooG 0.14.0 structures.
170 void cloog_program_dump_cloog(FILE * foo, CloogProgram * program)
171 { int i;
172 CloogLoop * loop ;
174 fprintf(foo,
175 "# CLooG -> CLooG\n"
176 "# This is an automatic dump of a CLooG input file from a CloogProgram data\n"
177 "# structure. WARNING: it is highly dangerous and MAY be correct ONLY if\n"
178 "# - it has been dumped before loop generation.\n"
179 "# - option -noscalars is used (it removes scalar dimensions otherwise)\n"
180 "# - option -l is at least the original scattering dimension number\n"
181 "# ASK THE AUTHOR IF YOU *NEED* SOMETHING MORE ROBUST\n") ;
183 /* Language. */
184 if (cloog_program_language (program) == 'c')
185 fprintf(foo,"# Language: C\n") ;
186 else
187 fprintf(foo,"# Language: FORTRAN\n") ;
188 fprintf(foo,"%c\n\n", cloog_program_language (program)) ;
190 /* Context. */
191 fprintf (foo,"# Context (%d parameter(s)):\n",
192 cloog_domain_dim (cloog_program_context (program)));
193 cloog_domain_print_structure (foo, cloog_program_context (program), 0);
194 fprintf(foo,"1 # Parameter name(s)\n") ;
195 for (i = 0; i < cloog_names_nb_parameters (cloog_program_names (program)); i++)
196 fprintf (foo, "%s ", cloog_names_parameter_elt (cloog_program_names (program), i));
198 /* Statement number. */
199 i = 0 ;
200 loop = cloog_program_loop (program);
201 while (loop != NULL)
202 { i++ ;
203 loop = cloog_loop_next (loop) ;
205 fprintf(foo,"\n\n# Statement number:\n%d\n\n",i) ;
207 /* Iteration domains. */
208 i = 1 ;
209 loop = cloog_program_loop (program) ;
210 while (loop != NULL)
211 { /* Name of the domain. */
212 fprintf(foo,"# Iteration domain of statement %d.\n",i) ;
214 /* Number of polyhedra inside the union of disjoint polyhedra. */
215 fprintf (foo, "%d\n", cloog_domain_nb_polyhedra (cloog_loop_domain (loop))) ;
217 /* The polyhedra themselves. */
218 cloog_domain_print_polyhedra (foo, cloog_loop_domain (loop));
219 fprintf(foo,"0 0 0 # For future options.\n\n") ;
221 i++ ;
222 loop = cloog_loop_next (loop) ;
224 fprintf(foo,"\n1 # Iterator name(s)\n") ;
225 for (i = 0; i < cloog_names_nb_scattering (cloog_program_names (program)); i++)
226 fprintf (foo, "%s ", cloog_names_scattering_elt (cloog_program_names (program), i));
227 for (i = 0; i < cloog_names_nb_iterators (cloog_program_names (program)); i++)
228 fprintf (foo, "%s ", cloog_names_iterator_elt (cloog_program_names (program), i));
229 fprintf(foo,"\n\n") ;
231 /* Scattering functions (none since included inside domains). */
232 fprintf(foo,"# No scattering functions.\n0\n\n") ;
237 * cloog_program_print function:
238 * This function prints the content of a CloogProgram structure (program) into a
239 * file (file, possibly stdout).
240 * - July 1st 2005: Now this very old function (probably as old as CLooG) is
241 * only a frontend to cloog_program_print_structure, with a
242 * quite better human-readable representation.
244 void cloog_program_print(FILE * file, CloogProgram * program)
245 { cloog_program_print_structure(file,program,0) ;
249 static void print_comment(FILE *file, CloogOptions *options,
250 const char *fmt, ...)
252 va_list args;
254 va_start(args, fmt);
255 if (options->language == LANGUAGE_FORTRAN) {
256 fprintf(file, "! ");
257 vfprintf(file, fmt, args);
258 fprintf(file, "\n");
259 } else {
260 fprintf(file, "/* ");
261 vfprintf(file, fmt, args);
262 fprintf(file, " */\n");
264 va_end (args);
268 * cloog_program_pprint function:
269 * This function prints the content of a CloogProgram structure (program) into a
270 * file (file, possibly stdout), in a C-like language.
271 * - June 22nd 2005: Adaptation for GMP.
273 void cloog_program_pprint(FILE *file, CloogProgram *program, CloogOptions *options)
274 { int i, j, nb_scattering, indentation=0 ;
275 CloogStatement * statement ;
276 CloogBlockList * blocklist ;
277 CloogBlock * block ;
278 struct clast_stmt *root;
280 if (cloog_program_language (program) == 'f')
281 options->language = LANGUAGE_FORTRAN ;
282 else
283 options->language = LANGUAGE_C ;
285 print_comment(file, options, "Generated from %s by %s in %.2fs.",
286 options->name, cloog_version(), options->time);
287 #ifdef CLOOG_MEMORY
288 print_comment(file, options, "CLooG asked for %d KBytes.", options->memory);
289 fprintf(stderr, "[CLooG]INFO: %.2fs and %dKB used for code generation.\n",
290 options->time,options->memory);
291 #endif
293 /* If the option "compilable" is set, we provide the whole stuff to generate
294 * a compilable code. This code just do nothing, but now the user can edit
295 * the source and set the statement macros and parameters values.
297 nb_scattering = cloog_program_nb_scattdims (program) ;
298 if (options->compilable && (cloog_program_language (program) == 'c'))
299 { /* The headers. */
300 fprintf(file,"/* DON'T FORGET TO USE -lm OPTION TO COMPILE. */\n\n") ;
301 fprintf(file,"/* Useful headers. */\n") ;
302 fprintf(file,"#include <stdio.h>\n") ;
303 fprintf(file,"#include <stdlib.h>\n") ;
304 fprintf(file,"#include <math.h>\n\n") ;
306 /* The value of parameters. */
307 fprintf(file,"/* Parameter value. */\n") ;
308 for (i = 1; i <= cloog_names_nb_parameters (cloog_program_names (program)); i++)
309 fprintf(file, "#define PARVAL%d %d\n", i, options->compilable);
311 /* The macros. */
312 fprintf(file,"/* Useful macros. */\n") ;
313 fprintf(file,"#define ceild(n,d) ceil(((double)(n))/((double)(d)))\n") ;
314 fprintf(file,"#define floord(n,d) floor(((double)(n))/((double)(d)))\n") ;
315 fprintf(file,"#define max(x,y) ((x) > (y)? (x) : (y)) \n") ;
316 fprintf(file,"#define min(x,y) ((x) < (y)? (x) : (y)) \n\n") ;
318 /* The statement macros. */
319 fprintf(file,"/* Statement macros (please set). */\n") ;
320 blocklist = cloog_program_blocklist (program) ;
321 while (blocklist != NULL)
323 block = cloog_block_list_block (blocklist) ;
324 statement = cloog_block_stmt (block) ;
325 while (statement != NULL)
327 fprintf (file, "#define S%d(", cloog_statement_number (statement));
328 if (cloog_block_depth (block) > 0)
330 fprintf (file, "%s", cloog_names_iterator_elt (cloog_program_names (program), 0));
331 for (j = 1; j < cloog_block_depth (block); j++)
332 fprintf (file, ",%s", cloog_names_iterator_elt (cloog_program_names (program), j)) ;
334 fprintf(file,") {total++;") ;
335 if (cloog_block_depth (block) > 0)
337 fprintf (file, " printf(\"S%d %%d", cloog_statement_number (statement));
338 for (j = 1; j < cloog_block_depth (block); j++)
339 fprintf (file, " %%d");
341 fprintf(file,"\\n\",%s", cloog_names_iterator_elt (cloog_program_names (program), 0));
342 for (j = 1;j < cloog_block_depth (block); j++)
343 fprintf (file, ",%s", cloog_names_iterator_elt (cloog_program_names (program), j)) ;
344 fprintf (file, ");");
346 fprintf(file,"}\n") ;
348 statement = cloog_statement_next (statement);
350 blocklist = cloog_block_list_next (blocklist) ;
353 /* The iterator and parameter declaration. */
354 fprintf(file,"\nint main() {\n") ;
355 if ((cloog_names_nb_scalars (cloog_program_names (program)) > 0) && (!options->csp))
356 { fprintf(file," /* Scalar dimension iterators. */\n") ;
357 fprintf (file," int %s", cloog_names_scalar_elt (cloog_program_names (program), 0));
358 for (i = 2; i <= cloog_names_nb_scalars (cloog_program_names (program)); i++)
359 fprintf (file, ", %s", cloog_names_scalar_elt (cloog_program_names (program), i - 1));
361 fprintf(file," ;\n") ;
363 if (cloog_names_nb_scattering (cloog_program_names (program)) > 0)
364 { fprintf(file," /* Scattering iterators. */\n") ;
365 fprintf (file, " int %s", cloog_names_scattering_elt (cloog_program_names (program), 0));
366 for(i=2;i<=cloog_names_nb_scattering (cloog_program_names (program));i++)
367 fprintf (file, ", %s", cloog_names_scattering_elt (cloog_program_names (program), i - 1));
369 fprintf(file," ;\n") ;
371 if (cloog_names_nb_iterators (cloog_program_names (program)) > 0)
372 { fprintf(file," /* Original iterators. */\n") ;
373 fprintf (file," int %s", cloog_names_iterator_elt (cloog_program_names (program), 0)) ;
374 for(i=2;i<=cloog_names_nb_iterators (cloog_program_names (program));i++)
375 fprintf(file,", %s", cloog_names_iterator_elt (cloog_program_names (program), i-1)) ;
377 fprintf(file," ;\n") ;
379 if (cloog_names_nb_parameters (cloog_program_names (program)) > 0)
380 { fprintf(file," /* Parameters. */\n") ;
381 fprintf(file, " int %s=PARVAL1", cloog_names_parameter_elt (cloog_program_names (program), 0));
382 for(i=2;i<=cloog_names_nb_parameters (cloog_program_names (program));i++)
383 fprintf(file, ", %s=PARVAL%d", cloog_names_parameter_elt (cloog_program_names (program), i - 1), i);
385 fprintf(file,";\n");
387 fprintf(file," int total=0;\n");
388 fprintf(file,"\n") ;
390 /* And we adapt the identation. */
391 indentation += 2 ;
394 root = cloog_clast_create(program, options);
395 pprint(file, root, indentation, options);
396 cloog_clast_free(root);
398 /* The end of the compilable code in case of 'compilable' option. */
399 if (options->compilable && (cloog_program_language (program) == 'c'))
400 { fprintf(file,"\n printf(\"Number of integral points: %%d.\\n\",total) ;") ;
401 fprintf(file,"\n return 0 ;\n}\n") ;
406 /******************************************************************************
407 * Memory deallocation function *
408 ******************************************************************************/
412 * cloog_program_free function:
413 * This function frees the allocated memory for a CloogProgram structure.
415 void cloog_program_free(CloogProgram * program)
416 { cloog_names_free(cloog_program_names (program)) ;
417 cloog_loop_free(cloog_program_loop (program)) ;
418 cloog_domain_free (cloog_program_context (program)) ;
419 cloog_block_list_free (cloog_program_blocklist (program)) ;
420 if (cloog_program_scaldims (program))
421 free (cloog_program_scaldims (program));
423 free(program) ;
427 /******************************************************************************
428 * Reading function *
429 ******************************************************************************/
433 * cloog_program_read function:
434 * This function read the informations to put in a CloogProgram structure from
435 * a file (file, possibly stdin). It returns a pointer to a CloogProgram
436 * structure containing the read informations.
437 * - October 25th 2001: first version.
438 * - September 9th 2002: - the big reading function is now split in several
439 * functions (one per read data structure).
440 * - adaptation to the new file format with naming.
442 CloogProgram * cloog_program_read(FILE * file, CloogOptions * options)
443 { int i, nb_statements, nb_parameters, nb_iterators, nb_scattering ;
444 char s[MAX_STRING], language, prefix[2]={'c','\0'},
445 ** scattering, ** iterators, ** parameters;
446 CloogLoop * current, * next ;
447 CloogBlockList * previous ;
448 CloogDomainList * scatteringl ;
449 CloogProgram * p ;
451 nb_scattering = 0 ;
452 scattering = NULL ;
454 /* Memory allocation for the CloogProgram structure. */
455 p = cloog_program_malloc() ;
457 /* First of all, we read the language to use. */
458 while (fgets(s,MAX_STRING,file) == 0) ;
459 while ((*s=='#'||*s=='\n') || (sscanf(s," %c",&language)<1))
460 fgets(s,MAX_STRING,file) ;
461 cloog_program_set_language (p, language);
463 /* We then read the context data. */
464 cloog_program_set_context (p, cloog_domain_read (file));
465 nb_parameters = cloog_domain_dim (cloog_program_context (p)) ;
467 /* First part of the CloogNames structure: reading of the parameter names. */
468 parameters=cloog_names_read_strings(file,nb_parameters,NULL,FIRST_PARAMETER) ;
470 /* We read the statement number. */
471 while (fgets(s,MAX_STRING,file) == 0) ;
472 while ((*s=='#'||*s=='\n') || (sscanf(s," %d",&nb_statements)<1))
473 fgets(s,MAX_STRING,file) ;
475 /* Statements and domains reading for each statement. */
476 if (nb_statements > 0)
477 { /* Reading of the first domain. */
478 cloog_program_set_loop (p, cloog_loop_read (file,0,nb_parameters));
479 cloog_program_set_blocklist
480 (p, cloog_block_list_alloc (cloog_loop_block (cloog_program_loop (p))));
481 previous = cloog_program_blocklist (p);
483 if (cloog_loop_domain (cloog_program_loop (p)) != NULL)
484 nb_iterators = cloog_domain_dim(cloog_loop_domain (cloog_program_loop (p))) - nb_parameters ;
485 else
486 nb_iterators = 0 ;
488 /* And the same for each next domain. */
489 current = cloog_program_loop (p) ;
490 for (i=2;i<=nb_statements;i++)
491 { next = cloog_loop_read(file,i-1,nb_parameters) ;
492 if (cloog_loop_domain (next) != NULL)
493 if ((int) cloog_domain_dim(cloog_loop_domain (next)) - nb_parameters > nb_iterators)
494 nb_iterators = cloog_domain_dim (cloog_loop_domain (next)) - nb_parameters ;
496 cloog_block_list_set_next (previous, cloog_block_list_alloc (cloog_loop_block (next)));
497 previous = cloog_block_list_next (previous) ;
499 cloog_loop_set_next (current, next);
500 current = cloog_loop_next (current) ;
503 /* Reading of the iterator names. */
504 iterators = cloog_names_read_strings(file,nb_iterators,NULL,FIRST_ITERATOR);
506 /* Reading and putting the scattering data in program structure. */
507 scatteringl = cloog_domain_list_read(file) ;
509 if (scatteringl != NULL)
511 if (cloog_domain_list_lazy_same(scatteringl)
512 /* Cloog should never print to stderr. */
513 && 0)
514 fprintf(stderr, "[CLooG]WARNING: some scattering functions are "
515 "similar.\n") ;
517 cloog_program_set_nb_scattdims (p,
518 cloog_domain_dim (cloog_domain (scatteringl)) -
519 cloog_domain_dim (cloog_loop_domain (cloog_program_loop (p)))) ;
520 nb_scattering = cloog_program_nb_scattdims (p);
521 scattering = cloog_names_read_strings (file, cloog_program_nb_scattdims (p), prefix, -1);
523 /* The boolean array for scalar dimensions is created and set to 0. */
524 cloog_program_set_scaldims (p, (int *) malloc (cloog_program_nb_scattdims (p) * sizeof (int)));
525 if (cloog_program_scaldims (p) == NULL)
527 fprintf(stderr, "[CLooG]ERROR: memory overflow.\n") ;
528 exit(1) ;
530 for (i=0;i<cloog_program_nb_scattdims (p);i++)
531 cloog_program_set_scaldim (p, i, 0);
533 /* We try to find blocks in the input problem to reduce complexity. */
534 if (!options->noblocks)
535 cloog_program_block(p,scatteringl) ;
536 if (!options->noscalars)
537 cloog_program_extract_scalars(p,scatteringl) ;
539 cloog_program_scatter(p,scatteringl) ;
540 cloog_domain_list_free(scatteringl) ;
542 else
544 cloog_program_set_nb_scattdims (p, 0);
545 cloog_program_set_scaldims (p, NULL);
548 cloog_program_set_names
549 (p, cloog_names_alloc (0, nb_scattering, nb_iterators, nb_parameters,
550 NULL, scattering, iterators, parameters));
552 cloog_names_scalarize (cloog_program_names (p), cloog_program_nb_scattdims (p),
553 cloog_program_scaldims (p));
555 else
557 cloog_program_set_loop (p, NULL);
558 cloog_program_set_names (p, NULL);
559 cloog_program_set_blocklist (p, NULL);
560 cloog_program_set_scaldims (p, NULL);
563 return(p) ;
567 /******************************************************************************
568 * Processing functions *
569 ******************************************************************************/
573 * cloog_program_malloc function:
574 * This function allocates the memory space for a CloogProgram structure and
575 * sets its fields with default values. Then it returns a pointer to the
576 * allocated space.
577 * - November 21th 2005: first version.
579 CloogProgram * cloog_program_malloc (void)
580 { CloogProgram * program ;
582 /* Memory allocation for the CloogProgram structure. */
583 program = (CloogProgram *)malloc(sizeof(CloogProgram)) ;
584 if (program == NULL)
585 { fprintf(stderr, "[CLooG]ERROR: memory overflow.\n") ;
586 exit(1) ;
589 /* We set the various fields with default values. */
590 cloog_program_set_language (program, 'c');
591 cloog_program_set_nb_scattdims (program, 0);
592 cloog_program_set_context (program, NULL);
593 cloog_program_set_loop (program, NULL);
594 cloog_program_set_names (program, NULL);
595 cloog_program_set_blocklist (program, NULL);
596 cloog_program_set_scaldims (program, NULL);
597 cloog_program_set_usr (program, NULL);
599 return program ;
604 * cloog_program_generate function:
605 * This function calls the Quillere algorithm for loop scanning. (see the
606 * Quillere paper) and calls the loop simplification function.
607 * - depth is the loop depth we want to optimize (guard free as possible),
608 * the first loop depth is 1 and anegative value is the infinity depth.
609 * - sep_level is the level number where we want to start loop separation.
611 * - October 26th 2001: first version.
612 * - April 19th 2005: some basic fixes and memory usage feature.
613 * - April 29th 2005: (bug fix, bug found by DaeGon Kim) see case 2 below.
615 CloogProgram * cloog_program_generate(CloogProgram *program, CloogOptions *options)
616 { float time ;
617 struct rusage start, end ;
618 CloogLoop * loop ;
619 #ifdef CLOOG_MEMORY
620 char status_path[MAX_STRING_VAL] ;
621 FILE * status ;
623 /* We initialize the memory need to 0. */
624 options->memory = 0 ;
625 #endif
627 if (options->override)
629 /* Cloog should never print to stderr. */
630 /* fprintf(stderr,
631 "[CLooG]WARNING: you are using -override option, be aware that the "
632 "generated\n code may be incorrect.\n") ;
635 else
636 { /* Playing with options may be dangerous, here are two possible issues :
637 * 1. Using -l option less than scattering dimension number may lead to
638 * an illegal target code (since the scattering is not respected), if
639 * it is the case, we set -l depth to the first acceptable value.
641 if ((cloog_program_nb_scattdims (program) > options->l) && (options->l >= 0))
643 /* Cloog should never print to stderr. */
644 /* fprintf(stderr,
645 "[CLooG]WARNING: -l depth is less than the scattering dimension number "
646 "(the \n generated code may be incorrect), it has been "
647 "automaticaly set\n to this value (use option -override "
648 "to override).\n") ;
650 options->l = cloog_program_nb_scattdims (program);
653 /* 2. Using -f option greater than one while -l depth is greater than the
654 * scattering dimension number may lead to iteration duplication (try
655 * test/daegon_lu_osp.cloog with '-f 3' to test) because of the step 4b
656 * of the cloog_loop_generate function, if it is the case, we set -l to
657 * the first acceptable value.
659 if (((options->f > 1) || (options->f < 0)) &&
660 ((options->l > cloog_program_nb_scattdims (program)) || (options->l < 0)))
662 /* Cloog should never print to stderr. */
663 /* fprintf(stderr,
664 "[CLooG]WARNING: -f depth is more than one, -l depth has been "
665 "automaticaly set\n to the scattering dimension number "
666 "(target code may have\n duplicated iterations), -l depth "
667 "has been automaticaly set to\n this value (use option "
668 "-override to override).\n") ;
670 options->l = cloog_program_nb_scattdims (program);
674 getrusage(RUSAGE_SELF, &start) ;
675 if (cloog_program_loop (program))
677 loop = cloog_program_loop (program) ;
679 /* Here we go ! */
680 loop = cloog_loop_generate(loop, cloog_program_context (program), 1, 0,
681 cloog_program_scaldims (program),
682 cloog_program_nb_scattdims (program),
683 cloog_domain_dim (cloog_program_context (program)),
684 options);
686 #ifdef CLOOG_MEMORY
687 /* We read into the status file of the process how many memory it uses. */
688 sprintf(status_path,"/proc/%d/status",getpid()) ;
689 status = fopen(status_path, "r") ;
690 while (fscanf(status,"%s",status_path) && strcmp(status_path,"VmData:")!=0);
691 fscanf(status,"%d",&(options->memory)) ;
692 fclose(status) ;
693 #endif
695 if ((!options->nosimplify) && cloog_program_loop (program))
696 loop = cloog_loop_simplify(loop, cloog_program_context (program), 1,
697 cloog_domain_dim (cloog_program_context (program))) ;
699 cloog_program_set_loop (program, loop);
702 getrusage(RUSAGE_SELF, &end) ;
703 /* We calculate the time spent in code generation. */
704 time = (end.ru_utime.tv_usec - start.ru_utime.tv_usec)/(float)(MEGA) ;
705 time += (float)(end.ru_utime.tv_sec - start.ru_utime.tv_sec) ;
706 options->time = time ;
708 return program ;
713 * cloog_program_block function:
714 * this function gives a last chance to the lazy user to consider statement
715 * blocks instead of some statement lists where the whole list may be
716 * considered as a single statement from a code generation point of view.
717 * For instance two statements with the same iteration domain and the same
718 * scattering functions may be considered as a block. This function is lazy
719 * and can only find very simple forms of trivial blocks (see
720 * cloog_domain_lazy_block function for more details). The useless loops and
721 * scattering functions are removed and freed while the statement list of
722 * according blocks are filled.
723 * - program is the whole program structure (befaore applying scattering),
724 * - scattering is the list of scattering functions.
726 * - April 30th 2005: first attempt.
727 * - June 10-11th 2005: first working version.
729 void cloog_program_block(CloogProgram * program, CloogDomainList * scattering)
730 { int blocked_reference=0, blocked=0, nb_blocked=0 ;
731 CloogLoop * reference, * start, * loop ;
732 CloogDomainList * scatt_reference, * scatt_loop, * scatt_start ;
733 CloogBlockList * previous ;
735 if ((cloog_program_loop (program) == NULL)
736 || (cloog_loop_next (cloog_program_loop (program)) == NULL))
737 return ;
739 /* We will have to rebuild the block list. */
740 cloog_block_list_free (cloog_program_blocklist (program)) ;
741 cloog_program_set_blocklist
742 (program, cloog_block_list_alloc (cloog_loop_block (cloog_program_loop (program))));
743 previous = cloog_program_blocklist (program);
745 /* The process will use three variables for the linked list :
746 * - 'start' is the starting point of a new block,
747 * - 'reference' is the node of the block used for the block checking,
748 * - 'loop' is the candidate to be inserted inside the block.
749 * At the beginning of the process, the linked lists are as follow:
750 * O------>O------>O------>O------>NULL
751 * | |
752 * start loop
753 * reference
756 reference = cloog_program_loop (program) ;
757 start = cloog_program_loop (program) ;
758 loop = cloog_loop_next (reference) ;
759 scatt_reference = scattering ;
760 scatt_start = scattering ;
761 scatt_loop = cloog_next_domain (scattering) ;
763 while (loop != NULL)
765 if (cloog_domain_lazy_equal (cloog_loop_domain (reference),
766 cloog_loop_domain (loop)) &&
767 cloog_domain_lazy_block(cloog_domain (scatt_reference),
768 cloog_domain (scatt_loop),
769 scattering, cloog_program_nb_scattdims (program)))
770 { /* If we find a block we update the links:
771 * +---------------+
772 * | v
773 * O O------>O------>O------>NULL
774 * | |
775 * start loop
776 * reference
778 blocked = 1 ;
779 nb_blocked ++ ;
780 cloog_block_merge(cloog_loop_block (start), cloog_loop_block (loop)); /* merge frees cloog_block (loop) */
781 cloog_loop_set_block (loop, NULL);
782 cloog_loop_set_next (start, cloog_loop_next (loop));
783 cloog_set_next_domain (scatt_start, cloog_next_domain (scatt_loop));
785 else
786 { /* If we didn't find a block, the next start of a block is updated:
787 * O------>O------>O------>O------>NULL
788 * | |
789 * reference start
790 * loop
792 blocked= 0 ;
793 start = loop ;
794 scatt_start = scatt_loop ;
796 /* We update the block list. */
797 cloog_block_list_set_next (previous, cloog_block_list_alloc (cloog_loop_block (start)));
798 previous = cloog_block_list_next (previous) ;
801 /* If the reference node has been included into a block, we can free it. */
802 if (blocked_reference)
803 { cloog_loop_set_next (reference, NULL);
804 cloog_loop_free (reference) ;
805 cloog_domain_free (cloog_domain (scatt_reference)) ;
806 free (scatt_reference) ;
809 /* The reference and the loop are now updated for the next try, the
810 * starting position depends on the previous step.
811 * O ? O------>O------>O------>NULL
812 * | |
813 * reference loop
815 reference = loop ;
816 loop = cloog_loop_next (loop) ;
817 scatt_reference = scatt_loop ;
818 scatt_loop = cloog_next_domain (scatt_loop) ;
820 /* We mark the new reference as being blocked or not, if will be freed
821 * during the next while loop execution.
823 if (blocked)
824 blocked_reference = 1 ;
825 else
826 blocked_reference = 0 ;
829 /* We free the last blocked reference if any (since in the while loop it was
830 * freed during the next loop execution, it was not possible to free the
831 * last one inside).
833 if (blocked_reference)
834 { cloog_loop_set_next (reference, NULL);
835 cloog_loop_free (reference) ;
836 cloog_domain_free (cloog_domain (scatt_reference)) ;
837 free (scatt_reference) ;
840 /* Cloog should never print to stderr. */
841 /* if (nb_blocked != 0)
842 fprintf(stderr, "[CLooG]INFO: %d domains have been blocked.\n",nb_blocked) ; */
847 * cloog_program_extract_scalars function:
848 * this functions finds and removes the dimensions of the scattering functions
849 * when they are scalar (i.e. of the shape "dim + scalar = 0") for all
850 * scattering functions. The reason is that the processing of such dimensions
851 * is trivial and do not need neither a row and a column in the matrix
852 * representation of the domain (this will save memory) neither the full
853 * Quillere processing (this will save time). The scalar dimensions data are
854 * dispatched in the CloogProgram structure (the boolean vector scaldims will
855 * say which original dimensions are scalar or not) and to the CloogBlock
856 * structures (each one has a scaldims vector that contains the scalar values).
857 * - June 14th 2005: first developments.
858 * - June 30th 2005: first version.
860 void cloog_program_extract_scalars(CloogProgram *program, CloogDomainList *scattering)
861 { int i, j, scalar, current, nb_scaldims=0 ;
862 CloogDomainList * start ;
863 CloogDomain * old ;
864 CloogBlockList * blocklist ;
865 CloogBlock * block ;
867 start = scattering ;
869 for (i = 0; i < cloog_program_nb_scattdims (program); i++)
870 { scalar = 1 ;
871 scattering = start ;
872 while (scattering != NULL)
874 if (!cloog_domain_lazy_isscalar (cloog_domain (scattering),i))
876 scalar = 0 ;
877 break ;
879 scattering = cloog_next_domain (scattering);
882 if (scalar)
884 nb_scaldims ++ ;
885 cloog_program_set_scaldim (program, i, 1);
889 /* If there are no scalar dimensions, we can continue directly. */
890 if (!nb_scaldims)
891 return ;
893 /* Otherwise, in each block, we have to put the number of scalar dimensions,
894 * and to allocate the memory for the scalar values.
896 blocklist = cloog_program_blocklist (program);
897 while (blocklist != NULL)
899 block = cloog_block_list_block (blocklist) ;
900 cloog_block_set_nb_scaldims (block, nb_scaldims);
901 cloog_block_set_scaldims (block, (Value *) malloc (nb_scaldims * sizeof (Value)));
903 for (i = 0; i < nb_scaldims; i++)
904 value_init_c (block->scaldims[i]);
906 blocklist = cloog_block_list_next (blocklist);
909 /* Then we have to fill these scalar values, so we can erase those dimensions
910 * from the scattering functions. It's easier to begin with the last one,
911 * since there would be an offset otherwise (if we remove the i^th dimension,
912 * then the next one is not the (i+1)^th but still the i^th...).
914 current = nb_scaldims - 1 ;
915 for (i = cloog_program_nb_scattdims (program) - 1; i >= 0; i--)
916 if (cloog_program_scaldim (program, i))
918 blocklist = cloog_program_blocklist (program);
919 scattering = start;
921 while (blocklist != NULL)
923 block = cloog_block_list_block (blocklist) ;
924 cloog_domain_scalar (cloog_domain (scattering), i,
925 &block->scaldims[current]);
926 blocklist = cloog_block_list_next (blocklist);
927 scattering = cloog_next_domain (scattering);
930 scattering = start ;
931 while (scattering != NULL)
933 old = cloog_domain (scattering) ;
934 cloog_set_domain (scattering, cloog_domain_erase_dimension (old, i)) ;
935 cloog_domain_free (old) ;
936 scattering = cloog_next_domain (scattering);
938 current-- ;
941 /* We postprocess the scaldims array in such a way that each entry is how
942 * many scalar dimensions follows + 1 (the current one). This will make
943 * some other processing easier (e.g. knowledge of some offsets).
945 for (i = 0; i < cloog_program_nb_scattdims (program) - 1; i++)
947 if (cloog_program_scaldim (program, i))
949 j = i + 1 ;
950 while ((j < cloog_program_nb_scattdims (program))
951 && cloog_program_scaldim (program, j))
953 cloog_program_set_scaldim (program, i,
954 cloog_program_scaldim (program, i) + 1);
955 j ++ ;
960 /* Cloog should never print to stderr. */
961 /* if (nb_scaldims != 0)
962 fprintf(stderr, "[CLooG]INFO: %d dimensions (over %d) are scalar.\n",
963 nb_scaldims, cloog_program_nb_scattdims (program)) ; */
968 * cloog_program_scatter function:
969 * This function adds the scattering (scheduling) informations in a program.
970 * If names is NULL, this function create names itself such that the i^th
971 * name is ci.
972 * - November 6th 2001: first version.
974 void cloog_program_scatter(CloogProgram *program, CloogDomainList *scattering)
976 CloogLoop * loop ;
978 if ((program != NULL) && (scattering != NULL))
980 loop = cloog_program_loop (program) ;
982 /* Finally we scatter all loops. */
983 cloog_loop_scatter(loop, cloog_domain (scattering)) ;
984 loop = cloog_loop_next (loop) ;
985 scattering = cloog_next_domain (scattering);
987 while ((loop != NULL) && (scattering != NULL))
989 cloog_loop_scatter(loop,cloog_domain (scattering)) ;
990 loop = cloog_loop_next (loop) ;
991 scattering = cloog_next_domain (scattering);