/** * osl_body_read function: * this function reads a body structure from a string complying to the * OpenScop textual format and returns a pointer to this body structure. * The input string should only contain the body this function * has to read (comments at the end of the line are accepted). The input * parameter is updated to the position in the input string this function * reach right after reading the strings structure. * \param[in,out] input The input string where to find a body structure. * Updated to the position after what has been read. * \return A pointer to the body structure that has been read. */ osl_body_p osl_body_sread(char ** input) { osl_body_p body = NULL; char * expression; int nb_iterators; if (input) { body = osl_body_malloc(); // Read the number of iterators. nb_iterators = osl_util_read_int(NULL, input); // Read the iterator strings if any. if (nb_iterators > 0) { body->iterators = osl_strings_sread(input); } else { body->iterators = osl_strings_malloc(); OSL_malloc(body->iterators->string, char **, sizeof(char *)); body->iterators->string[0] = NULL; } // Read the body: expression = osl_util_read_line(NULL, input); // Insert the body. body->expression = osl_strings_encapsulate(expression); } return body; }
/** * osl_strings_sread function: * this function reads a strings structure from a string complying to the * OpenScop textual format and returns a pointer to this strings structure. * The input string should only contain the list of strings this function * has to read (comments at the end of the line are accepted). The input * parameter is updated to the position in the input string this function * reach right after reading the strings structure. * \param[in,out] input The input string where to find a strings structure. * Updated to the position after what has been read. * \return A pointer to the strings structure that has been read. */ osl_strings_p osl_strings_sread(char ** input) { char tmp[OSL_MAX_STRING]; char * s; char ** string = NULL; int nb_strings; int i, count; osl_strings_p strings = NULL; // Skip blank/commented lines and spaces before the strings. osl_util_sskip_blank_and_comments(input); // Count the actual number of strings. nb_strings = 0; s = *input; while (1) { for (count = 0; *s && !isspace(*s) && *s != '#'; count++) s++; if (count != 0) nb_strings++; if ((!*s) || (*s == '#') || (*s == '\n')) break; else s++; } if (nb_strings > 0) { // Allocate the array of strings. Make it NULL-terminated. OSL_malloc(string, char **, sizeof(char *) * (nb_strings + 1)); string[nb_strings] = NULL; // Read the desired number of strings. s = *input; for (i = 0; i < nb_strings; i++) { for (count = 0; *s && !isspace(*s) && *s != '#'; count++) tmp[count] = *(s++); tmp[count] = '\0'; OSL_strdup(string[i], tmp); if (*s != '#') s++; } // Update the input pointer to the end of the strings structure. *input = s; // Build the strings structure strings = osl_strings_malloc(); free(strings->string); strings->string = string; }
/** * clan_scop_generate_scatnames function: * this function generates a scatnames extension for the scop passed as * an argument. Since Clan use a "2d+1" scattering strategy, the * scattering dimension names are generated by reusing the original * iterator names of the deepest statement and by inserting between those * names some beta vector elements (the Xth beta element is called bX). * \param[in,out] scop The scop to add a scatnames extension to. */ void clan_scop_generate_scatnames(osl_scop_p scop) { osl_statement_p current, deepest; osl_scatnames_p scatnames; osl_strings_p iterators = NULL; osl_strings_p names = NULL; osl_generic_p extension; osl_body_p body = NULL; char buffer[CLAN_MAX_STRING]; int max_depth = -1; int i; // Find the deepest statement to reuse its original iterators. current = scop->statement; while (current != NULL) { if (current->domain->nb_output_dims > max_depth) { max_depth = current->domain->nb_output_dims; deepest = current; body = (osl_body_p)osl_generic_lookup(deepest->extension, OSL_URI_BODY); if (body) iterators = body->iterators; } current = current->next; } // It there are no scattering dimension, do nothing. if (max_depth <= 0) return; // Create the NULL-terminated list of scattering dimension names. names = osl_strings_malloc(); for (i = 0; i < max_depth; i++) { sprintf(buffer, "b%d", i); osl_strings_add(names, buffer); osl_strings_add(names, iterators->string[i]); } sprintf(buffer, "b%d", max_depth); osl_strings_add(names, buffer); // Build the scatnames extension. scatnames = osl_scatnames_malloc(); scatnames->names = names; // Build the generic extension and insert it to the extension list. extension = osl_generic_malloc(); extension->interface = osl_scatnames_interface(); extension->data = scatnames; osl_generic_add(&scop->extension, extension); }