2 /*+-----------------------------------------------------------------**
4 **-----------------------------------------------------------------**
6 **-----------------------------------------------------------------**
7 ** First version: 30/04/2008 **
8 **-----------------------------------------------------------------**
11 *****************************************************************************
12 * OpenScop: Structures and formats for polyhedral tools to talk together *
13 *****************************************************************************
14 * ,___,,_,__,,__,,__,,__,,_,__,,_,__,,__,,___,_,__,,_,__, *
15 * / / / // // // // / / / // // / / // / /|,_, *
16 * / / / // // // // / / / // // / / // / / / /\ *
17 * |~~~|~|~~~|~~~|~~~|~~~|~|~~~|~|~~~|~~~|~~~|~|~~~|~|~~~|/_/ \ *
18 * | G |C| P | = | L | P |=| = |C| = | = | = |=| = |=| C |\ \ /\ *
19 * | R |l| o | = | e | l |=| = |a| = | = | = |=| = |=| L | \# \ /\ *
20 * | A |a| l | = | t | u |=| = |n| = | = | = |=| = |=| o | |\# \ \ *
21 * | P |n| l | = | s | t |=| = |d| = | = | = | | |=| o | | \# \ \ *
22 * | H | | y | | e | o | | = |l| | | = | | | | G | | \ \ \ *
23 * | I | | | | e | | | | | | | | | | | | | \ \ \ *
24 * | T | | | | | | | | | | | | | | | | | \ \ \ *
25 * | E | | | | | | | | | | | | | | | | | \ \ \ *
26 * | * |*| * | * | * | * |*| * |*| * | * | * |*| * |*| * | / \* \ \ *
27 * | O |p| e | n | S | c |o| p |-| L | i | b |r| a |r| y |/ \ \ / *
28 * '---'-'---'---'---'---'-'---'-'---'---'---'-'---'-'---' '--' *
30 * Copyright (C) 2008 University Paris-Sud 11 and INRIA *
32 * (3-clause BSD license) *
33 * Redistribution and use in source and binary forms, with or without *
34 * modification, are permitted provided that the following conditions *
37 * 1. Redistributions of source code must retain the above copyright notice, *
38 * this list of conditions and the following disclaimer. *
39 * 2. Redistributions in binary form must reproduce the above copyright *
40 * notice, this list of conditions and the following disclaimer in the *
41 * documentation and/or other materials provided with the distribution. *
42 * 3. The name of the author may not be used to endorse or promote products *
43 * derived from this software without specific prior written permission. *
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR *
46 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES *
47 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. *
48 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, *
49 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT *
50 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
51 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY *
52 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
53 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF *
54 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
56 * OpenScop Library, a library to manipulate OpenScop formats and data *
57 * structures. Written by: *
58 * Cedric Bastoul <Cedric.Bastoul@u-psud.fr> and *
59 * Louis-Noel Pouchet <Louis-Noel.pouchet@inria.fr> *
61 *****************************************************************************/
67 # include <openscop/scop.h>
70 /*+***************************************************************************
71 * Structure display functions *
72 *****************************************************************************/
76 * openscop_scop_print_structure function:
77 * Displays a openscop_scop_t structure (*scop) into a file (file, possibly
78 * stdout) in a way that trends to be understandable without falling in a deep
79 * depression or, for the lucky ones, getting a headache... It includes an
80 * indentation level (level) in order to work with others print_structure
82 * \param file File where informations are printed.
83 * \param scop The scop whose information have to be printed.
84 * \param level Number of spaces before printing, for each line.
87 openscop_scop_print_structure(FILE * file
, openscop_scop_p scop
, int level
)
93 // Go to the right level.
94 for (j
= 0; j
< level
; j
++)
96 fprintf(file
, "+-- openscop_scop_t\n");
99 for (j
= 0; j
<= level
+1; j
++)
100 fprintf(file
, "|\t");
103 // Print the language.
104 for (j
= 0; j
< level
; j
++)
105 fprintf(file
, "|\t");
106 fprintf(file
, "|\tLanguage: %s\n", scop
->language
);
109 for (j
= 0; j
<= level
+1; j
++)
110 fprintf(file
, "|\t");
113 // Print the context of the scop.
114 openscop_relation_print_structure(file
, scop
->context
, level
+1);
116 // Print the original parameter names.
117 for (i
= 0; i
<= level
; i
++)
118 fprintf(file
, "|\t");
119 if (scop
->nb_parameters
> 0)
121 fprintf(file
, "+-- Parameter strings:");
122 for (i
= 0; i
< scop
->nb_parameters
; i
++)
123 fprintf(file
, " %s", scop
->parameters
[i
]);
127 fprintf(file
, "+-- No parameter strings\n");
130 for (j
= 0; j
<= level
+1; j
++)
131 fprintf(file
, "|\t");
134 // Print the iterator names.
135 for (i
= 0; i
<= level
; i
++)
136 fprintf(file
, "|\t");
137 if (scop
->nb_iterators
> 0)
139 fprintf(file
, "+-- Iterator strings:");
140 for (i
= 0; i
< scop
->nb_iterators
; i
++)
141 fprintf(file
, " %s", scop
->iterators
[i
]);
145 fprintf(file
,"+-- No iterator string\n");
148 for (j
= 0; j
<= level
+1; j
++)
149 fprintf(file
, "|\t");
152 // Print the scattering dimension names.
153 for (i
= 0; i
<= level
; i
++)
154 fprintf(file
, "|\t");
155 if (scop
->nb_scattdims
> 0)
157 fprintf(file
, "+-- Scattering dimension strings:");
158 for (i
= 0; i
< scop
->nb_scattdims
; i
++)
159 fprintf(file
, " %s", scop
->scattdims
[i
]);
163 fprintf(file
, "+-- No scattering dimension string\n");
166 for (j
= 0; j
<= level
+1; j
++)
167 fprintf(file
, "|\t");
170 // Print the statements.
171 openscop_statement_print_structure(file
, scop
->statement
, level
+1);
175 // Go to the right level.
176 for (j
= 0; j
< level
; j
++)
177 fprintf(file
, "|\t");
178 fprintf(file
, "+-- NULL scop\n");
182 for (j
= 0; j
<= level
; j
++)
183 fprintf(file
, "|\t");
189 * openscop_scop_print function:
190 * This function prints the content of a openscop_scop_t structure (*scop) into
191 * a file (file, possibly stdout).
192 * \param file File where informations are printed.
193 * \param scop The scop whose information have to be printed.
196 openscop_scop_print(FILE * file
, openscop_scop_p scop
)
198 openscop_scop_print_structure(file
, scop
, 0);
203 * openscop_scop_print_openscop function:
204 * This function prints the content of a openscop_scop_t structure (*scop)
205 * into a file (file, possibly stdout) in the OpenScop format.
206 * \param file File where informations are printed.
207 * \param scop The scop whose information have to be printed.
210 openscop_scop_print_openscop(FILE * file
, openscop_scop_p scop
)
214 char ** arrays
= NULL
;
216 // Extract array names information.
217 arrays
= openscop_util_read_tag_arrays(scop
->extensions
, &nb_arrays
);
221 fprintf(file
, "# \n");
222 fprintf(file
, "# <| \n");
223 fprintf(file
, "# A \n");
224 fprintf(file
, "# /.\\ \n");
225 fprintf(file
, "# <| [\"\"M# \n");
226 fprintf(file
, "# A | # Clan McCloog Castle \n");
227 fprintf(file
, "# /.\\ [\"\"M# [Generated by the OpenScop ");
228 fprintf(file
, "Library %s %s bits]\n",OPENSCOP_RELEASE
, OPENSCOP_VERSION
);
229 fprintf(file
, "# [\"\"M# | # U\"U#U \n");
230 fprintf(file
, "# | # | # \\ .:/ \n");
231 fprintf(file
, "# | # | #___| # \n");
232 fprintf(file
, "# | \"--' .-\" \n");
233 fprintf(file
, "# |\"-\"-\"-\"-\"-#-#-## \n");
234 fprintf(file
, "# | # ## ###### \n");
235 fprintf(file
, "# \\ .::::'/ \n");
236 fprintf(file
, "# \\ ::::'/ \n");
237 fprintf(file
, "# :8a| # # ## \n");
238 fprintf(file
, "# ::88a ### \n");
239 fprintf(file
, "# ::::888a 8a ##::. \n");
240 fprintf(file
, "# ::::::888a88a[]:::: \n");
241 fprintf(file
, "# :::::::::SUNDOGa8a::::. .. \n");
242 fprintf(file
, "# :::::8::::888:Y8888:::::::::... \n");
243 fprintf(file
, "#::':::88::::888::Y88a______________________________");
244 fprintf(file
, "________________________\n");
245 fprintf(file
, "#:: ::::88a::::88a:Y88a ");
246 fprintf(file
, " __---__-- __\n");
247 fprintf(file
, "#' .: ::Y88a:::::8a:Y88a ");
248 fprintf(file
, "__----_-- -------_-__\n");
249 fprintf(file
, "# :' ::::8P::::::::::88aa. _ _- -");
250 fprintf(file
, "- --_ --- __ --- __--\n");
251 fprintf(file
, "#.:: :::::::::::::::::::Y88as88a...s88aa.\n");
255 fprintf(file
, "# [File generated by the OpenScop Library %s %s bits]\n",
256 OPENSCOP_RELEASE
,OPENSCOP_VERSION
);
259 fprintf(file
, "\nOpenScop\n\n");
260 fprintf(file
, "# =============================================== Global\n");
261 fprintf(file
, "# Language\n");
262 fprintf(file
, "%s\n\n", scop
->language
);
264 fprintf(file
, "# Context\n");
265 openscop_relation_print_openscop(file
, scop
->context
, OPENSCOP_TYPE_DOMAIN
,
267 scop
->nb_parameters
, scop
->parameters
,
271 if (scop
->nb_parameters
> 0)
273 fprintf(file
, "# Parameter names are provided\n");
274 fprintf(file
, "1\n");
275 fprintf(file
, "# Parameter names\n");
276 for (i
= 0; i
< scop
->nb_parameters
; i
++)
277 fprintf(file
, "%s ", scop
->parameters
[i
]);
278 fprintf(file
, "\n\n");
282 fprintf(file
, "# Parameter names are not provided\n");
283 fprintf(file
, "0\n\n");
286 if (scop
->nb_iterators
> 0)
288 fprintf(file
, "# Iterator names are provided\n");
289 fprintf(file
, "1\n");
290 fprintf(file
, "# Iterator names\n");
291 for (i
= 0; i
< scop
->nb_iterators
; i
++)
292 fprintf(file
, "%s ", scop
->iterators
[i
]);
293 fprintf(file
, "\n\n");
297 fprintf(file
, "# Iterator names are not provided\n");
298 fprintf(file
, "0\n\n");
301 if (scop
->nb_scattdims
> 0)
303 fprintf(file
, "# Scattering dimension names are provided\n");
304 fprintf(file
, "1\n");
305 fprintf(file
, "# Scattering dimension names\n");
306 for (i
= 0; i
< scop
->nb_scattdims
; i
++)
307 fprintf(file
, "%s ", scop
->scattdims
[i
]);
308 fprintf(file
, "\n\n");
312 fprintf(file
, "# Scattering dimension names are not provided\n");
313 fprintf(file
, "0\n\n");
316 fprintf(file
, "# Number of statements\n");
317 fprintf(file
, "%d\n\n",openscop_statement_number(scop
->statement
));
319 openscop_statement_print_openscop(file
, scop
->statement
,
320 scop
->nb_parameters
, scop
->parameters
,
323 fprintf(file
, "# =============================================== Options\n");
324 if (scop
->extensions
)
326 if (scop
->textual_extensions
)
327 fprintf(file
, "%s", (char *)scop
->extensions
);
329 openscop_extension_print(file
, (openscop_extension_p
)scop
->extensions
);
335 for (i
= 0; i
< nb_arrays
; i
++)
342 /*****************************************************************************
344 *****************************************************************************/
349 openscop_scop_update_val(int * variable
, int value
)
351 if ((*variable
== OPENSCOP_UNDEFINED
) || (*variable
== value
))
354 fprintf(stderr
, "[OpenScop] Warning: number of iterators and "
355 "parameters inconsistency.\n");
360 openscop_scop_update_properties(openscop_relation_p relation
,
361 int nb_output_dims
, int nb_input_dims
,
364 if (relation
!= NULL
)
366 openscop_scop_update_val(&(relation
->nb_output_dims
), nb_output_dims
);
367 openscop_scop_update_val(&(relation
->nb_input_dims
), nb_input_dims
);
368 openscop_scop_update_val(&(relation
->nb_parameters
), nb_parameters
);
374 * openscop_scop_propagate_properties internal function:
375 * This function tries to propagate information in all relations through the
376 * whole openscop representation. For instance, the number of parameters can
377 * be found in the context as well as in any relation: if it is undefined in
378 * the relation, this function defines it, if it is different than the
379 * expected value, it reports an error. This function does the same for
380 * the number of output and input dimensions.
381 * \param scop The SCoP we want to propagate properties.
385 openscop_scop_propagate_properties(openscop_scop_p scop
)
387 int i
, nb_parameters
;
388 openscop_statement_p statement
;
389 openscop_relation_p relation
;
390 openscop_relation_list_p list
;
392 // Context part: get the number of parameters.
393 if ((scop
->context
!= NULL
) &&
394 (openscop_relation_is_matrix(scop
->context
)))
396 nb_parameters
= scop
->context
->nb_columns
- 2;
397 openscop_scop_update_properties(scop
->context
, 0, 0, nb_parameters
);
402 // For each statement:
403 statement
= scop
->statement
;
404 while (statement
!= NULL
)
407 relation
= statement
->domain
;
408 if (openscop_relation_is_matrix(relation
))
410 while (relation
!= NULL
)
412 openscop_scop_update_properties(relation
,
413 relation
->nb_columns
- nb_parameters
- 2, 0, nb_parameters
);
414 relation
= relation
->next
;
418 // - Scattering part,
419 relation
= statement
->scattering
;
420 if (openscop_relation_is_matrix(relation
))
422 while (relation
!= NULL
)
424 openscop_scop_update_properties(relation
,
425 0, relation
->nb_columns
- nb_parameters
- 2, nb_parameters
);
426 relation
= relation
->next
;
431 for (i
= 0; i
< 2; i
++)
434 list
= statement
->read
;
436 list
= statement
->write
;
440 relation
= list
->elt
;
441 if (openscop_relation_is_matrix(relation
))
443 while (relation
!= NULL
)
445 openscop_scop_update_properties(relation
,
446 0, relation
->nb_columns
- nb_parameters
- 2, nb_parameters
);
447 relation
= relation
->next
;
455 statement
= statement
->next
;
461 * openscop_scop_read function:
462 * This function reads a openscop_scop_t structure from an input stream
463 * (possibly stdin) corresponding to an OpenScop input file. If some relation
464 * properties (number of input/output/local dimensions and number of
465 * parameters) are undefined, it will define them according to the available
467 * \param file The input stream
470 openscop_scop_read(FILE * file
)
472 openscop_scop_p scop
= NULL
;
473 openscop_statement_p stmt
= NULL
;
474 openscop_statement_p prev
= NULL
;
483 scop
= openscop_scop_malloc();
485 // Backup the arrays of the program. Buffer is reajustable.
486 /*int nb_arr = OPENSCOP_MAX_STRING;
487 char ** arrays = (char **) malloc (sizeof(char *) * nb_arr);
488 for (i = 0; i < nb_arr; ++i)
496 // Ensure the file is a .scop.
497 tmp
= openscop_util_read_strings(file
, 1, &max
);
498 if ((max
== 0) || (strcmp(*tmp
, "OpenScop")))
500 fprintf(stderr
, "[OpenScop] Error: not an OpenScop file "
501 "(type \"%s\".\n", *tmp
);
505 fprintf(stderr
, "[OpenScop] Warning: uninterpreted information "
506 "(after file type).\n");
510 // Read the language.
511 char ** language
= openscop_util_read_strings(file
, 1, &max
);
514 fprintf(stderr
, "[OpenScop] Error: no language (backend) specified.\n");
518 fprintf(stderr
, "[OpenScop] Warning: uninterpreted information "
519 "(after language).\n");
520 scop
->language
= *language
;
524 scop
->context
= openscop_relation_read(file
);
525 scop
->nb_parameters
= scop
->context
->nb_columns
- 2;
527 // Read the parameter names, if any.
528 if (openscop_util_read_int(file
, NULL
) > 0)
530 scop
->parameters
= openscop_util_read_strings(file
,
531 scop
->nb_parameters
, &max
);
532 if (max
< scop
->nb_parameters
)
534 fprintf(stderr
, "[OpenScop] Error: not enough parameter names.\n");
537 if (max
> scop
->nb_parameters
)
538 fprintf(stderr
, "[OpenScop] Warning: uninterpreted information "
539 "(after parameter names).\n");
542 scop
->parameters
= NULL
;
544 // Read the iterator names, if any.
545 if (openscop_util_read_int(file
, NULL
) > 0)
546 scop
->iterators
= openscop_util_read_strings(file
, -1,
547 &(scop
->nb_iterators
));
550 scop
->nb_iterators
= 0;
551 scop
->iterators
= NULL
;
554 // Read the scattering dimension names, if any.
555 if (openscop_util_read_int(file
, NULL
) > 0)
556 scop
->scattdims
= openscop_util_read_strings(file
, -1,
557 &(scop
->nb_scattdims
));
560 scop
->nb_scattdims
= 0;
561 scop
->scattdims
= NULL
;
565 // II. STATEMENT PART
568 // Read the number of statements.
569 nb_statements
= openscop_util_read_int(file
, NULL
);
571 for (i
= 0; i
< nb_statements
; ++i
)
573 // Read each statement.
574 stmt
= openscop_statement_read(file
);
575 if (scop
->statement
== NULL
)
576 scop
->statement
= stmt
;
586 // Read the remainder of the file, and store it in the extensions field.
587 scop
->textual_extensions
= 1;
588 scop
->extensions
= (void *)openscop_extension_read_string(file
);
591 // VI. FINALIZE AND CHECK
593 openscop_scop_propagate_properties(scop
);
595 if (!openscop_scop_integrity_check(scop
))
596 fprintf(stderr
, "[OpenScop] Warning: global integrity check failed.\n");
602 /*+***************************************************************************
603 * Memory allocation/deallocation functions *
604 *****************************************************************************/
608 * openscop_scop_malloc function:
609 * This function allocates the memory space for a openscop_scop_t structure and
610 * sets its fields with default values. Then it returns a pointer to the
612 * \return A pointer to an empty scop with fields set to default values.
615 openscop_scop_malloc()
617 openscop_scop_p scop
;
619 scop
= (openscop_scop_p
)malloc(sizeof(openscop_scop_t
));
622 fprintf(stderr
, "[OpenScop] Memory Overflow.\n");
627 scop
->textual_names
= 1;
628 scop
->textual_extensions
= 1;
629 scop
->language
= NULL
;
630 scop
->context
= NULL
;
631 scop
->nb_parameters
= 0;
632 scop
->nb_iterators
= 0;
633 scop
->nb_scattdims
= 0;
634 scop
->parameters
= NULL
;
635 scop
->iterators
= NULL
;
636 scop
->scattdims
= NULL
;
637 scop
->statement
= NULL
;
638 scop
->extensions
= NULL
;
646 * openscop_scop_free function:
647 * This function frees the allocated memory for a openscop_scop_t structure.
648 * \param scop The pointer to the scop we want to free.
651 openscop_scop_free(openscop_scop_p scop
)
657 if (scop
->language
!= NULL
)
658 free(scop
->language
);
660 openscop_relation_free(scop
->context
);
662 if (scop
->parameters
!= NULL
)
664 for (i
= 0; i
< scop
->nb_parameters
; i
++)
665 free(scop
->parameters
[i
]);
666 free(scop
->parameters
);
669 if (scop
->iterators
!= NULL
)
671 for (i
= 0; i
< scop
->nb_iterators
; i
++)
672 free(scop
->iterators
[i
]);
673 free(scop
->iterators
);
676 if (scop
->scattdims
!= NULL
)
678 for (i
= 0; i
< scop
->nb_scattdims
; i
++)
679 free(scop
->scattdims
[i
]);
680 free(scop
->scattdims
);
683 openscop_statement_free(scop
->statement
);
685 if (scop
->textual_extensions
)
686 free(scop
->extensions
);
688 openscop_extension_free((openscop_extension_p
)scop
->extensions
);
695 /*+***************************************************************************
696 * Processing functions *
697 *****************************************************************************/
701 * openscop_scop_copy function:
702 * This functions builds and returns a "hard copy" (not a pointer copy)
703 * of a openscop_statement_t data structure provided as parameter.
704 * Note that the usr field is not touched by this function.
705 * \param statement The pointer to the scop we want to copy.
706 * \return A pointer to the full copy of the scop provided as parameter.
709 openscop_scop_copy(openscop_scop_p scop
)
711 openscop_scop_p copy
;
713 copy
= openscop_scop_malloc();
714 copy
->textual_names
= scop
->textual_names
;
715 copy
->textual_extensions
= scop
->textual_extensions
;
716 copy
->version
= scop
->version
;
717 copy
->language
= strdup(scop
->language
);
718 copy
->context
= openscop_relation_copy(scop
->context
);
719 copy
->nb_parameters
= scop
->nb_parameters
;
720 copy
->nb_iterators
= scop
->nb_iterators
;
721 copy
->nb_scattdims
= scop
->nb_scattdims
;
722 copy
->parameters
= openscop_util_copy_strings(scop
->parameters
,
723 scop
->nb_parameters
);
724 copy
->iterators
= openscop_util_copy_strings(scop
->iterators
,
726 copy
->scattdims
= openscop_util_copy_strings(scop
->scattdims
,
728 copy
->statement
= openscop_statement_copy(scop
->statement
);
730 if (scop
->textual_extensions
)
731 copy
->extensions
= strdup((char *)scop
->extensions
);
733 copy
->extensions
= openscop_extension_copy((openscop_extension_p
)
741 * openscop_scop_equal function:
742 * this function returns true if the two scops are the same, false
743 * otherwise (the usr field is not tested).
744 * \param s1 The first scop.
745 * \param s2 The second scop.
746 * \return 1 if s1 and s2 are the same (content-wise), 0 otherwise.
749 openscop_scop_equal(openscop_scop_p s1
, openscop_scop_p s2
)
753 if (s1
->version
!= s2
->version
)
755 fprintf(stderr
, "[OpenScop] info: versions are not the same.\n");
759 if (strcmp(s1
->language
, s2
->language
) != 0)
761 fprintf(stderr
, "[OpenScop] info: languages are not the same.\n");
765 if (!openscop_relation_equal(s1
->context
, s2
->context
))
767 fprintf(stderr
, "[OpenScop] info: contexts are not the same.\n");
771 if (s1
->nb_parameters
!= s2
->nb_parameters
)
773 fprintf(stderr
, "[OpenScop] info: #parameters are not the same.\n");
777 if (s1
->nb_iterators
!= s2
->nb_iterators
)
779 fprintf(stderr
, "[OpenScop] info: #iterators are not the same.\n");
783 if (s1
->nb_scattdims
!= s2
->nb_scattdims
)
785 fprintf(stderr
, "[OpenScop] info: #scattdims are not the same.\n");
789 if (!openscop_statement_equal(s1
->statement
, s2
->statement
))
791 fprintf(stderr
, "[OpenScop] info: statements are not the same.\n");
795 if ((s1
->textual_extensions
!= s2
->textual_extensions
) ||
796 (s1
->textual_extensions
&& strcmp(s1
->extensions
, s2
->extensions
)) ||
797 (!s1
->textual_extensions
&& !openscop_extension_equal(s1
->extensions
,
800 fprintf(stderr
, "[OpenScop] info: extensions are not the same.\n");
804 for (i
= 0; i
< s1
->nb_parameters
; i
++)
805 if (strcmp(s1
->parameters
[i
], s2
->parameters
[i
]) != 0)
807 fprintf(stderr
, "[OpenScop] info: parameter names are not the same.\n");
811 for (i
= 0; i
< s1
->nb_iterators
; i
++)
812 if (strcmp(s1
->iterators
[i
], s2
->iterators
[i
]) != 0)
814 fprintf(stderr
, "[OpenScop] info: iterator names are not the same.\n");
818 for (i
= 0; i
< s1
->nb_scattdims
; i
++)
819 if (strcmp(s1
->scattdims
[i
], s2
->scattdims
[i
]) != 0)
821 fprintf(stderr
, "[OpenScop] info: scattdims names are not the same.\n");
830 * openscop_scop_integrity_check function:
831 * This function checks that a scop is "well formed". It returns 0 if the
832 * check failed or 1 if no problem has been detected.
833 * \param scop The scop we want to check.
834 * \return 0 if the integrity check fails, 1 otherwise.
837 openscop_scop_integrity_check(openscop_scop_p scop
)
839 int expected_nb_parameters
;
840 int nb_iterators
, max_nb_iterators
= 0;
841 int max_nb_scattdims
= 0;
842 openscop_statement_p statement
;
844 // Check the language.
845 if ((scop
->language
!= NULL
) &&
846 (!strcmp(scop
->language
, "caml") || !strcmp(scop
->language
, "Caml") ||
847 !strcmp(scop
->language
, "ocaml") || !strcmp(scop
->language
, "OCaml")))
848 fprintf(stderr
, "[OpenScop] Alert: Caml ?! Are you sure ?! ;)\n");
850 // Check the context.
851 if (!openscop_relation_integrity_check(scop
->context
,
852 OPENSCOP_TYPE_CONTEXT
,
853 0, 0, OPENSCOP_UNDEFINED
))
856 // Get the number of parameters.
857 if (scop
->context
!= NULL
)
859 if (openscop_relation_is_matrix(scop
->context
))
860 expected_nb_parameters
= scop
->context
->nb_columns
- 2;
862 expected_nb_parameters
= scop
->context
->nb_parameters
;
865 expected_nb_parameters
= OPENSCOP_UNDEFINED
;
867 if (!openscop_statement_integrity_check(scop
->statement
,
868 expected_nb_parameters
))
871 // Ensure we have enough names.
872 if (expected_nb_parameters
== OPENSCOP_UNDEFINED
)
873 expected_nb_parameters
= 0;
875 statement
= scop
->statement
;
876 while (statement
!= NULL
)
878 if (statement
->domain
!= NULL
)
880 if (openscop_relation_is_matrix(statement
->domain
))
882 nb_iterators
= statement
->domain
->nb_columns
-
883 expected_nb_parameters
- 2;
884 if (nb_iterators
> max_nb_iterators
)
885 max_nb_iterators
= nb_iterators
;
889 if (statement
->domain
->nb_output_dims
> max_nb_iterators
)
890 max_nb_iterators
= statement
->domain
->nb_output_dims
;
894 if (statement
->scattering
!= NULL
)
896 if (openscop_relation_is_matrix(statement
->scattering
))
898 if (statement
->domain
->nb_rows
> max_nb_scattdims
)
899 max_nb_scattdims
= statement
->scattering
->nb_rows
;
903 if (statement
->scattering
->nb_input_dims
> max_nb_scattdims
)
904 max_nb_scattdims
= statement
->scattering
->nb_input_dims
;
908 statement
= statement
->next
;
911 if ((scop
->nb_iterators
> 0) &&
912 (scop
->nb_iterators
< max_nb_iterators
))
914 fprintf(stderr
, "[OpenScop] Warning: not enough iterator names.\n");
918 if ((scop
->nb_scattdims
> 0) &&
919 (scop
->nb_scattdims
< max_nb_scattdims
))
921 fprintf(stderr
, "[OpenScop] Warning: not enough scattering "
922 "dimension names.\n");