Exemplo n.º 1
0
int isl_map_contains_point(__isl_keep isl_map *map, __isl_keep isl_point *point)
{
	int i;
	int found = 0;

	if (!map || !point)
		return -1;

	map = isl_map_copy(map);
	map = isl_map_compute_divs(map);
	if (!map)
		return -1;

	for (i = 0; i < map->n; ++i) {
		found = isl_basic_map_contains_point(map->p[i], point);
		if (found < 0)
			goto error;
		if (found)
			break;
	}
	isl_map_free(map);

	return found;
error:
	isl_map_free(map);
	return -1;
}
Exemplo n.º 2
0
void
free_poly_dr (poly_dr_p pdr)
{
  isl_map_free (pdr->accesses);
  isl_set_free (pdr->subscript_sizes);
  XDELETE (pdr);
}
Exemplo n.º 3
0
int main(int argc, char **argv)
{
	struct isl_ctx *ctx;
	struct isl_map *map;
	struct isl_options *options;
	isl_printer *p;
	int exact;

	options = isl_options_new_with_defaults();
	assert(options);
	argc = isl_options_parse(options, argc, argv, ISL_ARG_ALL);

	ctx = isl_ctx_alloc_with_options(&isl_options_args, options);

	p = isl_printer_to_file(ctx, stdout);

	map = isl_map_read_from_file(ctx, stdin);
	map = isl_map_transitive_closure(map, &exact);
	if (!exact)
		p = isl_printer_print_str(p, "# NOT exact\n");
	p = isl_printer_print_map(p, map);
	p = isl_printer_end_line(p);
	map = isl_map_compute_divs(map);
	map = isl_map_coalesce(map);
	p = isl_printer_print_str(p, "# coalesced\n");
	p = isl_printer_print_map(p, map);
	p = isl_printer_end_line(p);
	isl_map_free(map);

	isl_printer_free(p);

	isl_ctx_free(ctx);

	return 0;
}
Exemplo n.º 4
0
void freeStmtToIslMap(StatementToIslMapTy *Map) {
  for (StatementToIslMapTy::iterator MI = Map->begin(), ME = Map->end();
       MI != ME; ++MI)
    isl_map_free(MI->second);

  delete (Map);
}
Exemplo n.º 5
0
/* Set max_out to the maximal number of output dimensions over
 * all maps.
 */
static isl_stat update_max_out(__isl_take isl_map *map, void *user)
{
    int *max_out = user;
    int n_out = isl_map_dim(map, isl_dim_out);

    if (n_out > *max_out)
        *max_out = n_out;

    isl_map_free(map);
    return isl_stat_ok;
}
Exemplo n.º 6
0
struct isl_basic_map *isl_map_affine_hull(struct isl_map *map)
{
	int i;
	struct isl_basic_map *model = NULL;
	struct isl_basic_map *hull = NULL;
	struct isl_set *set;

	map = isl_map_detect_equalities(map);
	map = isl_map_align_divs(map);

	if (!map)
		return NULL;

	if (map->n == 0) {
		hull = isl_basic_map_empty_like_map(map);
		isl_map_free(map);
		return hull;
	}

	model = isl_basic_map_copy(map->p[0]);
	set = isl_map_underlying_set(map);
	set = isl_set_cow(set);
	if (!set)
		goto error;

