Esempio n. 1
0
/* Construct a morphism that first does morph2 and then morph1.
 */
__isl_give isl_morph *isl_morph_compose(__isl_take isl_morph *morph1,
	__isl_take isl_morph *morph2)
{
	isl_mat *map, *inv;
	isl_basic_set *dom, *ran;

	if (!morph1 || !morph2)
		goto error;

	map = isl_mat_product(isl_mat_copy(morph1->map), isl_mat_copy(morph2->map));
	inv = isl_mat_product(isl_mat_copy(morph2->inv), isl_mat_copy(morph1->inv));
	dom = isl_morph_basic_set(isl_morph_inverse(isl_morph_copy(morph2)),
				  isl_basic_set_copy(morph1->dom));
	dom = isl_basic_set_intersect(dom, isl_basic_set_copy(morph2->dom));
	ran = isl_morph_basic_set(isl_morph_copy(morph1),
				  isl_basic_set_copy(morph2->ran));
	ran = isl_basic_set_intersect(ran, isl_basic_set_copy(morph1->ran));

	isl_morph_free(morph1);
	isl_morph_free(morph2);

	return isl_morph_alloc(dom, ran, map, inv);
error:
	isl_morph_free(morph1);
	isl_morph_free(morph2);
	return NULL;
}
Esempio n. 2
0
Param_Polyhedron *ISL_P2PP(Polyhedron *P, Polyhedron *C,
			  struct barvinok_options *options)
{
	int i, j;
	isl_ctx *ctx = isl_ctx_alloc();
	isl_space *dim;
	isl_basic_set *bset, *context;
	isl_vertices *vertices;
	unsigned nparam = C->Dimension;
	unsigned nvar = P->Dimension - nparam;
	Param_Polyhedron *PP = isl_calloc_type(ctx, Param_Polyhedron);
	Param_Vertices **next_V;
	struct bv_add_chamber_data data;

	dim = isl_space_set_alloc(ctx, nparam, nvar);
	bset = isl_basic_set_new_from_polylib(P, dim);
	dim = isl_space_set_alloc(ctx, nparam, 0);
	context = isl_basic_set_new_from_polylib(C, dim);

	bset = isl_basic_set_intersect(bset, context);

	vertices = isl_basic_set_compute_vertices(bset);
	isl_basic_set_free(bset);

	PP->Rays = NULL;
	PP->nbV = isl_vertices_get_n_vertices(vertices);
	PP->Constraints = Polyhedron2Constraints(P);

	next_V = &PP->V;
	isl_vertices_foreach_vertex(vertices, &add_vertex, &next_V);

	data.next_D = &PP->D;
	data.vertex_len = (PP->nbV + INT_BITS - 1)/INT_BITS;
	isl_vertices_foreach_cell(vertices, &add_chamber, &data);

	isl_vertices_free(vertices);

	isl_ctx_free(ctx);

	return PP;
}
Esempio n. 3
0
/* Apply the morphism to the basic set.
 * We basically just compute the preimage of "bset" under the inverse mapping
 * in morph, add in stride constraints and intersect with the range
 * of the morphism.
 */
