Exemplo n.º 1
0
/* Used by libpluto interface */
static int extract_stmt(__isl_take isl_set *set, void *user)
{
    int r;
    Stmt **stmts;
    int id, i;

    stmts = (Stmt **) user;

    int dim = isl_set_dim(set, isl_dim_all);
    int npar = isl_set_dim(set, isl_dim_param);
    PlutoMatrix *trans = pluto_matrix_alloc(dim-npar, dim+1);
    pluto_matrix_set(trans, 0);
    trans->nrows = 0;

    /* A statement's domain (isl_set) should be named S_%d */
    const char *name = isl_set_get_tuple_name(set);
    assert(name);
    assert(strlen(name) >= 3);
    assert(name[0] == 'S');
    assert(name[1] == '_');
    assert(isdigit(name[2]));
    id = atoi(isl_set_get_tuple_name(set)+2);

    stmts[id] = pluto_stmt_alloc(dim-npar, NULL, trans);

    Stmt *stmt = stmts[id];
    stmt->type = ORIG;
    stmt->id = id;

    for (i=0; i<stmt->dim; i++) {
        char *iter = malloc(5);
        sprintf(iter, "i%d",  i);
        stmt->iterators[i] = iter;
    }

    struct pluto_extra_stmt_info info = {stmts, id};
    r = isl_set_foreach_basic_set(set, &extract_basic_set, &info);

    pluto_constraints_set_names_range(stmt->domain, stmt->iterators, 0, 0, stmt->dim);

    for (i=0; i<npar; i++) {
        char *param = malloc(5);
        sprintf(param, "p%d", i);
        stmt->domain->names[stmt->dim+i] = param;
    }

    pluto_matrix_free(trans);

    int j;
    for (j=0; j<stmt->dim; j++)  {
        stmt->is_orig_loop[j] = true;
    }

    isl_set_free(set);

    return r;
}
Exemplo n.º 2
0
/* Compute the size of a bounding box around the origin and "set",
 * where "set" is assumed to contain only non-negative elements.
 * In particular, compute the maximal value of "set" in each direction
 * and add one.
 */
__isl_give isl_multi_pw_aff *ppcg_size_from_extent(__isl_take isl_set *set)
{
	int i, n;
	isl_multi_pw_aff *mpa;

	n = isl_set_dim(set, isl_dim_set);
	mpa = isl_multi_pw_aff_zero(isl_set_get_space(set));
	for (i = 0; i < n; ++i) {
		isl_space *space;
		isl_aff *one;
		isl_pw_aff *bound;

		if (!isl_set_dim_has_upper_bound(set, isl_dim_set, i)) {
			const char *name;
			name = isl_set_get_tuple_name(set);
			if (!name)
				name = "";
			fprintf(stderr, "unable to determine extent of '%s' "
				"in dimension %d\n", name, i);
			set = isl_set_free(set);
		}
		bound = isl_set_dim_max(isl_set_copy(set), i);

		space = isl_pw_aff_get_domain_space(bound);
		one = isl_aff_zero_on_domain(isl_local_space_from_space(space));
		one = isl_aff_add_constant_si(one, 1);
		bound = isl_pw_aff_add(bound, isl_pw_aff_from_aff(one));
		mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, bound);
	}
	isl_set_free(set);

	return mpa;
}
Exemplo n.º 3
0
Arquivo: Cloog.cpp Projeto: CIB/polly
CloogInput *Cloog::buildCloogInput() {
  // XXX: We do not copy the context of the scop, but use an unconstrained
  //      context. This 'hack' is necessary as the context may contain bounds
  //      on parameters such as [n] -> {:0 <= n < 2^32}. Those large
  //      integers will cause CLooG to construct a clast that contains
  //      expressions that include these large integers. Such expressions can
  //      possibly not be evaluated correctly with i64 types. The cloog
  //      based code generation backend, however, can not derive types
  //      automatically and just assumes i64 types. Hence, it will break or
  //      generate incorrect code.
  //      This hack does not remove all possibilities of incorrectly generated
  //      code, but it is ensures that for most problems the problems do not
  //      show up. The correct solution, will be to automatically derive the
  //      minimal types for each expression. This could be added to CLooG and it
  //      will be available in the isl based code generation.
  isl_set *EmptyContext = isl_set_universe(S->getParamSpace());
  CloogDomain *Context = cloog_domain_from_isl_set(EmptyContext);
  CloogUnionDomain *Statements = buildCloogUnionDomain();

  isl_set *ScopContext = S->getContext();

  for (unsigned i = 0; i < isl_set_dim(ScopContext, isl_dim_param); i++) {
    isl_id *id = isl_set_get_dim_id(ScopContext, isl_dim_param, i);
    Statements = cloog_union_domain_set_name(Statements, CLOOG_PARAM, i,
                                             isl_id_get_name(id));
    isl_id_free(id);
  }

  isl_set_free(ScopContext);

  CloogInput *Input = cloog_input_alloc(Context, Statements);
  return Input;
}
Exemplo n.º 4
0
/* Extract a common guard from the grafts in "list" that can be hoisted
 * out of the current level.  If no such guard can be found, then return
 * a universal set.
 *
 * If all the grafts in the list have the same guard and if this guard
 * is independent of the current level, then it can be hoisted out.
 * Otherwise, we return the unshifted simple hull of the guards.
 *
 * The special case for equal guards is needed in case those guards
 * are non-convex.  Taking the simple hull would remove information
 * and would not allow for these guards to be hoisted completely.
 */
