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 void isl_dim_map_range(__isl_keep isl_dim_map
*dim_map
,
46 unsigned dst_pos
, int dst_stride
, unsigned src_pos
, int src_stride
,
54 for (i
= 0; i
< n
; ++i
) {
55 unsigned d
= 1 + dst_pos
+ dst_stride
* i
;
56 unsigned s
= 1 + src_pos
+ src_stride
* i
;
57 dim_map
->m
[d
].pos
= s
;
58 dim_map
->m
[d
].sgn
= sign
;
62 void isl_dim_map_dim_range(__isl_keep isl_dim_map
*dim_map
,
63 __isl_keep isl_space
*dim
, enum isl_dim_type type
,
64 unsigned first
, unsigned n
, unsigned dst_pos
)
72 src_pos
= 1 + isl_space_offset(dim
, type
);
73 for (i
= 0; i
< n
; ++i
) {
74 dim_map
->m
[1 + dst_pos
+ i
].pos
= src_pos
+ first
+ i
;
75 dim_map
->m
[1 + dst_pos
+ i
].sgn
= 1;
79 void isl_dim_map_dim(__isl_keep isl_dim_map
*dim_map
,
80 __isl_keep isl_space
*space
, enum isl_dim_type type
, unsigned dst_pos
)
82 isl_dim_map_dim_range(dim_map
, space
, type
,
83 0, isl_space_dim(space
, type
), dst_pos
);
86 void isl_dim_map_div(__isl_keep isl_dim_map
*dim_map
,
87 __isl_keep isl_basic_map
*bmap
, unsigned dst_pos
)
92 if (!dim_map
|| !bmap
)
95 src_pos
= 1 + isl_space_dim(bmap
->dim
, isl_dim_all
);
96 for (i
= 0; i
< bmap
->n_div
; ++i
) {
97 dim_map
->m
[1 + dst_pos
+ i
].pos
= src_pos
+ i
;
98 dim_map
->m
[1 + dst_pos
+ i
].sgn
= 1;
102 void isl_dim_map_dump(struct isl_dim_map
*dim_map
)
106 for (i
= 0; i
< dim_map
->len
; ++i
)
107 fprintf(stderr
, "%d -> %d * %d; ", i
,
108 dim_map
->m
[i
].sgn
, dim_map
->m
[i
].pos
);
109 fprintf(stderr
, "\n");
112 static void copy_constraint_dim_map(isl_int
*dst
, isl_int
*src
,
113 struct isl_dim_map
*dim_map
)
117 for (i
= 0; i
< dim_map
->len
; ++i
) {
118 if (dim_map
->m
[i
].sgn
== 0)
119 isl_int_set_si(dst
[i
], 0);
120 else if (dim_map
->m
[i
].sgn
> 0)
121 isl_int_set(dst
[i
], src
[dim_map
->m
[i
].pos
]);
123 isl_int_neg(dst
[i
], src
[dim_map
->m
[i
].pos
]);
127 static void copy_div_dim_map(isl_int
*dst
, isl_int
*src
,
128 struct isl_dim_map
*dim_map
)
130 isl_int_set(dst
[0], src
[0]);
131 copy_constraint_dim_map(dst
+1, src
+1, dim_map
);
134 __isl_give isl_basic_map
*isl_basic_map_add_constraints_dim_map(
135 __isl_take isl_basic_map
*dst
, __isl_take isl_basic_map
*src
,
136 __isl_take isl_dim_map
*dim_map
)
140 if (!src
|| !dst
|| !dim_map
)
143 for (i
= 0; i
< src
->n_eq
; ++i
) {
144 int i1
= isl_basic_map_alloc_equality(dst
);
147 copy_constraint_dim_map(dst
->eq
[i1
], src
->eq
[i
], dim_map
);
150 for (i
= 0; i
< src
->n_ineq
; ++i
) {
151 int i1
= isl_basic_map_alloc_inequality(dst
);
154 copy_constraint_dim_map(dst
->ineq
[i1
], src
->ineq
[i
], dim_map
);
157 for (i
= 0; i
< src
->n_div
; ++i
) {
158 int i1
= isl_basic_map_alloc_div(dst
);
161 copy_div_dim_map(dst
->div
[i1
], src
->div
[i
], dim_map
);
165 isl_basic_map_free(src
);
170 isl_basic_map_free(src
);
171 isl_basic_map_free(dst
);
175 __isl_give isl_basic_set
*isl_basic_set_add_constraints_dim_map(
176 __isl_take isl_basic_set
*dst
, __isl_take isl_basic_set
*src
,
177 __isl_take isl_dim_map
*dim_map
)
179 return isl_basic_map_add_constraints_dim_map(dst
, src
, dim_map
);
182 /* Extend the given dim_map with mappings for the divs in bmap.
184 __isl_give isl_dim_map
*isl_dim_map_extend(__isl_keep isl_dim_map
*dim_map
,
185 __isl_keep isl_basic_map
*bmap
)
188 struct isl_dim_map
*res
;
194 offset
= isl_basic_map_offset(bmap
, isl_dim_div
);
196 res
= isl_dim_map_alloc(bmap
->ctx
, dim_map
->len
- 1 + bmap
->n_div
);
200 for (i
= 0; i
< dim_map
->len
; ++i
)
201 res
->m
[i
] = dim_map
->m
[i
];
202 for (i
= 0; i
< bmap
->n_div
; ++i
) {
203 res
->m
[dim_map
->len
+ i
].pos
= offset
+ i
;
204 res
->m
[dim_map
->len
+ i
].sgn
= 1;
210 /* Extract a dim_map from a reordering.
211 * We essentially need to reverse the mapping, and add an offset
212 * of 1 for the constant term.
214 __isl_give isl_dim_map
*isl_dim_map_from_reordering(
215 __isl_keep isl_reordering
*exp
)
220 struct isl_dim_map
*dim_map
;
225 ctx
= isl_reordering_get_ctx(exp
);
226 space
= isl_reordering_peek_space(exp
);
227 dim_map
= isl_dim_map_alloc(ctx
, isl_space_dim(space
, isl_dim_all
));
231 for (i
= 0; i
< exp
->len
; ++i
) {
232 dim_map
->m
[1 + exp
->pos
[i
]].pos
= 1 + i
;
233 dim_map
->m
[1 + exp
->pos
[i
]].sgn
= 1;