1/* 2 * Copyright 2010 INRIA Saclay 3 * 4 * Use of this software is governed by the MIT license 5 * 6 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, 7 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, 8 * 91893 Orsay, France 9 */ 10 11#include <isl_ctx_private.h> 12#include <isl_space_private.h> 13#include <isl_reordering.h> 14 15__isl_give isl_reordering *isl_reordering_alloc(isl_ctx *ctx, int len) 16{ 17 isl_reordering *exp; 18 19 exp = isl_alloc(ctx, struct isl_reordering, 20 sizeof(struct isl_reordering) + (len - 1) * sizeof(int)); 21 if (!exp) 22 return NULL; 23 24 exp->ref = 1; 25 exp->len = len; 26 exp->dim = NULL; 27 28 return exp; 29} 30 31__isl_give isl_reordering *isl_reordering_copy(__isl_keep isl_reordering *exp) 32{ 33 if (!exp) 34 return NULL; 35 36 exp->ref++; 37 return exp; 38} 39 40__isl_give isl_reordering *isl_reordering_dup(__isl_keep isl_reordering *r) 41{ 42 int i; 43 isl_reordering *dup; 44 45 if (!r) 46 return NULL; 47 48 dup = isl_reordering_alloc(r->dim->ctx, r->len); 49 if (!dup) 50 return NULL; 51 52 dup->dim = isl_space_copy(r->dim); 53 if (!dup->dim) 54 return isl_reordering_free(dup); 55 for (i = 0; i < dup->len; ++i) 56 dup->pos[i] = r->pos[i]; 57 58 return dup; 59} 60 61__isl_give isl_reordering *isl_reordering_cow(__isl_take isl_reordering *r) 62{ 63 if (!r) 64 return NULL; 65 66 if (r->ref == 1) 67 return r; 68 r->ref--; 69 return isl_reordering_dup(r); 70} 71 72void *isl_reordering_free(__isl_take isl_reordering *exp) 73{ 74 if (!exp) 75 return NULL; 76 77 if (--exp->ref > 0) 78 return NULL; 79 80 isl_space_free(exp->dim); 81 free(exp); 82 return NULL; 83} 84 85/* Construct a reordering that maps the parameters of "alignee" 86 * to the corresponding parameters in a new dimension specification 87 * that has the parameters of "aligner" first, followed by 88 * any remaining parameters of "alignee" that do not occur in "aligner". 89 */ 90__isl_give isl_reordering *isl_parameter_alignment_reordering( 91 __isl_keep isl_space *alignee, __isl_keep isl_space *aligner) 92{ 93 int i, j; 94 isl_reordering *exp; 95 96 if (!alignee || !aligner) 97 return NULL; 98 99 exp = isl_reordering_alloc(alignee->ctx, alignee->nparam); 100 if (!exp) 101 return NULL; 102 103 exp->dim = isl_space_copy(aligner); 104 105 for (i = 0; i < alignee->nparam; ++i) { 106 isl_id *id_i; 107 id_i = isl_space_get_dim_id(alignee, isl_dim_param, i); 108 if (!id_i) 109 isl_die(alignee->ctx, isl_error_invalid, 110 "cannot align unnamed parameters", goto error); 111 for (j = 0; j < aligner->nparam; ++j) { 112 isl_id *id_j; 113 id_j = isl_space_get_dim_id(aligner, isl_dim_param, j); 114 isl_id_free(id_j); 115 if (id_i == id_j) 116 break; 117 } 118 if (j < aligner->nparam) { 119 exp->pos[i] = j; 120 isl_id_free(id_i); 121 } else { 122 int pos; 123 pos = isl_space_dim(exp->dim, isl_dim_param); 124 exp->dim = isl_space_add_dims(exp->dim, isl_dim_param, 1); 125 exp->dim = isl_space_set_dim_id(exp->dim, 126 isl_dim_param, pos, id_i); 127 exp->pos[i] = pos; 128 } 129 } 130 131 if (!exp->dim) 132 return isl_reordering_free(exp); 133 return exp; 134error: 135 isl_reordering_free(exp); 136 return NULL; 137} 138 139__isl_give isl_reordering *isl_reordering_extend(__isl_take isl_reordering *exp, 140 unsigned extra) 141{ 142 int i; 143 isl_reordering *res; 144 int offset; 145 146 if (!exp) 147 return NULL; 148 if (extra == 0) 149 return exp; 150 151 offset = isl_space_dim(exp->dim, isl_dim_all) - exp->len; 152 res = isl_reordering_alloc(exp->dim->ctx, exp->len + extra); 153 if (!res) 154 goto error; 155 res->dim = isl_space_copy(exp->dim); 156 for (i = 0; i < exp->len; ++i) 157 res->pos[i] = exp->pos[i]; 158 for (i = exp->len; i < res->len; ++i) 159 res->pos[i] = offset + i; 160 161 isl_reordering_free(exp); 162 163 return res; 164error: 165 isl_reordering_free(exp); 166 return NULL; 167} 168 169__isl_give isl_reordering *isl_reordering_extend_space( 170 __isl_take isl_reordering *exp, __isl_take isl_space *dim) 171{ 172 isl_reordering *res; 173 174 if (!exp || !dim) 175 goto error; 176 177 res = isl_reordering_extend(isl_reordering_copy(exp), 178 isl_space_dim(dim, isl_dim_all) - exp->len); 179 res = isl_reordering_cow(res); 180 if (!res) 181 goto error; 182 isl_space_free(res->dim); 183 res->dim = isl_space_replace(dim, isl_dim_param, exp->dim); 184 185 isl_reordering_free(exp); 186 187 if (!res->dim) 188 return isl_reordering_free(res); 189 190 return res; 191error: 192 isl_reordering_free(exp); 193 isl_space_free(dim); 194 return NULL; 195} 196 197void isl_reordering_dump(__isl_keep isl_reordering *exp) 198{ 199 int i; 200 201 for (i = 0; i < exp->len; ++i) 202 fprintf(stderr, "%d -> %d; ", i, exp->pos[i]); 203 fprintf(stderr, "\n"); 204} 205