Exemplo n.º 1
0
/**
 * Integer emptiness test on a given polyhedron.
 *
 */
static
int
candl_ddv_has_point(CandlMatrix* system)
{
  return pip_has_rational_point (system, NULL, 1);
}
Exemplo n.º 2
0
Arquivo: ddv.c Projeto: Ced/candl
/**
 * 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;
}