static __isl_give isl_set *extract_hoistable_guard(
	__isl_keep isl_ast_graft_list *list, __isl_keep isl_ast_build *build)
{
	int i, n;
	int depth;
	isl_ast_graft *graft_0;
	int equal;
	isl_set *guard;

	if (!list || !build)
		return NULL;

	n = isl_ast_graft_list_n_ast_graft(list);
	if (n == 0)
		return isl_set_universe(isl_ast_build_get_space(build, 1));

	equal = equal_independent_guards(list, build);
	if (equal < 0)
		return NULL;

	graft_0 = isl_ast_graft_list_get_ast_graft(list, 0);
	if (!graft_0)
		return NULL;
	guard = isl_set_copy(graft_0->guard);
	isl_ast_graft_free(graft_0);
	if (equal)
		return guard;

	depth = isl_ast_build_get_depth(build);
	if (depth < isl_set_dim(guard, isl_dim_set)) {
		guard = isl_set_remove_divs_involving_dims(guard,
						isl_dim_set, depth, 1);
		guard = isl_set_eliminate(guard, isl_dim_set, depth, 1);
		guard = isl_set_compute_divs(guard);
	}

	for (i = 1; i < n; ++i) {
		isl_ast_graft *graft;
		isl_basic_set *hull;
		int is_universe;

		is_universe = isl_set_plain_is_universe(guard);
		if (is_universe < 0)
			guard = isl_set_free(guard);
		if (is_universe)
			break;

		graft = isl_ast_graft_list_get_ast_graft(list, i);
		if (!graft) {
			guard = isl_set_free(guard);
			break;
		}
		guard = isl_set_union(guard, isl_set_copy(graft->guard));
		hull = isl_set_unshifted_simple_hull(guard);
		guard = isl_set_from_basic_set(hull);
		isl_ast_graft_free(graft);
	}

	return guard;
}
Exemplo n.º 5
0
/* Hoist "guard" out of the current level (given by "build").
 *
 * In particular, eliminate the dimension corresponding to the current depth.
 */
static __isl_give isl_set *hoist_guard(__isl_take isl_set *guard,
	__isl_keep isl_ast_build *build)
{
	int depth;

	depth = isl_ast_build_get_depth(build);
	if (depth < isl_set_dim(guard, isl_dim_set)) {
		guard = isl_set_remove_divs_involving_dims(guard,
						isl_dim_set, depth, 1);
		guard = isl_set_eliminate(guard, isl_dim_set, depth, 1);
		guard = isl_set_compute_divs(guard);
	}

	return guard;
}
Exemplo n.º 6
0
/* Equate the dimensions of "set" starting at "first" to
 * freshly created parameters with identifiers "ids".
 * The number of equated dimensions is equal to the number of elements in "ids".
 */
