3 At the university of Ghent, we are starting to look
4 at automatic optimization of loops to optimize the implementation
5 in an FPGA. With the advent of your Cloog tool, we think
6 it becomes possible to use the polyhedral model
7 for the kind of optimizations we are thinking about, instead of using
8 optimizations based on transforming abstract syntax trees.
10 As a first test, we started with the representation of a
11 wavelet decoder loop kernel in Cloog format. We do this
12 by starting from a Fortran77-description, parse it
13 using our FPT compiler and PolyAst-library, and then
14 generate the Cloog data structures. Then we use
15 the function cloog_program_dump_cloog to obtain an
16 ASCII-file representing the code in Cloog-format.
18 However, when trying to read in the generated file,
19 we found that the generated file was incorrect, and
20 I think the cause is in two small bugs in the
21 function cloog_program_dump_cloog. After I've
22 corrected them, the generated file seems correct
23 (i.e. cloog can correctly read the generated file).
25 I've attached the adapted program.c source file.
26 I only changed the function cloog_program_dump_cloog,
27 and now it looks as follows:
29 void cloog_program_dump_cloog(FILE * foo, CloogProgram * program)
32 Polyhedron * polyhedron ;
37 "# This is an automatic dump of an input file from a CloogProgram data\n"
38 "# structure. It can be correct ONLY if dumped before loop generation.\n") ;
41 if (program->language == 'c')
42 fprintf(foo,"# Langage: C\n") ;
44 fprintf(foo,"# Langage: FORTRAN\n") ;
45 fprintf(foo,"%c\n\n",program->language) ;
48 fprintf(foo,"# Context (%d parameter(s)):\n",program->context->Dimension) ;
49 matrix = cloog_domain_domain2matrix(program->context) ;
50 cloog_domain_matrix_print(foo,matrix);
51 cloog_domain_matrix_free(matrix);
52 fprintf(foo,"1 # Parameter name(s)\n") ;
53 for (i=0;i<program->names->nb_parameters;i++)
54 fprintf(foo,"%s ",program->names->parameters[i]) ;
56 /* Statement number. */
58 loop = program->loop ;
63 fprintf(foo,"\n\n# Statement number:\n%d\n\n",i) ;
65 /* Iteration domains. */
67 loop = program->loop ;
69 { /* Name of the domain. */
70 fprintf(foo,"# Iteration domain of statement %d.\n",i) ;
72 /* Number of polyhedron inside the union of disjoint polyhedra. */
74 polyhedron = /* KB 15.05.2005 remove program->, since otherwise
75 the number of polytopes describing the iteration
76 space of the first loop will be printed, instead
77 of the number of polytopes for the current loop. program->*/loop->domain ;
78 while (polyhedron != NULL)
80 polyhedron = polyhedron->next ;
82 fprintf(foo,"%d\n",j) ;
84 /* The polyhedra themselves. */
85 polyhedron = loop->domain ;
86 while (polyhedron != NULL)
87 { matrix = cloog_domain_domain2matrix(polyhedron) ;
88 cloog_domain_matrix_print(foo,matrix);
89 cloog_domain_matrix_free(matrix);
90 polyhedron = polyhedron->next ;
92 /* KB 15.05.2005 : options should be printed once per statement, not once
94 fprintf(foo,"0 0 0 # For future options.\n\n") ;
98 fprintf(foo,"\n1 # Iterator name(s)\n") ;
99 for (i=0;i<program->names->nb_iterators;i++)
100 fprintf(foo,"%s ",program->names->iterators[i]) ;
101 fprintf(foo,"\n\n") ;
103 /* Scattering functions (none since included inside domains). */
104 fprintf(foo,"# No scattering functions.\n0\n\n") ;
108 The two changes are indicated by comments starting with the letters 'KB'.
110 I'm sending you these changes, so that they can be incorporated in the
111 next version of cloog, if you find them to be correct.
117 P.S.: I'm currently studying your work about loop chunking, since I'll
118 need some kind of generalized loop tiling transformation that extends over
119 multiple loop nests, to get an efficient implementation of the wavelet
123 -- -------------------------------------------------------------------- Parallel Information Systems Tel: +32(9)2649528 Universiteit Gent Fax: +32(9)2643594 St.-Pietersnieuwstraat 41 E-mail: Kristof.Beyls@elis.ugent.be B-9000 Gent, Belgium http://www.elis.ugent.be/~kbeyls --------------------------------------------------------------------
128 /**-------------------------------------------------------------------**
130 **-------------------------------------------------------------------**
132 **-------------------------------------------------------------------**
133 ** First version: october 25th 2001 **
134 **-------------------------------------------------------------------**/
137 /******************************************************************************
138 * CLooG : the Chunky Loop Generator (experimental) *
139 ******************************************************************************
141 * Copyright (C) 2001 Cedric Bastoul *
143 * This is free software; you can redistribute it and/or modify it under the *
144 * terms of the GNU General Public License as published by the Free Software *
145 * Foundation; either version 2 of the License, or (at your option) any later *
148 * This software is distributed in the hope that it will be useful, but *
149 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
150 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License *
151 * for more details. *
153 * You should have received a copy of the GNU General Public License along *
154 * with software; if not, write to the Free Software Foundation, Inc., *
155 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
157 * CLooG, the Chunky Loop Generator *
158 * Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
160 ******************************************************************************/
161 /* CAUTION: the english used for comments is probably the worst you ever read,
162 * please feel free to correct and improve it !
166 # include <sys/types.h>
167 # include <sys/time.h>
168 # include <sys/resource.h>
173 # include "../include/cloog/cloog.h"
176 /******************************************************************************
177 * Structure display function *
178 ******************************************************************************/
180 /* cloog_program_print function:
181 * This function prints the content of a CloogProgram structure (program) into a
182 * file (foo, possibly stdout).
184 void cloog_program_print(FILE * foo, CloogProgram * program)
185 { fprintf(foo,"Program:\n") ;
186 fprintf(foo,"Language %c.\n",program->language) ;
187 fprintf(foo,"Scattering dimension number = %d.\n",program->scattdims) ;
189 cloog_names_print(foo,program->names) ;
191 fprintf(foo,"Under the context:\n") ;
192 cloog_domain_print(foo,program->context) ;
194 cloog_loop_print(foo,program->loop) ;
198 /* cloog_program_dump_cloog function:
199 * This function dumps a CloogProgram structure supposed to be completely
200 * filled in a CLooG input file (foo possibly stdout) such as CLooG can
201 * rebuild almost exactly the data structure from the input file (the number
202 * of scattering functions is lost since they are included inside the
203 * iteration domains, this can only lead to a less beautiful pretty printing).
204 * 27 june 2003: first version.
206 void cloog_program_dump_cloog(FILE * foo, CloogProgram * program)
209 Polyhedron * polyhedron ;
214 "# This is an automatic dump of an input file from a CloogProgram data\n"
215 "# structure. It can be correct ONLY if dumped before loop generation.\n") ;
218 if (program->language == 'c')
219 fprintf(foo,"# Langage: C\n") ;
221 fprintf(foo,"# Langage: FORTRAN\n") ;
222 fprintf(foo,"%c\n\n",program->language) ;
225 fprintf(foo,"# Context (%d parameter(s)):\n",program->context->Dimension) ;
226 matrix = cloog_domain_domain2matrix(program->context) ;
227 cloog_domain_matrix_print(foo,matrix);
228 cloog_domain_matrix_free(matrix);
229 fprintf(foo,"1 # Parameter name(s)\n") ;
230 for (i=0;i<program->names->nb_parameters;i++)
231 fprintf(foo,"%s ",program->names->parameters[i]) ;
233 /* Statement number. */
235 loop = program->loop ;
240 fprintf(foo,"\n\n# Statement number:\n%d\n\n",i) ;
242 /* Iteration domains. */
244 loop = program->loop ;
246 { /* Name of the domain. */
247 fprintf(foo,"# Iteration domain of statement %d.\n",i) ;
249 /* Number of polyhedron inside the union of disjoint polyhedra. */
251 polyhedron = /* KB 15.05.2005 remove program->, since otherwise
252 the number of polytopes describing the iteration
253 space of the first loop will be printed, instead
254 of the number of polytopes for the current loop. program->*/loop->domain ;
255 while (polyhedron != NULL)
257 polyhedron = polyhedron->next ;
259 fprintf(foo,"%d\n",j) ;
261 /* The polyhedra themselves. */
262 polyhedron = loop->domain ;
263 while (polyhedron != NULL)
264 { matrix = cloog_domain_domain2matrix(polyhedron) ;
265 cloog_domain_matrix_print(foo,matrix);
266 cloog_domain_matrix_free(matrix);
267 polyhedron = polyhedron->next ;
269 /* KB 15.05.2005 : options should be printed once per statement, not once
271 fprintf(foo,"0 0 0 # For future options.\n\n") ;
275 fprintf(foo,"\n1 # Iterator name(s)\n") ;
276 for (i=0;i<program->names->nb_iterators;i++)
277 fprintf(foo,"%s ",program->names->iterators[i]) ;
278 fprintf(foo,"\n\n") ;
280 /* Scattering functions (none since included inside domains). */
281 fprintf(foo,"# No scattering functions.\n0\n\n") ;
285 /* cloog_program_dump_loopgen function:
286 * This function dumps a CloogProgram structure supposed to be completely
287 * filled in a LoopGen input file (foo possibly stdout) such as LoopGen can
288 * generate the code for this problem. If the user of CLooG had the bad idea
289 * to put the scattering functions directly inside the iteration domains, the
290 * time dimension of LoopGen is supposed to be 1.
291 * 27 june 2003: first version (should work but do not...).
293 void cloog_program_dump_loopgen(FILE * foo, CloogProgram * program)
296 Polyhedron * polyhedron ;
299 /* Statement number and time dimensions. */
301 loop = program->loop ;
306 if (program->scattdims)
307 time = program->scattdims ;
310 fprintf(foo,"%d %d 1\n\n",i,time) ;
313 "# CLooG -> LoopGen\n"
314 "# This is an automatic dump of an input file from a CloogProgram data\n"
315 "# structure. It can be correct ONLY if dumped before loop generation.\n\n") ;
318 fprintf(foo,"# Context (%d parameter(s)):\n1\n",program->context->Dimension) ;
319 matrix = cloog_domain_domain2matrix(program->context) ;
320 cloog_domain_matrix_print(foo,matrix);
321 cloog_domain_matrix_free(matrix);
324 /* Iteration domains. */
326 loop = program->loop ;
328 { /* Number of polyhedron inside the union of disjoint polyhedra. */
330 polyhedron = program->loop->domain ;
331 while (polyhedron != NULL)
333 polyhedron = polyhedron->next ;
335 fprintf(foo,"%d\n",j) ;
337 /* Name of the domain. */
338 fprintf(foo,"# Iteration domain of statement %d.\n",i) ;
340 /* The polyhedra themselves. */
341 polyhedron = loop->domain ;
342 while (polyhedron != NULL)
343 { matrix = cloog_domain_domain2matrix(polyhedron) ;
344 cloog_domain_matrix_print(foo,matrix);
345 cloog_domain_matrix_free(matrix);
346 polyhedron = polyhedron->next ;
355 /* cloog_program_dump_omega function:
356 * This function dumps a CloogProgram structure supposed to be completely
357 * filled in a OMEGA Calculator file (foo possibly stdout) such as OC can
358 * generate the code for this problem. If the user of CLooG had the bad idea
359 * to put the scattering functions directly inside the iteration domains, they
360 * will be added in the corresponding iteration domain for OMEGA with some
361 * equalities, so he need to pray (because OMEGA and equalities are really
363 * December 7th 2003: first version.
365 void cloog_program_dump_omega(FILE * foo, CloogProgram * program)
366 { int i, j, k, first, nb_iterators, nb_parameters, max_depth=0,
368 Polyhedron * polyhedron ;
374 "# This is an automatic dump of an input file from a CloogProgram data\n"
375 "# structure. It can be correct ONLY if dumped before loop generation.\n\n") ;
377 nb_parameters = program->context->Dimension ;
380 fprintf(foo,"# Context (%d parameter(s)).\n",nb_parameters) ;
381 if (nb_parameters >= 1)
382 { fprintf(foo,"Symbolic %s",program->names->parameters[0]) ;
383 for (i=1;i<nb_parameters;i++)
384 fprintf(foo,", %s",program->names->parameters[i]) ;
385 fprintf(foo," ;\n\n") ;
389 fprintf(foo,"# Iteration domains:\n") ;
390 statement_number = 1 ;
391 loop = program->loop ;
393 { nb_iterators = loop->domain->Dimension - nb_parameters ;
394 if (nb_iterators > max_depth)
395 max_depth = nb_iterators ;
397 /* Name of the statement. */
398 fprintf(foo,"IS%d0:={",statement_number) ;
402 if (nb_iterators-program->scattdims >= 1)
403 { fprintf(foo,"%s",program->names->iterators[program->scattdims]) ;
404 for (j=program->scattdims+1;j<nb_iterators;j++)
405 fprintf(foo,",%s",program->names->iterators[j]) ;
409 /* Number of polyhedron inside the union of disjoint polyhedra
410 * (must be 1 for OMEGA, we just check it).
413 polyhedron = program->loop->domain ;
414 while (polyhedron != NULL)
416 polyhedron = polyhedron->next ;
419 { fprintf(stderr,"[CLooG]ERROR: the problem cannot be dumped for OMEGA.\n");
423 /* The polyhedra themselves. */
424 polyhedron = loop->domain ;
425 for (j=program->scattdims;j<polyhedron->NbConstraints;j++)
428 if (j > program->scattdims)
429 fprintf(foo," && ") ;
431 /* The coefficients of the iterators and the parameters. */
432 for (k=1;k<=polyhedron->Dimension;k++)
433 if (polyhedron->Constraint[j][k] != 0)
435 { if (polyhedron->Constraint[j][k] > 0)
441 if ((polyhedron->Constraint[j][k] != 1) &&
442 (polyhedron->Constraint[j][k] != -1))
443 fprintf(foo,VALUE_FMT,polyhedron->Constraint[j][k]) ;
445 if (polyhedron->Constraint[j][k] == -1)
449 fprintf(foo,"%s",program->names->iterators[k-1]) ;
451 fprintf(foo,"%s",program->names->parameters[k-1-nb_iterators]) ;
454 /* The constant (k has the good value after the loop). */
455 if (polyhedron->Constraint[j][k] != 0)
457 { if (polyhedron->Constraint[j][k] > 0)
460 fprintf(foo,VALUE_FMT,polyhedron->Constraint[j][k]) ;
463 /* The (in)equality to 0. */
464 if (polyhedron->Constraint[j][0] == 0)
469 fprintf(foo,"} ;\n") ;
471 if ((loop = loop->next) != NULL)
472 statement_number ++ ;
475 /* Scattering functions (scheduling for OMEGA). */
476 loop = program->loop ;
477 if (program->scattdims > 0)
478 { statement_number = 1 ;
479 loop = program->loop ;
480 fprintf(foo,"\n# Schedules:\n") ;
483 { nb_iterators = loop->domain->Dimension - nb_parameters ;
484 if (nb_iterators > max_depth)
485 max_depth = nb_iterators ;
487 /* Name of the statement. */
488 fprintf(foo,"T%d0:={",statement_number) ;
492 if (nb_iterators-program->scattdims >= 1)
493 { fprintf(foo,"%s",program->names->iterators[program->scattdims]) ;
494 for (j=program->scattdims+1;j<nb_iterators;j++)
495 fprintf(foo,",%s",program->names->iterators[j]) ;
497 fprintf(foo,"] -> [") ;
499 /* The functions themselves. */
500 polyhedron = loop->domain ;
501 for (j=0;j<program->scattdims;j++)
507 /* We assume that the coefficient of the scattering iterator is 1. */
508 if ((polyhedron->Constraint[j][j+1] != 1) &&
509 (polyhedron->Constraint[j][j+1] != -1))
510 { fprintf(stderr,"[CLooG]ERROR: scattering dimension coefficients must "
511 "be 1 or -1to dump for OMEGA.") ;
515 /* Depending on the sign of the scattering coefficient, the
516 * coefficient for the scheduling expression.
518 if (polyhedron->Constraint[j][j+1] == 1)
523 /* The coefficients of the iterators and the parameters. */
524 for (k=program->scattdims+1;k<=polyhedron->Dimension;k++)
525 if (polyhedron->Constraint[j][k] != 0)
527 { if (sign*polyhedron->Constraint[j][k] > 0)
533 if ((polyhedron->Constraint[j][k] != 1) &&
534 (polyhedron->Constraint[j][k] != -1))
535 fprintf(foo,VALUE_FMT,sign*polyhedron->Constraint[j][k]) ;
537 if (sign*polyhedron->Constraint[j][k] == -1)
541 fprintf(foo,"%s",program->names->iterators[k-1]) ;
543 fprintf(foo,"%s",program->names->parameters[k-1-nb_iterators]) ;
546 /* The constant (k has the good value after the loop). */
547 if (polyhedron->Constraint[j][k] != 0)
549 { if (sign*polyhedron->Constraint[j][k] > 0)
552 fprintf(foo,VALUE_FMT,sign*polyhedron->Constraint[j][k]) ;
560 /* The scheduling expressions 'a la CLooG' end with the original
563 if (nb_iterators >= 1)
564 { for (j=program->scattdims;j<nb_iterators;j++)
565 fprintf(foo,",%s",program->names->iterators[j]) ;
568 /* ...and possibly zeros in order for the scheduling functions to have
569 * the same dimension number.
571 for (j=nb_iterators;j<max_depth;j++)
574 fprintf(foo,"]} ;\n") ;
576 if ((loop = loop->next) != NULL)
577 statement_number ++ ;
581 /* The codegen call. */
582 fprintf(foo,"\n# CodeGen call:\n") ;
583 fprintf(foo,"codegen %d ",max_depth) ;
584 if (statement_number > 0)
585 { if (program->scattdims != 0)
586 fprintf(foo,"T10:") ;
587 fprintf(foo,"IS10") ;
588 for (i=1;i<statement_number;i++)
589 { fprintf(foo,", ") ;
590 if (program->scattdims != 0)
591 fprintf(foo,"T%d0:",i+1) ;
592 fprintf(foo,"IS%d0",i+1) ;
595 fprintf(foo," ;\n") ;
599 /* cloog_program_pprint function:
600 * This function prints the content of a CloogProgram structure (program) into a
601 * file (foo, possibly stdout), in a C-like language.
603 void cloog_program_pprint(foo, program, options)
605 CloogProgram * program ;
606 CloogOptions * options ;
607 { CloogInfos * infos ;
609 infos = (CloogInfos *)malloc(sizeof(CloogInfos)) ;
610 infos->nb_iterators = program->names->nb_iterators ;
611 infos->nb_parameters = program->names->nb_parameters ;
612 infos->iterators = program->names->iterators ;
613 infos->parameters = program->names->parameters ;
614 infos->scattdims = program->scattdims ;
615 infos->options = options ;
616 /* Allocation for the array of strides, there is a +1 since the statement can
617 * be included inside an external loop without iteration domain.
619 infos->stride =(Value *)malloc((infos->nb_iterators+1)*sizeof(Value)) ;
621 if (program->language == 'f')
622 infos->language = LANGUAGE_FORTRAN ;
624 infos->language = LANGUAGE_C ;
626 if (program->language == 'f')
627 fprintf(foo,"! Generated from %s by CLooG v%s %s bits in %.2fs.\n",
628 options->name,CLOOG_RELEASE,CLOOG_VERSION,options->time) ;
630 fprintf(foo,"/* Generated from %s by CLooG v%s %s bits in %.2fs. */\n",
631 options->name,CLOOG_RELEASE,CLOOG_VERSION,options->time) ;
633 pprint(foo,program->loop,NULL,1,0,infos) ;
635 free(infos->stride) ;
640 /******************************************************************************
641 * Memory deallocation function *
642 ******************************************************************************/
645 /* cloog_program_free function:
646 * This function frees the allocated memory for a CloogProgram structure.
648 void cloog_program_free(CloogProgram * program)
649 { cloog_names_free(program->names) ;
650 cloog_loop_free(program->loop) ;
651 cloog_domain_free(program->context) ;
656 /******************************************************************************
658 ******************************************************************************/
661 /* cloog_program_read function:
662 * This function read the informations to put in a CloogProgram structure from
663 * a file (foo, possibly stdin). It returns a pointer to a CloogProgram
664 * structure containing the read informations.
665 * October 25th 2001: first version.
666 * September 9th 2002: - the big reading function is now splitted in several
667 * functions (one per read data structure).
668 * - adaptation to the new file format with naming.
670 CloogProgram * cloog_program_read(FILE * foo)
671 { int i, nb_statements, nb_parameters, nb_iterators ;
672 char s[MAX_STRING], language, ** scat_names, prefix[2]={'c','\0'} ;
673 CloogLoop * current, * next ;
675 CloogDomainList * scattering ;
678 /* Memory allocation for the CloogProgram structure. */
679 p = (CloogProgram *)malloc(sizeof(CloogProgram)) ;
681 { fprintf(stderr, "[CLooG]ERROR: memory overflow.\n") ;
685 /* Memory allocation for the CloogNames structure. */
686 names = (CloogNames *)malloc(sizeof(CloogNames)) ;
688 { fprintf(stderr, "[CLooG]ERROR: memory overflow.\n") ;
692 /* First of all, we read the language to use. */
693 while (fgets(s,MAX_STRING,foo) == 0) ;
694 while ((*s=='#'||*s=='\n') || (sscanf(s," %c",&language)<1))
695 fgets(s,MAX_STRING,foo) ;
696 p->language = language ;
698 /* We then read the context data. */
699 p->context = cloog_domain_read(foo) ;
700 nb_parameters = p->context->Dimension ;
702 /* Reading of the parameter names. */
703 names->nb_parameters = nb_parameters ;
704 names->parameters = cloog_names_read(foo,nb_parameters,NULL,FIRST_PARAMETER) ;
706 /* We read the statement number. */
707 while (fgets(s,MAX_STRING,foo) == 0) ;
708 while ((*s=='#'||*s=='\n') || (sscanf(s," %d",&nb_statements)<1))
709 fgets(s,MAX_STRING,foo) ;
711 /*printf("%d ",nb_statements) ;*/
713 /* Domains reading for each statement. */
714 if (nb_statements > 0)
715 { /* Reading of the first domain. */
716 p->loop = cloog_loop_read(foo,1,nb_parameters) ;
717 if (p->loop->domain != NULL)
718 nb_iterators = p->loop->domain->Dimension - nb_parameters ;
722 /* And the same for each next domain. */
724 for (i=2;i<=nb_statements;i++)
725 { next = cloog_loop_read(foo,i,nb_parameters) ;
726 if (next->domain != NULL)
727 if (next->domain->Dimension - nb_parameters > nb_iterators)
728 nb_iterators = next->domain->Dimension - nb_parameters ;
730 current->next = next ;
731 current = current->next ;
734 /* Reading of the iterator names. */
735 names->nb_iterators = nb_iterators ;
736 names->iterators = cloog_names_read(foo,nb_iterators,NULL,FIRST_ITERATOR) ;
739 /* Reading and puting the scattering data in program structure. */
740 scattering = cloog_domain_list_read(foo) ;
742 if (scattering != NULL)
743 { if (cloog_domain_list_quick_same(scattering))
744 { fprintf(stderr, "[CLooG]WARNING: some scattering functions are "
748 p->scattdims = scattering->domain->Dimension - p->loop->domain->Dimension;
749 scat_names = cloog_names_read(foo,p->scattdims,prefix,'1') ;
750 cloog_program_scatter(p,scattering,scat_names) ;
751 cloog_domain_list_free(scattering) ;
752 /* Now we can free scat_names since cloog_program_scatter copied it. */
753 for (i=0;i<p->scattdims;i++)
754 free(scat_names[i]) ;
769 /******************************************************************************
770 * Processing functions *
771 ******************************************************************************/
774 /* cloog_program_statement_count function:
775 * This function returns the number of statements in the whole program. This has
776 * nothing to do here, and I don't remember why and when I wrote it, anyway...
778 int cloog_program_statement_count(CloogLoop * start)
781 CloogStatement * statement ;
786 { if (loop->inner != NULL)
787 count += cloog_program_statement_count(loop->inner) ;
789 statement = loop->statement ;
791 while (statement != NULL)
793 statement = statement->next ;
802 /* cloog_program_generate function:
803 * This function calls the Quillere algorithm for loop scanning. (see the
804 * Quillere paper) and calls the loop simplification function.
805 * - depth is the loop depth we want to optimize (guard free as possible),
806 * the first loop depth is 1 and anegative value is the infinity depth.
807 * - sep_level is the level number where we want to start loop separation.
808 * October 26th 2001: first version.
810 CloogProgram * cloog_program_generate(program, options)
811 CloogProgram * program ;
812 CloogOptions * options ;
814 struct rusage start, end ;
815 CloogLoop * loop, * simplified ;
817 if ((program->scattdims > options->l) && (options->l > 0))
818 fprintf(stderr, "[CLooG]WARNING: -l depth is less than scattering dimension "
819 "number (the generated code may be illegal).\n") ;
821 if (program->loop == NULL)
824 { loop = program->loop ;
825 getrusage(RUSAGE_SELF, &start) ;
828 loop = cloog_loop_generate(loop,program->context,1,
829 program->context->Dimension,options) ;
831 getrusage(RUSAGE_SELF, &end) ;
832 /* We calculate the time spent in code generation. */
833 time = (end.ru_utime.tv_usec - start.ru_utime.tv_usec)/(float)(MEGA) ;
834 time += (float)(end.ru_utime.tv_sec - start.ru_utime.tv_sec) ;
835 options->time = time ;
838 { program->loop = NULL ;
842 { /*cloog_loop_print(stdout,loop) ;*/
843 simplified = cloog_loop_simplify(loop,program->context,1,
844 program->context->Dimension);
845 program->loop = simplified ;
846 /*program->loop = loop ;*/
853 /* cloog_program_scatter function:
854 * This function adds the scattering (scheduling) informations in a program.
855 * If names is NULL, this function create names itself such that the i^th
857 * November 6th 2001: first version.
859 void cloog_program_scatter(program, scattering, names)
860 CloogProgram * program ;
861 CloogDomainList * scattering ;
863 { int i, scattering_dim, scattering_dim2, new_dim, not_enough_constraints=0 ;
867 if ((program != NULL) && (scattering != NULL))
868 { loop = program->loop ;
870 /* We compute the scattering dimension and check it is >=0. */
871 scattering_dim = scattering->domain->Dimension - loop->domain->Dimension ;
872 if (scattering_dim <= 0)
873 { fprintf(stderr, "[CLooG]ERROR: scattering has not enough dimensions.\n") ;
876 if (scattering_dim >= scattering->domain->NbConstraints)
877 not_enough_constraints ++ ;
879 /* We add scattering names in program->iterators. */
880 new_dim = program->names->nb_iterators + scattering_dim ;
881 iterators = (char **)malloc(new_dim*sizeof(char *)) ;
882 if (iterators == NULL)
883 { fprintf(stderr, "[CLooG]ERROR: memory overflow.\n") ;
886 for (i=0;i<scattering_dim;i++)
887 { iterators[i] = (char *)malloc(MAX_NAME*sizeof(char)) ;
888 if (iterators[i] == NULL)
889 { fprintf(stderr, "[CLooG]ERROR: memory overflow.\n") ;
893 strcpy(iterators[i],names[i]) ;
895 sprintf(iterators[i],"c%d",i+1) ;
897 for (i=scattering_dim;i<new_dim;i++)
898 iterators[i] = program->names->iterators[i-scattering_dim] ;
899 free(program->names->iterators) ;
900 program->names->iterators = iterators ;
902 /* We update nb_iterators. */
903 program->names->nb_iterators = new_dim ;
905 /* Finally we scatter all loops. */
906 cloog_loop_scatter(loop,scattering->domain) ;
908 scattering = scattering->next ;
910 while ((loop != NULL) && (scattering != NULL))
911 { scattering_dim2 = scattering->domain->Dimension - loop->domain->Dimension;
912 if (scattering_dim2 != scattering_dim)
913 { fprintf(stderr, "[CLooG]ERROR: "
914 "scattering dimensions are not the same.\n") ;
917 if (scattering_dim2 >= scattering->domain->NbConstraints)
918 not_enough_constraints ++ ;
920 cloog_loop_scatter(loop,scattering->domain) ;
922 scattering = scattering->next ;
924 if ((loop != NULL) || (scattering != NULL))
925 fprintf(stderr, "[CLooG]WARNING: "
926 "there is not a scattering for each statement.\n");
928 if (not_enough_constraints)
929 fprintf(stderr, "[CLooG]WARNING: not enough constraints for "
930 "%d scattering function(s).\n",not_enough_constraints) ;