/** * Creates a ddv of size equal to the maximal loop depth of the source * and target of the statement, according to the dependence polyhedron. * */ static CandlDDV* candl_ddv_create_from_dep(CandlDependence* dep, int loop_id, int ddv_size) { int i, j; int pos; CandlMatrix* mat = dep->domain; CandlStatement* src = dep->source; CandlDDV* dv = candl_ddv_alloc(ddv_size); dv->loop_id = loop_id; dv->deptype = dep->type; // Create the template of the system to operate on. // Add one dimension at the beginning, and one row for the extra constraint. int nb_par = src->domain->NbColumns - 2 - src->depth; CandlMatrix* testsyst = candl_matrix_malloc(mat->NbRows + 1, mat->NbColumns + 1); for (pos = 0; pos < mat->NbRows; ++pos) { CANDL_assign(testsyst->p[pos][0], mat->p[pos][0]); for (j = 1; j < mat->NbColumns; ++j) CANDL_assign(testsyst->p[pos][j + 1], mat->p[pos][j]); } int has_eq, has_pos, has_neg, has_cst; int scal1, scal2; for (i = 1; i <= ddv_size; ++i) { // Test for '='. CANDL_set_si(testsyst->p[pos][0], 0); CANDL_set_si(testsyst->p[pos][1 + i], 1); CANDL_set_si(testsyst->p[pos][1 + i + src->depth], -1); CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], 0); has_eq = candl_ddv_has_point(testsyst); // Test for '>'. CANDL_set_si(testsyst->p[pos][0], 1); CANDL_set_si(testsyst->p[pos][1 + i], 1); CANDL_set_si(testsyst->p[pos][1 + i + src->depth], -1); CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], -1); has_pos = candl_ddv_has_point(testsyst); // Test for '<'. CANDL_set_si(testsyst->p[pos][0], 1); CANDL_set_si(testsyst->p[pos][1 + i], -1); CANDL_set_si(testsyst->p[pos][1 + i + src->depth], 1); CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], -1); has_neg = candl_ddv_has_point(testsyst); // Test for constant distance. // min(x_R^i - x_S^i) // max(x_R^i - x_S^i) = - min(- x_R^i + x_S^i) CANDL_set_si(testsyst->p[pos][0], 0); CANDL_set_si(testsyst->p[pos][1], 1); CANDL_set_si(testsyst->p[pos][1 + i], -1); CANDL_set_si(testsyst->p[pos][1 + i + src->depth], 1); CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], 0); has_cst = candl_ddv_constant_val(testsyst, &scal1, nb_par); if (has_cst) { CANDL_set_si(testsyst->p[pos][1 + i], 1); CANDL_set_si(testsyst->p[pos][1 + i + src->depth], -1); CANDL_set_si(testsyst->p[pos][1], 1); has_cst = candl_ddv_constant_val(testsyst, &scal2, nb_par); scal2 *= -1; if (has_cst) has_cst = (scal1 == scal2); } if (has_cst && scal1 != 0) { candl_ddv_set_type_at (dv, candl_dv_scalar, i - 1); candl_ddv_set_value_at (dv, scal1, i - 1); } else if (has_pos && has_neg) candl_ddv_set_type_at (dv, candl_dv_star, i - 1); else if (has_pos) candl_ddv_set_type_at (dv, candl_dv_plus, i - 1); else if (has_neg) candl_ddv_set_type_at (dv, candl_dv_minus, i - 1); else if (has_eq) { candl_ddv_set_type_at (dv, candl_dv_eq, i - 1); candl_ddv_set_value_at (dv, 0, i - 1); } // Reset the constraint. CANDL_set_si(testsyst->p[pos][0], 0); CANDL_set_si(testsyst->p[pos][1], 0); CANDL_set_si(testsyst->p[pos][1 + i], 0); CANDL_set_si(testsyst->p[pos][1 + i + src->depth], 0); CANDL_set_si(testsyst->p[pos][testsyst->NbColumns - 1], 0); } return dv; }
/** * Creates a ddv of size equal to the maximal loop depth of the source * and target of the statement, according to the dependence polyhedron. * */ static CandlDDV* candl_ddv_create_from_dep(osl_dependence_p dep, int loop_id, int ddv_size) { osl_relation_p mat = dep->domain; osl_statement_p src = dep->stmt_source_ptr; candl_statement_usr_p usr = src->usr; CandlDDV* dv = candl_ddv_alloc(ddv_size); int precision = src->domain->precision; int i, j; int pos; dv->loop_id = loop_id; dv->deptype = dep->type; // Create the template of the system to operate on. // Add one dimension at the beginning, and one row for the extra constraint. int nb_par = src->domain->nb_parameters; osl_relation_p testsyst = osl_relation_pmalloc(precision, mat->nb_rows + 1, mat->nb_columns + 1); for (pos = 0; pos < mat->nb_rows; ++pos) { osl_int_assign(precision, &testsyst->m[pos][0], mat->m[pos][0]); for (j = 1; j < mat->nb_columns; ++j) osl_int_assign(precision, &testsyst->m[pos][j + 1],mat->m[pos][j]); } int has_eq, has_pos, has_neg, has_cst; int scal1, scal2; for (i = 1; i <= ddv_size; ++i) { // Test for '='. osl_int_set_si(precision, &testsyst->m[pos][0], 0); osl_int_set_si(precision, &testsyst->m[pos][1 + i], 1); osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], -1); osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], 0); has_eq = pip_has_rational_point(testsyst, NULL, 1); // Test for '>'. osl_int_set_si(precision, &testsyst->m[pos][0], 1); osl_int_set_si(precision, &testsyst->m[pos][1 + i], 1); osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], -1); osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], -1); has_pos = pip_has_rational_point(testsyst, NULL, 1); // Test for '<'. osl_int_set_si(precision, &testsyst->m[pos][0], 1); osl_int_set_si(precision, &testsyst->m[pos][1 + i], -1); osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], 1); osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], -1); has_neg = pip_has_rational_point(testsyst, NULL, 1); // Test for constant distance. // min(x_R^i - x_S^i) // max(x_R^i - x_S^i) = - min(- x_R^i + x_S^i) osl_int_set_si(precision, &testsyst->m[pos][0], 0); osl_int_set_si(precision, &testsyst->m[pos][1], 1); osl_int_set_si(precision, &testsyst->m[pos][1 + i], -1); osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], 1); osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], 0); has_cst = candl_ddv_constant_val(testsyst, &scal1, nb_par); if (has_cst) { osl_int_set_si(precision, &testsyst->m[pos][1 + i], 1); osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], -1); osl_int_set_si(precision, &testsyst->m[pos][1], 1); has_cst = candl_ddv_constant_val(testsyst, &scal2, nb_par); scal2 *= -1; if (has_cst) has_cst = (scal1 == scal2); } if (has_cst && scal1 != 0) { candl_ddv_set_type_at(dv, candl_dv_scalar, i - 1); candl_ddv_set_value_at(dv, scal1, i - 1); } else if (has_pos && has_neg) candl_ddv_set_type_at(dv, candl_dv_star, i - 1); else if (has_pos) candl_ddv_set_type_at(dv, candl_dv_plus, i - 1); else if (has_neg) candl_ddv_set_type_at(dv, candl_dv_minus, i - 1); else if (has_eq) { candl_ddv_set_type_at(dv, candl_dv_eq, i - 1); candl_ddv_set_value_at(dv, 0, i - 1); } // Reset the constraint. osl_int_set_si(precision, &testsyst->m[pos][0], 0); osl_int_set_si(precision, &testsyst->m[pos][1], 0); osl_int_set_si(precision, &testsyst->m[pos][1 + i], 0); osl_int_set_si(precision, &testsyst->m[pos][1 + i + usr->depth], 0); osl_int_set_si(precision, &testsyst->m[pos][testsyst->nb_columns-1], 0); } return dv; }