/// Translate a isl_set to a ScopLib matrix. /// /// @param PS The set to be translated /// @return A ScopLib Matrix scoplib_matrix_p ScopLib::domainToMatrix(__isl_take isl_set *set) { set = isl_set_compute_divs (set); set = isl_set_align_divs (set); // Initialize the matrix. unsigned NbRows, NbColumns; NbRows = 0; NbColumns = isl_set_n_dim(set) + isl_set_n_param(set) + 2; scoplib_matrix_p matrix = scoplib_matrix_malloc(NbRows, NbColumns); // Copy the content into the matrix. isl_set_foreach_basic_set(set, &domainToMatrix_basic_set, matrix); isl_set_free(set); return matrix; }
/// Create the memory access matrix for scoplib /// /// @param S The polly statement the access matrix is created for. /// @param isRead Are we looking for read or write accesses? /// @param ArrayMap A map translating from the memory references to the scoplib /// indeces /// /// @return The memory access matrix, as it is required by scoplib. scoplib_matrix_p ScopLib::createAccessMatrix(ScopStmt *S, bool isRead) { unsigned NbColumns = S->getNumIterators() + S->getNumParams() + 2; scoplib_matrix_p m = scoplib_matrix_malloc(0, NbColumns); for (ScopStmt::memacc_iterator MI = S->memacc_begin(), ME = S->memacc_end(); MI != ME; ++MI) if ((*MI)->isRead() == isRead) { // Extract the access function. isl_map *AccessRelation = (*MI)->getAccessRelation(); isl_map_foreach_basic_map(AccessRelation, &accessToMatrix_basic_map, m); isl_map_free(AccessRelation); // Set the index of the memory access base element. std::map<const Value*, int>::iterator BA = ArrayMap.find((*MI)->getBaseAddr()); isl_int_set_si(m->p[m->NbRows - 1][0], (*BA).second + 1); } return m; }
/// Translate a isl_map to a ScopLib matrix. /// /// @param map The map to be translated /// @return A ScopLib Matrix scoplib_matrix_p ScopLib::scatteringToMatrix(__isl_take isl_map *map) { map = isl_map_compute_divs (map); map = isl_map_align_divs (map); // Initialize the matrix. unsigned NbRows, NbColumns; NbRows = 0; NbColumns = isl_map_n_in(map) + isl_map_n_param(map) + 2; scoplib_matrix_p matrix = scoplib_matrix_malloc(NbRows, NbColumns); // Copy the content into the matrix. isl_map_foreach_basic_map(map, &scatteringToMatrix_basic_map, matrix); // Only keep the relevant rows. scoplib_matrix_p reduced = scoplib_matrix_ncopy(matrix, isl_map_n_in(map) * 2 + 1); scoplib_matrix_free (matrix); isl_map_free(map); return reduced; }
/** * Create a CLooG schedule from a pluto scattering. * What a mess for tiling into the scattering! * */ static scoplib_matrix_p cloogify_schedule(scoplib_matrix_p mat, int nb_scatt, int nb_par) { int i, j, k, l; int nb_ineq; int nb_eq; // Count the number of inequalities. Foolishly assume two // inequalities per tloop... for (i = 0, nb_ineq = 0, nb_eq = 0; i < mat->NbRows; ++i) { if (SCOPVAL_get_si(mat->p[i][0]) == 1) ++nb_ineq; else ++nb_eq; } int nb_tile_loops = nb_ineq / 2; nb_scatt -= nb_tile_loops; // Allocate new schedule. 'mat' already contains extra columns for // the tloop. scoplib_matrix_p ret = scoplib_matrix_malloc (nb_scatt + nb_ineq, mat->NbColumns + nb_scatt); // -I for the scattering. for (i = 0; i < nb_scatt; ++i) SCOPVAL_set_si(ret->p[i][i + 1], -1); int neq = 0; // Copy the RHS of the schedule (that connects to actual iterations). for (i = 0; i < mat->NbRows; ++i) { if (SCOPVAL_get_si(mat->p[i][0]) == 0) { SCOPVAL_set_si(ret->p[i][0], 0); // Equality defining the schedule. for (j = 1; j < mat->NbColumns; ++j) SCOPVAL_set_si(ret->p[i][j + nb_scatt], SCOPVAL_get_si(mat->p[i][j])); ++neq; } else { // Inequality defining the domain of the scattering. SCOPVAL_set_si(ret->p[i][0], 1); for (j = 0; j < neq; ++j) if (SCOPVAL_get_si(mat->p[j][1 + (i - neq) / 2]) != 0) break; if (j < neq) { for (j = 1; j < mat->NbColumns; ++j) SCOPVAL_set_si(ret->p[i][j + nb_scatt], SCOPVAL_get_si(mat->p[i][j])); } else { SCOPVAL_set_si(ret->p[i][0], 0); SCOPVAL_set_si(ret->p[i][1 + (i - neq) / 2 + neq], -1); ++i; } } } return ret; }