/** * scoplib_scop_dup function: * This function returns a fresh identical (non shadow) copy of the * input scop. * \param scop The scop whose information have to be printed. ** */ scoplib_scop_p scoplib_scop_dup(scoplib_scop_p scop) { int i; scoplib_statement_p stm; scoplib_statement_p tmp = NULL; scoplib_symbol_p tmpsymbol = NULL; scoplib_symbol_p symbol; scoplib_scop_p ret = scoplib_scop_malloc(); ret->context = scoplib_matrix_copy(scop->context); ret->nb_parameters = scop->nb_parameters; ret->parameters = (char**) malloc(sizeof(char*) * ret->nb_parameters); for (i = 0; i < ret->nb_parameters; ++i) ret->parameters[i] = strdup(scop->parameters[i]); ret->nb_arrays = scop->nb_arrays; ret->arrays = (char**) malloc(sizeof(char*) * ret->nb_arrays); for (i = 0; i < ret->nb_arrays; ++i) ret->arrays[i] = strdup(scop->arrays[i]); for (stm = scop->statement; stm; stm = stm->next) { scoplib_statement_p newstm = scoplib_statement_malloc(); newstm->domain = scoplib_matrix_list_malloc(); newstm->domain->elt = scoplib_matrix_copy(stm->domain->elt); newstm->schedule = scoplib_matrix_copy(stm->schedule); newstm->read = scoplib_matrix_copy(stm->read); newstm->write = scoplib_matrix_copy(stm->write); newstm->nb_iterators = stm->nb_iterators; newstm->iterators = (char**) malloc(sizeof(char*) * newstm->nb_iterators); for (i = 0; i < newstm->nb_iterators; ++i) newstm->iterators[i] = strdup(stm->iterators[i]); newstm->body = strdup (stm->body); if (ret->statement == NULL) ret->statement = tmp = newstm; else { tmp->next = newstm; tmp = tmp->next; } } for(symbol = scop->symbol_table;symbol;symbol = symbol->next) { scoplib_symbol_p newsymbol = scoplib_symbol_malloc(); newsymbol->identifier = strdup(symbol->identifier); newsymbol->type = symbol->type; if(ret->symbol_table == NULL ) ret->symbol_table = tmpsymbol = newsymbol; else { tmpsymbol->next = newsymbol; tmpsymbol = tmpsymbol->next; } } if (scop->optiontags) ret->optiontags = strdup(scop->optiontags); ret->usr = scop->usr; return ret; }
candl_program_p candl_program_convert_scop(scoplib_scop_p scop, int** indices) { int i, j, k, l; candl_program_p res = candl_program_malloc(); scoplib_statement_p s = scop->statement; /* Duplicate the context. */ res->context = (CandlMatrix*) scoplib_matrix_copy(scop->context); if (res->context == NULL) res->context = candl_matrix_malloc(0, 2); /* Count the number of statements. */ for (res->nb_statements = 0; s; s = s->next, res->nb_statements++) ; /* Allocate the statements array. */ res->statement = (CandlStatement**) malloc(res->nb_statements * sizeof(CandlStatement*)); /* Initialize structures used in iterator indices computation. */ int max = 0; int max_loop_depth = 128; int cur_index[max_loop_depth]; int last[max_loop_depth]; for (i = 0; i < max_loop_depth; ++i) { cur_index[i] = i; last[i] = 0; } /* Create the statements. */ for (i = 0, s = scop->statement; s; s = s->next, ++i) { CandlStatement* statement = candl_statement_malloc(); statement->label = i; statement->ref = s; if (s->domain->next != NULL) CANDL_FAIL("Error: union of domains not supported"); statement->domain = (CandlMatrix*) scoplib_matrix_copy(s->domain->elt); /* For the moment, we do not parse the statement to extract its type. */ statement->type = CANDL_ASSIGNMENT; statement->depth = statement->domain->NbColumns - 2 - scop->nb_parameters; statement->written = (CandlMatrix*) scoplib_matrix_copy(s->write); if (statement->written == NULL) statement->written = candl_matrix_malloc(0, statement->domain->NbColumns); statement->read = (CandlMatrix*) scoplib_matrix_copy(s->read); if (statement->read == NULL) statement->read = candl_matrix_malloc(0, statement->domain->NbColumns); statement->index = (int*) malloc(statement->depth * sizeof(int)); if (indices != NULL) /* Iterator indices are provided. */ for (j = 0; j < statement->depth; ++j) statement->index[j] = indices[i][j]; else { /* Iterator indices must be computed from the scattering matrix. */ scoplib_matrix_p m = s->schedule; if (m == NULL) CANDL_FAIL("Error: No scheduling matrix and no loop " "indices specification"); /* FIXME: Sort the statements in their execution order. */ /* It must be a 2d+1 identity scheduling matrix, and statements must be sorted in their execution order. */ /* Check that it is a identity matrix. */ int error = 0; if (m->NbRows != 2 * statement->depth + 1) error = 1; /*else for (l = 0; l < m->NbRows; ++l) { for (k = 1; k < m->NbColumns - 1; ++k){ switch (CANDL_get_si(m->p[l][k])) { case 0: if (l % 2 && k == (l / 2) + 1) error = 1; break; case 1: if ((l % 2 && k != (l / 2) + 1) || (! l % 2)) error = 1; break; default: error = 1; break; } } if (l % 2 && CANDL_get_si(m->p[l][k])) error = 1; }*/ if (error) CANDL_FAIL("Error: schedule is not identity 2d+1 shaped.\n" "Consider using the <indices> option tag to declare " " iterator indices"); /* Compute the value of the iterator indices. */ for (j = 0; j < statement->depth; ++j) { int val = CANDL_get_si(m->p[2 * j][m->NbColumns - 1]); if (last[j] < val) { last[j] = val; for (k = j + 1; k < max_loop_depth; ++k) last[k] = 0; for (k = j; k < max_loop_depth; ++k) cur_index[k] = max + (k - j) + 1; break; } } for (j = 0; j < statement->depth; ++j) statement->index[j] = cur_index[j]; max = max < cur_index[j - 1] ? cur_index[j - 1] : max; } /* Store the statement. */ res->statement[i] = statement; } return res; }