2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 * Copyright 2010-2011 INRIA Saclay
5 * Use of this software is governed by the MIT license
7 * Written by Sven Verdoolaege, K.U.Leuven, Departement
8 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
9 * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite,
10 * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France
13 #include <isl_map_private.h>
14 #include <isl_space_private.h>
15 #include <isl_dim_map.h>
16 #include <isl_reordering.h>
18 struct isl_dim_map_entry
{
23 /* Maps dst positions to src positions */
26 struct isl_dim_map_entry m
[1];
29 __isl_give isl_dim_map
*isl_dim_map_alloc(isl_ctx
*ctx
, unsigned len
)
32 struct isl_dim_map
*dim_map
;
33 dim_map
= isl_alloc(ctx
, struct isl_dim_map
,
34 sizeof(struct isl_dim_map
) + len
* sizeof(struct isl_dim_map_entry
));
37 dim_map
->len
= 1 + len
;
38 dim_map
->m
[0].pos
= 0;
39 dim_map
->m
[0].sgn
= 1;
40 for (i
= 0; i
< len
; ++i
)
41 dim_map
->m
[1 + i
].sgn
= 0;
45 /* Free "dim_map" and return NULL.
47 __isl_null isl_dim_map
*isl_dim_map_free(__isl_take isl_dim_map
*dim_map
)
53 void isl_dim_map_range(__isl_keep isl_dim_map
*dim_map
,
54 unsigned dst_pos
, int dst_stride
, unsigned src_pos
, int src_stride
,
62 for (i
= 0; i
< n
; ++i
) {
63 unsigned d
= 1 + dst_pos
+ dst_stride
* i
;
64 unsigned s
= 1 + src_pos
+ src_stride
* i
;
65 dim_map
->m
[d
].pos
= s
;
66 dim_map
->m
[d
].sgn
= sign
;
70 void isl_dim_map_dim_range(__isl_keep isl_dim_map
*dim_map
,
71 __isl_keep isl_space
*space
, enum isl_dim_type type
,
72 unsigned first
, unsigned n
, unsigned dst_pos
)
77 if (!dim_map
|| !space
)
80 src_pos
= 1 + isl_space_offset(space
, type
);
81 for (i
= 0; i
< n
; ++i
) {
82 dim_map
->m
[1 + dst_pos
+ i
].pos
= src_pos
+ first
+ i
;
83 dim_map
->m
[1 + dst_pos
+ i
].sgn
= 1;
87 void isl_dim_map_dim(__isl_keep isl_dim_map
*dim_map
,
88 __isl_keep isl_space
*space
, enum isl_dim_type type
, unsigned dst_pos
)
90 isl_dim_map_dim_range(dim_map
, space
, type
,
91 0, isl_space_dim(space
, type
), dst_pos
);
94 void isl_dim_map_div(__isl_keep isl_dim_map
*dim_map
,
95 __isl_keep isl_basic_map
*bmap
, unsigned dst_pos
)
100 if (!dim_map
|| !bmap
)
103 src_pos
= 1 + isl_space_dim(bmap
->dim
, isl_dim_all
);
104 for (i
= 0; i
< bmap
->n_div
; ++i
) {
105 dim_map
->m
[1 + dst_pos
+ i
].pos
= src_pos
+ i
;
106 dim_map
->m
[1 + dst_pos
+ i
].sgn
= 1;
110 void isl_dim_map_dump(struct isl_dim_map
*dim_map
)
114 for (i
= 0; i
< dim_map
->len
; ++i
)
115 fprintf(stderr
, "%d -> %d * %d; ", i
,
116 dim_map
->m
[i
].sgn
, dim_map
->m
[i
].pos
);
117 fprintf(stderr
, "\n");
120 static void copy_constraint_dim_map(isl_int
*dst
, isl_int
*src
,
121 struct isl_dim_map
*dim_map
)
125 for (i
= 0; i
< dim_map
->len
; ++i
) {
126 if (dim_map
->m
[i
].sgn
== 0)
127 isl_int_set_si(dst
[i
], 0);
128 else if (dim_map
->m
[i
].sgn
> 0)
129 isl_int_set(dst
[i
], src
[dim_map
->m
[i
].pos
]);
131 isl_int_neg(dst
[i
], src
[dim_map
->m
[i
].pos
]);
135 static void copy_div_dim_map(isl_int
*dst
, isl_int
*src
,
136 struct isl_dim_map
*dim_map
)
138 isl_int_set(dst
[0], src
[0]);
139 copy_constraint_dim_map(dst
+1, src
+1, dim_map
);
142 __isl_give isl_basic_map
*isl_basic_map_add_constraints_dim_map(
143 __isl_take isl_basic_map
*dst
, __isl_take isl_basic_map
*src
,
144 __isl_take isl_dim_map
*dim_map
)
148 if (!src
|| !dst
|| !dim_map
)
151 for (i
= 0; i
< src
->n_eq
; ++i
) {
152 int i1
= isl_basic_map_alloc_equality(dst
);
155 copy_constraint_dim_map(dst
->eq
[i1
], src
->eq
[i
], dim_map
);
158 for (i
= 0; i
< src
->n_ineq
; ++i
) {
159 int i1
= isl_basic_map_alloc_inequality(dst
);
162 copy_constraint_dim_map(dst
->ineq
[i1
], src
->ineq
[i
], dim_map
);
165 for (i
= 0; i
< src
->n_div
; ++i
) {
166 int i1
= isl_basic_map_alloc_div(dst
);
169 copy_div_dim_map(dst
->div
[i1
], src
->div
[i
], dim_map
);
172 isl_dim_map_free(dim_map
);
173 isl_basic_map_free(src
);
177 isl_dim_map_free(dim_map
);
178 isl_basic_map_free(src
);
179 isl_basic_map_free(dst
);
183 __isl_give isl_basic_set
*isl_basic_set_add_constraints_dim_map(
184 __isl_take isl_basic_set
*dst
, __isl_take isl_basic_set
*src
,
185 __isl_take isl_dim_map
*dim_map
)
187 return isl_basic_map_add_constraints_dim_map(dst
, src
, dim_map
);
190 /* Extend the given dim_map with mappings for the divs in bmap.
192 __isl_give isl_dim_map
*isl_dim_map_extend(__isl_keep isl_dim_map
*dim_map
,
193 __isl_keep isl_basic_map
*bmap
)
196 struct isl_dim_map
*res
;
202 offset
= isl_basic_map_offset(bmap
, isl_dim_div
);
204 res
= isl_dim_map_alloc(bmap
->ctx
, dim_map
->len
- 1 + bmap
->n_div
);
208 for (i
= 0; i
< dim_map
->len
; ++i
)
209 res
->m
[i
] = dim_map
->m
[i
];
210 for (i
= 0; i
< bmap
->n_div
; ++i
) {
211 res
->m
[dim_map
->len
+ i
].pos
= offset
+ i
;
212 res
->m
[dim_map
->len
+ i
].sgn
= 1;
218 /* Extract a dim_map from a reordering.
219 * We essentially need to reverse the mapping, and add an offset
220 * of 1 for the constant term.
222 __isl_give isl_dim_map
*isl_dim_map_from_reordering(
223 __isl_keep isl_reordering
*exp
)
228 struct isl_dim_map
*dim_map
;
233 ctx
= isl_reordering_get_ctx(exp
);
234 space
= isl_reordering_peek_space(exp
);
235 dim_map
= isl_dim_map_alloc(ctx
, isl_space_dim(space
, isl_dim_all
));
239 for (i
= 0; i
< exp
->len
; ++i
) {
240 dim_map
->m
[1 + exp
->pos
[i
]].pos
= 1 + i
;
241 dim_map
->m
[1 + exp
->pos
[i
]].sgn
= 1;