static
int compute_array_dimensionality (scoplib_scop_p scop, int array_id)
{
  scoplib_statement_p s;
  int max_dim = 0;
  scoplib_matrix_p m;
  int cnt;
  for (s = scop->statement; s; s = s->next)
    for (m = s->read, cnt = 0; m && cnt < 2; m = s->write, cnt++)
      {
	int j;
	for (j = 0; j < m->NbRows; ++j)
	  if (SCOPVAL_get_si(m->p[j][0]) == array_id)
	    {
	      max_dim = 1; ++j;
	      while (j < m->NbRows && SCOPVAL_get_si(m->p[j][0]) == 0)
		{
		  ++max_dim;
		  ++j;
		}
	    }
      }

  return max_dim;
}
static
isl_map* build_access_function (scoplib_scop_p scop,
				                    scoplib_statement_p s,
				                    scoplib_matrix_p m,
						    isl_space* space,
						    isl_ctx* ctxt,
						    int* row_pos,
						    int array_id)
{
  isl_map* ret = NULL;
  int i;
  isl_val* tmp = isl_val_int_from_si (ctxt, 0);
  for (i = *row_pos; i < m->NbRows; ++i)
    {
      if (SCOPVAL_get_si(m->p[i][0]) == array_id)
	{
	  ret = isl_map_universe (isl_space_copy (space));
	  int pos = 0;
	  do
	    {
	      isl_local_space* ls =
		isl_local_space_from_space (isl_space_copy (space));
	      isl_constraint* cst = isl_equality_alloc (isl_local_space_copy (ls));

	      // Set input dimensions.
	      int k;
	      for (k = 0; k < s->nb_iterators; ++k)
		{
		  tmp = isl_val_set_si (tmp, SCOPVAL_get_si(m->p[i][k+1]));
		  cst = isl_constraint_set_coefficient_val (cst, isl_dim_in, k, isl_val_copy(tmp));
		}
	      for (k = 0; k < scop->nb_parameters; ++k)
		{
		  tmp =
		    isl_val_set_si (tmp, SCOPVAL_get_si(m->p[i][k+1+s->nb_iterators]));
		  cst =
		    isl_constraint_set_coefficient_val (cst, isl_dim_param, k,
							isl_val_copy (tmp));
		}
	      tmp = isl_val_set_si (tmp, SCOPVAL_get_si(m->p[i][m->NbColumns - 1]));
	      cst = isl_constraint_set_constant_val (cst, isl_val_copy(tmp));
	      // Set output dimension.
	      tmp = isl_val_set_si (tmp, -1);
	      isl_constraint_set_coefficient_val (cst, isl_dim_out, pos++, isl_val_copy (tmp));

	      // Insert constraint.
	      ret = isl_map_add_constraint (ret, cst);
	      ++i;
	    }
	  while (i < m->NbRows && SCOPVAL_get_si(m->p[i][0]) == 0);
	  *row_pos = i;
	  break;
       }
    }
  isl_val_free (tmp);

  return ret;
}
static
isl_set* build_iteration_domain (scoplib_scop_p scop,
				                   scoplib_statement_p s,
						    isl_space* space,
						    isl_ctx* ctxt)
{
  isl_set* ret = isl_set_universe (isl_space_domain (isl_space_copy (space)));
  int i;
  isl_val* tmp = isl_val_int_from_si (ctxt, 0);
  scoplib_matrix_p m = s->domain->elt;
  for (i = 0; i < m->NbRows; ++i)
    {
      isl_local_space* ls =
  	isl_local_space_from_space (isl_set_get_space (ret));
      isl_constraint* cst;
      if (SCOPVAL_get_si(m->p[i][0]) == 0)
  	cst = isl_equality_alloc (isl_local_space_copy (ls));
      else
  	cst = isl_inequality_alloc (isl_local_space_copy (ls));

      // Set input dimensions.
      int k;
      for (k = 0; k < s->nb_iterators; ++k)
  	{
  	  tmp = isl_val_set_si (tmp, SCOPVAL_get_si(m->p[i][k+1]));
  	  cst = isl_constraint_set_coefficient_val (cst, isl_dim_set, k, isl_val_copy (tmp));
  	}
      for (k = 0; k < scop->nb_parameters; ++k)
  	{
  	  tmp =
  	    isl_val_set_si (tmp, SCOPVAL_get_si(m->p[i][k+1+s->nb_iterators]));
  	  cst =
  	    isl_constraint_set_coefficient_val (cst, isl_dim_param, k,
  						isl_val_copy (tmp));
  	}
      tmp = isl_val_set_si (tmp, SCOPVAL_get_si(m->p[i][m->NbColumns - 1]));
      cst = isl_constraint_set_constant_val (cst, isl_val_copy (tmp));

      // Insert constraint.
      ret = isl_set_add_constraint (ret, cst);
    }
  isl_val_free (tmp);

  return ret;
}
Exemplo n.º 4
0
static
CloogMatrix* convert_to_cloogmatrix(scoplib_matrix_p mat)
{
  CloogMatrix* ret = cloog_matrix_alloc (mat->NbRows, mat->NbColumns);

  int i, j;
  for (i = 0; i < mat->NbRows; ++i)
    for (j = 0; j < mat->NbColumns; ++j)
      cloog_int_set_si(ret->p[i][j], SCOPVAL_get_si(mat->p[i][j]));

  return ret;
}
Exemplo n.º 5
0
/**
 * scoplib_scop_read function:
 * This function reads a scoplib_scop_t structure from an input stream
 * (possibly stdin) corresponding to a scoplib SCoP dump.
 * \param file		The input stream
 */