	for (i = 0; i < set->n; ++i) {
		set->p[i] = isl_basic_set_cow(set->p[i]);
		set->p[i] = isl_basic_set_affine_hull(set->p[i]);
		set->p[i] = isl_basic_set_gauss(set->p[i], NULL);
		if (!set->p[i])
			goto error;
	}
	set = isl_set_remove_empty_parts(set);
	if (set->n == 0) {
		hull = isl_basic_map_empty_like(model);
		isl_basic_map_free(model);
	} else {
		struct isl_basic_set *bset;
		while (set->n > 1) {
			set->p[0] = affine_hull(set->p[0], set->p[--set->n]);
			if (!set->p[0])
				goto error;
		}
		bset = isl_basic_set_copy(set->p[0]);
		hull = isl_basic_map_overlying_set(bset, model);
	}
	isl_set_free(set);
	hull = isl_basic_map_simplify(hull);
	return isl_basic_map_finalize(hull);
error:
	isl_basic_map_free(model);
	isl_set_free(set);
	return NULL;
}
Exemplo n.º 7
0
void isl_token_free(struct isl_token *tok)
{
	if (!tok)
		return;
	if (tok->type == ISL_TOKEN_VALUE)
		isl_int_clear(tok->u.v);
	else if (tok->type == ISL_TOKEN_MAP)
		isl_map_free(tok->u.map);
	else if (tok->type == ISL_TOKEN_AFF)
		isl_pw_aff_free(tok->u.pwaff);
	else
		free(tok->u.s);
	free(tok);
}
Exemplo n.º 8
0
struct isl_map *isl_map_implicit_equalities(struct isl_map *map)
{
	int i;

	if (!map)
		return map;

	for (i = 0; i < map->n; ++i) {
		map->p[i] = isl_basic_map_implicit_equalities(map->p[i]);
		if (!map->p[i])
			goto error;
	}

	return map;
error:
	isl_map_free(map);
	return NULL;
}
Exemplo n.º 9
0
/* Given a set of validity and proximity schedule constraints "map"
 * between statements in consecutive leaves in a valid schedule,
 * should the two leaves be merged into one?
 *
 * In particular, the two are merged if the constraints form
 * a bijection between every instance of the first statement and
 * every instance of the second statement.  Moreover, each
 * pair of such dependent instances needs to be executed consecutively
 * in the input schedule.  That is, they need to be assigned
 * the same value by their prefix schedules.
 *
 * What this means is that for each instance of the first statement
 * there is exactly one instance of the second statement that
 * is executed immediately after the instance of the first statement and
 * that, moreover, both depends on this statement instance and
 * should be brought as close as possible to this statement instance.
 * In other words, it is both possible to execute the two instances
 * together (according to the input schedule) and desirable to do so
 * (according to the validity and proximity schedule constraints).
 */
