From 9d39138c75ca827990993fbcfd3c1e56b8c12ca5 Mon Sep 17 00:00:00 2001 From: Cedric Bastoul Date: Thu, 23 Jun 2011 02:15:36 +0200 Subject: [PATCH] One list to rule all accesses --- doc/openscop.texi | 76 +++++++++++++------ include/openscop/relation.h | 1 + include/openscop/relation_list.h | 14 ++-- include/openscop/statement.h | 17 ++--- source/relation.c | 47 ++++++------ source/relation_list.c | 123 +++++++++++++++++++++++-------- source/scop.c | 56 ++++++-------- source/statement.c | 154 +++++++++++++++++++++++---------------- source/util.c | 5 +- tests/openscop_test.c | 2 +- tests/polynom.scop | 16 ++-- 11 files changed, 311 insertions(+), 200 deletions(-) diff --git a/doc/openscop.texi b/doc/openscop.texi index 39d7580..d557e5b 100644 --- a/doc/openscop.texi +++ b/doc/openscop.texi @@ -1685,7 +1685,8 @@ C[i][j] = C[i][j] + A[i][k] * B[k][j]; @subsection OpenScop Core Part File Format Specification The following grammar describes the structure of the first part of the -OpenScop file format where terminals are preceeded by "_". Each +OpenScop file format where terminals are preceeded by "_". There can be +at most one terminal per line in the file. Each relevant part will be explained in more details momentarily. It looks long but it has been artificially extended to be easily understood. It can be easily simplified to few rules: @@ -1700,20 +1701,13 @@ Statements ::= Nb_statements Statement_list Statement_list ::= Statement Statement_list | (void) String_list ::= _String String_list | (void) Relation_list ::= _Relation Relation_list | (void) -Statement ::= Iteration_domain Scattering Access Body -Scattering ::= "0" | "1" Scattering_relation -Access ::= "0" | "1" Read_relations Write_relations +Statement ::= Statement_relations Body Body ::= "0" | "1" Iterator_list Body_text Parameter_list ::= "0" | "1" String_list Iterator_list ::= "0" | "1" String_list Scattdim_list ::= "0" | "1" String_list -Read_relations ::= Nb_relations Relation_List -Write_relations ::= Nb_relations Relation_List +Statement_relations ::= Nb_relations Relation_List Parameter_domain ::= _Relation -Iteration_domain ::= _Relation -Scattering_relation ::= _Relation -Read_relation ::= _Relation -Write_relation ::= _Relation Language ::= _String Body_text ::= _Text_line Nb_Relations ::= _Integer @@ -1725,8 +1719,8 @@ Nb_Relations ::= _Integer consists on the target language, the global constraints on the parameters and optionally the various names which may be necessary for the code generation process. The constraints on the parameters - are represented as a relation (@pxref{Relation Representation}) with - zero input and zero output dimensions. Three lists of names may + are represented as a relation (@pxref{Context Domain Representation}) + with zero input and zero output dimensions. Three lists of names may be provided. The first one corresponds to parameters, the second one to iterators and the third one to scattering dimensions. Each list starts with an integer: a @samp{0} means that we don't provide @@ -1737,18 +1731,16 @@ Nb_Relations ::= _Integer @samp{Nb_statements} is the number of statements in the SCoP, i.e. the number of @samp{Statement} items in the @samp{Statement_list}. @samp{Statement} represents the information on a given statement. - To each statement is associated four piece of information. - The first one is the statement iteration domain - @samp{Iteration_domain} and is mandatory. Then, one can provide - optionnally the scattering information, the data access - information and the statement body, in this order. - Each optional information is preceeded by a boolean which precises - whether the optional information is provided or not. - The iteration domain (@pxref{Iteration Domain Representation}), - the scattering information (@pxref{Scattering Relation Representation}) and the - the access information (@pxref{Access Relation Representation}) - are all represented as (a list of) relations - (@pxref{Relation Representation}). The statement body is made of two + To each statement is associated a list of relations and, + optionaly, a body. The list of relations may include + one iteration domain (@pxref{Iteration Domain Representation}), + one scattering relation (@pxref{Scattering Relation Representation}) + and several access relations (@pxref{Access Relation Representation}). + There is no mandatory ordering, but for consistency reason it would + be much appreciated that iteration domain comes first (if present) + then scattering (if present), then accesses (if present). + The statement body is an optional information. It is preceded by a + boolean which precises whether it is provided or not. It is made of two parts: first, the list of surrounding loop counters in the original program and second, the text string of the statement. This representation allows to apply the substitution of the original @@ -1761,6 +1753,7 @@ scattering and access information) are detailed in the next subsections. @menu * Relation Representation:: * Iteration Domain Representation:: +* Context Domain Representation:: * Scattering Relation Representation:: * Access Relation Representation:: @end menu @@ -1841,6 +1834,7 @@ Iteration domain represents the set instances of the corresponding statement. OpenScop iteration domains are represented as relations (@pxref{Relation Representation}), with the following conventions: @itemize @bullet +@item the type is @code{DOMAIN}, @item there is 0 input dimension, @item loop iterators correspond to output dimensions. @end itemize @@ -1950,6 +1944,20 @@ DOMAIN @end group @end example +@node Context Domain Representation +@subsubsection Context Domain Representation + +The context domain is a particular case of iteration domain +(@pxref{Iteration Domain Representation}) where there are only +constraints about parameters (no loop iterators). Hence it is the same +as iteration domain, with the following conventions: +@itemize @bullet +@item the type is @code{CONTEXT}, +@item there is 0 input dimension, +@item there is 0 output dimension. +@end itemize + + @node Scattering Relation Representation @subsubsection Scattering Relation Representation @@ -1961,6 +1969,7 @@ conventions depend on the representation. For the matrix representation: @itemize @bullet +@item the type is @code{SCATTERING}, @item there is 0 output dimension, @item loop iterators correspond to input dimensions, @item the ith row corresponds to the ith scattering dimension. @@ -1969,6 +1978,7 @@ For the matrix representation: For the relation representation: @itemize @bullet +@item the type is @code{SCATTERING}, @item output dimensions correspond to scattering dimensions, @item loop iterators correspond to input dimensions. @end itemize @@ -2031,6 +2041,15 @@ conventions depend on the representation. For the matrix representation: @itemize @bullet +@item the type is one of the following: + @itemize @bullet + @item @code{READ}, for read accesses, + @item @code{WRITE}, for write accesses, + @item @code{RDWR}, for read/write accesses, + @item @code{MAY_READ}, for may read accesses, + @item @code{MAY_WRITE}, for may write accesses, + @item @code{MAY_RDWR}, for may read/write accesses, + @end itemize @item there is 0 output dimension, @item loop iterators correspond to input dimensions, @item the first row corresponds to the array identifier, @@ -2039,6 +2058,15 @@ For the matrix representation: For the relation representation: @itemize @bullet +@item the type is one of the following: + @itemize @bullet + @item @code{READ}, for read accesses, + @item @code{WRITE}, for write accesses, + @item @code{RDWR}, for read/write accesses, + @item @code{MAY_READ}, for may read accesses, + @item @code{MAY_WRITE}, for may write accesses, + @item @code{MAY_RDWR}, for may read/write accesses, + @end itemize @item output dimensions correspond to the array identifier and dimensions, @item the first output dimension corresponds to the array identifier, @item the (i+1)th output dimension corresponds to the ith array dimension (i>1), diff --git a/include/openscop/relation.h b/include/openscop/relation.h index 9085036..5be77e2 100644 --- a/include/openscop/relation.h +++ b/include/openscop/relation.h @@ -178,6 +178,7 @@ openscop_relation_p openscop_relation_union(openscop_relation_p, openscop_relation_p); void openscop_relation_set_type(openscop_relation_p, int); int openscop_relation_get_array_id(openscop_relation_p); +int openscop_relation_is_access(openscop_relation_p); # if defined(__cplusplus) diff --git a/include/openscop/relation_list.h b/include/openscop/relation_list.h index c7d7c30..2e3a687 100644 --- a/include/openscop/relation_list.h +++ b/include/openscop/relation_list.h @@ -93,12 +93,12 @@ typedef struct openscop_relation_list * openscop_relation_list_p; /*+*************************************************************************** * Structure display function * *****************************************************************************/ -void openscop_relation_list_idump(FILE *, - openscop_relation_list_p, int); +void openscop_relation_list_idump(FILE *, openscop_relation_list_p, int); void openscop_relation_list_dump(FILE *, openscop_relation_list_p); -void openscop_relation_list_print(FILE *, - openscop_relation_list_p, - openscop_names_p); +void openscop_relation_list_print_elts(FILE *, openscop_relation_list_p, + openscop_names_p); +void openscop_relation_list_print(FILE *, openscop_relation_list_p, + openscop_names_p); /***************************************************************************** @@ -129,6 +129,10 @@ int openscop_relation_list_integrity_check( int, int, int, int); void openscop_relation_list_set_type( openscop_relation_list_p, int); +openscop_relation_list_p openscop_relation_list_filter( + openscop_relation_list_p, int); +int openscop_relation_list_count( + openscop_relation_list_p); # if defined(__cplusplus) } diff --git a/include/openscop/statement.h b/include/openscop/statement.h index 9f8bd1f..924276b 100644 --- a/include/openscop/statement.h +++ b/include/openscop/statement.h @@ -84,15 +84,14 @@ extern "C" * conventions (e.g. "S1" for the first statement in the list). */ struct openscop_statement { - openscop_relation_p domain; /**< Iteration domain of the statement */ - openscop_relation_p scattering; /**< Scattering function for the statement */ - openscop_relation_list_p read; /**< Array read access informations */ - openscop_relation_list_p write; /**< Array write access informations */ - int nb_iterators; /**< Number of names in 'iterators' */ - char ** iterators; /**< Array of iterator names */ - char * body; /**< Original statement body */ - void * usr; /**< A user-defined field, not touched - AT ALL by the OpenScop Library. */ + openscop_relation_p domain; /**< Iteration domain of the statement */ + openscop_relation_p scattering; /**< Scattering relation of the statement */ + openscop_relation_list_p access; /**< Access information */ + int nb_iterators; /**< Number of names in 'iterators' */ + char ** iterators; /**< Array of iterator names */ + char * body; /**< Original statement body */ + void * usr; /**< A user-defined field, not touched + AT ALL by the OpenScop Library. */ struct openscop_statement * next; /**< Next statement in the linked list */ }; typedef struct openscop_statement openscop_statement_t; diff --git a/source/relation.c b/source/relation.c index d315749..fa602c8 100644 --- a/source/relation.c +++ b/source/relation.c @@ -424,29 +424,6 @@ char * openscop_relation_expression(openscop_relation_p relation, /** - * openscop_relation_is_access function: - * this function returns 1 if the relation corresponds to an access relation, - * whatever its precise type (read, write etc.), 0 otherwise. - * \param relation The relation to check wheter it is an access relation or not. - * \return 1 if the relation is an access relation, 0 otherwise. - */ -static -int openscop_relation_is_access(openscop_relation_p relation) { - - if ((relation->type == OPENSCOP_TYPE_ACCESS) || - (relation->type == OPENSCOP_TYPE_READ) || - (relation->type == OPENSCOP_TYPE_WRITE) || - (relation->type == OPENSCOP_TYPE_RDWR) || - (relation->type == OPENSCOP_TYPE_MAY_READ) || - (relation->type == OPENSCOP_TYPE_MAY_WRITE) || - (relation->type == OPENSCOP_TYPE_MAY_RDWR)) - return 1; - - return 0; -} - - -/** * openscop_relation_properties function: * this function returns, through its parameters, the values of every possible * "property" (nb_iterators, nb_parameters etc) of a relation, depending on @@ -1885,3 +1862,27 @@ int openscop_relation_get_array_id(openscop_relation_p relation) { return array_id; } + +/** + * openscop_relation_is_access function: + * this function returns 1 if the relation corresponds to an access relation, + * whatever its precise type (read, write etc.), 0 otherwise. + * \param relation The relation to check wheter it is an access relation or not. + * \return 1 if the relation is an access relation, 0 otherwise. + */ +int openscop_relation_is_access(openscop_relation_p relation) { + + if ((relation->type == OPENSCOP_TYPE_ACCESS) || + (relation->type == OPENSCOP_TYPE_READ) || + (relation->type == OPENSCOP_TYPE_WRITE) || + (relation->type == OPENSCOP_TYPE_RDWR) || + (relation->type == OPENSCOP_TYPE_MAY_READ) || + (relation->type == OPENSCOP_TYPE_MAY_WRITE) || + (relation->type == OPENSCOP_TYPE_MAY_RDWR)) + return 1; + + return 0; +} + + + diff --git a/source/relation_list.c b/source/relation_list.c index d4f4003..e05c419 100644 --- a/source/relation_list.c +++ b/source/relation_list.c @@ -143,6 +143,29 @@ void openscop_relation_list_dump(FILE * file, openscop_relation_list_p list) { } +void openscop_relation_list_print_elts(FILE * file, + openscop_relation_list_p list, + openscop_names_p names) { + int i; + openscop_relation_list_p head = list; + + // Count the number of elements in the list with non-NULL content. + i = openscop_relation_list_count(list); + + // Print each element of the relation list. + if (i > 0) { + i = 0; + while (head) { + if (head->elt != NULL) { + fprintf(file, "# List element No.%d\n", i); + openscop_relation_print(file, head->elt, names); + i++; + } + head = head->next; + } + } +} + /** * openscop_relation_list_print function: * This function prints the content of a openscop_relation_list_t structure @@ -159,15 +182,9 @@ void openscop_relation_list_print(FILE * file, openscop_relation_list_p list, openscop_names_p names) { int i; - openscop_relation_list_p head = list; // Count the number of elements in the list with non-NULL content. - i = 0; - while (list != NULL) { - if (list->elt != NULL) - i++; - list = list->next; - } + i = openscop_relation_list_count(list); // Print it. if (i > 1) @@ -176,17 +193,7 @@ void openscop_relation_list_print(FILE * file, fprintf(file,"# List of %d element \n%d\n", i, i); // Print each element of the relation list. - if (i > 0) { - i = 0; - while (head) { - if (head->elt != NULL) { - fprintf(file, "# List element No.%d\n", i); - openscop_relation_print(file, head->elt, names); - i++; - } - head = head->next; - } - } + openscop_relation_list_print_elts(file, list, names); } @@ -202,24 +209,14 @@ void openscop_relation_list_print(FILE * file, * \param file The input stream. * \return A pointer to the relation list structure that has been read. */ -openscop_relation_list_p openscop_relation_list_read(FILE* file) { - char s[OPENSCOP_MAX_STRING]; +openscop_relation_list_p openscop_relation_list_read(FILE * file) { int i; openscop_relation_list_p list; openscop_relation_list_p res; int nb_mat; - // Skip blank/commented lines. - while (fgets(s, OPENSCOP_MAX_STRING, file) == 0 || s[0] == '#' || - isspace(s[0])) - continue; - // Read the number of relations to read. - if (sscanf(s, "%d", &nb_mat) != 1) { - fprintf(stderr, "[OpenScop] Error: not possible to read the " - "number of relations.\n"); - exit(1); - } + nb_mat = openscop_util_read_int(file, NULL); if (nb_mat < 0) { fprintf(stderr, "[OpenScop] Error: negative number of relations.\n"); @@ -465,3 +462,69 @@ void openscop_relation_list_set_type(openscop_relation_list_p list, int type) { } +/** + * openscop_relation_list_filter function: + * this function returns a copy of the input relation list, restricted to + * the relations of a given type. The special type OPENSCOP_TYPE_ACCESS + * filters any kind of access (read, write, rdwr etc.). + * \param list The relation list to copy/filter. + * \param type The filtering type. + * \return A copy of the input list with only relation of the given type. + */ +openscop_relation_list_p openscop_relation_list_filter( + openscop_relation_list_p list, + int type) { + + openscop_relation_list_p copy = openscop_relation_list_copy(list); + openscop_relation_list_p filtered = NULL; + openscop_relation_list_p previous = NULL; + openscop_relation_list_p trash; + int first = 1; + + while (copy != NULL) { + if (((type == OPENSCOP_TYPE_ACCESS) && + (openscop_relation_is_access(copy->elt))) || + ((type != OPENSCOP_TYPE_ACCESS) && + (type == copy->elt->type))) { + if (first) { + filtered = copy; + first = 0; + } + + previous = copy; + copy = copy->next; + } + else { + trash = copy; + if (!first) + previous->next = copy->next; + copy = copy->next; + trash->next = NULL; + openscop_relation_list_free(trash); + } + } + + return filtered; +} + + +/** + * openscop_relation_list_count function: + * this function returns the number of elements with non-NULL content + * in a relation list. + * \param list The relation list to count the number of elements. + * \return The number of nodes with non-NULL content in the relation list. + */ +int openscop_relation_list_count(openscop_relation_list_p list) { + int i = 0; + + while (list != NULL) { + if (list->elt != NULL) + i++; + list = list->next; + } + + return i; +} + + diff --git a/source/scop.c b/source/scop.c index 8b13aed..d2ebf2b 100644 --- a/source/scop.c +++ b/source/scop.c @@ -167,7 +167,7 @@ void openscop_scop_name_limits(openscop_scop_p scop, int * nb_scattdims, int * nb_localdims, int * nb_arrays) { - int k, tmp, array_id; + int tmp, array_id; openscop_statement_p statement; openscop_relation_list_p list; @@ -229,19 +229,13 @@ void openscop_scop_name_limits(openscop_scop_p scop, } // * The number of arrays are defined by accesses, - for (k = 0; k < 2; k++) { - if (k == 0) - list = statement->read; - else - list = statement->write; - - while (list != NULL) { - array_id = openscop_relation_get_array_id(list->elt); - if (array_id > *nb_arrays) - *nb_arrays = array_id; - - list = list->next; - } + list = statement->access; + while (list != NULL) { + array_id = openscop_relation_get_array_id(list->elt); + if (array_id > *nb_arrays) + *nb_arrays = array_id; + + list = list->next; } statement = statement->next; @@ -434,7 +428,7 @@ void openscop_scop_update_properties(openscop_relation_p relation, */ static void openscop_scop_propagate_properties(openscop_scop_p scop) { - int i, nb_parameters; + int nb_parameters; openscop_statement_p statement; openscop_relation_p relation; openscop_relation_list_p list; @@ -473,27 +467,20 @@ void openscop_scop_propagate_properties(openscop_scop_p scop) { } // - Access part. - for (i = 0; i < 2; i++) { - if (i == 0) - list = statement->read; - else - list = statement->write; - - while (list != NULL) { - relation = list->elt; - if (openscop_relation_is_matrix(relation)) { - while (relation != NULL) { - openscop_scop_update_properties( - relation, 0, relation->nb_columns - nb_parameters - 2, - nb_parameters); - relation = relation->next; - } + list = statement->access; + while (list != NULL) { + relation = list->elt; + if (openscop_relation_is_matrix(relation)) { + while (relation != NULL) { + openscop_scop_update_properties( + relation, 0, relation->nb_columns - nb_parameters - 2, + nb_parameters); + relation = relation->next; } - - list = list->next; } + list = list->next; } - + statement = statement->next; } } @@ -573,7 +560,8 @@ openscop_scop_p openscop_scop_read(FILE * file) { // Read the number of statements. nb_statements = openscop_util_read_int(file, NULL); - for (i = 0; i < nb_statements; ++i) { + for (i = 0; i < nb_statements; i++) { + printf("Coucou %d\n", i); // Read each statement. stmt = openscop_statement_read(file, nb_parameters); if (scop->statement == NULL) diff --git a/source/statement.c b/source/statement.c index 84ad243..31d215b 100644 --- a/source/statement.c +++ b/source/statement.c @@ -119,11 +119,8 @@ void openscop_statement_idump(FILE * file, // Print the scattering of the statement. openscop_relation_idump(file, statement->scattering, level+1); - // Print the array read access informations of the statement. - openscop_relation_list_idump(file, statement->read, level+1); - - // Print the array write access informations of the statement. - openscop_relation_list_idump(file, statement->write, level+1); + // Print the array access information of the statement. + openscop_relation_list_idump(file, statement->access, level+1); // Print the original iterator names. for (i = 0; i <= level; i++) @@ -200,13 +197,14 @@ void openscop_statement_print(FILE * file, openscop_statement_p statement, openscop_names_p names) { int i, switched, number = 1; + int nb_relations = 0; int tmp_nb_iterators = 0; char ** tmp_iterators = NULL; while (statement != NULL) { // Switch iterator names to the current statement names if possible. switched = 0; - if (statement->nb_iterators > 0) { + if ((statement->nb_iterators > 0) && (names != NULL)) { tmp_nb_iterators = names->nb_iterators; tmp_iterators = names->iterators; names->nb_iterators = statement->nb_iterators; @@ -217,40 +215,29 @@ void openscop_statement_print(FILE * file, fprintf(file, "# =============================================== "); fprintf(file, "Statement %d\n", number); + fprintf(file, "# Number of relations describing the statement:\n"); + + if (statement->domain != NULL) + nb_relations ++; + if (statement->scattering != NULL) + nb_relations ++; + nb_relations += openscop_relation_list_count(statement->access); + + fprintf(file, "%d\n", nb_relations); + fprintf(file, "# ---------------------------------------------- "); fprintf(file, "%2d.1 Domain\n", number); - fprintf(file, "# Iteration domain\n"); openscop_relation_print(file, statement->domain, names); fprintf(file, "\n"); fprintf(file, "# ---------------------------------------------- "); fprintf(file, "%2d.2 Scattering\n", number); - if (statement->scattering != NULL) { - fprintf(file, "# Scattering function is provided\n"); - fprintf(file, "1\n"); - fprintf(file, "# Scattering function\n"); - openscop_relation_print(file, statement->scattering, names); - } - else { - fprintf(file, "# Scattering function is not provided\n"); - fprintf(file, "0\n"); - } + openscop_relation_print(file, statement->scattering, names); fprintf(file, "\n"); fprintf(file, "# ---------------------------------------------- "); fprintf(file, "%2d.3 Access\n", number); - if ((statement->read != NULL) || (statement->write != NULL)) { - fprintf(file, "# Access information is provided\n"); - fprintf(file, "1\n"); - fprintf(file, "\n# Read access information\n"); - openscop_relation_list_print(file, statement->read, names); - fprintf(file, "\n# Write access information\n"); - openscop_relation_list_print(file, statement->write, names); - } - else { - fprintf(file, "# Access information is not provided\n"); - fprintf(file, "0\n"); - } + openscop_relation_list_print_elts(file, statement->access, names); fprintf(file, "\n"); fprintf(file, "# ---------------------------------------------- "); @@ -292,6 +279,63 @@ void openscop_statement_print(FILE * file, /** + * openscop_statement_dispatch function: + * this function dispatches the relations from a relation list to the + * convenient fields of a statement structure: it extracts the domain, + * the scattering and the access list and store them accordingly in the + * statement structure provided as a parameter. + * \param stmt The statement where to dispatch the relations. + * \param list The "brute" relation list to sort and dispatch (freed). + */ +static +void openscop_statement_dispatch(openscop_statement_p stmt, + openscop_relation_list_p list) { + openscop_relation_list_p domain_list; + openscop_relation_list_p scattering_list; + int nb_domains, nb_scattering, nb_accesses; + + // Domain. + domain_list = openscop_relation_list_filter(list, OPENSCOP_TYPE_DOMAIN); + nb_domains = openscop_relation_list_count(domain_list); + if (nb_domains > 1) { + fprintf(stderr, "[OpenScop] Error: more than one domain for a " + "statement.\n"); + exit(1); + } + if (domain_list != NULL) + stmt->domain = domain_list->elt; + else + stmt->domain = NULL; + + // Scattering. + scattering_list=openscop_relation_list_filter(list,OPENSCOP_TYPE_SCATTERING); + nb_scattering = openscop_relation_list_count(scattering_list); + if (nb_scattering > 1) { + fprintf(stderr, "[OpenScop] Error: more than one scattering relation " + "for a statement.\n"); + exit(1); + } + if (scattering_list != NULL) + stmt->scattering = scattering_list->elt; + else + stmt->scattering = NULL; + + // Access. + stmt->access = openscop_relation_list_filter(list, OPENSCOP_TYPE_ACCESS); + nb_accesses = openscop_relation_list_count(stmt->access); + + if ((nb_domains + nb_scattering + nb_accesses) != + (openscop_relation_list_count(list))) { + fprintf(stderr, "[OpenScop] Error: unexpected relation type to define " + "a statement.\n"); + exit(1); + } + + openscop_relation_list_free(list); +} + + +/** * openscop_statement_read function: * This function reads a openscop_statement_t structure from an input stream * (possibly stdin). @@ -302,23 +346,16 @@ void openscop_statement_print(FILE * file, openscop_statement_p openscop_statement_read(FILE * file, int nb_parameters) { openscop_statement_p stmt = openscop_statement_malloc(); + openscop_relation_list_p list; char buff[OPENSCOP_MAX_STRING], * start, * end; int expected_nb_iterators, nb_iterators; if (file) { - // Read the domain matrices. - stmt->domain = openscop_relation_read(file); + // Read all statement relations. + list = openscop_relation_list_read(file); - // Read the scattering, if any. - if (openscop_util_read_int(file, NULL) > 0) { - stmt->scattering = openscop_relation_read(file); - } - - // Read the access relations, if any. - if (openscop_util_read_int(file, NULL) > 0) { - stmt->read = openscop_relation_list_read(file); - stmt->write = openscop_relation_list_read(file); - } + // Store relations at the right place according to their type. + openscop_statement_dispatch(stmt, list); // Read the body information, if any. if (openscop_util_read_int(file, NULL) > 0) { @@ -394,8 +431,7 @@ openscop_statement_p openscop_statement_malloc() { statement->domain = NULL; statement->scattering = NULL; - statement->read = NULL; - statement->write = NULL; + statement->access = NULL; statement->nb_iterators = 0; statement->iterators = NULL; statement->body = NULL; @@ -419,8 +455,7 @@ void openscop_statement_free(openscop_statement_p statement) { next = statement->next; openscop_relation_free(statement->domain); openscop_relation_free(statement->scattering); - openscop_relation_list_free(statement->read); - openscop_relation_list_free(statement->write); + openscop_relation_list_free(statement->access); if (statement->iterators != NULL) { for (i = 0; i < statement->nb_iterators; i++) free(statement->iterators[i]); @@ -489,8 +524,7 @@ openscop_statement_p openscop_statement_copy(openscop_statement_p statement) { node = openscop_statement_malloc(); node->domain = openscop_relation_copy(statement->domain); node->scattering = openscop_relation_copy(statement->scattering); - node->read = openscop_relation_list_copy(statement->read); - node->write = openscop_relation_list_copy(statement->write); + node->access = openscop_relation_list_copy(statement->access); node->nb_iterators = statement->nb_iterators; node->iterators = openscop_util_strings_copy(statement->iterators, statement->nb_iterators); @@ -538,10 +572,9 @@ int openscop_statement_equal(openscop_statement_p s1, return 0; if ((s1->nb_iterators != s2->nb_iterators) || - (!openscop_relation_equal(s1->domain, s2->domain)) || - (!openscop_relation_equal(s1->scattering, s2->scattering)) || - (!openscop_relation_list_equal(s1->read, s2->read)) || - (!openscop_relation_list_equal(s1->write, s2->write))) + (!openscop_relation_equal(s1->domain, s2->domain)) || + (!openscop_relation_equal(s1->scattering, s2->scattering)) || + (!openscop_relation_list_equal(s1->access, s2->access))) return 0; if (((s1->body == NULL) && (s2->body != NULL)) || @@ -611,7 +644,7 @@ int openscop_statement_integrity_check(openscop_statement_p statement, expected_nb_iterators = statement->domain->nb_output_dims; } - // Check the scattering function. + // Check the scattering relation. if ((openscop_relation_is_matrix(statement->scattering) && !openscop_relation_integrity_check(statement->scattering, OPENSCOP_TYPE_SCATTERING, @@ -627,17 +660,12 @@ int openscop_statement_integrity_check(openscop_statement_p statement, return 0; } - // Check the access functions. - if (!openscop_relation_list_integrity_check(statement->read, - OPENSCOP_TYPE_ACCESS, - OPENSCOP_UNDEFINED, - expected_nb_iterators, - expected_nb_parameters) || - !openscop_relation_list_integrity_check(statement->write, - OPENSCOP_TYPE_ACCESS, - OPENSCOP_UNDEFINED, - expected_nb_iterators, - expected_nb_parameters)) { + // Check the access relations. + if (!openscop_relation_list_integrity_check(statement->access, + OPENSCOP_TYPE_ACCESS, + OPENSCOP_UNDEFINED, + expected_nb_iterators, + expected_nb_parameters)) { return 0; } diff --git a/source/util.c b/source/util.c index b092472..395871f 100644 --- a/source/util.c +++ b/source/util.c @@ -405,7 +405,10 @@ int openscop_util_read_int(FILE * file, char ** str) { if (file != NULL) { // Parse from a file. start = openscop_util_skip_blank_and_comments(file, s); - sscanf(start, " %d", &res); + if (sscanf(start, " %d", &res) != 1) { + fprintf(stderr, "[OpenScop] Error: an int was expected.\n"); + exit(1); + } } if (str != NULL) { // Parse from a string. diff --git a/tests/openscop_test.c b/tests/openscop_test.c index d97885d..2b5748d 100644 --- a/tests/openscop_test.c +++ b/tests/openscop_test.c @@ -108,7 +108,7 @@ int test_file(char * input_name, int verbose) // Dump the OpenScop data structures to OpenScop file format. output_name = tmpnam(NULL); output_file = fopen(output_name, "w"); - //openscop_scop_print(stdout, input_scop); + openscop_scop_print(stdout, input_scop); openscop_scop_print(output_file, input_scop); fclose(output_file); diff --git a/tests/polynom.scop b/tests/polynom.scop index 3e58dde..7f71773 100644 --- a/tests/polynom.scop +++ b/tests/polynom.scop @@ -55,8 +55,10 @@ c0 c1 c2 c3 c4 1 # =============================================== Statement 1 +# Number of relations describing the statement +6 + # ---------------------------------------------- 1.1 Domain -# Iteration domain DOMAIN 2 4 5 2 0 -1 1 @@ -72,9 +74,6 @@ DOMAIN 1 0 -1 1 -1 ## -j+N-1 >= 0 # ---------------------------------------------- 1.2 Scattering -# Scattering function is provided -1 -# Scattering function SCATTERING 5 5 0 0 0 0 0 ## 0 @@ -84,24 +83,21 @@ SCATTERING 0 0 0 0 0 ## 0 # ---------------------------------------------- 1.3 Access -# Access informations are provided -1 -# Read access information -3 READ 2 5 0 0 0 0 1 ## C[i+j] 0 1 1 0 0 ## + READ 2 5 0 0 0 0 2 ## A[i] 0 1 0 0 0 ## + READ 2 5 0 0 0 0 3 ## B[j] 0 0 1 0 0 ## -# Write access information -1 + WRITE 2 5 0 0 0 0 1 ## C[i+j] -- 2.11.4.GIT