/*
 * Copyright 2010      INRIA Saclay
 *
 * Use of this software is governed by the MIT license
 *
 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
 * 91893 Orsay, France
 */

#include <isl_ctx_private.h>
#include <isl_space_private.h>
#include <isl_reordering.h>

__isl_give isl_reordering *isl_reordering_alloc(isl_ctx *ctx, int len)
{
	isl_reordering *exp;

	exp = isl_alloc(ctx, struct isl_reordering,
			sizeof(struct isl_reordering) + (len - 1) * sizeof(int));
	if (!exp)
		return NULL;

	exp->ref = 1;
	exp->len = len;
	exp->dim = NULL;

	return exp;
}

__isl_give isl_reordering *isl_reordering_copy(__isl_keep isl_reordering *exp)
{
	if (!exp)
		return NULL;

	exp->ref++;
	return exp;
}

__isl_give isl_reordering *isl_reordering_dup(__isl_keep isl_reordering *r)
{
	int i;
	isl_reordering *dup;

	if (!r)
		return NULL;

	dup = isl_reordering_alloc(r->dim->ctx, r->len);
	if (!dup)
		return NULL;

	dup->dim = isl_space_copy(r->dim);
	if (!dup->dim)
		return isl_reordering_free(dup);
	for (i = 0; i < dup->len; ++i)
		dup->pos[i] = r->pos[i];

	return dup;
}

__isl_give isl_reordering *isl_reordering_cow(__isl_take isl_reordering *r)
{
	if (!r)
		return NULL;

	if (r->ref == 1)
		return r;
	r->ref--;
	return isl_reordering_dup(r);
}

void *isl_reordering_free(__isl_take isl_reordering *exp)
{
	if (!exp)
		return NULL;

	if (--exp->ref > 0)
		return NULL;

	isl_space_free(exp->dim);
	free(exp);
	return NULL;
}

/* Construct a reordering that maps the parameters of "alignee"
 * to the corresponding parameters in a new dimension specification
 * that has the parameters of "aligner" first, followed by
 * any remaining parameters of "alignee" that do not occur in "aligner".
 */
__isl_give isl_reordering *isl_parameter_alignment_reordering(
	__isl_keep isl_space *alignee, __isl_keep isl_space *aligner)
{
	int i, j;
	isl_reordering *exp;

	if (!alignee || !aligner)
		return NULL;

	exp = isl_reordering_alloc(alignee->ctx, alignee->nparam);
	if (!exp)
		return NULL;

	exp->dim = isl_space_copy(aligner);

	for (i = 0; i < alignee->nparam; ++i) {
		isl_id *id_i;
		id_i = isl_space_get_dim_id(alignee, isl_dim_param, i);
		if (!id_i)
			isl_die(alignee->ctx, isl_error_invalid,
				"cannot align unnamed parameters", goto error);
		for (j = 0; j < aligner->nparam; ++j) {
			isl_id *id_j;
			id_j = isl_space_get_dim_id(aligner, isl_dim_param, j);
			isl_id_free(id_j);
			if (id_i == id_j)
				break;
		}
		if (j < aligner->nparam) {
			exp->pos[i] = j;
			isl_id_free(id_i);
		} else {
			int pos;
			pos = isl_space_dim(exp->dim, isl_dim_param);
			exp->dim = isl_space_add_dims(exp->dim, isl_dim_param, 1);
			exp->dim = isl_space_set_dim_id(exp->dim,
						isl_dim_param, pos, id_i);
			exp->pos[i] = pos;
		}
	}

	if (!exp->dim)
		return isl_reordering_free(exp);
	return exp;
error:
	isl_reordering_free(exp);
	return NULL;
}

__isl_give isl_reordering *isl_reordering_extend(__isl_take isl_reordering *exp,
	unsigned extra)
{
	int i;
	isl_reordering *res;
	int offset;

	if (!exp)
		return NULL;
	if (extra == 0)
		return exp;

	offset = isl_space_dim(exp->dim, isl_dim_all) - exp->len;
	res = isl_reordering_alloc(exp->dim->ctx, exp->len + extra);
	if (!res)
		goto error;
	res->dim = isl_space_copy(exp->dim);
	for (i = 0; i < exp->len; ++i)
		res->pos[i] = exp->pos[i];
	for (i = exp->len; i < res->len; ++i)
		res->pos[i] = offset + i;

	isl_reordering_free(exp);

	return res;
error:
	isl_reordering_free(exp);
	return NULL;
}

__isl_give isl_reordering *isl_reordering_extend_space(
	__isl_take isl_reordering *exp, __isl_take isl_space *space)
{
	isl_reordering *res;

	if (!exp || !space)
		goto error;

	res = isl_reordering_extend(isl_reordering_copy(exp),
				isl_space_dim(space, isl_dim_all) - exp->len);
	res = isl_reordering_cow(res);
	if (!res)
		goto error;
	isl_space_free(res->dim);
	res->dim = isl_space_replace_params(space, exp->dim);

	isl_reordering_free(exp);

	if (!res->dim)
		return isl_reordering_free(res);

	return res;
error:
	isl_reordering_free(exp);
	isl_space_free(space);
	return NULL;
}

void isl_reordering_dump(__isl_keep isl_reordering *exp)
{
	int i;

	isl_space_dump(exp->dim);
	for (i = 0; i < exp->len; ++i)
		fprintf(stderr, "%d -> %d; ", i, exp->pos[i]);
	fprintf(stderr, "\n");
}