static isl_stat check_merge(__isl_take isl_map *map, void *user)
{
	struct ppcg_merge_leaves_data *data = user;
	isl_bool ok;

	ok = covers_src_and_dst(map, data->src, data->dst);
	if (ok >= 0 && ok)
		ok = isl_map_is_bijective(map);
	if (ok >= 0 && ok)
		ok = matches_prefix(map, data->src, data->dst);

	isl_map_free(map);

	if (ok < 0)
		return isl_stat_error;
	if (!ok)
		return isl_stat_ok;

	data->merge = 1;
	return isl_stat_error;
}
Exemplo n.º 10
0
/// 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;
}
Exemplo n.º 11
0
/// 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;
}
Exemplo n.º 12
0
__isl_give isl_map *isl_map_inline_foreach_basic_map(__isl_take isl_map *map,
	__isl_give isl_basic_map *(*fn)(__isl_take isl_basic_map *bmap))
{
	struct isl_basic_map *bmap;
	int i;

	if (!map)
		return NULL;

	for (i = 0; i < map->n; ++i) {
		bmap = isl_basic_map_copy(map->p[i]);
		bmap = fn(bmap);
		if (!bmap)
			goto error;
		isl_basic_map_free(map->p[i]);
		map->p[i] = bmap;
	}

	return map;
error:
	isl_map_free(map);
	return NULL;
}
Exemplo n.º 13
0
static void
pdr_stride_in_loop (mpz_t stride, graphite_dim_t depth, poly_dr_p pdr)
{
  poly_bb_p pbb = PDR_PBB (pdr);
  isl_map *map;
  isl_set *set;
  isl_aff *aff;
  isl_space *dc;
  isl_constraint *lma, *c;
  isl_int islstride;
  graphite_dim_t time_depth;
  unsigned offset, nt;
  unsigned i;
  /* XXX isl rewrite following comments.  */
  /* Builds a partial difference equations and inserts them
     into pointset powerset polyhedron P.  Polyhedron is assumed
     to have the format: T|I|T'|I'|G|S|S'|l1|l2.

     TIME_DEPTH is the time dimension w.r.t. which we are
     differentiating.
     OFFSET represents the number of dimensions between
     columns t_{time_depth} and t'_{time_depth}.
     DIM_SCTR is the number of scattering dimensions.  It is
     essentially the dimensionality of the T vector.

     The following equations are inserted into the polyhedron P:
     | t_1 = t_1'
     | ...
     | t_{time_depth-1} = t'_{time_depth-1}
     | t_{time_depth} = t'_{time_depth} + 1
     | t_{time_depth+1} = t'_{time_depth + 1}
     | ...
     | t_{dim_sctr} = t'_{dim_sctr}.  */

  /* Add the equality: t_{time_depth} = t'_{time_depth} + 1.
     This is the core part of this alogrithm, since this
     constraint asks for the memory access stride (difference)
     between two consecutive points in time dimensions.  */

  /* Add equalities:
     | t1 = t1'
     | ...
     | t_{time_depth-1} = t'_{time_depth-1}
     | t_{time_depth+1} = t'_{time_depth+1}
     | ...
     | t_{dim_sctr} = t'_{dim_sctr}

     This means that all the time dimensions are equal except for
     time_depth, where the constraint is t_{depth} = t'_{depth} + 1
     step.  More to this: we should be careful not to add equalities
     to the 'coupled' dimensions, which happens when the one dimension
     is stripmined dimension, and the other dimension corresponds
     to the point loop inside stripmined dimension.  */

  /* pdr->accesses:    [P1..nb_param,I1..nb_domain]->[a,S1..nb_subscript]
          ??? [P] not used for PDRs?
     pdr->extent:      [a,S1..nb_subscript]
     pbb->domain:      [P1..nb_param,I1..nb_domain]
     pbb->transformed: [P1..nb_param,I1..nb_domain]->[T1..Tnb_sctr]
          [T] includes local vars (currently unused)
     
     First we create [P,I] -> [T,a,S].  */
  
  map = isl_map_flat_range_product (isl_map_copy (pbb->transformed),
				    isl_map_copy (pdr->accesses));
  /* Add a dimension for L: [P,I] -> [T,a,S,L].*/
  map = isl_map_add_dims (map, isl_dim_out, 1);
  /* Build a constraint for "lma[S] - L == 0", effectively calculating
     L in terms of subscripts.  */
  lma = build_linearized_memory_access (map, pdr);
  /* And add it to the map, so we now have:
     [P,I] -> [T,a,S,L] : lma([S]) == L.  */
  map = isl_map_add_constraint (map, lma);

  /* Then we create  [P,I,P',I'] -> [T,a,S,L,T',a',S',L'].  */
  map = isl_map_flat_product (map, isl_map_copy (map));

  /* Now add the equality T[time_depth] == T'[time_depth]+1.  This will
     force L' to be the linear address at T[time_depth] + 1. */
  time_depth = psct_dynamic_dim (pbb, depth);
  /* Length of [a,S] plus [L] ...  */
  offset = 1 + isl_map_dim (pdr->accesses, isl_dim_out);
  /* ... plus [T].  */
  offset += isl_map_dim (pbb->transformed, isl_dim_out);

  c = isl_equality_alloc (isl_local_space_from_space (isl_map_get_space (map)));
  c = isl_constraint_set_coefficient_si (c, isl_dim_out, time_depth, 1);
  c = isl_constraint_set_coefficient_si (c, isl_dim_out,
					 offset + time_depth, -1);
  c = isl_constraint_set_constant_si (c, 1);
  map = isl_map_add_constraint (map, c);

  /* Now we equate most of the T/T' elements (making PITaSL nearly
     the same is (PITaSL)', except for one dimension, namely for 'depth'
     (an index into [I]), after translating to index into [T].  Take care
     to not produce an empty map, which indicates we wanted to equate
     two dimensions that are already coupled via the above time_depth
     dimension.  Happens with strip mining where several scatter dimension
     are interdependend.  */
  /* Length of [T].  */
  nt = pbb_nb_scattering_transform (pbb) + pbb_nb_local_vars (pbb);
  for (i = 0; i < nt; i++)
    if (i != time_depth)
      {
	isl_map *temp = isl_map_equate (isl_map_copy (map),
					isl_dim_out, i,
					isl_dim_out, offset + i);
	if (isl_map_is_empty (temp))
	  isl_map_free (temp);
	else
	  {
	    isl_map_free (map);
	    map = temp;
	  }
      }

  /* Now maximize the expression L' - L.  */
  set = isl_map_range (map);
  dc = isl_set_get_space (set);
  aff = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
  aff = isl_aff_set_coefficient_si (aff, isl_dim_in, offset - 1, -1);
  aff = isl_aff_set_coefficient_si (aff, isl_dim_in, offset + offset - 1, 1);
  isl_int_init (islstride);
  isl_set_max (set, aff, &islstride);
  isl_int_get_gmp (islstride, stride);
  isl_int_clear (islstride);
  isl_aff_free (aff);
  isl_set_free (set);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      char *str;
      void (*gmp_free) (void *, size_t);

      fprintf (dump_file, "\nStride in BB_%d, DR_%d, depth %d:",
	       pbb_index (pbb), PDR_ID (pdr), (int) depth);
      str = mpz_get_str (0, 10, stride);
      fprintf (dump_file, "  %s ", str);
      mp_get_memory_functions (NULL, NULL, &gmp_free);
      (*gmp_free) (str, strlen (str) + 1);
    }
}
Exemplo n.º 14
0
Data::~Data() {
  if (access != NULL) {
    isl_map_free(access);
  }
}
Exemplo n.º 15
0
static void isl_obj_map_free(void *v)
{
	isl_map_free((struct isl_map *)v);
}
/**
 * Converts a SCoP as extracted by PolyOpt's auto-scop detection
 * into ISL representation.
 *
 * bugs/limitations:
 *    (a) not robust to union of iteration domains in scoplib
 *    (b) code is leaking, need proper copy constructor that duplicates all
 *          ISL structures.
 */
