llvm/polly/lib/External/isl/isl_stride.c

/*
 * Copyright 2012-2013 Ecole Normale Superieure
 *
 * Use of this software is governed by the MIT license
 *
 * Written by Sven Verdoolaege,
 * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
 */

#include <isl/val.h>
#include <isl_map_private.h>
#include <isl_aff_private.h>
#include <isl/constraint.h>
#include <isl/set.h>

/* Stride information about a specific set dimension.
 * The values of the set dimension are equal to
 * "offset" plus a multiple of "stride".
 */
struct isl_stride_info {};

/* Return the ctx to which "si" belongs.
 */
isl_ctx *isl_stride_info_get_ctx(__isl_keep isl_stride_info *si)
{}

/* Free "si" and return NULL.
 */
__isl_null isl_stride_info *isl_stride_info_free(
	__isl_take isl_stride_info *si)
{}

/* Construct an isl_stride_info object with given offset and stride.
 */
__isl_give isl_stride_info *isl_stride_info_alloc(
	__isl_take isl_val *stride, __isl_take isl_aff *offset)
{}

/* Make a copy of "si" and return it.
 */
__isl_give isl_stride_info *isl_stride_info_copy(
	__isl_keep isl_stride_info *si)
{}

/* Return the stride of "si".
 */
__isl_give isl_val *isl_stride_info_get_stride(__isl_keep isl_stride_info *si)
{}

/* Return the offset of "si".
 */
__isl_give isl_aff *isl_stride_info_get_offset(__isl_keep isl_stride_info *si)
{}

/* Information used inside detect_stride.
 *
 * "pos" is the set dimension at which the stride is being determined.
 * "want_offset" is set if the offset should be computed.
 * "found" is set if some stride was found already.
 * "stride" and "offset" contain the (combined) stride and offset
 * found so far and are NULL when "found" is not set.
 * If "want_offset" is not set, then "offset" remains NULL.
 */
struct isl_detect_stride_data {};

/* 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)
{}

/* Check if constraint "c" imposes any stride on dimension data->pos
 * and, if so, update the stride information in "data".
 *
 * In order to impose a stride on the dimension, "c" needs to be an equality
 * and it needs to involve the dimension.  Note that "c" may also be
 * a div constraint and thus an inequality that we cannot use.
 *
 * Let c be of the form
 *
 *	h(p) + g * v * i + g * stride * f(alpha) = 0
 *
 * with h(p) an expression in terms of the parameters and other dimensions
 * and f(alpha) an expression in terms of the existentially quantified
 * variables.
 *
 * If "stride" is not zero and not one, then it represents a non-trivial stride
 * on "i".  We compute a and b such that
 *
 *	a v + b stride = 1
 *
 * We have
 *
 *	g v i = -h(p) + g stride f(alpha)
 *
 *	a g v i = -a h(p) + g stride f(alpha)
 *
 *	a g v i + b g stride i = -a h(p) + g stride * (...)
 *
 *	g i = -a h(p) + g stride * (...)
 *
 *	i = -a h(p)/g + stride * (...)
 *
 * The expression "-a h(p)/g" can therefore be used as offset.
 */
static isl_stat detect_stride(__isl_take isl_constraint *c, void *user)
{}

/* Check if the constraints in "set" imply any stride on set dimension "pos" and
 * store the results in data->stride and data->offset.
 *
 * In particular, compute the affine hull and then check if
 * any of the constraints in the hull impose any stride on the dimension.
 * If no such constraint can be found, then the offset is taken
 * to be the zero expression and the stride is taken to be one.
 */
static void set_detect_stride(__isl_keep isl_set *set, int pos,
	struct isl_detect_stride_data *data)
{}

/* Check if the constraints in "set" imply any stride on set dimension "pos" and
 * return the results in the form of an offset and a stride.
 */
__isl_give isl_stride_info *isl_set_get_stride_info(__isl_keep isl_set *set,
	int pos)
{}

/* Check if the constraints in "set" imply any stride on set dimension "pos" and
 * return this stride.
 */
__isl_give isl_val *isl_set_get_stride(__isl_keep isl_set *set, int pos)
{}

/* Check if the constraints in "map" imply any stride on output dimension "pos",
 * independently of any other output dimensions, and
 * return the results in the form of an offset and a stride.
 *
 * Convert the input to a set with only the input dimensions and
 * the single output dimension such that it be passed to
 * isl_set_get_stride_info and convert the result back to
 * an expression defined over the domain of "map".
 */
__isl_give isl_stride_info *isl_map_get_range_stride_info(
	__isl_keep isl_map *map, int pos)
{}