Пример #1
0
/* Set the stride and offset of data->pos to the given
 * value and expression.
 *
 * If we had already found a stride before, then the two strides
 * are combined into a single stride.
 *
 * In particular, if the new stride information is of the form
 *
 *	i = f + s (...)
 *
 * and the old stride information is of the form
 *
 *	i = f2 + s2 (...)
 *
 * then we compute the extended gcd of s and s2
 *
 *	a s + b s2 = g,
 *
 * with g = gcd(s,s2), multiply the first equation with t1 = b s2/g
 * and the second with t2 = a s1/g.
 * This results in
 *
 *	i = (b s2 + a s1)/g i = t1 f + t2 f2 + (s s2)/g (...)
 *
 * so that t1 f + t2 f2 is the combined offset and (s s2)/g = lcm(s,s2)
 * is the combined stride.
 */
static isl_stat set_stride(struct isl_detect_stride_data *data,
	__isl_take isl_val *stride, __isl_take isl_aff *offset)
{
	int pos;

	if (!stride || !offset)
		goto error;

	pos = data->pos;

	if (data->found) {
		isl_val *stride2, *a, *b, *g;
		isl_aff *offset2;

		stride2 = data->stride;
		g = isl_val_gcdext(isl_val_copy(stride), isl_val_copy(stride2),
					&a, &b);
		a = isl_val_mul(a, isl_val_copy(stride));
		a = isl_val_div(a, isl_val_copy(g));
		stride2 = isl_val_div(stride2, g);
		b = isl_val_mul(b, isl_val_copy(stride2));
		stride = isl_val_mul(stride, stride2);

		if (!data->want_offset) {
			isl_val_free(a);
			isl_val_free(b);
		} else {
			offset2 = data->offset;
			offset2 = isl_aff_scale_val(offset2, a);
			offset = isl_aff_scale_val(offset, b);
			offset = isl_aff_add(offset, offset2);
		}
	}

	data->found = 1;
	data->stride = stride;
	if (data->want_offset)
		data->offset = offset;
	else
		isl_aff_free(offset);
	if (!data->stride || (data->want_offset && !data->offset))
		return isl_stat_error;

	return isl_stat_ok;
error:
	isl_val_free(stride);
	isl_aff_free(offset);
	return isl_stat_error;
}
Пример #2
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_ctx *ctx;

    isl_val *size, *subsize, *size1;

    res = isl_equality_alloc (ls);
    ctx = isl_local_space_get_ctx (ls);
    size = isl_val_int_from_ui (ctx, 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;

        size1 = isl_val_copy (size);
        res = isl_constraint_set_coefficient_val (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);
        subsize = isl_set_max_val (pdr->extent, aff);
        isl_aff_free (aff);
        size = isl_val_mul (size1, subsize);
    }

    isl_val_free (size);

    return res;
}