Blame isl-0.14/isl_reordering.c

Packit fb9d21
/*
Packit fb9d21
 * Copyright 2010      INRIA Saclay
Packit fb9d21
 *
Packit fb9d21
 * Use of this software is governed by the MIT license
Packit fb9d21
 *
Packit fb9d21
 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
Packit fb9d21
 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
Packit fb9d21
 * 91893 Orsay, France
Packit fb9d21
 */
Packit fb9d21
Packit fb9d21
#include <isl_ctx_private.h>
Packit fb9d21
#include <isl_space_private.h>
Packit fb9d21
#include <isl_reordering.h>
Packit fb9d21
Packit fb9d21
__isl_give isl_reordering *isl_reordering_alloc(isl_ctx *ctx, int len)
Packit fb9d21
{
Packit fb9d21
	isl_reordering *exp;
Packit fb9d21
Packit fb9d21
	exp = isl_alloc(ctx, struct isl_reordering,
Packit fb9d21
			sizeof(struct isl_reordering) + (len - 1) * sizeof(int));
Packit fb9d21
	if (!exp)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	exp->ref = 1;
Packit fb9d21
	exp->len = len;
Packit fb9d21
	exp->dim = NULL;
Packit fb9d21
Packit fb9d21
	return exp;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_reordering *isl_reordering_copy(__isl_keep isl_reordering *exp)
Packit fb9d21
{
Packit fb9d21
	if (!exp)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	exp->ref++;
Packit fb9d21
	return exp;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_reordering *isl_reordering_dup(__isl_keep isl_reordering *r)
Packit fb9d21
{
Packit fb9d21
	int i;
Packit fb9d21
	isl_reordering *dup;
Packit fb9d21
Packit fb9d21
	if (!r)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	dup = isl_reordering_alloc(r->dim->ctx, r->len);
Packit fb9d21
	if (!dup)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	dup->dim = isl_space_copy(r->dim);
Packit fb9d21
	if (!dup->dim)
Packit fb9d21
		return isl_reordering_free(dup);
Packit fb9d21
	for (i = 0; i < dup->len; ++i)
Packit fb9d21
		dup->pos[i] = r->pos[i];
Packit fb9d21
Packit fb9d21
	return dup;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_reordering *isl_reordering_cow(__isl_take isl_reordering *r)
Packit fb9d21
{
Packit fb9d21
	if (!r)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	if (r->ref == 1)
Packit fb9d21
		return r;
Packit fb9d21
	r->ref--;
Packit fb9d21
	return isl_reordering_dup(r);
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
void *isl_reordering_free(__isl_take isl_reordering *exp)
Packit fb9d21
{
Packit fb9d21
	if (!exp)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	if (--exp->ref > 0)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	isl_space_free(exp->dim);
Packit fb9d21
	free(exp);
Packit fb9d21
	return NULL;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
/* Construct a reordering that maps the parameters of "alignee"
Packit fb9d21
 * to the corresponding parameters in a new dimension specification
Packit fb9d21
 * that has the parameters of "aligner" first, followed by
Packit fb9d21
 * any remaining parameters of "alignee" that do not occur in "aligner".
Packit fb9d21
 */
Packit fb9d21
__isl_give isl_reordering *isl_parameter_alignment_reordering(
Packit fb9d21
	__isl_keep isl_space *alignee, __isl_keep isl_space *aligner)
Packit fb9d21
{
Packit fb9d21
	int i, j;
Packit fb9d21
	isl_reordering *exp;
Packit fb9d21
Packit fb9d21
	if (!alignee || !aligner)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	exp = isl_reordering_alloc(alignee->ctx, alignee->nparam);
Packit fb9d21
	if (!exp)
Packit fb9d21
		return NULL;
Packit fb9d21
Packit fb9d21
	exp->dim = isl_space_copy(aligner);
Packit fb9d21
Packit fb9d21
	for (i = 0; i < alignee->nparam; ++i) {
Packit fb9d21
		isl_id *id_i;
Packit fb9d21
		id_i = isl_space_get_dim_id(alignee, isl_dim_param, i);
Packit fb9d21
		if (!id_i)
Packit fb9d21
			isl_die(alignee->ctx, isl_error_invalid,
Packit fb9d21
				"cannot align unnamed parameters", goto error);
Packit fb9d21
		for (j = 0; j < aligner->nparam; ++j) {
Packit fb9d21
			isl_id *id_j;
Packit fb9d21
			id_j = isl_space_get_dim_id(aligner, isl_dim_param, j);
Packit fb9d21
			isl_id_free(id_j);
Packit fb9d21
			if (id_i == id_j)
Packit fb9d21
				break;
Packit fb9d21
		}
Packit fb9d21
		if (j < aligner->nparam) {
Packit fb9d21
			exp->pos[i] = j;
Packit fb9d21
			isl_id_free(id_i);
Packit fb9d21
		} else {
Packit fb9d21
			int pos;
Packit fb9d21
			pos = isl_space_dim(exp->dim, isl_dim_param);
Packit fb9d21
			exp->dim = isl_space_add_dims(exp->dim, isl_dim_param, 1);
Packit fb9d21
			exp->dim = isl_space_set_dim_id(exp->dim,
Packit fb9d21
						isl_dim_param, pos, id_i);
Packit fb9d21
			exp->pos[i] = pos;
Packit fb9d21
		}
Packit fb9d21
	}
Packit fb9d21
Packit fb9d21
	if (!exp->dim)
Packit fb9d21
		return isl_reordering_free(exp);
Packit fb9d21
	return exp;
Packit fb9d21
error:
Packit fb9d21
	isl_reordering_free(exp);
Packit fb9d21
	return NULL;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_reordering *isl_reordering_extend(__isl_take isl_reordering *exp,
Packit fb9d21
	unsigned extra)
Packit fb9d21
{
Packit fb9d21
	int i;
Packit fb9d21
	isl_reordering *res;
Packit fb9d21
	int offset;
Packit fb9d21
Packit fb9d21
	if (!exp)
Packit fb9d21
		return NULL;
Packit fb9d21
	if (extra == 0)
Packit fb9d21
		return exp;
Packit fb9d21
Packit fb9d21
	offset = isl_space_dim(exp->dim, isl_dim_all) - exp->len;
Packit fb9d21
	res = isl_reordering_alloc(exp->dim->ctx, exp->len + extra);
Packit fb9d21
	if (!res)
Packit fb9d21
		goto error;
Packit fb9d21
	res->dim = isl_space_copy(exp->dim);
Packit fb9d21
	for (i = 0; i < exp->len; ++i)
Packit fb9d21
		res->pos[i] = exp->pos[i];
Packit fb9d21
	for (i = exp->len; i < res->len; ++i)
Packit fb9d21
		res->pos[i] = offset + i;
Packit fb9d21
Packit fb9d21
	isl_reordering_free(exp);
Packit fb9d21
Packit fb9d21
	return res;
Packit fb9d21
error:
Packit fb9d21
	isl_reordering_free(exp);
Packit fb9d21
	return NULL;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
__isl_give isl_reordering *isl_reordering_extend_space(
Packit fb9d21
	__isl_take isl_reordering *exp, __isl_take isl_space *dim)
Packit fb9d21
{
Packit fb9d21
	isl_reordering *res;
Packit fb9d21
Packit fb9d21
	if (!exp || !dim)
Packit fb9d21
		goto error;
Packit fb9d21
Packit fb9d21
	res = isl_reordering_extend(isl_reordering_copy(exp),
Packit fb9d21
				    isl_space_dim(dim, isl_dim_all) - exp->len);
Packit fb9d21
	res = isl_reordering_cow(res);
Packit fb9d21
	if (!res)
Packit fb9d21
		goto error;
Packit fb9d21
	isl_space_free(res->dim);
Packit fb9d21
	res->dim = isl_space_replace(dim, isl_dim_param, exp->dim);
Packit fb9d21
Packit fb9d21
	isl_reordering_free(exp);
Packit fb9d21
Packit fb9d21
	if (!res->dim)
Packit fb9d21
		return isl_reordering_free(res);
Packit fb9d21
Packit fb9d21
	return res;
Packit fb9d21
error:
Packit fb9d21
	isl_reordering_free(exp);
Packit fb9d21
	isl_space_free(dim);
Packit fb9d21
	return NULL;
Packit fb9d21
}
Packit fb9d21
Packit fb9d21
void isl_reordering_dump(__isl_keep isl_reordering *exp)
Packit fb9d21
{
Packit fb9d21
	int i;
Packit fb9d21
Packit fb9d21
	isl_space_dump(exp->dim);
Packit fb9d21
	for (i = 0; i < exp->len; ++i)
Packit fb9d21
		fprintf(stderr, "%d -> %d; ", i, exp->pos[i]);
Packit fb9d21
	fprintf(stderr, "\n");
Packit fb9d21
}