static __isl_give isl_set *parametrize(__isl_take isl_set *set,
                                       int first, __isl_keep isl_id_list *ids)
{
    int i, n;
    unsigned nparam;

    nparam = isl_set_dim(set, isl_dim_param);

    set = add_params(set, ids);

    n = isl_id_list_n_id(ids);
    for (i = 0; i < n; ++i)
        set = isl_set_equate(set, isl_dim_param, nparam + i,
                             isl_dim_set, first + i);

    return set;
}
Exemplo n.º 7
0
/* Add parameters with identifiers "ids" to "set".
 */
static __isl_give isl_set *add_params(__isl_take isl_set *set,
                                      __isl_keep isl_id_list *ids)
{
    int i, n;
    unsigned nparam;

    n = isl_id_list_n_id(ids);

    nparam = isl_set_dim(set, isl_dim_param);
    set = isl_set_add_dims(set, isl_dim_param, n);

    for (i = 0; i < n; ++i) {
        isl_id *id;

        id = isl_id_list_get_id(ids, i);
        set = isl_set_set_dim_id(set, isl_dim_param, nparam + i, id);
    }

    return set;
}
Exemplo n.º 8
0
static isl_constraint *
build_linearized_memory_access (isl_map *map, poly_dr_p pdr)
{
  isl_constraint *res;
  isl_local_space *ls = isl_local_space_from_space (isl_map_get_space (map));
  unsigned offset, nsubs;
  int i;
  isl_int size, subsize;

  res = isl_equality_alloc (ls);
  isl_int_init (size);
  isl_int_set_ui (size, 1);
  isl_int_init (subsize);
  isl_int_set_ui (subsize, 1);

  nsubs = isl_set_dim (pdr->extent, isl_dim_set);
  /* -1 for the already included L dimension.  */
  offset = isl_map_dim (map, isl_dim_out) - 1 - nsubs;
  res = isl_constraint_set_coefficient_si (res, isl_dim_out, offset + nsubs, -1);
  /* Go through all subscripts from last to first.  First dimension
     is the alias set, ignore it.  */
  for (i = nsubs - 1; i >= 1; i--)
    {
      isl_space *dc;
      isl_aff *aff;

      res = isl_constraint_set_coefficient (res, isl_dim_out, offset + i, size);

      dc = isl_set_get_space (pdr->extent);
      aff = isl_aff_zero_on_domain (isl_local_space_from_space (dc));
      aff = isl_aff_set_coefficient_si (aff, isl_dim_in, i, 1);
      isl_set_max (pdr->extent, aff, &subsize);
      isl_aff_free (aff);
      isl_int_mul (size, size, subsize);
    }

  isl_int_clear (subsize);
  isl_int_clear (size);

  return res;
}
Exemplo n.º 9
0
/* Do all the grafts in "list" have the same guard and is this guard
 * independent of the current depth?
 */
static int equal_independent_guards(__isl_keep isl_ast_graft_list *list,
	__isl_keep isl_ast_build *build)
{
	int i, n;
	int depth;
	isl_ast_graft *graft_0;
	int equal = 1;
	int skip;

	graft_0 = isl_ast_graft_list_get_ast_graft(list, 0);
	if (!graft_0)
		return -1;

	depth = isl_ast_build_get_depth(build);
	if (isl_set_dim(graft_0->guard, isl_dim_set) <= depth)
		skip = 0;
	else
		skip = isl_set_involves_dims(graft_0->guard,
						isl_dim_set, depth, 1);
	if (skip < 0 || skip) {
		isl_ast_graft_free(graft_0);
		return skip < 0 ? -1 : 0;
	}

	n = isl_ast_graft_list_n_ast_graft(list);
	for (i = 1; i < n; ++i) {
		isl_ast_graft *graft;
		graft = isl_ast_graft_list_get_ast_graft(list, i);
		if (!graft)
			equal = -1;
		else
			equal = isl_set_is_equal(graft_0->guard, graft->guard);
		isl_ast_graft_free(graft);
		if (equal < 0 || !equal)
			break;
	}

	isl_ast_graft_free(graft_0);

	return equal;
}