/* * Copyright 2010 INRIA Saclay * * Use of this software is governed by the GNU LGPLv2.1 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 #include __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; } void isl_reordering_free(__isl_take isl_reordering *exp) { if (!exp) return; if (--exp->ref > 0) return; isl_dim_free(exp->dim); free(exp); } /* 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_dim *alignee, __isl_keep isl_dim *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_dim_copy(aligner); for (i = 0; i < alignee->nparam; ++i) { const char *name_i; name_i = isl_dim_get_name(alignee, isl_dim_param, i); if (!name_i) isl_die(alignee->ctx, isl_error_invalid, "cannot align unnamed parameters", goto error); for (j = 0; j < aligner->nparam; ++j) { const char *name_j; name_j = isl_dim_get_name(aligner, isl_dim_param, j); if (name_i == name_j) break; } if (j < aligner->nparam) exp->pos[i] = j; else { int pos; pos = isl_dim_size(exp->dim, isl_dim_param); exp->dim = isl_dim_add(exp->dim, isl_dim_param, 1); exp->dim = isl_dim_set_name(exp->dim, isl_dim_param, pos, name_i); exp->pos[i] = pos; } } 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_dim_total(exp->dim) - exp->len; res = isl_reordering_alloc(exp->dim->ctx, exp->len + extra); if (!res) goto error; res->dim = isl_dim_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_dim( __isl_take isl_reordering *exp, __isl_take isl_dim *dim) { int i; isl_reordering *res; int offset; if (!exp || !dim) goto error; res = isl_reordering_extend(isl_reordering_copy(exp), isl_dim_total(dim) - exp->len); if (!res) goto error; isl_dim_free(res->dim); res->dim = isl_dim_replace(dim, isl_dim_param, exp->dim); isl_reordering_free(exp); return res; error: isl_reordering_free(exp); isl_dim_free(dim); return NULL; } void isl_reordering_dump(__isl_keep isl_reordering *exp) { int i; for (i = 0; i < exp->len; ++i) fprintf(stderr, "%d -> %d; ", i, exp->pos[i]); fprintf(stderr, "\n"); }