scoplib_scop_p
scoplib_scop_read(FILE* file)
{
  char tmpbuff[SCOPLIB_MAX_STRING];
  scoplib_scop_p scop = NULL;
  scoplib_statement_p stmt = NULL;
  scoplib_statement_p prev = NULL;
  int nb_statements;
  char** tmp;
  int i;
  char* content;

  if (file == NULL)
    return NULL;

  scop = scoplib_scop_malloc();

  /* Backup the arrays of the program. Buffer is reajustable. */
  int nb_arr = SCOPLIB_MAX_STRING;
  char** arrays = (char**) malloc (sizeof(char*) * nb_arr);
  for (i = 0; i < nb_arr; ++i)
    arrays[i] = NULL;

  /* Ensure the file is a .scop. */
  tmp = scoplib_scop_read_strings(file, 1);
  if (strcmp(*tmp, "SCoP"))
    {
      fprintf(stderr, "[Scoplib] Error. The file is not a .scop\n");
      exit (1);
    }
  free(*tmp);
  free(tmp);

  /* Read the language. */
  char** language =  scoplib_scop_read_strings(file, 1);
  if (strcmp(*language, "C") && strcmp(*language, "JAVA") &&
      strcmp(*language, "C#"))
    {
      fprintf(stderr, "[Scoplib] Error. The language is not recognized\n");
      exit (1);
    }
  /* language is not used so far. */
  free(*language);
  free(language);

  /* Read the context. */
  scop->context  = scoplib_matrix_read (file);
  scop->nb_parameters = scop->context->NbColumns - 2;

  /* Read the parameter names, if any. */
  if (scoplib_scop_read_int(file, NULL) > 0)
    scop->parameters = scoplib_scop_read_strings (file, scop->nb_parameters);
  else
    scop->parameters = scoplib_scop_generate_names("M", scop->nb_parameters);

  /* Read the number of statements. */
  nb_statements = scoplib_scop_read_int (file, NULL);

  for (i = 0; i < nb_statements; ++i)
    {
      /* Read each statement. */
      stmt = scoplib_statement_read (file, scop->nb_parameters,
				  &arrays, &nb_arr);
      if (scop->statement == NULL)
	scop->statement = stmt;
      else
	prev->next = stmt;
      prev = stmt;
    }

  /* Read the remainder of the file, and store it in the optiontags
     field. */
  /* Skip blank lines. */
  while (! feof(file) &&
	 (fgets(tmpbuff, SCOPLIB_MAX_STRING, file) == 0 ||
	  tmpbuff[0] == '#' || isspace(tmpbuff[0]) || tmpbuff[0] != '<'))
    ;
  /* Store the remainder of the file, if any. */
  if (tmpbuff[0])
    {
      int count = strlen(tmpbuff);
      int pos = 0;
      int bufs = SCOPLIB_MAX_STRING;
      scop->optiontags = (char*) malloc(bufs * sizeof(char));
      do
	{
	  scop->optiontags = (char*) realloc
	    (scop->optiontags, (bufs += count) * sizeof(char));
	  for (i = 0; i < count; ++i)
	    scop->optiontags[pos++] = tmpbuff[i];
	}
      while ((count = fread(tmpbuff, sizeof(char), SCOPLIB_MAX_STRING, file))
	     > 0);
    }

  /* Count the number of referenced arrays/variables. */
  scop->nb_arrays = 0;
  for (stmt = scop->statement; stmt; stmt = stmt->next)
    {
      if (stmt->read)
	for (i = 0; i < stmt->read->NbRows; ++i)
	  if (scop->nb_arrays < SCOPVAL_get_si(stmt->read->p[i][0]))
	    scop->nb_arrays = SCOPVAL_get_si(stmt->read->p[i][0]);
      if (stmt->write)
	for (i = 0; i < stmt->write->NbRows; ++i)
	  if (scop->nb_arrays < SCOPVAL_get_si(stmt->write->p[i][0]))
	    scop->nb_arrays = SCOPVAL_get_si(stmt->write->p[i][0]);
    }

  /* Allocate the array names array. */
  scop->arrays = (char**) malloc(sizeof(char*) * (scop->nb_arrays + 1));
  for (i = 0; i < scop->nb_arrays; ++i)
    scop->arrays[i] = NULL;

  /* Populate the array list with referenced in the <array> tag, if
     any. */
  if ((content = scoplib_scop_tag_content(scop, "<arrays>", "</arrays>")))
    {
      char* start = content;
      int n_arr = scoplib_scop_read_int(NULL, &content);
      char buff2[SCOPLIB_MAX_STRING];
      int idx_array;
      i = 0;
      while (n_arr--)
	{
	  /* Skip blank or commented lines. */
	  while (*content == '#' || *content == '\n')
	    {
	      for (; *content != '\n'; ++content)
		;
	      ++content;
	    }
	  /* Get the variable id. */
	  for (i = 0; *content && ! isspace(*content); ++i, ++content)
	    buff2[i] = *content;
	  buff2[i] = '\0';
	  sscanf (buff2, "%d", &idx_array);
	  /* Get the variable name. */
	  while (*content && isspace(*content))
	    ++content;
	  for (i = 0; *content && ! isspace(*content); ++i, ++content)
	    buff2[i] = *content;
	  buff2[i] = '\0';
	  /* array is in 0-basis. */
	  if (arrays[idx_array - 1])
	    free(arrays[idx_array - 1]);
	  arrays[idx_array - 1] = strdup(buff2);
	  /* Go to the end of line. */
	  while (*content && *content != '\n')
	    ++content;
	}
      content = start;
    }

  /* Fill the array of array names. */
  char** tmparrays = scoplib_scop_generate_names("var", scop->nb_arrays);
  for (i = 0; i < scop->nb_arrays; ++i)
    {
      if (arrays[i] == NULL || arrays[i][0] == '\0')
	{
	  /* Use a generated name in case no array name was parsed. */
	  scop->arrays[i] = tmparrays[i];
	  if (arrays[i])
	    free(arrays[i]);
	}
      else
	{
	  /* Use the parsed array name. */
	  scop->arrays[i] = arrays[i];
	  free(tmparrays[i]);
	}
    }
  scop->arrays[i] = NULL;
  free(arrays);
  free(tmparrays);


  return scop;
}
static
isl_map* build_schedule (scoplib_scop_p scop,
				         scoplib_statement_p s,
			                 isl_space* sp,
			                 isl_ctx* ctxt)
{
  // Set up the space.
  isl_space* space_in  = isl_space_domain (isl_space_copy (sp));
  int dout = s->schedule->NbRows;
  isl_space* space_out = isl_space_set_alloc(ctxt, scop->nb_parameters, dout);
  int i;
  char buffer[32];
  char* name;
  for (i = 0; i < dout; ++i)
    {
      sprintf (buffer, "t%d", i);
      name = strdup (buffer);
      space_out = isl_space_set_dim_name (space_out, isl_dim_set, i, name);
    }
  for (i = 0; i < scop->nb_parameters; ++i)
    {
      name = strdup (((SgVariableSymbol*)(scop->parameters[i]))->get_name().str());
      space_out = isl_space_set_dim_name (space_out, isl_dim_param, i, name);
    }

  isl_space* space = isl_space_map_from_domain_and_range
    (isl_space_copy (space_in), isl_space_copy (space_out));
  isl_map* ret = isl_map_universe (isl_space_copy (space));
  isl_val* tmp = isl_val_int_from_si (ctxt, 0);
  scoplib_matrix_p m = s->schedule;
  for (i = 0; i < m->NbRows; ++i)
    {
      isl_local_space* ls =
  	isl_local_space_from_space (isl_space_copy (space));
      isl_constraint* cst;
      if (SCOPVAL_get_si(m->p[i][0]) == 0)
  	cst = isl_equality_alloc (isl_local_space_copy (ls));
      else
  	cst = isl_inequality_alloc (isl_local_space_copy (ls));

      // Set input dimensions.
      int k;
      for (k = 0; k < s->nb_iterators; ++k)
  	{
  	  tmp = isl_val_set_si (tmp, SCOPVAL_get_si(m->p[i][k+1]));
  	  cst = isl_constraint_set_coefficient_val (cst, isl_dim_in, k, isl_val_copy (tmp));
  	}
      for (k = 0; k < scop->nb_parameters; ++k)
  	{
  	  tmp =
  	    isl_val_set_si (tmp, SCOPVAL_get_si(m->p[i][k+1+s->nb_iterators]));
  	  cst =
  	    isl_constraint_set_coefficient_val (cst, isl_dim_param, k,
  						isl_val_copy (tmp));
  	}
      tmp = isl_val_set_si (tmp, SCOPVAL_get_si(m->p[i][m->NbColumns - 1]));
      cst = isl_constraint_set_constant_val (cst, isl_val_copy (tmp));

      // Set output dimension.
      tmp = isl_val_set_si (tmp, -1);
      isl_constraint_set_coefficient_val (cst, isl_dim_out, i, isl_val_copy (tmp));

      // Insert constraint.
      ret = isl_map_add_constraint (ret, cst);
    }
  isl_val_free (tmp);

  return ret;
}
Exemplo n.º 7
0
/**
 * 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;
}