| #include <ctype.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include "../include/cloog/cloog.h" |
| |
| #ifdef OSL_SUPPORT |
| #include <osl/scop.h> |
| #endif |
| |
| #define ALLOC(type) (type*)malloc(sizeof(type)) |
| |
| static char *next_line(FILE *input, char *line, unsigned len) |
| { |
| char *p; |
| |
| do { |
| if (!(p = fgets(line, len, input))) |
| return NULL; |
| while (isspace(*p) && *p != '\n') |
| ++p; |
| } while (*p == '#' || *p == '\n'); |
| |
| return p; |
| } |
| |
| #ifdef OSL_SUPPORT |
| /** |
| * This function translates an OpenScop scop to a CLooG input. |
| * \param[in,out] state CLooG state. |
| * \param[in] scop Scop to translate. |
| * \return A CloogInput corresponding to the scop input. |
| */ |
| CloogInput *cloog_input_from_osl_scop(CloogState *state, osl_scop_p scop) { |
| CloogInput *input = NULL; |
| CloogDomain *context = NULL; |
| CloogUnionDomain *ud = NULL; |
| |
| if (scop) { |
| /* Extract the context. */ |
| context = cloog_domain_from_osl_relation(state, scop->context); |
| |
| /* Extract the union of domains. */ |
| ud = cloog_union_domain_from_osl_scop(state, scop); |
| |
| /* Build and return the input. */ |
| input = cloog_input_alloc(context, ud); |
| } |
| |
| return input; |
| } |
| #endif |
| |
| /** |
| * Read input from a .cloog file, putting most of the information |
| * in the returned CloogInput. The chosen language is put in |
| * options->language. |
| */ |
| CloogInput *cloog_input_read(FILE *file, CloogOptions *options) |
| { |
| char line[MAX_STRING]; |
| char language; |
| CloogDomain *context; |
| CloogUnionDomain *ud; |
| int nb_par; |
| |
| #ifdef OSL_SUPPORT |
| if (options->openscop) { |
| osl_scop_p scop = osl_scop_read(file); |
| CloogInput * input = cloog_input_from_osl_scop(options->state, |
| scop); |
| cloog_options_copy_from_osl_scop(scop, options); |
| return input; |
| } |
| #endif |
| |
| /* First of all, we read the language to use. */ |
| if (!next_line(file, line, sizeof(line))) |
| cloog_die("Input error.\n"); |
| if (sscanf(line, "%c", &language) != 1) |
| cloog_die("Input error.\n"); |
| |
| if (language == 'f') |
| options->language = CLOOG_LANGUAGE_FORTRAN; |
| else |
| options->language = CLOOG_LANGUAGE_C; |
| |
| /* We then read the context data. */ |
| context = cloog_domain_read_context(options->state, file); |
| nb_par = cloog_domain_parameter_dimension(context); |
| |
| ud = cloog_union_domain_read(file, nb_par, options); |
| |
| return cloog_input_alloc(context, ud); |
| } |
| |
| /** |
| * Create a CloogInput from a CloogDomain context and a CloogUnionDomain. |
| */ |
| CloogInput *cloog_input_alloc(CloogDomain *context, CloogUnionDomain *ud) |
| { |
| CloogInput *input; |
| |
| input = ALLOC(CloogInput); |
| if (!input) |
| cloog_die("memory overflow.\n"); |
| |
| input->context = context; |
| input->ud = ud; |
| |
| return input; |
| } |
| |
| void cloog_input_free(CloogInput *input) |
| { |
| cloog_domain_free(input->context); |
| cloog_union_domain_free(input->ud); |
| free(input); |
| } |
| |
| static void print_names(FILE *file, CloogUnionDomain *ud, |
| enum cloog_dim_type type, const char *name) |
| { |
| int i; |
| |
| fprintf(file, "\n%d # %s name(s)\n", ud->name[type] ? 1 : 0, name); |
| if (!ud->name[type]) |
| return; |
| |
| for (i = 0; i < ud->n_name[type]; i++) |
| fprintf(file, "%s ", ud->name[type][i]); |
| |
| fprintf(file, "\n"); |
| } |
| |
| /** |
| * Dump the .cloog description of a CloogInput and a CloogOptions data structure |
| * into a file. The generated .cloog file will contain the same information as |
| * the data structures. The file can be used to run the cloog program on the |
| * example. |
| */ |
| void cloog_input_dump_cloog(FILE *file, CloogInput *input, CloogOptions *opt) |
| { |
| int i, num_statements; |
| CloogUnionDomain *ud = input->ud; |
| CloogNamedDomainList *ndl = ud->domain; |
| |
| fprintf(file, |
| "# CLooG -> CLooG\n" |
| "# This is an automatic dump of a CLooG input file from a " |
| "CloogInput data\n" |
| "# structure.\n\n"); |
| |
| /* Language. */ |
| if (opt->language == CLOOG_LANGUAGE_FORTRAN) { |
| fprintf(file, "# Language: FORTRAN\n"); |
| fprintf(file, "f\n\n"); |
| } else { |
| fprintf(file, "# Language: C\n"); |
| fprintf(file, "c\n\n"); |
| } |
| |
| /* Context. */ |
| fprintf(file, "# Context:\n"); |
| cloog_domain_print_constraints(file, input->context, 1); |
| |
| print_names(file, ud, CLOOG_PARAM, "Parameter"); |
| |
| /* Statement number. */ |
| i = 0; |
| while (ndl != NULL) { |
| i++; |
| ndl = ndl->next; |
| } |
| num_statements = i; |
| fprintf(file, "\n# Statement number:\n%d\n\n", num_statements); |
| |
| /* Iteration domains. */ |
| i = 1; |
| ndl = ud->domain; |
| while (ndl != NULL) { |
| fprintf(file, "# Iteration domain of statement %d (%s).\n", i, |
| ndl->name); |
| |
| cloog_domain_print_constraints(file, ndl->domain, 1); |
| fprintf(file,"\n0 0 0 # For future options.\n\n"); |
| |
| i++; |
| ndl = ndl->next; |
| } |
| |
| print_names(file, ud, CLOOG_ITER, "Iterator"); |
| |
| /* Exit, if no scattering is supplied. */ |
| if (!ud->domain || !ud->domain->scattering) { |
| fprintf(file, "# No scattering functions.\n0\n\n"); |
| return; |
| } |
| |
| /* Scattering relations. */ |
| fprintf(file, |
| "# --------------------- SCATTERING --------------------\n"); |
| |
| fprintf(file, "%d # Scattering functions\n", num_statements); |
| |
| i = 1; |
| ndl = ud->domain; |
| while (ndl != NULL) { |
| fprintf(file, "\n# Scattering of statement %d (%s).\n", i, |
| ndl->name); |
| |
| cloog_scattering_print_constraints(file, ndl->scattering); |
| |
| i++; |
| ndl = ndl->next; |
| } |
| |
| print_names(file, ud, CLOOG_SCAT, "Scattering dimension"); |
| } |