__isl_give isl_basic_set *isl_morph_basic_set(__isl_take isl_morph *morph,
	__isl_take isl_basic_set *bset)
{
	isl_basic_set *res = NULL;
	isl_mat *mat = NULL;
	int i, k;
	int max_stride;

	if (!morph || !bset)
		goto error;

	isl_assert(bset->ctx, isl_space_is_equal(bset->dim, morph->dom->dim),
		    goto error);

	max_stride = morph->inv->n_row - 1;
	if (isl_int_is_one(morph->inv->row[0][0]))
		max_stride = 0;
	res = isl_basic_set_alloc_space(isl_space_copy(morph->ran->dim),
		bset->n_div + max_stride, bset->n_eq + max_stride, bset->n_ineq);

	for (i = 0; i < bset->n_div; ++i)
		if (isl_basic_set_alloc_div(res) < 0)
			goto error;

	mat = isl_mat_sub_alloc6(bset->ctx, bset->eq, 0, bset->n_eq,
					0, morph->inv->n_row);
	mat = isl_mat_product(mat, isl_mat_copy(morph->inv));
	if (!mat)
		goto error;
	for (i = 0; i < bset->n_eq; ++i) {
		k = isl_basic_set_alloc_equality(res);
		if (k < 0)
			goto error;
		isl_seq_cpy(res->eq[k], mat->row[i], mat->n_col);
		isl_seq_scale(res->eq[k] + mat->n_col, bset->eq[i] + mat->n_col,
				morph->inv->row[0][0], bset->n_div);
	}
	isl_mat_free(mat);

	mat = isl_mat_sub_alloc6(bset->ctx, bset->ineq, 0, bset->n_ineq,
					0, morph->inv->n_row);
	mat = isl_mat_product(mat, isl_mat_copy(morph->inv));
	if (!mat)
		goto error;
	for (i = 0; i < bset->n_ineq; ++i) {
		k = isl_basic_set_alloc_inequality(res);
		if (k < 0)
			goto error;
		isl_seq_cpy(res->ineq[k], mat->row[i], mat->n_col);
		isl_seq_scale(res->ineq[k] + mat->n_col,
				bset->ineq[i] + mat->n_col,
				morph->inv->row[0][0], bset->n_div);
	}
	isl_mat_free(mat);

	mat = isl_mat_sub_alloc6(bset->ctx, bset->div, 0, bset->n_div,
					1, morph->inv->n_row);
	mat = isl_mat_product(mat, isl_mat_copy(morph->inv));
	if (!mat)
		goto error;
	for (i = 0; i < bset->n_div; ++i) {
		isl_int_mul(res->div[i][0],
				morph->inv->row[0][0], bset->div[i][0]);
		isl_seq_cpy(res->div[i] + 1, mat->row[i], mat->n_col);
		isl_seq_scale(res->div[i] + 1 + mat->n_col,
				bset->div[i] + 1 + mat->n_col,
				morph->inv->row[0][0], bset->n_div);
	}
	isl_mat_free(mat);

	res = add_strides(res, morph);

	if (isl_basic_set_is_rational(bset))
		res = isl_basic_set_set_rational(res);

	res = isl_basic_set_simplify(res);
	res = isl_basic_set_finalize(res);

	res = isl_basic_set_intersect(res, isl_basic_set_copy(morph->ran));

	isl_morph_free(morph);
	isl_basic_set_free(bset);
	return res;
error:
	isl_mat_free(mat);
	isl_morph_free(morph);
	isl_basic_set_free(bset);
	isl_basic_set_free(res);
	return NULL;
}
Esempio n. 4
0
/**
 * Reduce the modulo guard expressed by "constraints" using equalities
 * found in outer nesting levels (stored in "equal").
 * The modulo guard may be an equality or a pair of inequalities.
 * In case of a pair of inequalities, *bound contains the bound on the
 * corresponding modulo expression.  If any reduction is performed
 * then this bound is recomputed.
 *
 * "level" may not correspond to an existentially quantified variable.
 *
 * We first check if there are any equalities we can use.  If not,
 * there is again nothing to reduce.
 * For the actual reduction, we use isl_basic_set_gist, but this
 * function will only perform the reduction we want here if the
 * the variable that imposes the modulo constraint has been projected
 * out (i.e., turned into an existentially quantified variable).
 * After the call to isl_basic_set_gist, we need to move the
 * existential variable back into the position where the calling
 * function expects it (assuming there are any constraints left).
 * We do this by adding an equality between the given dimension and
 * the existentially quantified variable.
 *
 * If there are no existentially quantified variables left, then
 * we don't need to add this equality.
 * If, on the other hand, the resulting basic set involves more
 * than one existentially quantified variable, then the caller
 * will not be able to handle the result, so we just return the
 * original input instead.
 */
CloogConstraintSet *cloog_constraint_set_reduce(CloogConstraintSet *constraints,
	int level, CloogEqualities *equal, int nb_par, cloog_int_t *bound)
{
	int j;
	isl_space *idim;
	struct isl_basic_set *eq;
	struct isl_basic_map *id;
	struct cloog_isl_dim dim;
	struct isl_constraint *c;
	unsigned constraints_dim;
	unsigned n_div;
	isl_basic_set *bset, *orig;

	bset = cloog_constraints_set_to_isl(constraints);
	orig = isl_basic_set_copy(bset);
	dim = set_cloog_dim_to_isl_dim(constraints, level - 1);
	assert(dim.type == isl_dim_set);

	eq = NULL;
	for (j = 0; j < level - 1; ++j) {
		isl_basic_set *bset_j;
		if (equal->types[j] != EQTYPE_EXAFFINE)
			continue;
		bset_j = equality_to_basic_set(equal, j);
		if (!eq)
			eq = bset_j;
		else
			eq = isl_basic_set_intersect(eq, bset_j);
	}
	if (!eq) {
		isl_basic_set_free(orig);
		return cloog_constraint_set_from_isl_basic_set(bset);
	}

	idim = isl_space_map_from_set(isl_basic_set_get_space(bset));
	id = isl_basic_map_identity(idim);
	id = isl_basic_map_remove_dims(id, isl_dim_out, dim.pos, 1);
	bset = isl_basic_set_apply(bset, isl_basic_map_copy(id));
	bset = isl_basic_set_apply(bset, isl_basic_map_reverse(id));

	constraints_dim = isl_basic_set_dim(bset, isl_dim_set);
	eq = isl_basic_set_remove_dims(eq, isl_dim_set, constraints_dim,
			isl_basic_set_dim(eq, isl_dim_set) - constraints_dim);
	bset = isl_basic_set_gist(bset, eq);
	n_div = isl_basic_set_dim(bset, isl_dim_div);
	if (n_div > 1) {
		isl_basic_set_free(bset);
		return cloog_constraint_set_from_isl_basic_set(orig);
	}
	if (n_div < 1) {
		isl_basic_set_free(orig);
		return cloog_constraint_set_from_isl_basic_set(bset);
	}

	c = isl_equality_alloc(isl_basic_set_get_local_space(bset));
	c = isl_constraint_set_coefficient_si(c, isl_dim_div, 0, 1);
	c = isl_constraint_set_coefficient_si(c, isl_dim_set, dim.pos, -1);
	bset = isl_basic_set_add_constraint(bset, c);

	isl_int_set_si(*bound, 0);
	constraints = cloog_constraint_set_from_isl_basic_set(bset);
	cloog_constraint_set_foreach_constraint(constraints,
						add_constant_term, bound);

	isl_basic_set_free(orig);
	return cloog_constraint_set_from_isl_basic_set(bset);
}