2 /**-------------------------------------------------------------------**
4 **-------------------------------------------------------------------**
6 **-------------------------------------------------------------------**
7 ** First version: october 25th 2001 **
8 **-------------------------------------------------------------------**/
11 /******************************************************************************
12 * CLooG : the Chunky Loop Generator (experimental) *
13 ******************************************************************************
15 * Copyright (C) 2001-2005 Cedric Bastoul *
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 *
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 *
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 *
31 * CLooG, the Chunky Loop Generator *
32 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
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>
48 # include "../include/cloog/cloog.h"
49 #ifdef HAS_SYS_RESOURCE_H
50 # include <sys/resource.h>
54 /******************************************************************************
55 * Memory leaks hunting *
56 ******************************************************************************/
60 * These global variables are devoted to memory leaks hunting: we
61 * want to know at each moment how many Value variables have been allocated
62 * since in GMP mode they have to be freed (see domain.c for the declaration).
63 * - July 3rd->11th 2003: first version (memory leaks hunt and correction).
66 extern int cloog_value_allocated
;
67 extern int cloog_value_freed
;
68 extern int cloog_value_max
;
71 /******************************************************************************
72 * Structure display function *
73 ******************************************************************************/
77 * cloog_program_print function:
78 * this function is a human-friendly way to display the CloogProgram data
79 * structure, it shows all the different fields and includes an indentation
80 * level (level) in order to work with others print_structure functions.
81 * - July 1st 2005: first version based on the old cloog_program_print function.
83 void cloog_program_print_structure(FILE *file
, CloogProgram
*program
, int level
)
86 /* Go to the right level. */
87 for (i
=0; i
<level
; i
++)
90 fprintf(file
,"+-- CloogProgram\n") ;
93 for (i
=0; i
<=level
+1; i
++)
97 /* Print the language. */
98 for (i
=0; i
<=level
; i
++)
100 fprintf(file
, "Language: %c\n",cloog_program_language (program
)) ;
103 for (i
=0; i
<=level
+1; i
++)
104 fprintf(file
,"|\t") ;
107 /* Print the scattering dimension number. */
108 for (i
=0; i
<=level
; i
++)
109 fprintf(file
,"|\t") ;
110 fprintf(file
,"Scattering dimension number: %d\n",
111 cloog_program_nb_scattdims (program
)) ;
114 for (i
=0; i
<=level
+1; i
++)
115 fprintf(file
,"|\t") ;
118 /* Print the scalar scattering dimension informations. */
119 for (i
=0; i
<=level
; i
++)
120 fprintf(file
,"|\t") ;
121 if (cloog_program_scaldims (program
))
123 fprintf (file
,"Scalar dimensions:");
124 for (i
= 0; i
< cloog_program_nb_scattdims (program
); i
++)
125 fprintf (file
," %d:%d ", i
, cloog_program_scaldim (program
, i
));
129 fprintf (file
, "No scalar scattering dimensions\n");
132 for (i
=0; i
<=level
+1; i
++)
133 fprintf(file
,"|\t") ;
136 /* Print the parameter and the iterator names. */
137 cloog_names_print_structure (file
, cloog_program_names (program
), level
+ 1);
140 for (i
=0; i
<=level
+1; i
++)
141 fprintf(file
,"|\t") ;
144 /* Print the context. */
145 cloog_domain_print_structure(file
, cloog_program_context (program
), level
+1);
147 /* Print the loop. */
148 cloog_loop_print_structure (file
,cloog_program_loop (program
), level
+ 1);
150 /* One more time something that is here only for a better look. */
152 { for (i
=0; i
<=level
; i
++)
153 fprintf(file
,"|\t") ;
161 * cloog_program_dump_cloog function:
162 * This function dumps a CloogProgram structure supposed to be completely
163 * filled in a CLooG input file (foo possibly stdout) such as CLooG can
164 * rebuild almost exactly the data structure from the input file (the number
165 * of scattering functions is lost since they are included inside the
166 * iteration domains, this can only lead to a less beautiful pretty printing).
167 * WARNING: this function do not respect CloogDomain as an object.
168 * - June 27th 2003: first version.
169 * - May 15th 2005: (debug) several patches by Kristof Beyls.
170 * - November 16th 2005: adaptation for CLooG 0.14.0 structures.
172 void cloog_program_dump_cloog(FILE * foo
, CloogProgram
* program
)
178 "# This is an automatic dump of a CLooG input file from a CloogProgram data\n"
179 "# structure. WARNING: it is highly dangerous and MAY be correct ONLY if\n"
180 "# - it has been dumped before loop generation.\n"
181 "# - option -noscalars is used (it removes scalar dimensions otherwise)\n"
182 "# - option -l is at least the original scattering dimension number\n"
183 "# ASK THE AUTHOR IF YOU *NEED* SOMETHING MORE ROBUST\n") ;
186 if (cloog_program_language (program
) == 'c')
187 fprintf(foo
,"# Language: C\n") ;
189 fprintf(foo
,"# Language: FORTRAN\n") ;
190 fprintf(foo
,"%c\n\n", cloog_program_language (program
)) ;
193 fprintf (foo
,"# Context (%d parameter(s)):\n",
194 cloog_domain_dim (cloog_program_context (program
)));
195 cloog_domain_print_structure (foo
, cloog_program_context (program
), 0);
196 fprintf(foo
,"1 # Parameter name(s)\n") ;
197 for (i
= 0; i
< cloog_names_nb_parameters (cloog_program_names (program
)); i
++)
198 fprintf (foo
, "%s ", cloog_names_parameter_elt (cloog_program_names (program
), i
));
200 /* Statement number. */
202 loop
= cloog_program_loop (program
);
205 loop
= cloog_loop_next (loop
) ;
207 fprintf(foo
,"\n\n# Statement number:\n%d\n\n",i
) ;
209 /* Iteration domains. */
211 loop
= cloog_program_loop (program
) ;
213 { /* Name of the domain. */
214 fprintf(foo
,"# Iteration domain of statement %d.\n",i
) ;
216 /* Number of polyhedra inside the union of disjoint polyhedra. */
217 fprintf (foo
, "%d\n", cloog_domain_nb_polyhedra (cloog_loop_domain (loop
))) ;
219 /* The polyhedra themselves. */
220 cloog_domain_print_polyhedra (foo
, cloog_loop_domain (loop
));
221 fprintf(foo
,"0 0 0 # For future options.\n\n") ;
224 loop
= cloog_loop_next (loop
) ;
226 fprintf(foo
,"\n1 # Iterator name(s)\n") ;
227 for (i
= 0; i
< cloog_names_nb_scattering (cloog_program_names (program
)); i
++)
228 fprintf (foo
, "%s ", cloog_names_scattering_elt (cloog_program_names (program
), i
));
229 for (i
= 0; i
< cloog_names_nb_iterators (cloog_program_names (program
)); i
++)
230 fprintf (foo
, "%s ", cloog_names_iterator_elt (cloog_program_names (program
), i
));
231 fprintf(foo
,"\n\n") ;
233 /* Scattering functions (none since included inside domains). */
234 fprintf(foo
,"# No scattering functions.\n0\n\n") ;
239 * cloog_program_print function:
240 * This function prints the content of a CloogProgram structure (program) into a
241 * file (file, possibly stdout).
242 * - July 1st 2005: Now this very old function (probably as old as CLooG) is
243 * only a frontend to cloog_program_print_structure, with a
244 * quite better human-readable representation.
246 void cloog_program_print(FILE * file
, CloogProgram
* program
)
247 { cloog_program_print_structure(file
,program
,0) ;
251 static void print_comment(FILE *file
, CloogOptions
*options
,
252 const char *fmt
, ...)
257 if (options
->language
== LANGUAGE_FORTRAN
) {
259 vfprintf(file
, fmt
, args
);
262 fprintf(file
, "/* ");
263 vfprintf(file
, fmt
, args
);
264 fprintf(file
, " */\n");
270 * cloog_program_pprint function:
271 * This function prints the content of a CloogProgram structure (program) into a
272 * file (file, possibly stdout), in a C-like language.
273 * - June 22nd 2005: Adaptation for GMP.
275 void cloog_program_pprint(FILE *file
, CloogProgram
*program
, CloogOptions
*options
)
276 { int i
, j
, nb_scattering
, indentation
=0 ;
277 CloogStatement
* statement
;
278 CloogBlockList
* blocklist
;
280 struct clast_stmt
*root
;
282 if (cloog_program_language (program
) == 'f')
283 options
->language
= LANGUAGE_FORTRAN
;
285 options
->language
= LANGUAGE_C
;
287 print_comment(file
, options
, "Generated from %s by %s in %.2fs.",
288 options
->name
, cloog_version(), options
->time
);
290 print_comment(file
, options
, "CLooG asked for %d KBytes.", options
->memory
);
291 fprintf(stderr
, "[CLooG]INFO: %.2fs and %dKB used for code generation.\n",
292 options
->time
,options
->memory
);
295 /* If the option "compilable" is set, we provide the whole stuff to generate
296 * a compilable code. This code just do nothing, but now the user can edit
297 * the source and set the statement macros and parameters values.
299 nb_scattering
= cloog_program_nb_scattdims (program
) ;
300 if (options
->compilable
&& (cloog_program_language (program
) == 'c'))
302 fprintf(file
,"/* DON'T FORGET TO USE -lm OPTION TO COMPILE. */\n\n") ;
303 fprintf(file
,"/* Useful headers. */\n") ;
304 fprintf(file
,"#include <stdio.h>\n") ;
305 fprintf(file
,"#include <stdlib.h>\n") ;
306 fprintf(file
,"#include <math.h>\n\n") ;
308 /* The value of parameters. */
309 fprintf(file
,"/* Parameter value. */\n") ;
310 for (i
= 1; i
<= cloog_names_nb_parameters (cloog_program_names (program
)); i
++)
311 fprintf(file
, "#define PARVAL%d %d\n", i
, options
->compilable
);
314 fprintf(file
,"/* Useful macros. */\n") ;
315 fprintf(file
,"#define ceild(n,d) ceil(((double)(n))/((double)(d)))\n") ;
316 fprintf(file
,"#define floord(n,d) floor(((double)(n))/((double)(d)))\n") ;
317 fprintf(file
,"#define max(x,y) ((x) > (y)? (x) : (y)) \n") ;
318 fprintf(file
,"#define min(x,y) ((x) < (y)? (x) : (y)) \n\n") ;
320 /* The statement macros. */
321 fprintf(file
,"/* Statement macros (please set). */\n") ;
322 blocklist
= cloog_program_blocklist (program
) ;
323 while (blocklist
!= NULL
)
325 block
= cloog_block_list_block (blocklist
) ;
326 statement
= cloog_block_stmt (block
) ;
327 while (statement
!= NULL
)
329 fprintf (file
, "#define S%d(", cloog_statement_number (statement
));
330 if (cloog_block_depth (block
) > 0)
332 fprintf (file
, "%s", cloog_names_iterator_elt (cloog_program_names (program
), 0));
333 for (j
= 1; j
< cloog_block_depth (block
); j
++)
334 fprintf (file
, ",%s", cloog_names_iterator_elt (cloog_program_names (program
), j
)) ;
336 fprintf(file
,") {total++;") ;
337 if (cloog_block_depth (block
) > 0)
339 fprintf (file
, " printf(\"S%d %%d", cloog_statement_number (statement
));
340 for (j
= 1; j
< cloog_block_depth (block
); j
++)
341 fprintf (file
, " %%d");
343 fprintf(file
,"\\n\",%s", cloog_names_iterator_elt (cloog_program_names (program
), 0));
344 for (j
= 1;j
< cloog_block_depth (block
); j
++)
345 fprintf (file
, ",%s", cloog_names_iterator_elt (cloog_program_names (program
), j
)) ;
346 fprintf (file
, ");");
348 fprintf(file
,"}\n") ;
350 statement
= cloog_statement_next (statement
);
352 blocklist
= cloog_block_list_next (blocklist
) ;
355 /* The iterator and parameter declaration. */
356 fprintf(file
,"\nint main() {\n") ;
357 if ((cloog_names_nb_scalars (cloog_program_names (program
)) > 0) && (!options
->csp
))
358 { fprintf(file
," /* Scalar dimension iterators. */\n") ;
359 fprintf (file
," int %s", cloog_names_scalar_elt (cloog_program_names (program
), 0));
360 for (i
= 2; i
<= cloog_names_nb_scalars (cloog_program_names (program
)); i
++)
361 fprintf (file
, ", %s", cloog_names_scalar_elt (cloog_program_names (program
), i
- 1));
363 fprintf(file
," ;\n") ;
365 if (cloog_names_nb_scattering (cloog_program_names (program
)) > 0)
366 { fprintf(file
," /* Scattering iterators. */\n") ;
367 fprintf (file
, " int %s", cloog_names_scattering_elt (cloog_program_names (program
), 0));
368 for(i
=2;i
<=cloog_names_nb_scattering (cloog_program_names (program
));i
++)
369 fprintf (file
, ", %s", cloog_names_scattering_elt (cloog_program_names (program
), i
- 1));
371 fprintf(file
," ;\n") ;
373 if (cloog_names_nb_iterators (cloog_program_names (program
)) > 0)
374 { fprintf(file
," /* Original iterators. */\n") ;
375 fprintf (file
," int %s", cloog_names_iterator_elt (cloog_program_names (program
), 0)) ;
376 for(i
=2;i
<=cloog_names_nb_iterators (cloog_program_names (program
));i
++)
377 fprintf(file
,", %s", cloog_names_iterator_elt (cloog_program_names (program
), i
-1)) ;
379 fprintf(file
," ;\n") ;
381 if (cloog_names_nb_parameters (cloog_program_names (program
)) > 0)
382 { fprintf(file
," /* Parameters. */\n") ;
383 fprintf(file
, " int %s=PARVAL1", cloog_names_parameter_elt (cloog_program_names (program
), 0));
384 for(i
=2;i
<=cloog_names_nb_parameters (cloog_program_names (program
));i
++)
385 fprintf(file
, ", %s=PARVAL%d", cloog_names_parameter_elt (cloog_program_names (program
), i
- 1), i
);
389 fprintf(file
," int total=0;\n");
392 /* And we adapt the identation. */
396 root
= cloog_clast_create(program
, options
);
397 pprint(file
, root
, indentation
, options
);
398 cloog_clast_free(root
);
400 /* The end of the compilable code in case of 'compilable' option. */
401 if (options
->compilable
&& (cloog_program_language (program
) == 'c'))
402 { fprintf(file
,"\n printf(\"Number of integral points: %%d.\\n\",total) ;") ;
403 fprintf(file
,"\n return 0 ;\n}\n") ;
408 /******************************************************************************
409 * Memory deallocation function *
410 ******************************************************************************/
414 * cloog_program_free function:
415 * This function frees the allocated memory for a CloogProgram structure.
417 void cloog_program_free(CloogProgram
* program
)
418 { cloog_names_free(cloog_program_names (program
)) ;
419 cloog_loop_free(cloog_program_loop (program
)) ;
420 cloog_domain_free (cloog_program_context (program
)) ;
421 cloog_block_list_free (cloog_program_blocklist (program
)) ;
422 if (cloog_program_scaldims (program
))
423 free (cloog_program_scaldims (program
));
429 /******************************************************************************
431 ******************************************************************************/
435 * cloog_program_read function:
436 * This function read the informations to put in a CloogProgram structure from
437 * a file (file, possibly stdin). It returns a pointer to a CloogProgram
438 * structure containing the read informations.
439 * - October 25th 2001: first version.
440 * - September 9th 2002: - the big reading function is now split in several
441 * functions (one per read data structure).
442 * - adaptation to the new file format with naming.
444 CloogProgram
* cloog_program_read(FILE * file
, CloogOptions
* options
)
445 { int i
, nb_statements
, nb_parameters
, nb_iterators
, nb_scattering
;
446 char s
[MAX_STRING
], language
, prefix
[2]={'c','\0'},
447 ** scattering
, ** iterators
, ** parameters
;
448 CloogLoop
* current
, * next
;
449 CloogBlockList
* previous
;
450 CloogDomainList
* scatteringl
;
456 /* Memory allocation for the CloogProgram structure. */
457 p
= cloog_program_malloc() ;
459 /* First of all, we read the language to use. */
460 while (fgets(s
,MAX_STRING
,file
) == 0) ;
461 while ((*s
=='#'||*s
=='\n') || (sscanf(s
," %c",&language
)<1))
462 fgets(s
,MAX_STRING
,file
) ;
463 cloog_program_set_language (p
, language
);
465 /* We then read the context data. */
466 cloog_program_set_context (p
, cloog_domain_read (file
));
467 nb_parameters
= cloog_domain_dim (cloog_program_context (p
)) ;
469 /* First part of the CloogNames structure: reading of the parameter names. */
470 parameters
=cloog_names_read_strings(file
,nb_parameters
,NULL
,FIRST_PARAMETER
) ;
472 /* We read the statement number. */
473 while (fgets(s
,MAX_STRING
,file
) == 0) ;
474 while ((*s
=='#'||*s
=='\n') || (sscanf(s
," %d",&nb_statements
)<1))
475 fgets(s
,MAX_STRING
,file
) ;
477 /* Statements and domains reading for each statement. */
478 if (nb_statements
> 0)
479 { /* Reading of the first domain. */
480 cloog_program_set_loop (p
, cloog_loop_read (file
,0,nb_parameters
));
481 cloog_program_set_blocklist
482 (p
, cloog_block_list_alloc (cloog_loop_block (cloog_program_loop (p
))));
483 previous
= cloog_program_blocklist (p
);
485 if (cloog_loop_domain (cloog_program_loop (p
)) != NULL
)
486 nb_iterators
= cloog_domain_dim(cloog_loop_domain (cloog_program_loop (p
))) - nb_parameters
;
490 /* And the same for each next domain. */
491 current
= cloog_program_loop (p
) ;
492 for (i
=2;i
<=nb_statements
;i
++)
493 { next
= cloog_loop_read(file
,i
-1,nb_parameters
) ;
494 if (cloog_loop_domain (next
) != NULL
)
495 if ((int) cloog_domain_dim(cloog_loop_domain (next
)) - nb_parameters
> nb_iterators
)
496 nb_iterators
= cloog_domain_dim (cloog_loop_domain (next
)) - nb_parameters
;
498 cloog_block_list_set_next (previous
, cloog_block_list_alloc (cloog_loop_block (next
)));
499 previous
= cloog_block_list_next (previous
) ;
501 cloog_loop_set_next (current
, next
);
502 current
= cloog_loop_next (current
) ;
505 /* Reading of the iterator names. */
506 iterators
= cloog_names_read_strings(file
,nb_iterators
,NULL
,FIRST_ITERATOR
);
508 /* Reading and putting the scattering data in program structure. */
509 scatteringl
= cloog_domain_list_read(file
) ;
511 if (scatteringl
!= NULL
)
513 if (cloog_domain_list_lazy_same(scatteringl
)
514 /* Cloog should never print to stderr. */
516 fprintf(stderr
, "[CLooG]WARNING: some scattering functions are "
519 cloog_program_set_nb_scattdims (p
,
520 cloog_domain_dim (cloog_domain (scatteringl
)) -
521 cloog_domain_dim (cloog_loop_domain (cloog_program_loop (p
)))) ;
522 nb_scattering
= cloog_program_nb_scattdims (p
);
523 scattering
= cloog_names_read_strings (file
, cloog_program_nb_scattdims (p
), prefix
, -1);
525 /* The boolean array for scalar dimensions is created and set to 0. */
526 cloog_program_set_scaldims (p
, (int *) malloc (cloog_program_nb_scattdims (p
) * sizeof (int)));
527 if (cloog_program_scaldims (p
) == NULL
)
529 fprintf(stderr
, "[CLooG]ERROR: memory overflow.\n") ;
532 for (i
=0;i
<cloog_program_nb_scattdims (p
);i
++)
533 cloog_program_set_scaldim (p
, i
, 0);
535 /* We try to find blocks in the input problem to reduce complexity. */
536 if (!options
->noblocks
)
537 cloog_program_block(p
,scatteringl
) ;
538 if (!options
->noscalars
)
539 cloog_program_extract_scalars(p
,scatteringl
) ;
541 cloog_program_scatter(p
,scatteringl
) ;
542 cloog_domain_list_free(scatteringl
) ;
546 cloog_program_set_nb_scattdims (p
, 0);
547 cloog_program_set_scaldims (p
, NULL
);
550 cloog_program_set_names
551 (p
, cloog_names_alloc (0, nb_scattering
, nb_iterators
, nb_parameters
,
552 NULL
, scattering
, iterators
, parameters
));
554 cloog_names_scalarize (cloog_program_names (p
), cloog_program_nb_scattdims (p
),
555 cloog_program_scaldims (p
));
559 cloog_program_set_loop (p
, NULL
);
560 cloog_program_set_names (p
, NULL
);
561 cloog_program_set_blocklist (p
, NULL
);
562 cloog_program_set_scaldims (p
, NULL
);
569 /******************************************************************************
570 * Processing functions *
571 ******************************************************************************/
575 * cloog_program_malloc function:
576 * This function allocates the memory space for a CloogProgram structure and
577 * sets its fields with default values. Then it returns a pointer to the
579 * - November 21th 2005: first version.
581 CloogProgram
* cloog_program_malloc (void)
582 { CloogProgram
* program
;
584 /* Memory allocation for the CloogProgram structure. */
585 program
= (CloogProgram
*)malloc(sizeof(CloogProgram
)) ;
587 { fprintf(stderr
, "[CLooG]ERROR: memory overflow.\n") ;
591 /* We set the various fields with default values. */
592 cloog_program_set_language (program
, 'c');
593 cloog_program_set_nb_scattdims (program
, 0);
594 cloog_program_set_context (program
, NULL
);
595 cloog_program_set_loop (program
, NULL
);
596 cloog_program_set_names (program
, NULL
);
597 cloog_program_set_blocklist (program
, NULL
);
598 cloog_program_set_scaldims (program
, NULL
);
599 cloog_program_set_usr (program
, NULL
);
606 * cloog_program_generate function:
607 * This function calls the Quillere algorithm for loop scanning. (see the
608 * Quillere paper) and calls the loop simplification function.
609 * - depth is the loop depth we want to optimize (guard free as possible),
610 * the first loop depth is 1 and anegative value is the infinity depth.
611 * - sep_level is the level number where we want to start loop separation.
613 * - October 26th 2001: first version.
614 * - April 19th 2005: some basic fixes and memory usage feature.
615 * - April 29th 2005: (bug fix, bug found by DaeGon Kim) see case 2 below.
617 CloogProgram
* cloog_program_generate(CloogProgram
*program
, CloogOptions
*options
)
619 #ifdef HAS_SYS_RESOURCE_H
620 struct rusage start
, end
;
624 char status_path
[MAX_STRING_VAL
] ;
627 /* We initialize the memory need to 0. */
628 options
->memory
= 0 ;
631 if (options
->override
)
633 /* Cloog should never print to stderr. */
635 "[CLooG]WARNING: you are using -override option, be aware that the "
636 "generated\n code may be incorrect.\n") ;
640 { /* Playing with options may be dangerous, here are two possible issues :
641 * 1. Using -l option less than scattering dimension number may lead to
642 * an illegal target code (since the scattering is not respected), if
643 * it is the case, we set -l depth to the first acceptable value.
645 if ((cloog_program_nb_scattdims (program
) > options
->l
) && (options
->l
>= 0))
647 /* Cloog should never print to stderr. */
649 "[CLooG]WARNING: -l depth is less than the scattering dimension number "
650 "(the \n generated code may be incorrect), it has been "
651 "automaticaly set\n to this value (use option -override "
654 options
->l
= cloog_program_nb_scattdims (program
);
657 /* 2. Using -f option greater than one while -l depth is greater than the
658 * scattering dimension number may lead to iteration duplication (try
659 * test/daegon_lu_osp.cloog with '-f 3' to test) because of the step 4b
660 * of the cloog_loop_generate function, if it is the case, we set -l to
661 * the first acceptable value.
663 if (((options
->f
> 1) || (options
->f
< 0)) &&
664 ((options
->l
> cloog_program_nb_scattdims (program
)) || (options
->l
< 0)))
666 /* Cloog should never print to stderr. */
668 "[CLooG]WARNING: -f depth is more than one, -l depth has been "
669 "automaticaly set\n to the scattering dimension number "
670 "(target code may have\n duplicated iterations), -l depth "
671 "has been automaticaly set to\n this value (use option "
672 "-override to override).\n") ;
674 options
->l
= cloog_program_nb_scattdims (program
);
678 #ifdef HAS_SYS_RESOURCE_H
679 getrusage(RUSAGE_SELF
, &start
) ;
682 if (cloog_program_loop (program
))
684 loop
= cloog_program_loop (program
) ;
687 loop
= cloog_loop_generate(loop
, cloog_program_context (program
), 1, 0,
688 cloog_program_scaldims (program
),
689 cloog_program_nb_scattdims (program
),
690 cloog_domain_dim (cloog_program_context (program
)),
694 /* We read into the status file of the process how many memory it uses. */
695 sprintf(status_path
,"/proc/%d/status",getpid()) ;
696 status
= fopen(status_path
, "r") ;
697 while (fscanf(status
,"%s",status_path
) && strcmp(status_path
,"VmData:")!=0);
698 fscanf(status
,"%d",&(options
->memory
)) ;
702 if ((!options
->nosimplify
) && cloog_program_loop (program
))
703 loop
= cloog_loop_simplify(loop
, cloog_program_context (program
), 1,
704 cloog_domain_dim (cloog_program_context (program
))) ;
706 cloog_program_set_loop (program
, loop
);
709 #ifdef HAS_SYS_RESOURCE_H
710 getrusage(RUSAGE_SELF
, &end
) ;
711 /* We calculate the time spent in code generation. */
712 time
= (end
.ru_utime
.tv_usec
- start
.ru_utime
.tv_usec
)/(float)(MEGA
) ;
713 time
+= (float)(end
.ru_utime
.tv_sec
- start
.ru_utime
.tv_sec
) ;
714 options
->time
= time
;
722 * cloog_program_block function:
723 * this function gives a last chance to the lazy user to consider statement
724 * blocks instead of some statement lists where the whole list may be
725 * considered as a single statement from a code generation point of view.
726 * For instance two statements with the same iteration domain and the same
727 * scattering functions may be considered as a block. This function is lazy
728 * and can only find very simple forms of trivial blocks (see
729 * cloog_domain_lazy_block function for more details). The useless loops and
730 * scattering functions are removed and freed while the statement list of
731 * according blocks are filled.
732 * - program is the whole program structure (befaore applying scattering),
733 * - scattering is the list of scattering functions.
735 * - April 30th 2005: first attempt.
736 * - June 10-11th 2005: first working version.
738 void cloog_program_block(CloogProgram
* program
, CloogDomainList
* scattering
)
739 { int blocked_reference
=0, blocked
=0, nb_blocked
=0 ;
740 CloogLoop
* reference
, * start
, * loop
;
741 CloogDomainList
* scatt_reference
, * scatt_loop
, * scatt_start
;
742 CloogBlockList
* previous
;
744 if ((cloog_program_loop (program
) == NULL
)
745 || (cloog_loop_next (cloog_program_loop (program
)) == NULL
))
748 /* We will have to rebuild the block list. */
749 cloog_block_list_free (cloog_program_blocklist (program
)) ;
750 cloog_program_set_blocklist
751 (program
, cloog_block_list_alloc (cloog_loop_block (cloog_program_loop (program
))));
752 previous
= cloog_program_blocklist (program
);
754 /* The process will use three variables for the linked list :
755 * - 'start' is the starting point of a new block,
756 * - 'reference' is the node of the block used for the block checking,
757 * - 'loop' is the candidate to be inserted inside the block.
758 * At the beginning of the process, the linked lists are as follow:
759 * O------>O------>O------>O------>NULL
765 reference
= cloog_program_loop (program
) ;
766 start
= cloog_program_loop (program
) ;
767 loop
= cloog_loop_next (reference
) ;
768 scatt_reference
= scattering
;
769 scatt_start
= scattering
;
770 scatt_loop
= cloog_next_domain (scattering
) ;
774 if (cloog_domain_lazy_equal (cloog_loop_domain (reference
),
775 cloog_loop_domain (loop
)) &&
776 cloog_domain_lazy_block(cloog_domain (scatt_reference
),
777 cloog_domain (scatt_loop
),
778 scattering
, cloog_program_nb_scattdims (program
)))
779 { /* If we find a block we update the links:
782 * O O------>O------>O------>NULL
789 cloog_block_merge(cloog_loop_block (start
), cloog_loop_block (loop
)); /* merge frees cloog_block (loop) */
790 cloog_loop_set_block (loop
, NULL
);
791 cloog_loop_set_next (start
, cloog_loop_next (loop
));
792 cloog_set_next_domain (scatt_start
, cloog_next_domain (scatt_loop
));
795 { /* If we didn't find a block, the next start of a block is updated:
796 * O------>O------>O------>O------>NULL
803 scatt_start
= scatt_loop
;
805 /* We update the block list. */
806 cloog_block_list_set_next (previous
, cloog_block_list_alloc (cloog_loop_block (start
)));
807 previous
= cloog_block_list_next (previous
) ;
810 /* If the reference node has been included into a block, we can free it. */
811 if (blocked_reference
)
812 { cloog_loop_set_next (reference
, NULL
);
813 cloog_loop_free (reference
) ;
814 cloog_domain_free (cloog_domain (scatt_reference
)) ;
815 free (scatt_reference
) ;
818 /* The reference and the loop are now updated for the next try, the
819 * starting position depends on the previous step.
820 * O ? O------>O------>O------>NULL
825 loop
= cloog_loop_next (loop
) ;
826 scatt_reference
= scatt_loop
;
827 scatt_loop
= cloog_next_domain (scatt_loop
) ;
829 /* We mark the new reference as being blocked or not, if will be freed
830 * during the next while loop execution.
833 blocked_reference
= 1 ;
835 blocked_reference
= 0 ;
838 /* We free the last blocked reference if any (since in the while loop it was
839 * freed during the next loop execution, it was not possible to free the
842 if (blocked_reference
)
843 { cloog_loop_set_next (reference
, NULL
);
844 cloog_loop_free (reference
) ;
845 cloog_domain_free (cloog_domain (scatt_reference
)) ;
846 free (scatt_reference
) ;
849 /* Cloog should never print to stderr. */
850 /* if (nb_blocked != 0)
851 fprintf(stderr, "[CLooG]INFO: %d domains have been blocked.\n",nb_blocked) ; */
856 * cloog_program_extract_scalars function:
857 * this functions finds and removes the dimensions of the scattering functions
858 * when they are scalar (i.e. of the shape "dim + scalar = 0") for all
859 * scattering functions. The reason is that the processing of such dimensions
860 * is trivial and do not need neither a row and a column in the matrix
861 * representation of the domain (this will save memory) neither the full
862 * Quillere processing (this will save time). The scalar dimensions data are
863 * dispatched in the CloogProgram structure (the boolean vector scaldims will
864 * say which original dimensions are scalar or not) and to the CloogBlock
865 * structures (each one has a scaldims vector that contains the scalar values).
866 * - June 14th 2005: first developments.
867 * - June 30th 2005: first version.
869 void cloog_program_extract_scalars(CloogProgram
*program
, CloogDomainList
*scattering
)
870 { int i
, j
, scalar
, current
, nb_scaldims
=0 ;
871 CloogDomainList
* start
;
873 CloogBlockList
* blocklist
;
878 for (i
= 0; i
< cloog_program_nb_scattdims (program
); i
++)
881 while (scattering
!= NULL
)
883 if (!cloog_domain_lazy_isscalar (cloog_domain (scattering
),i
))
888 scattering
= cloog_next_domain (scattering
);
894 cloog_program_set_scaldim (program
, i
, 1);
898 /* If there are no scalar dimensions, we can continue directly. */
902 /* Otherwise, in each block, we have to put the number of scalar dimensions,
903 * and to allocate the memory for the scalar values.
905 blocklist
= cloog_program_blocklist (program
);
906 while (blocklist
!= NULL
)
908 block
= cloog_block_list_block (blocklist
) ;
909 cloog_block_set_nb_scaldims (block
, nb_scaldims
);
910 cloog_block_set_scaldims (block
, (Value
*) malloc (nb_scaldims
* sizeof (Value
)));
912 for (i
= 0; i
< nb_scaldims
; i
++)
913 value_init_c (block
->scaldims
[i
]);
915 blocklist
= cloog_block_list_next (blocklist
);
918 /* Then we have to fill these scalar values, so we can erase those dimensions
919 * from the scattering functions. It's easier to begin with the last one,
920 * since there would be an offset otherwise (if we remove the i^th dimension,
921 * then the next one is not the (i+1)^th but still the i^th...).
923 current
= nb_scaldims
- 1 ;
924 for (i
= cloog_program_nb_scattdims (program
) - 1; i
>= 0; i
--)
925 if (cloog_program_scaldim (program
, i
))
927 blocklist
= cloog_program_blocklist (program
);
930 while (blocklist
!= NULL
)
932 block
= cloog_block_list_block (blocklist
) ;
933 cloog_domain_scalar (cloog_domain (scattering
), i
,
934 &block
->scaldims
[current
]);
935 blocklist
= cloog_block_list_next (blocklist
);
936 scattering
= cloog_next_domain (scattering
);
940 while (scattering
!= NULL
)
942 old
= cloog_domain (scattering
) ;
943 cloog_set_domain (scattering
, cloog_domain_erase_dimension (old
, i
)) ;
944 cloog_domain_free (old
) ;
945 scattering
= cloog_next_domain (scattering
);
950 /* We postprocess the scaldims array in such a way that each entry is how
951 * many scalar dimensions follows + 1 (the current one). This will make
952 * some other processing easier (e.g. knowledge of some offsets).
954 for (i
= 0; i
< cloog_program_nb_scattdims (program
) - 1; i
++)
956 if (cloog_program_scaldim (program
, i
))
959 while ((j
< cloog_program_nb_scattdims (program
))
960 && cloog_program_scaldim (program
, j
))
962 cloog_program_set_scaldim (program
, i
,
963 cloog_program_scaldim (program
, i
) + 1);
969 /* Cloog should never print to stderr. */
970 /* if (nb_scaldims != 0)
971 fprintf(stderr, "[CLooG]INFO: %d dimensions (over %d) are scalar.\n",
972 nb_scaldims, cloog_program_nb_scattdims (program)) ; */
977 * cloog_program_scatter function:
978 * This function adds the scattering (scheduling) informations in a program.
979 * If names is NULL, this function create names itself such that the i^th
981 * - November 6th 2001: first version.
983 void cloog_program_scatter(CloogProgram
*program
, CloogDomainList
*scattering
)
987 if ((program
!= NULL
) && (scattering
!= NULL
))
989 loop
= cloog_program_loop (program
) ;
991 /* Finally we scatter all loops. */
992 cloog_loop_scatter(loop
, cloog_domain (scattering
)) ;
993 loop
= cloog_loop_next (loop
) ;
994 scattering
= cloog_next_domain (scattering
);
996 while ((loop
!= NULL
) && (scattering
!= NULL
))
998 cloog_loop_scatter(loop
,cloog_domain (scattering
)) ;
999 loop
= cloog_loop_next (loop
) ;
1000 scattering
= cloog_next_domain (scattering
);