int
PolyOptISLRepresentation::convertScoplibToISL (scoplib_scop_p scop)
{
  int i;
  isl_union_map* all_reads = NULL;
  isl_union_map* all_writes = NULL;
  isl_union_map* all_scheds = NULL;
  isl_ctx* ctxt = isl_ctx_alloc();

  // 1. Prepare the arrays of unique names for statements and arrays.
  char buffer[32];
  int nb_statements;
  scoplib_statement_p s;
  for (nb_statements = 0, s = scop->statement; s; s = s->next, nb_statements++)
    ;
  char* stmt_names[nb_statements];
  for (i = 0; i < nb_statements; ++i)
    {
      sprintf (buffer, "S_%d", i);
      stmt_names[i] = strdup (buffer);
    }
  char* array_names[scop->nb_arrays];
  for (i = 0; i < scop->nb_arrays; ++i)
    array_names[i] =
      strdup (((SgVariableSymbol*)(scop->arrays[i]))->get_name().str());

  isl_union_map* umap;
  int stmt_id;
  for (s = scop->statement, stmt_id = 0; s; s = s->next, ++stmt_id)
    {
      isl_union_map* all_reads_stmt = NULL;
      isl_union_map* all_writes_stmt = NULL;
      isl_space* sp = NULL;
      for (i = 0; i < scop->nb_arrays; ++i)
	{
	  sp = build_isl_space (scop, s, i+1, ctxt);

	  // 1. Handle access matrices.
	  scoplib_matrix_p m;
	  int k;
	  for (k = 0, m = s->read, umap = all_reads_stmt; k < 2;
	       k++, m = s->write, umap = all_writes_stmt)
	    {
	      isl_map* acc_map = NULL;
	      int row_pos = 0;
	      do
		{
		  acc_map = build_access_function
		    (scop, s, m, sp, ctxt, &row_pos, i+1);
		  if (acc_map)
		    {
		      acc_map = isl_map_set_tuple_name
			(acc_map, isl_dim_in, stmt_names[stmt_id]);
		      acc_map = isl_map_set_tuple_name
			(acc_map, isl_dim_out, array_names[i]);
		      if (umap == NULL)
			umap = isl_union_map_from_map (isl_map_copy (acc_map));
		      else
			umap = isl_union_map_union
			  (umap, isl_union_map_from_map (isl_map_copy (acc_map)));
		      isl_map_free (acc_map);
		    }
		}
	      while (acc_map != NULL);
	      if (k == 0)
		all_reads_stmt = umap;
	      else
		all_writes_stmt = umap;
	    }
	}
      // Store the union of access functions of statement i.
      stmt_accfunc_read.push_back (all_reads_stmt);
      stmt_accfunc_write.push_back (all_writes_stmt);

      // 2. Handle iteration domains.
      isl_set* dom = build_iteration_domain (scop, s, sp, ctxt);
      dom = isl_set_set_tuple_name (dom, stmt_names[stmt_id]);
      if (all_reads_stmt != NULL)
	all_reads_stmt = isl_union_map_intersect_domain
	  (isl_union_map_copy (all_reads_stmt),
	   isl_union_set_from_set (isl_set_copy (dom)));
      if (all_writes_stmt != NULL)
	all_writes_stmt = isl_union_map_intersect_domain
	  (all_writes_stmt, isl_union_set_from_set (isl_set_copy (dom)));

      // Store the iteration domain of statement i.
      stmt_iterdom.push_back (dom);
      // Store the union of access functions of statement i after intersection by domain.
      stmt_read_domain.push_back (all_reads_stmt);
      stmt_write_domain.push_back (all_writes_stmt);

      // Unionize the result.
      if (all_reads == NULL)
	all_reads = isl_union_map_copy (all_reads_stmt);
      else
	all_reads = isl_union_map_union
	  (all_reads, isl_union_map_copy (all_reads_stmt));
      if (all_writes == NULL)
	all_writes = isl_union_map_copy (all_writes_stmt);
      else
	all_writes = isl_union_map_union
	  (all_writes, isl_union_map_copy (all_writes_stmt));
      // isl_union_map_free (all_reads_stmt);
      // isl_union_map_free (all_writes_stmt);

      // 3. Handle schedules.
      isl_map* sched = build_schedule (scop, s, sp, ctxt);
      sched = isl_map_set_tuple_name (sched, isl_dim_in, stmt_names[stmt_id]);
      if (all_scheds == NULL)
	all_scheds = isl_union_map_from_map (isl_map_copy (sched));
      else
	all_scheds = isl_union_map_union
	  (all_scheds, isl_union_map_from_map (isl_map_copy (sched)));
      // Store the schedule of statement i.
      stmt_schedule.push_back (sched);

      // 4. Finalize info about the statement.
      stmt_body.push_back (((SgNode*)(s->body))->unparseToCompleteString());
      stmt_body_ir.push_back ((SgNode*)(s->body));
    }

  // // Debug.
  // isl_printer* pr = isl_printer_to_file (ctxt, stdout);
  // std::cout << "UNION MAP READS" << std::endl;
  // isl_printer_print_union_map(pr, all_reads);
  // printf ("\n");
  // std::cout << "UNION MAP WRITES" << std::endl;
  // isl_printer_print_union_map(pr, all_writes);
  // printf ("\n");
  // std::cout << "UNION MAP SCHEDULES" << std::endl;
  // isl_printer_print_union_map(pr, all_scheds);
  // printf ("\n");
  for (std::vector<std::string>::iterator i = stmt_body.begin();
       i != stmt_body.end(); ++i)
    std::cout << "stmt body: " << *i << std::endl;
  // Finalize SCoP representation.
  scop_nb_arrays = scop->nb_arrays;
  scop_nb_statements = stmt_schedule.size();
  scop_reads = all_reads;
  scop_writes = all_writes;
  scop_scheds = all_scheds;

  return EXIT_SUCCESS;
}