/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/polly/lib/External/isl/isl_output.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2008-2009 Katholieke Universiteit Leuven |
3 | | * Copyright 2010 INRIA Saclay |
4 | | * Copyright 2012-2013 Ecole Normale Superieure |
5 | | * |
6 | | * Use of this software is governed by the MIT license |
7 | | * |
8 | | * Written by Sven Verdoolaege, K.U.Leuven, Departement |
9 | | * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium |
10 | | * and INRIA Saclay - Ile-de-France, Parc Club Orsay Universite, |
11 | | * ZAC des vignes, 4 rue Jacques Monod, 91893 Orsay, France |
12 | | * and Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France |
13 | | */ |
14 | | |
15 | | #include <stdlib.h> |
16 | | #include <string.h> |
17 | | #include <isl_ctx_private.h> |
18 | | #include <isl_map_private.h> |
19 | | #include <isl/set.h> |
20 | | #include <isl_seq.h> |
21 | | #include <isl_polynomial_private.h> |
22 | | #include <isl_printer_private.h> |
23 | | #include <isl_space_private.h> |
24 | | #include <isl_mat_private.h> |
25 | | #include <isl_vec_private.h> |
26 | | #include <isl/union_set.h> |
27 | | #include <isl/union_map.h> |
28 | | #include <isl/constraint.h> |
29 | | #include <isl_local_space_private.h> |
30 | | #include <isl_aff_private.h> |
31 | | #include <isl_val_private.h> |
32 | | #include <isl_constraint_private.h> |
33 | | #include <isl/ast_build.h> |
34 | | #include <isl_sort.h> |
35 | | #include <isl_output_private.h> |
36 | | |
37 | | #include <bset_to_bmap.c> |
38 | | #include <set_to_map.c> |
39 | | #include <uset_to_umap.c> |
40 | | |
41 | | static const char *s_to[2] = { " -> ", " \\to " }; |
42 | | static const char *s_and[2] = { " and ", " \\wedge " }; |
43 | | static const char *s_or[2] = { " or ", " \\vee " }; |
44 | | static const char *s_le[2] = { "<=", "\\le" }; |
45 | | static const char *s_ge[2] = { ">=", "\\ge" }; |
46 | | static const char *s_open_set[2] = { "{ ", "\\{\\, " }; |
47 | | static const char *s_close_set[2] = { " }", " \\,\\}" }; |
48 | | static const char *s_open_list[2] = { "[", "(" }; |
49 | | static const char *s_close_list[2] = { "]", ")" }; |
50 | | static const char *s_such_that[2] = { " : ", " \\mid " }; |
51 | | static const char *s_open_exists[2] = { "exists (", "\\exists \\, " }; |
52 | | static const char *s_close_exists[2] = { ")", "" }; |
53 | | static const char *s_div_prefix[2] = { "e", "\\alpha_" }; |
54 | | static const char *s_mod[2] = { "mod", "\\bmod" }; |
55 | | static const char *s_param_prefix[2] = { "p", "p_" }; |
56 | | static const char *s_input_prefix[2] = { "i", "i_" }; |
57 | | static const char *s_output_prefix[2] = { "o", "o_" }; |
58 | | |
59 | | static __isl_give isl_printer *print_constraint_polylib( |
60 | | struct isl_basic_map *bmap, int ineq, int n, __isl_take isl_printer *p) |
61 | 0 | { |
62 | 0 | int i; |
63 | 0 | unsigned n_in = isl_basic_map_dim(bmap, isl_dim_in); |
64 | 0 | unsigned n_out = isl_basic_map_dim(bmap, isl_dim_out); |
65 | 0 | unsigned nparam = isl_basic_map_dim(bmap, isl_dim_param); |
66 | 0 | isl_int *c = ineq ? bmap->ineq[n] : bmap->eq[n]; |
67 | 0 |
|
68 | 0 | p = isl_printer_start_line(p); |
69 | 0 | p = isl_printer_print_int(p, ineq); |
70 | 0 | for (i = 0; i < n_out; ++i) { |
71 | 0 | p = isl_printer_print_str(p, " "); |
72 | 0 | p = isl_printer_print_isl_int(p, c[1+nparam+n_in+i]); |
73 | 0 | } |
74 | 0 | for (i = 0; i < n_in; ++i) { |
75 | 0 | p = isl_printer_print_str(p, " "); |
76 | 0 | p = isl_printer_print_isl_int(p, c[1+nparam+i]); |
77 | 0 | } |
78 | 0 | for (i = 0; i < bmap->n_div; ++i) { |
79 | 0 | p = isl_printer_print_str(p, " "); |
80 | 0 | p = isl_printer_print_isl_int(p, c[1+nparam+n_in+n_out+i]); |
81 | 0 | } |
82 | 0 | for (i = 0; i < nparam; ++i) { |
83 | 0 | p = isl_printer_print_str(p, " "); |
84 | 0 | p = isl_printer_print_isl_int(p, c[1+i]); |
85 | 0 | } |
86 | 0 | p = isl_printer_print_str(p, " "); |
87 | 0 | p = isl_printer_print_isl_int(p, c[0]); |
88 | 0 | p = isl_printer_end_line(p); |
89 | 0 | return p; |
90 | 0 | } |
91 | | |
92 | | static __isl_give isl_printer *print_constraints_polylib( |
93 | | struct isl_basic_map *bmap, __isl_take isl_printer *p) |
94 | 0 | { |
95 | 0 | int i; |
96 | 0 |
|
97 | 0 | p = isl_printer_set_isl_int_width(p, 5); |
98 | 0 |
|
99 | 0 | for (i = 0; i < bmap->n_eq; ++i) |
100 | 0 | p = print_constraint_polylib(bmap, 0, i, p); |
101 | 0 | for (i = 0; i < bmap->n_ineq; ++i) |
102 | 0 | p = print_constraint_polylib(bmap, 1, i, p); |
103 | 0 |
|
104 | 0 | return p; |
105 | 0 | } |
106 | | |
107 | | static __isl_give isl_printer *bset_print_constraints_polylib( |
108 | | struct isl_basic_set *bset, __isl_take isl_printer *p) |
109 | 0 | { |
110 | 0 | return print_constraints_polylib(bset_to_bmap(bset), p); |
111 | 0 | } |
112 | | |
113 | | static __isl_give isl_printer *isl_basic_map_print_polylib( |
114 | | __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, int ext) |
115 | 0 | { |
116 | 0 | unsigned total = isl_basic_map_total_dim(bmap); |
117 | 0 | p = isl_printer_start_line(p); |
118 | 0 | p = isl_printer_print_int(p, bmap->n_eq + bmap->n_ineq); |
119 | 0 | p = isl_printer_print_str(p, " "); |
120 | 0 | p = isl_printer_print_int(p, 1 + total + 1); |
121 | 0 | if (ext) { |
122 | 0 | p = isl_printer_print_str(p, " "); |
123 | 0 | p = isl_printer_print_int(p, |
124 | 0 | isl_basic_map_dim(bmap, isl_dim_out)); |
125 | 0 | p = isl_printer_print_str(p, " "); |
126 | 0 | p = isl_printer_print_int(p, |
127 | 0 | isl_basic_map_dim(bmap, isl_dim_in)); |
128 | 0 | p = isl_printer_print_str(p, " "); |
129 | 0 | p = isl_printer_print_int(p, |
130 | 0 | isl_basic_map_dim(bmap, isl_dim_div)); |
131 | 0 | p = isl_printer_print_str(p, " "); |
132 | 0 | p = isl_printer_print_int(p, |
133 | 0 | isl_basic_map_dim(bmap, isl_dim_param)); |
134 | 0 | } |
135 | 0 | p = isl_printer_end_line(p); |
136 | 0 | return print_constraints_polylib(bmap, p); |
137 | 0 | } |
138 | | |
139 | | static __isl_give isl_printer *isl_basic_set_print_polylib( |
140 | | __isl_keep isl_basic_set *bset, __isl_take isl_printer *p, int ext) |
141 | 0 | { |
142 | 0 | return isl_basic_map_print_polylib(bset_to_bmap(bset), p, ext); |
143 | 0 | } |
144 | | |
145 | | static __isl_give isl_printer *isl_map_print_polylib(__isl_keep isl_map *map, |
146 | | __isl_take isl_printer *p, int ext) |
147 | 0 | { |
148 | 0 | int i; |
149 | 0 |
|
150 | 0 | p = isl_printer_start_line(p); |
151 | 0 | p = isl_printer_print_int(p, map->n); |
152 | 0 | p = isl_printer_end_line(p); |
153 | 0 | for (i = 0; i < map->n; ++i) { |
154 | 0 | p = isl_printer_start_line(p); |
155 | 0 | p = isl_printer_end_line(p); |
156 | 0 | p = isl_basic_map_print_polylib(map->p[i], p, ext); |
157 | 0 | } |
158 | 0 | return p; |
159 | 0 | } |
160 | | |
161 | | static __isl_give isl_printer *isl_set_print_polylib(__isl_keep isl_set *set, |
162 | | __isl_take isl_printer *p, int ext) |
163 | 0 | { |
164 | 0 | return isl_map_print_polylib(set_to_map(set), p, ext); |
165 | 0 | } |
166 | | |
167 | | static int count_same_name(__isl_keep isl_space *dim, |
168 | | enum isl_dim_type type, unsigned pos, const char *name) |
169 | 34.6k | { |
170 | 34.6k | enum isl_dim_type t; |
171 | 34.6k | unsigned p, s; |
172 | 34.6k | int count = 0; |
173 | 34.6k | |
174 | 94.6k | for (t = isl_dim_param; t <= type && t <= isl_dim_out72.3k ; ++t59.9k ) { |
175 | 59.9k | s = t == type ? pos22.2k : isl_space_dim(dim, t)37.6k ; |
176 | 338k | for (p = 0; p < s; ++p278k ) { |
177 | 278k | const char *n = isl_space_get_dim_name(dim, t, p); |
178 | 278k | if (n && !strcmp(n, name)238k ) |
179 | 0 | count++; |
180 | 278k | } |
181 | 59.9k | } |
182 | 34.6k | return count; |
183 | 34.6k | } |
184 | | |
185 | | /* Print the name of the variable of type "type" and position "pos" |
186 | | * in "space" to "p". |
187 | | */ |
188 | | static __isl_give isl_printer *print_name(__isl_keep isl_space *space, |
189 | | __isl_take isl_printer *p, enum isl_dim_type type, unsigned pos, |
190 | | int latex) |
191 | 34.6k | { |
192 | 34.6k | const char *name; |
193 | 34.6k | char buffer[20]; |
194 | 34.6k | int primes; |
195 | 34.6k | |
196 | 34.6k | name = type == isl_dim_div ? NULL |
197 | 34.6k | : isl_space_get_dim_name(space, type, pos)34.6k ; |
198 | 34.6k | |
199 | 34.6k | if (!name) { |
200 | 12.3k | const char *prefix; |
201 | 12.3k | if (type == isl_dim_param) |
202 | 0 | prefix = s_param_prefix[latex]; |
203 | 12.3k | else if (type == isl_dim_div) |
204 | 10 | prefix = s_div_prefix[latex]; |
205 | 12.3k | else if (isl_space_is_set(space) || type == isl_dim_in10.4k ) |
206 | 11.4k | prefix = s_input_prefix[latex]; |
207 | 882 | else |
208 | 882 | prefix = s_output_prefix[latex]; |
209 | 12.3k | snprintf(buffer, sizeof(buffer), "%s%d", prefix, pos); |
210 | 12.3k | name = buffer; |
211 | 12.3k | } |
212 | 34.6k | primes = count_same_name(space, name == buffer ? isl_dim_div12.3k : type22.2k , |
213 | 34.6k | pos, name); |
214 | 34.6k | p = isl_printer_print_str(p, name); |
215 | 34.6k | while (primes-- > 0) |
216 | 0 | p = isl_printer_print_str(p, "'"); |
217 | 34.6k | return p; |
218 | 34.6k | } |
219 | | |
220 | | static enum isl_dim_type pos2type(__isl_keep isl_space *dim, unsigned *pos) |
221 | 11.9k | { |
222 | 11.9k | enum isl_dim_type type; |
223 | 11.9k | unsigned n_in = isl_space_dim(dim, isl_dim_in); |
224 | 11.9k | unsigned n_out = isl_space_dim(dim, isl_dim_out); |
225 | 11.9k | unsigned nparam = isl_space_dim(dim, isl_dim_param); |
226 | 11.9k | |
227 | 11.9k | if (*pos < 1 + nparam) { |
228 | 5.72k | type = isl_dim_param; |
229 | 5.72k | *pos -= 1; |
230 | 6.26k | } else if (*pos < 1 + nparam + n_in) { |
231 | 4.43k | type = isl_dim_in; |
232 | 4.43k | *pos -= 1 + nparam; |
233 | 4.43k | } else if (1.83k *pos < 1 + nparam + n_in + n_out1.83k ) { |
234 | 1.63k | type = isl_dim_out; |
235 | 1.63k | *pos -= 1 + nparam + n_in; |
236 | 1.63k | } else { |
237 | 202 | type = isl_dim_div; |
238 | 202 | *pos -= 1 + nparam + n_in + n_out; |
239 | 202 | } |
240 | 11.9k | |
241 | 11.9k | return type; |
242 | 11.9k | } |
243 | | |
244 | | /* Can the div expression of the integer division at position "row" of "div" |
245 | | * be printed? |
246 | | * In particular, are the div expressions available and does the selected |
247 | | * variable have a known explicit representation? |
248 | | * Furthermore, the Omega format does not allow any div expressions |
249 | | * to be printed. |
250 | | */ |
251 | | static isl_bool can_print_div_expr(__isl_keep isl_printer *p, |
252 | | __isl_keep isl_mat *div, int pos) |
253 | 618 | { |
254 | 618 | if (p->output_format == ISL_FORMAT_OMEGA) |
255 | 618 | return isl_bool_false0 ; |
256 | 618 | if (!div) |
257 | 0 | return isl_bool_false; |
258 | 618 | return !isl_int_is_zero(div->row[pos][0]); |
259 | 618 | } |
260 | | |
261 | | static __isl_give isl_printer *print_div(__isl_keep isl_space *dim, |
262 | | __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p); |
263 | | |
264 | | static __isl_give isl_printer *print_term(__isl_keep isl_space *space, |
265 | | __isl_keep isl_mat *div, |
266 | | isl_int c, unsigned pos, __isl_take isl_printer *p, int latex) |
267 | 18.2k | { |
268 | 18.2k | enum isl_dim_type type; |
269 | 18.2k | int print_div_def; |
270 | 18.2k | |
271 | 18.2k | if (!p || !space) |
272 | 0 | return isl_printer_free(p); |
273 | 18.2k | |
274 | 18.2k | if (pos == 0) |
275 | 6.59k | return isl_printer_print_isl_int(p, c); |
276 | 11.6k | |
277 | 11.6k | type = pos2type(space, &pos); |
278 | 11.6k | print_div_def = type == isl_dim_div && can_print_div_expr(p, div, pos)125 ; |
279 | 11.6k | |
280 | 11.6k | if (isl_int_is_one(c)) |
281 | 11.6k | ;10.4k |
282 | 1.19k | else if (isl_int_is_negone(c)) |
283 | 1.19k | p = isl_printer_print_str(p, "-")232 ; |
284 | 966 | else { |
285 | 966 | p = isl_printer_print_isl_int(p, c); |
286 | 966 | if (p->output_format == ISL_FORMAT_C || print_div_def) |
287 | 117 | p = isl_printer_print_str(p, "*"); |
288 | 966 | } |
289 | 11.6k | if (print_div_def) |
290 | 117 | p = print_div(space, div, pos, p); |
291 | 11.5k | else |
292 | 11.5k | p = print_name(space, p, type, pos, latex); |
293 | 11.6k | return p; |
294 | 11.6k | } |
295 | | |
296 | | static __isl_give isl_printer *print_affine_of_len(__isl_keep isl_space *dim, |
297 | | __isl_keep isl_mat *div, |
298 | | __isl_take isl_printer *p, isl_int *c, int len) |
299 | 14.9k | { |
300 | 14.9k | int i; |
301 | 14.9k | int first; |
302 | 14.9k | |
303 | 117k | for (i = 0, first = 1; i < len; ++i102k ) { |
304 | 102k | int flip = 0; |
305 | 102k | if (isl_int_is_zero(c[i])) |
306 | 102k | continue89.4k ; |
307 | 12.6k | if (!first) { |
308 | 1.93k | if (isl_int_is_neg(c[i])) { |
309 | 485 | flip = 1; |
310 | 485 | isl_int_neg(c[i], c[i]); |
311 | 485 | p = isl_printer_print_str(p, " - "); |
312 | 485 | } else |
313 | 1.45k | p = isl_printer_print_str(p, " + "); |
314 | 1.93k | } |
315 | 12.6k | first = 0; |
316 | 12.6k | p = print_term(dim, div, c[i], i, p, 0); |
317 | 12.6k | if (flip) |
318 | 12.6k | isl_int_neg485 (c[i], c[i]); |
319 | 12.6k | } |
320 | 14.9k | if (first) |
321 | 4.19k | p = isl_printer_print_str(p, "0"); |
322 | 14.9k | return p; |
323 | 14.9k | } |
324 | | |
325 | | /* Print an affine expression "c" |
326 | | * to "p", with the variable names taken from "space" and |
327 | | * the integer division definitions taken from "div". |
328 | | */ |
329 | | static __isl_give isl_printer *print_affine(__isl_take isl_printer *p, |
330 | | __isl_keep isl_space *space, __isl_keep isl_mat *div, isl_int *c) |
331 | 8.04k | { |
332 | 8.04k | unsigned n_div; |
333 | 8.04k | unsigned len; |
334 | 8.04k | |
335 | 8.04k | if (!space || !div) |
336 | 0 | return isl_printer_free(p); |
337 | 8.04k | n_div = isl_mat_rows(div); |
338 | 8.04k | len = 1 + isl_space_dim(space, isl_dim_all) + n_div; |
339 | 8.04k | return print_affine_of_len(space, div, p, c, len); |
340 | 8.04k | } |
341 | | |
342 | | /* offset is the offset of local_dim inside data->type of data->space. |
343 | | */ |
344 | | static __isl_give isl_printer *print_nested_var_list(__isl_take isl_printer *p, |
345 | | __isl_keep isl_space *local_dim, enum isl_dim_type local_type, |
346 | | struct isl_print_space_data *data, int offset) |
347 | 15.3k | { |
348 | 15.3k | int i; |
349 | 15.3k | |
350 | 15.3k | if (data->space != local_dim && local_type == isl_dim_out114 ) |
351 | 57 | offset += local_dim->n_in; |
352 | 15.3k | |
353 | 44.8k | for (i = 0; i < isl_space_dim(local_dim, local_type); ++i29.4k ) { |
354 | 29.4k | if (i) |
355 | 15.8k | p = isl_printer_print_str(p, ", "); |
356 | 29.4k | if (data->print_dim) |
357 | 13.1k | p = data->print_dim(p, data, offset + i); |
358 | 16.3k | else |
359 | 16.3k | p = print_name(data->space, p, data->type, offset + i, |
360 | 16.3k | data->latex); |
361 | 29.4k | } |
362 | 15.3k | return p; |
363 | 15.3k | } |
364 | | |
365 | | static __isl_give isl_printer *print_var_list(__isl_take isl_printer *p, |
366 | | __isl_keep isl_space *space, enum isl_dim_type type) |
367 | 0 | { |
368 | 0 | struct isl_print_space_data data = { .space = space, .type = type }; |
369 | 0 |
|
370 | 0 | return print_nested_var_list(p, space, type, &data, 0); |
371 | 0 | } |
372 | | |
373 | | static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p, |
374 | | __isl_keep isl_space *local_dim, |
375 | | struct isl_print_space_data *data, int offset); |
376 | | |
377 | | static __isl_give isl_printer *print_nested_tuple(__isl_take isl_printer *p, |
378 | | __isl_keep isl_space *local_dim, enum isl_dim_type local_type, |
379 | | struct isl_print_space_data *data, int offset) |
380 | 15.4k | { |
381 | 15.4k | const char *name = NULL; |
382 | 15.4k | unsigned n = isl_space_dim(local_dim, local_type); |
383 | 15.4k | if ((local_type == isl_dim_in || local_type == isl_dim_out10.9k )) { |
384 | 10.6k | name = isl_space_get_tuple_name(local_dim, local_type); |
385 | 10.6k | if (name) { |
386 | 9.17k | if (data->latex) |
387 | 0 | p = isl_printer_print_str(p, "\\mathrm{"); |
388 | 9.17k | p = isl_printer_print_str(p, name); |
389 | 9.17k | if (data->latex) |
390 | 0 | p = isl_printer_print_str(p, "}"); |
391 | 9.17k | } |
392 | 10.6k | } |
393 | 15.4k | if (!data->latex || n != 10 || name0 ) |
394 | 15.4k | p = isl_printer_print_str(p, s_open_list[data->latex]); |
395 | 15.4k | if ((local_type == isl_dim_in || local_type == isl_dim_out10.9k ) && |
396 | 15.4k | local_dim->nested[local_type - isl_dim_in]10.6k ) { |
397 | 57 | if (data->space != local_dim && local_type == isl_dim_out0 ) |
398 | 0 | offset += local_dim->n_in; |
399 | 57 | p = print_nested_map_dim(p, |
400 | 57 | local_dim->nested[local_type - isl_dim_in], |
401 | 57 | data, offset); |
402 | 57 | } else |
403 | 15.3k | p = print_nested_var_list(p, local_dim, local_type, data, |
404 | 15.3k | offset); |
405 | 15.4k | if (!data->latex || n != 10 || name0 ) |
406 | 15.4k | p = isl_printer_print_str(p, s_close_list[data->latex]); |
407 | 15.4k | return p; |
408 | 15.4k | } |
409 | | |
410 | | static __isl_give isl_printer *print_tuple(__isl_keep isl_space *dim, |
411 | | __isl_take isl_printer *p, enum isl_dim_type type, |
412 | | struct isl_print_space_data *data) |
413 | 15.3k | { |
414 | 15.3k | data->space = dim; |
415 | 15.3k | data->type = type; |
416 | 15.3k | return print_nested_tuple(p, dim, type, data, 0); |
417 | 15.3k | } |
418 | | |
419 | | static __isl_give isl_printer *print_nested_map_dim(__isl_take isl_printer *p, |
420 | | __isl_keep isl_space *local_dim, |
421 | | struct isl_print_space_data *data, int offset) |
422 | 57 | { |
423 | 57 | p = print_nested_tuple(p, local_dim, isl_dim_in, data, offset); |
424 | 57 | p = isl_printer_print_str(p, s_to[data->latex]); |
425 | 57 | p = print_nested_tuple(p, local_dim, isl_dim_out, data, offset); |
426 | 57 | |
427 | 57 | return p; |
428 | 57 | } |
429 | | |
430 | | __isl_give isl_printer *isl_print_space(__isl_keep isl_space *space, |
431 | | __isl_take isl_printer *p, int rational, |
432 | | struct isl_print_space_data *data) |
433 | 8.17k | { |
434 | 8.17k | if (rational && !data->latex0 ) |
435 | 0 | p = isl_printer_print_str(p, "rat: "); |
436 | 8.17k | if (isl_space_is_params(space)) |
437 | 2.31k | ; |
438 | 5.85k | else if (isl_space_is_set(space)) |
439 | 1.49k | p = print_tuple(space, p, isl_dim_set, data); |
440 | 4.36k | else { |
441 | 4.36k | p = print_tuple(space, p, isl_dim_in, data); |
442 | 4.36k | p = isl_printer_print_str(p, s_to[data->latex]); |
443 | 4.36k | p = print_tuple(space, p, isl_dim_out, data); |
444 | 4.36k | } |
445 | 8.17k | |
446 | 8.17k | return p; |
447 | 8.17k | } |
448 | | |
449 | | static __isl_give isl_printer *print_omega_parameters(__isl_keep isl_space *dim, |
450 | | __isl_take isl_printer *p) |
451 | 0 | { |
452 | 0 | if (isl_space_dim(dim, isl_dim_param) == 0) |
453 | 0 | return p; |
454 | 0 | |
455 | 0 | p = isl_printer_start_line(p); |
456 | 0 | p = isl_printer_print_str(p, "symbolic "); |
457 | 0 | p = print_var_list(p, dim, isl_dim_param); |
458 | 0 | p = isl_printer_print_str(p, ";"); |
459 | 0 | p = isl_printer_end_line(p); |
460 | 0 | return p; |
461 | 0 | } |
462 | | |
463 | | /* Does the inequality constraint following "i" in "bmap" |
464 | | * have an opposite value for the same last coefficient? |
465 | | * "last" is the position of the last coefficient of inequality "i". |
466 | | * If the next constraint is a div constraint, then it is ignored |
467 | | * since div constraints are not printed. |
468 | | */ |
469 | | static int next_is_opposite(__isl_keep isl_basic_map *bmap, int i, int last) |
470 | 7.72k | { |
471 | 7.72k | unsigned total = isl_basic_map_total_dim(bmap); |
472 | 7.72k | unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div); |
473 | 7.72k | |
474 | 7.72k | if (i + 1 >= bmap->n_ineq) |
475 | 3.47k | return 0; |
476 | 4.24k | if (isl_seq_last_non_zero(bmap->ineq[i + 1], 1 + total) != last) |
477 | 1.58k | return 0; |
478 | 2.66k | if (last >= o_div) { |
479 | 79 | isl_bool is_div; |
480 | 79 | is_div = isl_basic_map_is_div_constraint(bmap, |
481 | 79 | bmap->ineq[i + 1], last - o_div); |
482 | 79 | if (is_div < 0) |
483 | 0 | return -1; |
484 | 79 | if (is_div) |
485 | 12 | return 0; |
486 | 2.65k | } |
487 | 2.65k | return isl_int_abs_eq(bmap->ineq[i][last], bmap->ineq[i + 1][last]) && |
488 | 2.65k | !2.61k isl_int_eq2.61k (bmap->ineq[i][last], bmap->ineq[i + 1][last]); |
489 | 2.65k | } |
490 | | |
491 | | /* Return a string representation of the operator used when |
492 | | * printing a constraint where the LHS is greater than or equal to the LHS |
493 | | * (sign > 0) or smaller than or equal to the LHS (sign < 0). |
494 | | * If "strict" is set, then return the strict version of the comparison |
495 | | * operator. |
496 | | */ |
497 | | static const char *constraint_op(int sign, int strict, int latex) |
498 | 7.72k | { |
499 | 7.72k | if (strict) |
500 | 1.25k | return sign < 0 ? "<"810 : ">"441 ; |
501 | 6.47k | if (sign < 0) |
502 | 5.15k | return s_le[latex]; |
503 | 1.31k | else |
504 | 1.31k | return s_ge[latex]; |
505 | 6.47k | } |
506 | | |
507 | | /* Print one side of a constraint "c" to "p", with |
508 | | * the variable names taken from "space" and the integer division definitions |
509 | | * taken from "div". |
510 | | * "last" is the position of the last non-zero coefficient. |
511 | | * Let c' be the result of zeroing out this coefficient, then |
512 | | * the partial constraint |
513 | | * |
514 | | * c' op |
515 | | * |
516 | | * is printed. |
517 | | */ |
518 | | static __isl_give isl_printer *print_half_constraint(__isl_take isl_printer *p, |
519 | | __isl_keep isl_space *space, __isl_keep isl_mat *div, |
520 | | isl_int *c, int last, const char *op, int latex) |
521 | 2.37k | { |
522 | 2.37k | isl_int_set_si(c[last], 0); |
523 | 2.37k | p = print_affine(p, space, div, c); |
524 | 2.37k | |
525 | 2.37k | p = isl_printer_print_str(p, " "); |
526 | 2.37k | p = isl_printer_print_str(p, op); |
527 | 2.37k | p = isl_printer_print_str(p, " "); |
528 | 2.37k | |
529 | 2.37k | return p; |
530 | 2.37k | } |
531 | | |
532 | | /* Print a constraint "c" to "p", with the variable names |
533 | | * taken from "space" and the integer division definitions taken from "div". |
534 | | * "last" is the position of the last non-zero coefficient, which is |
535 | | * moreover assumed to be negative. |
536 | | * Let c' be the result of zeroing out this coefficient, then |
537 | | * the constraint is printed in the form |
538 | | * |
539 | | * -c[last] op c' |
540 | | */ |
541 | | static __isl_give isl_printer *print_constraint(__isl_take isl_printer *p, |
542 | | __isl_keep isl_space *space, __isl_keep isl_mat *div, |
543 | | isl_int *c, int last, const char *op, int latex) |
544 | 5.59k | { |
545 | 5.59k | isl_int_abs(c[last], c[last]); |
546 | 5.59k | |
547 | 5.59k | p = print_term(space, div, c[last], last, p, latex); |
548 | 5.59k | |
549 | 5.59k | p = isl_printer_print_str(p, " "); |
550 | 5.59k | p = isl_printer_print_str(p, op); |
551 | 5.59k | p = isl_printer_print_str(p, " "); |
552 | 5.59k | |
553 | 5.59k | isl_int_set_si(c[last], 0); |
554 | 5.59k | p = print_affine(p, space, div, c); |
555 | 5.59k | |
556 | 5.59k | return p; |
557 | 5.59k | } |
558 | | |
559 | | /* Given an integer division |
560 | | * |
561 | | * floor(f/m) |
562 | | * |
563 | | * at position "pos" in "div", print the corresponding modulo expression |
564 | | * |
565 | | * (f) mod m |
566 | | * |
567 | | * to "p". The variable names are taken from "space", while any |
568 | | * nested integer division definitions are taken from "div". |
569 | | */ |
570 | | static __isl_give isl_printer *print_mod(__isl_take isl_printer *p, |
571 | | __isl_keep isl_space *space, __isl_keep isl_mat *div, int pos, |
572 | | int latex) |
573 | 75 | { |
574 | 75 | if (!p || !div) |
575 | 0 | return isl_printer_free(p); |
576 | 75 | |
577 | 75 | p = isl_printer_print_str(p, "("); |
578 | 75 | p = print_affine_of_len(space, div, p, |
579 | 75 | div->row[pos] + 1, div->n_col - 1); |
580 | 75 | p = isl_printer_print_str(p, ") "); |
581 | 75 | p = isl_printer_print_str(p, s_mod[latex]); |
582 | 75 | p = isl_printer_print_str(p, " "); |
583 | 75 | p = isl_printer_print_isl_int(p, div->row[pos][0]); |
584 | 75 | return p; |
585 | 75 | } |
586 | | |
587 | | /* Can the equality constraints "c" be printed as a modulo constraint? |
588 | | * In particular, is of the form |
589 | | * |
590 | | * f - a m floor(g/m) = 0, |
591 | | * |
592 | | * with c = -a m the coefficient at position "pos"? |
593 | | * Return the position of the corresponding integer division if so. |
594 | | * Return the number of integer divisions if not. |
595 | | * Return -1 on error. |
596 | | * |
597 | | * Modulo constraints are currently not printed in C format. |
598 | | * Other than that, "pos" needs to correspond to an integer division |
599 | | * with explicit representation and "c" needs to be a multiple |
600 | | * of the denominator of the integer division. |
601 | | */ |
602 | | static int print_as_modulo_pos(__isl_keep isl_printer *p, |
603 | | __isl_keep isl_space *space, __isl_keep isl_mat *div, unsigned pos, |
604 | | isl_int c) |
605 | 316 | { |
606 | 316 | isl_bool can_print; |
607 | 316 | unsigned n_div; |
608 | 316 | enum isl_dim_type type; |
609 | 316 | |
610 | 316 | if (!p || !space) |
611 | 0 | return -1; |
612 | 316 | n_div = isl_mat_rows(div); |
613 | 316 | if (p->output_format == ISL_FORMAT_C) |
614 | 316 | return n_div0 ; |
615 | 316 | type = pos2type(space, &pos); |
616 | 316 | if (type != isl_dim_div) |
617 | 239 | return n_div; |
618 | 77 | can_print = can_print_div_expr(p, div, pos); |
619 | 77 | if (can_print < 0) |
620 | 0 | return -1; |
621 | 77 | if (!can_print) |
622 | 0 | return n_div; |
623 | 77 | if (!isl_int_is_divisible_by(c, div->row[pos][0])) |
624 | 77 | return n_div2 ; |
625 | 75 | return pos; |
626 | 75 | } |
627 | | |
628 | | /* Print equality constraint "c" to "p" as a modulo constraint, |
629 | | * with the variable names taken from "space" and |
630 | | * the integer division definitions taken from "div". |
631 | | * "last" is the position of the last non-zero coefficient, which is |
632 | | * moreover assumed to be negative and a multiple of the denominator |
633 | | * of the corresponding integer division. "div_pos" is the corresponding |
634 | | * position in the sequence of integer divisions. |
635 | | * |
636 | | * The equality is of the form |
637 | | * |
638 | | * f - a m floor(g/m) = 0. |
639 | | * |
640 | | * Print it as |
641 | | * |
642 | | * a (g mod m) = -f + a g |
643 | | */ |
644 | | static __isl_give isl_printer *print_eq_mod_constraint( |
645 | | __isl_take isl_printer *p, __isl_keep isl_space *space, |
646 | | __isl_keep isl_mat *div, unsigned div_pos, |
647 | | isl_int *c, int last, int latex) |
648 | 75 | { |
649 | 75 | isl_ctx *ctx; |
650 | 75 | int multiple; |
651 | 75 | |
652 | 75 | ctx = isl_printer_get_ctx(p); |
653 | 75 | isl_int_divexact(c[last], c[last], div->row[div_pos][0]); |
654 | 75 | isl_int_abs(c[last], c[last]); |
655 | 75 | multiple = !isl_int_is_one(c[last]); |
656 | 75 | if (multiple) { |
657 | 0 | p = isl_printer_print_isl_int(p, c[last]); |
658 | 0 | p = isl_printer_print_str(p, "*("); |
659 | 0 | } |
660 | 75 | p = print_mod(p, space, div, div_pos, latex); |
661 | 75 | if (multiple) |
662 | 0 | p = isl_printer_print_str(p, ")"); |
663 | 75 | p = isl_printer_print_str(p, " = "); |
664 | 75 | isl_seq_combine(c, ctx->negone, c, |
665 | 75 | c[last], div->row[div_pos] + 1, last); |
666 | 75 | isl_int_set_si(c[last], 0); |
667 | 75 | p = print_affine(p, space, div, c); |
668 | 75 | return p; |
669 | 75 | } |
670 | | |
671 | | /* Print equality constraint "c" to "p", with the variable names |
672 | | * taken from "space" and the integer division definitions taken from "div". |
673 | | * "last" is the position of the last non-zero coefficient, which is |
674 | | * moreover assumed to be negative. |
675 | | * |
676 | | * If possible, print the equality constraint as a modulo constraint. |
677 | | */ |
678 | | static __isl_give isl_printer *print_eq_constraint(__isl_take isl_printer *p, |
679 | | __isl_keep isl_space *space, __isl_keep isl_mat *div, isl_int *c, |
680 | | int last, int latex) |
681 | 316 | { |
682 | 316 | unsigned n_div; |
683 | 316 | int div_pos; |
684 | 316 | |
685 | 316 | n_div = isl_mat_rows(div); |
686 | 316 | div_pos = print_as_modulo_pos(p, space, div, last, c[last]); |
687 | 316 | if (div_pos < 0) |
688 | 0 | return isl_printer_free(p); |
689 | 316 | if (div_pos < n_div) |
690 | 75 | return print_eq_mod_constraint(p, space, div, div_pos, |
691 | 75 | c, last, latex); |
692 | 241 | return print_constraint(p, space, div, c, last, "=", latex); |
693 | 241 | } |
694 | | |
695 | | /* Print the constraints of "bmap" to "p". |
696 | | * The names of the variables are taken from "space" and |
697 | | * the integer division definitions are taken from "div". |
698 | | * Div constraints are only printed in "dump" mode. |
699 | | * The constraints are sorted prior to printing (except in "dump" mode). |
700 | | * |
701 | | * If x is the last variable with a non-zero coefficient, |
702 | | * then a lower bound |
703 | | * |
704 | | * f - a x >= 0 |
705 | | * |
706 | | * is printed as |
707 | | * |
708 | | * a x <= f |
709 | | * |
710 | | * while an upper bound |
711 | | * |
712 | | * f + a x >= 0 |
713 | | * |
714 | | * is printed as |
715 | | * |
716 | | * a x >= -f |
717 | | * |
718 | | * If the next constraint has an opposite sign for the same last coefficient, |
719 | | * then it is printed as |
720 | | * |
721 | | * f >= a x |
722 | | * |
723 | | * or |
724 | | * |
725 | | * -f <= a x |
726 | | * |
727 | | * instead. In fact, the "a x" part is not printed explicitly, but |
728 | | * reused from the next constraint, which is therefore treated as |
729 | | * a first constraint in the conjunction. |
730 | | * |
731 | | * If the constant term of "f" is -1, then "f" is replaced by "f + 1" and |
732 | | * the comparison operator is replaced by the strict variant. |
733 | | * Essentially, ">= 1" is replaced by "> 0". |
734 | | */ |
735 | | static __isl_give isl_printer *print_constraints(__isl_keep isl_basic_map *bmap, |
736 | | __isl_keep isl_space *space, __isl_keep isl_mat *div, |
737 | | __isl_take isl_printer *p, int latex) |
738 | 3.67k | { |
739 | 3.67k | int i; |
740 | 3.67k | isl_vec *c = NULL; |
741 | 3.67k | int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL); |
742 | 3.67k | unsigned total = isl_basic_map_total_dim(bmap); |
743 | 3.67k | unsigned o_div = isl_basic_map_offset(bmap, isl_dim_div); |
744 | 3.67k | int first = 1; |
745 | 3.67k | int dump; |
746 | 3.67k | |
747 | 3.67k | if (!p) |
748 | 0 | return NULL; |
749 | 3.67k | bmap = isl_basic_map_copy(bmap); |
750 | 3.67k | dump = p->dump; |
751 | 3.67k | if (!dump) |
752 | 3.67k | bmap = isl_basic_map_sort_constraints(bmap); |
753 | 3.67k | if (!bmap) |
754 | 0 | goto error; |
755 | 3.67k | |
756 | 3.67k | c = isl_vec_alloc(bmap->ctx, 1 + total); |
757 | 3.67k | if (!c) |
758 | 0 | goto error; |
759 | 3.67k | |
760 | 3.99k | for (i = bmap->n_eq - 1; 3.67k i >= 0; --i316 ) { |
761 | 316 | int l = isl_seq_last_non_zero(bmap->eq[i], 1 + total); |
762 | 316 | if (l < 0) { |
763 | 0 | if (i != bmap->n_eq - 1) |
764 | 0 | p = isl_printer_print_str(p, s_and[latex]); |
765 | 0 | p = isl_printer_print_str(p, "0 = 0"); |
766 | 0 | continue; |
767 | 0 | } |
768 | 316 | if (!first) |
769 | 13 | p = isl_printer_print_str(p, s_and[latex]); |
770 | 316 | if (isl_int_is_neg(bmap->eq[i][l])) |
771 | 316 | isl_seq_cpy(c->el, bmap->eq[i], 1 + total)0 ; |
772 | 316 | else |
773 | 316 | isl_seq_neg(c->el, bmap->eq[i], 1 + total); |
774 | 316 | p = print_eq_constraint(p, space, div, c->el, l, latex); |
775 | 316 | first = 0; |
776 | 316 | } |
777 | 11.4k | for (i = 0; i < bmap->n_ineq; ++i7.79k ) { |
778 | 7.79k | int l = isl_seq_last_non_zero(bmap->ineq[i], 1 + total); |
779 | 7.79k | int strict; |
780 | 7.79k | int s; |
781 | 7.79k | const char *op; |
782 | 7.79k | if (l < 0) |
783 | 0 | continue; |
784 | 7.79k | if (!dump && l >= o_div && |
785 | 7.79k | can_print_div_expr(p, div, l - o_div)231 ) { |
786 | 223 | isl_bool is_div; |
787 | 223 | is_div = isl_basic_map_is_div_constraint(bmap, |
788 | 223 | bmap->ineq[i], l - o_div); |
789 | 223 | if (is_div < 0) |
790 | 0 | goto error; |
791 | 223 | if (is_div) |
792 | 67 | continue; |
793 | 7.72k | } |
794 | 7.72k | if (!first) |
795 | 1.98k | p = isl_printer_print_str(p, s_and[latex]); |
796 | 7.72k | s = isl_int_sgn(bmap->ineq[i][l]); |
797 | 7.72k | strict = !rational && isl_int_is_negone(bmap->ineq[i][0]); |
798 | 7.72k | if (s < 0) |
799 | 3.59k | isl_seq_cpy(c->el, bmap->ineq[i], 1 + total); |
800 | 4.13k | else |
801 | 4.13k | isl_seq_neg(c->el, bmap->ineq[i], 1 + total); |
802 | 7.72k | if (strict) |
803 | 7.72k | isl_int_set_si1.25k (c->el[0], 0); |
804 | 7.72k | if (!dump && next_is_opposite(bmap, i, l)) { |
805 | 2.37k | op = constraint_op(-s, strict, latex); |
806 | 2.37k | p = print_half_constraint(p, space, div, c->el, l, |
807 | 2.37k | op, latex); |
808 | 2.37k | first = 1; |
809 | 5.35k | } else { |
810 | 5.35k | op = constraint_op(s, strict, latex); |
811 | 5.35k | p = print_constraint(p, space, div, c->el, l, |
812 | 5.35k | op, latex); |
813 | 5.35k | first = 0; |
814 | 5.35k | } |
815 | 7.72k | } |
816 | 3.67k | |
817 | 3.67k | isl_basic_map_free(bmap); |
818 | 3.67k | isl_vec_free(c); |
819 | 3.67k | |
820 | 3.67k | return p; |
821 | 0 | error: |
822 | 0 | isl_basic_map_free(bmap); |
823 | 0 | isl_vec_free(c); |
824 | 0 | isl_printer_free(p); |
825 | 0 | return NULL; |
826 | 3.67k | } |
827 | | |
828 | | static __isl_give isl_printer *print_div(__isl_keep isl_space *dim, |
829 | | __isl_keep isl_mat *div, int pos, __isl_take isl_printer *p) |
830 | 117 | { |
831 | 117 | int c; |
832 | 117 | |
833 | 117 | if (!p || !div) |
834 | 0 | return isl_printer_free(p); |
835 | 117 | |
836 | 117 | c = p->output_format == ISL_FORMAT_C; |
837 | 117 | p = isl_printer_print_str(p, c ? "floord("0 : "floor(("); |
838 | 117 | p = print_affine_of_len(dim, div, p, |
839 | 117 | div->row[pos] + 1, div->n_col - 1); |
840 | 117 | p = isl_printer_print_str(p, c ? ", "0 : ")/"); |
841 | 117 | p = isl_printer_print_isl_int(p, div->row[pos][0]); |
842 | 117 | p = isl_printer_print_str(p, ")"); |
843 | 117 | return p; |
844 | 117 | } |
845 | | |
846 | | /* Print a comma separated list of div names, except those that have |
847 | | * a definition that can be printed. |
848 | | * If "print_defined_divs" is set, then those div names are printed |
849 | | * as well, along with their definitions. |
850 | | */ |
851 | | static __isl_give isl_printer *print_div_list(__isl_take isl_printer *p, |
852 | | __isl_keep isl_space *space, __isl_keep isl_mat *div, int latex, |
853 | | int print_defined_divs) |
854 | 2 | { |
855 | 2 | int i; |
856 | 2 | int first = 1; |
857 | 2 | unsigned n_div; |
858 | 2 | |
859 | 2 | if (!p || !space || !div) |
860 | 0 | return isl_printer_free(p); |
861 | 2 | |
862 | 2 | n_div = isl_mat_rows(div); |
863 | 2 | |
864 | 6 | for (i = 0; i < n_div; ++i4 ) { |
865 | 4 | if (!print_defined_divs && can_print_div_expr(p, div, i)) |
866 | 2 | continue; |
867 | 2 | if (!first) |
868 | 0 | p = isl_printer_print_str(p, ", "); |
869 | 2 | p = print_name(space, p, isl_dim_div, i, latex); |
870 | 2 | first = 0; |
871 | 2 | if (!can_print_div_expr(p, div, i)) |
872 | 2 | continue; |
873 | 0 | p = isl_printer_print_str(p, " = "); |
874 | 0 | p = print_div(space, div, i, p); |
875 | 0 | } |
876 | 2 | |
877 | 2 | return p; |
878 | 2 | } |
879 | | |
880 | | /* Does printing an object with local variables described by "div" |
881 | | * require an "exists" clause? |
882 | | * That is, are there any local variables without an explicit representation? |
883 | | * An exists clause is also needed in "dump" mode because |
884 | | * explicit div representations are not printed inline in that case. |
885 | | */ |
886 | | static isl_bool need_exists(__isl_keep isl_printer *p, __isl_keep isl_mat *div) |
887 | 3.67k | { |
888 | 3.67k | int i, n; |
889 | 3.67k | |
890 | 3.67k | if (!p || !div) |
891 | 0 | return isl_bool_error; |
892 | 3.67k | n = isl_mat_rows(div); |
893 | 3.67k | if (n == 0) |
894 | 3.51k | return isl_bool_false; |
895 | 161 | if (p->dump) |
896 | 0 | return isl_bool_true; |
897 | 338 | for (i = 0; 161 i < n; ++i177 ) |
898 | 179 | if (!can_print_div_expr(p, div, i)) |
899 | 2 | return isl_bool_true; |
900 | 161 | return isl_bool_false159 ; |
901 | 161 | } |
902 | | |
903 | | /* Print the start of an exists clause, i.e., |
904 | | * |
905 | | * (exists variables: |
906 | | * |
907 | | * In dump mode, local variables with an explicit definition are printed |
908 | | * as well because they will not be printed inline. |
909 | | */ |
910 | | static __isl_give isl_printer *open_exists(__isl_take isl_printer *p, |
911 | | __isl_keep isl_space *space, __isl_keep isl_mat *div, int latex) |
912 | 2 | { |
913 | 2 | int dump; |
914 | 2 | |
915 | 2 | if (!p) |
916 | 0 | return NULL; |
917 | 2 | |
918 | 2 | dump = p->dump; |
919 | 2 | p = isl_printer_print_str(p, s_open_exists[latex]); |
920 | 2 | p = print_div_list(p, space, div, latex, dump); |
921 | 2 | p = isl_printer_print_str(p, ": "); |
922 | 2 | |
923 | 2 | return p; |
924 | 2 | } |
925 | | |
926 | | /* Remove the explicit representations of all local variables in "div". |
927 | | */ |
928 | | static __isl_give isl_mat *mark_all_unknown(__isl_take isl_mat *div) |
929 | 0 | { |
930 | 0 | int i, n_div; |
931 | 0 |
|
932 | 0 | if (!div) |
933 | 0 | return NULL; |
934 | 0 | |
935 | 0 | n_div = isl_mat_rows(div); |
936 | 0 | for (i = 0; i < n_div; ++i) |
937 | 0 | div = isl_mat_set_element_si(div, i, 0, 0); |
938 | 0 | return div; |
939 | 0 | } |
940 | | |
941 | | /* Print the constraints of "bmap" to "p". |
942 | | * The names of the variables are taken from "space". |
943 | | * "latex" is set if the constraints should be printed in LaTeX format. |
944 | | * Do not print inline explicit div representations in "dump" mode. |
945 | | */ |
946 | | static __isl_give isl_printer *print_disjunct(__isl_keep isl_basic_map *bmap, |
947 | | __isl_keep isl_space *space, __isl_take isl_printer *p, int latex) |
948 | 3.67k | { |
949 | 3.67k | int dump; |
950 | 3.67k | isl_mat *div; |
951 | 3.67k | isl_bool exists; |
952 | 3.67k | |
953 | 3.67k | if (!p) |
954 | 0 | return NULL; |
955 | 3.67k | dump = p->dump; |
956 | 3.67k | div = isl_basic_map_get_divs(bmap); |
957 | 3.67k | exists = need_exists(p, div); |
958 | 3.67k | if (exists >= 0 && exists) |
959 | 2 | p = open_exists(p, space, div, latex); |
960 | 3.67k | |
961 | 3.67k | if (dump) |
962 | 0 | div = mark_all_unknown(div); |
963 | 3.67k | p = print_constraints(bmap, space, div, p, latex); |
964 | 3.67k | isl_mat_free(div); |
965 | 3.67k | |
966 | 3.67k | if (exists >= 0 && exists) |
967 | 2 | p = isl_printer_print_str(p, s_close_exists[latex]); |
968 | 3.67k | return p; |
969 | 3.67k | } |
970 | | |
971 | | /* Print a colon followed by the constraints of "bmap" |
972 | | * to "p", provided there are any constraints. |
973 | | * The names of the variables are taken from "space". |
974 | | * "latex" is set if the constraints should be printed in LaTeX format. |
975 | | */ |
976 | | static __isl_give isl_printer *print_optional_disjunct( |
977 | | __isl_keep isl_basic_map *bmap, __isl_keep isl_space *space, |
978 | | __isl_take isl_printer *p, int latex) |
979 | 0 | { |
980 | 0 | if (isl_basic_map_plain_is_universe(bmap)) |
981 | 0 | return p; |
982 | 0 | |
983 | 0 | p = isl_printer_print_str(p, ": "); |
984 | 0 | p = print_disjunct(bmap, space, p, latex); |
985 | 0 |
|
986 | 0 | return p; |
987 | 0 | } |
988 | | |
989 | | static __isl_give isl_printer *basic_map_print_omega( |
990 | | __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p) |
991 | 0 | { |
992 | 0 | p = isl_printer_print_str(p, "{ ["); |
993 | 0 | p = print_var_list(p, bmap->dim, isl_dim_in); |
994 | 0 | p = isl_printer_print_str(p, "] -> ["); |
995 | 0 | p = print_var_list(p, bmap->dim, isl_dim_out); |
996 | 0 | p = isl_printer_print_str(p, "] "); |
997 | 0 | p = print_optional_disjunct(bmap, bmap->dim, p, 0); |
998 | 0 | p = isl_printer_print_str(p, " }"); |
999 | 0 | return p; |
1000 | 0 | } |
1001 | | |
1002 | | static __isl_give isl_printer *basic_set_print_omega( |
1003 | | __isl_keep isl_basic_set *bset, __isl_take isl_printer *p) |
1004 | 0 | { |
1005 | 0 | p = isl_printer_print_str(p, "{ ["); |
1006 | 0 | p = print_var_list(p, bset->dim, isl_dim_set); |
1007 | 0 | p = isl_printer_print_str(p, "] "); |
1008 | 0 | p = print_optional_disjunct(bset, bset->dim, p, 0); |
1009 | 0 | p = isl_printer_print_str(p, " }"); |
1010 | 0 | return p; |
1011 | 0 | } |
1012 | | |
1013 | | static __isl_give isl_printer *isl_map_print_omega(__isl_keep isl_map *map, |
1014 | | __isl_take isl_printer *p) |
1015 | 0 | { |
1016 | 0 | int i; |
1017 | 0 |
|
1018 | 0 | for (i = 0; i < map->n; ++i) { |
1019 | 0 | if (i) |
1020 | 0 | p = isl_printer_print_str(p, " union "); |
1021 | 0 | p = basic_map_print_omega(map->p[i], p); |
1022 | 0 | } |
1023 | 0 | return p; |
1024 | 0 | } |
1025 | | |
1026 | | static __isl_give isl_printer *isl_set_print_omega(__isl_keep isl_set *set, |
1027 | | __isl_take isl_printer *p) |
1028 | 0 | { |
1029 | 0 | int i; |
1030 | 0 |
|
1031 | 0 | for (i = 0; i < set->n; ++i) { |
1032 | 0 | if (i) |
1033 | 0 | p = isl_printer_print_str(p, " union "); |
1034 | 0 | p = basic_set_print_omega(set->p[i], p); |
1035 | 0 | } |
1036 | 0 | return p; |
1037 | 0 | } |
1038 | | |
1039 | | /* Print the list of parameters in "space", followed by an arrow, to "p", |
1040 | | * if there are any parameters. |
1041 | | */ |
1042 | | static __isl_give isl_printer *print_param_tuple(__isl_take isl_printer *p, |
1043 | | __isl_keep isl_space *space, struct isl_print_space_data *data) |
1044 | 8.12k | { |
1045 | 8.12k | if (!p || !space) |
1046 | 0 | return isl_printer_free(p); |
1047 | 8.12k | if (isl_space_dim(space, isl_dim_param) == 0) |
1048 | 3.36k | return p; |
1049 | 4.76k | |
1050 | 4.76k | p = print_tuple(space, p, isl_dim_param, data); |
1051 | 4.76k | p = isl_printer_print_str(p, s_to[data->latex]); |
1052 | 4.76k | |
1053 | 4.76k | return p; |
1054 | 4.76k | } |
1055 | | |
1056 | | static __isl_give isl_printer *isl_basic_map_print_isl( |
1057 | | __isl_keep isl_basic_map *bmap, __isl_take isl_printer *p, |
1058 | | int latex) |
1059 | 0 | { |
1060 | 0 | struct isl_print_space_data data = { .latex = latex }; |
1061 | 0 | int rational = ISL_F_ISSET(bmap, ISL_BASIC_MAP_RATIONAL); |
1062 | 0 |
|
1063 | 0 | p = print_param_tuple(p, bmap->dim, &data); |
1064 | 0 | p = isl_printer_print_str(p, "{ "); |
1065 | 0 | p = isl_print_space(bmap->dim, p, rational, &data); |
1066 | 0 | p = isl_printer_print_str(p, " : "); |
1067 | 0 | p = print_disjunct(bmap, bmap->dim, p, latex); |
1068 | 0 | p = isl_printer_print_str(p, " }"); |
1069 | 0 | return p; |
1070 | 0 | } |
1071 | | |
1072 | | /* Print the disjuncts of a map (or set) "map" to "p". |
1073 | | * The names of the variables are taken from "space". |
1074 | | * "latex" is set if the constraints should be printed in LaTeX format. |
1075 | | */ |
1076 | | static __isl_give isl_printer *print_disjuncts_core(__isl_keep isl_map *map, |
1077 | | __isl_keep isl_space *space, __isl_take isl_printer *p, int latex) |
1078 | 3.30k | { |
1079 | 3.30k | int i; |
1080 | 3.30k | |
1081 | 3.30k | if (map->n == 0) |
1082 | 371 | p = isl_printer_print_str(p, "false"); |
1083 | 6.82k | for (i = 0; i < map->n; ++i3.51k ) { |
1084 | 3.51k | if (i) |
1085 | 582 | p = isl_printer_print_str(p, s_or[latex]); |
1086 | 3.51k | if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 11.01k ) |
1087 | 288 | p = isl_printer_print_str(p, "("); |
1088 | 3.51k | p = print_disjunct(map->p[i], space, p, latex); |
1089 | 3.51k | if (map->n > 1 && map->p[i]->n_eq + map->p[i]->n_ineq > 11.01k ) |
1090 | 288 | p = isl_printer_print_str(p, ")"); |
1091 | 3.51k | } |
1092 | 3.30k | return p; |
1093 | 3.30k | } |
1094 | | |
1095 | | /* Print the disjuncts of a map (or set) "map" to "p". |
1096 | | * The names of the variables are taken from "space". |
1097 | | * "hull" describes constraints shared by all disjuncts of "map". |
1098 | | * "latex" is set if the constraints should be printed in LaTeX format. |
1099 | | * |
1100 | | * Print the disjuncts as a conjunction of "hull" and |
1101 | | * the result of removing the constraints of "hull" from "map". |
1102 | | * If this result turns out to be the universe, then simply print "hull". |
1103 | | */ |
1104 | | static __isl_give isl_printer *print_disjuncts_in_hull(__isl_keep isl_map *map, |
1105 | | __isl_keep isl_space *space, __isl_take isl_basic_map *hull, |
1106 | | __isl_take isl_printer *p, int latex) |
1107 | 156 | { |
1108 | 156 | isl_bool is_universe; |
1109 | 156 | |
1110 | 156 | p = print_disjunct(hull, space, p, latex); |
1111 | 156 | map = isl_map_plain_gist_basic_map(isl_map_copy(map), hull); |
1112 | 156 | is_universe = isl_map_plain_is_universe(map); |
1113 | 156 | if (is_universe < 0) |
1114 | 0 | goto error; |
1115 | 156 | if (!is_universe) { |
1116 | 152 | p = isl_printer_print_str(p, s_and[latex]); |
1117 | 152 | p = isl_printer_print_str(p, "("); |
1118 | 152 | p = print_disjuncts_core(map, space, p, latex); |
1119 | 152 | p = isl_printer_print_str(p, ")"); |
1120 | 152 | } |
1121 | 156 | isl_map_free(map); |
1122 | 156 | |
1123 | 156 | return p; |
1124 | 0 | error: |
1125 | 0 | isl_map_free(map); |
1126 | 0 | isl_printer_free(p); |
1127 | 0 | return NULL; |
1128 | 156 | } |
1129 | | |
1130 | | /* Print the disjuncts of a map (or set) "map" to "p". |
1131 | | * The names of the variables are taken from "space". |
1132 | | * "latex" is set if the constraints should be printed in LaTeX format. |
1133 | | * |
1134 | | * If there are at least two disjuncts and "dump" mode is not turned out, |
1135 | | * check for any shared constraints among all disjuncts. |
1136 | | * If there are any, then print them separately in print_disjuncts_in_hull. |
1137 | | */ |
1138 | | static __isl_give isl_printer *print_disjuncts(__isl_keep isl_map *map, |
1139 | | __isl_keep isl_space *space, __isl_take isl_printer *p, int latex) |
1140 | 7.73k | { |
1141 | 7.73k | if (isl_map_plain_is_universe(map)) |
1142 | 4.42k | return p; |
1143 | 3.31k | |
1144 | 3.31k | p = isl_printer_print_str(p, s_such_that[latex]); |
1145 | 3.31k | if (!p) |
1146 | 0 | return NULL; |
1147 | 3.31k | |
1148 | 3.31k | if (!p->dump && map->n >= 2) { |
1149 | 439 | isl_basic_map *hull; |
1150 | 439 | isl_bool is_universe; |
1151 | 439 | |
1152 | 439 | hull = isl_map_plain_unshifted_simple_hull(isl_map_copy(map)); |
1153 | 439 | is_universe = isl_basic_map_plain_is_universe(hull); |
1154 | 439 | if (is_universe < 0) |
1155 | 0 | p = isl_printer_free(p); |
1156 | 439 | else if (!is_universe) |
1157 | 156 | return print_disjuncts_in_hull(map, space, hull, |
1158 | 156 | p, latex); |
1159 | 283 | isl_basic_map_free(hull); |
1160 | 283 | } |
1161 | 3.31k | |
1162 | 3.31k | return print_disjuncts_core(map, space, p, latex)3.15k ; |
1163 | 3.31k | } |
1164 | | |
1165 | | /* Print the disjuncts of a map (or set). |
1166 | | * The names of the variables are taken from "space". |
1167 | | * "latex" is set if the constraints should be printed in LaTeX format. |
1168 | | * |
1169 | | * If the map turns out to be a universal parameter domain, then |
1170 | | * we need to print the colon. Otherwise, the output looks identical |
1171 | | * to the empty set. |
1172 | | */ |
1173 | | static __isl_give isl_printer *print_disjuncts_map(__isl_keep isl_map *map, |
1174 | | __isl_keep isl_space *space, __isl_take isl_printer *p, int latex) |
1175 | 7.57k | { |
1176 | 7.57k | if (isl_map_plain_is_universe(map) && isl_space_is_params(map->dim)4.45k ) |
1177 | 755 | return isl_printer_print_str(p, s_such_that[latex]); |
1178 | 6.81k | else |
1179 | 6.81k | return print_disjuncts(map, space, p, latex); |
1180 | 7.57k | } |
1181 | | |
1182 | | /* Print the disjuncts of a set. |
1183 | | * The names of the variables are taken from "space". |
1184 | | * "latex" is set if the constraints should be printed in LaTeX format. |
1185 | | */ |
1186 | | static __isl_give isl_printer *print_disjuncts_set(__isl_keep isl_set *set, |
1187 | | __isl_keep isl_space *space, __isl_take isl_printer *p, int latex) |
1188 | 5 | { |
1189 | 5 | return print_disjuncts_map(set_to_map(set), space, p, latex); |
1190 | 5 | } |
1191 | | |
1192 | | struct isl_aff_split { |
1193 | | isl_basic_map *aff; |
1194 | | isl_map *map; |
1195 | | }; |
1196 | | |
1197 | | static void free_split(__isl_take struct isl_aff_split *split, int n) |
1198 | 7.31k | { |
1199 | 7.31k | int i; |
1200 | 7.31k | |
1201 | 7.31k | if (!split) |
1202 | 371 | return; |
1203 | 6.94k | |
1204 | 14.7k | for (i = 0; 6.94k i < n; ++i7.76k ) { |
1205 | 7.76k | isl_basic_map_free(split[i].aff); |
1206 | 7.76k | isl_map_free(split[i].map); |
1207 | 7.76k | } |
1208 | 6.94k | |
1209 | 6.94k | free(split); |
1210 | 6.94k | } |
1211 | | |
1212 | | static __isl_give isl_basic_map *get_aff(__isl_take isl_basic_map *bmap) |
1213 | 7.76k | { |
1214 | 7.76k | int i, j; |
1215 | 7.76k | unsigned nparam, n_in, n_out, total; |
1216 | 7.76k | |
1217 | 7.76k | bmap = isl_basic_map_cow(bmap); |
1218 | 7.76k | if (!bmap) |
1219 | 0 | return NULL; |
1220 | 7.76k | if (isl_basic_map_free_inequality(bmap, bmap->n_ineq) < 0) |
1221 | 0 | goto error; |
1222 | 7.76k | |
1223 | 7.76k | nparam = isl_basic_map_dim(bmap, isl_dim_param); |
1224 | 7.76k | n_in = isl_basic_map_dim(bmap, isl_dim_in); |
1225 | 7.76k | n_out = isl_basic_map_dim(bmap, isl_dim_out); |
1226 | 7.76k | total = isl_basic_map_dim(bmap, isl_dim_all); |
1227 | 13.8k | for (i = bmap->n_eq - 1; i >= 0; --i6.04k ) { |
1228 | 6.04k | j = isl_seq_last_non_zero(bmap->eq[i] + 1, total); |
1229 | 6.04k | if (j >= nparam && j < nparam + n_in + n_out5.85k && |
1230 | 6.04k | (5.77k isl_int_is_one5.77k (bmap->eq[i][1 + j]) || |
1231 | 5.77k | isl_int_is_negone6 (bmap->eq[i][1 + j]))) |
1232 | 5.77k | continue; |
1233 | 276 | if (isl_basic_map_drop_equality(bmap, i) < 0) |
1234 | 0 | goto error; |
1235 | 276 | } |
1236 | 7.76k | |
1237 | 7.76k | bmap = isl_basic_map_finalize(bmap); |
1238 | 7.76k | |
1239 | 7.76k | return bmap; |
1240 | 0 | error: |
1241 | 0 | isl_basic_map_free(bmap); |
1242 | 0 | return NULL; |
1243 | 7.76k | } |
1244 | | |
1245 | | static int aff_split_cmp(const void *p1, const void *p2, void *user) |
1246 | 990 | { |
1247 | 990 | const struct isl_aff_split *s1, *s2; |
1248 | 990 | s1 = (const struct isl_aff_split *) p1; |
1249 | 990 | s2 = (const struct isl_aff_split *) p2; |
1250 | 990 | |
1251 | 990 | return isl_basic_map_plain_cmp(s1->aff, s2->aff); |
1252 | 990 | } |
1253 | | |
1254 | | static __isl_give isl_basic_map *drop_aff(__isl_take isl_basic_map *bmap, |
1255 | | __isl_keep isl_basic_map *aff) |
1256 | 7.76k | { |
1257 | 7.76k | int i, j; |
1258 | 7.76k | unsigned total; |
1259 | 7.76k | |
1260 | 7.76k | if (!bmap || !aff) |
1261 | 0 | goto error; |
1262 | 7.76k | |
1263 | 7.76k | total = isl_space_dim(bmap->dim, isl_dim_all); |
1264 | 7.76k | |
1265 | 13.8k | for (i = bmap->n_eq - 1; i >= 0; --i6.04k ) { |
1266 | 6.04k | if (isl_seq_first_non_zero(bmap->eq[i] + 1 + total, |
1267 | 6.04k | bmap->n_div) != -1) |
1268 | 81 | continue; |
1269 | 9.75k | for (j = 0; 5.96k j < aff->n_eq; ++j3.78k ) { |
1270 | 9.55k | if (!isl_seq_eq(bmap->eq[i], aff->eq[j], 1 + total) && |
1271 | 9.55k | !isl_seq_is_neg(bmap->eq[i], aff->eq[j], 1 + total)3.78k ) |
1272 | 3.78k | continue; |
1273 | 5.77k | if (isl_basic_map_drop_equality(bmap, i) < 0) |
1274 | 0 | goto error; |
1275 | 5.77k | break; |
1276 | 5.77k | } |
1277 | 5.96k | } |
1278 | 7.76k | |
1279 | 7.76k | return bmap; |
1280 | 0 | error: |
1281 | 0 | isl_basic_map_free(bmap); |
1282 | 0 | return NULL; |
1283 | 7.76k | } |
1284 | | |
1285 | | static __isl_give struct isl_aff_split *split_aff(__isl_keep isl_map *map) |
1286 | 6.94k | { |
1287 | 6.94k | int i, n; |
1288 | 6.94k | struct isl_aff_split *split; |
1289 | 6.94k | isl_ctx *ctx; |
1290 | 6.94k | |
1291 | 6.94k | ctx = isl_map_get_ctx(map); |
1292 | 6.94k | split = isl_calloc_array(ctx, struct isl_aff_split, map->n); |
1293 | 6.94k | if (!split) |
1294 | 0 | return NULL; |
1295 | 6.94k | |
1296 | 14.7k | for (i = 0; 6.94k i < map->n; ++i7.76k ) { |
1297 | 7.76k | isl_basic_map *bmap; |
1298 | 7.76k | split[i].aff = get_aff(isl_basic_map_copy(map->p[i])); |
1299 | 7.76k | bmap = isl_basic_map_copy(map->p[i]); |
1300 | 7.76k | bmap = isl_basic_map_cow(bmap); |
1301 | 7.76k | bmap = drop_aff(bmap, split[i].aff); |
1302 | 7.76k | split[i].map = isl_map_from_basic_map(bmap); |
1303 | 7.76k | if (!split[i].aff || !split[i].map) |
1304 | 0 | goto error; |
1305 | 7.76k | } |
1306 | 6.94k | |
1307 | 6.94k | if (isl_sort(split, map->n, sizeof(struct isl_aff_split), |
1308 | 6.94k | &aff_split_cmp, NULL) < 0) |
1309 | 0 | goto error; |
1310 | 6.94k | |
1311 | 6.94k | n = map->n; |
1312 | 7.76k | for (i = n - 1; i >= 1; --i818 ) { |
1313 | 818 | if (!isl_basic_map_plain_is_equal(split[i - 1].aff, |
1314 | 818 | split[i].aff)) |
1315 | 254 | continue; |
1316 | 564 | isl_basic_map_free(split[i].aff); |
1317 | 564 | split[i - 1].map = isl_map_union(split[i - 1].map, |
1318 | 564 | split[i].map); |
1319 | 564 | if (i != n - 1) |
1320 | 19 | split[i] = split[n - 1]; |
1321 | 564 | split[n - 1].aff = NULL; |
1322 | 564 | split[n - 1].map = NULL; |
1323 | 564 | --n; |
1324 | 564 | } |
1325 | 6.94k | |
1326 | 6.94k | return split; |
1327 | 0 | error: |
1328 | 0 | free_split(split, map->n); |
1329 | 0 | return NULL; |
1330 | 6.94k | } |
1331 | | |
1332 | | static int defining_equality(__isl_keep isl_basic_map *eq, |
1333 | | __isl_keep isl_space *dim, enum isl_dim_type type, int pos) |
1334 | 12.4k | { |
1335 | 12.4k | int i; |
1336 | 12.4k | unsigned total; |
1337 | 12.4k | |
1338 | 12.4k | if (!eq) |
1339 | 0 | return -1; |
1340 | 12.4k | |
1341 | 12.4k | pos += isl_space_offset(dim, type); |
1342 | 12.4k | total = isl_basic_map_total_dim(eq); |
1343 | 12.4k | |
1344 | 24.4k | for (i = 0; i < eq->n_eq; ++i11.9k ) { |
1345 | 17.6k | if (isl_seq_last_non_zero(eq->eq[i] + 1, total) != pos) |
1346 | 11.9k | continue; |
1347 | 5.67k | if (isl_int_is_one(eq->eq[i][1 + pos])) |
1348 | 5.67k | isl_seq_neg(eq->eq[i], eq->eq[i], 1 + total); |
1349 | 5.67k | return i; |
1350 | 5.67k | } |
1351 | 12.4k | |
1352 | 12.4k | return -16.76k ; |
1353 | 12.4k | } |
1354 | | |
1355 | | /* Print dimension "pos" of data->space to "p". |
1356 | | * |
1357 | | * data->user is assumed to be an isl_basic_map keeping track of equalities. |
1358 | | * |
1359 | | * If the current dimension is defined by these equalities, then print |
1360 | | * the corresponding expression, assigned to the name of the dimension |
1361 | | * if there is any. Otherwise, print the name of the dimension. |
1362 | | */ |
1363 | | static __isl_give isl_printer *print_dim_eq(__isl_take isl_printer *p, |
1364 | | struct isl_print_space_data *data, unsigned pos) |
1365 | 12.4k | { |
1366 | 12.4k | isl_basic_map *eq = data->user; |
1367 | 12.4k | int j; |
1368 | 12.4k | |
1369 | 12.4k | j = defining_equality(eq, data->space, data->type, pos); |
1370 | 12.4k | if (j >= 0) { |
1371 | 5.67k | if (isl_space_has_dim_name(data->space, data->type, pos)) { |
1372 | 1 | p = print_name(data->space, p, data->type, pos, |
1373 | 1 | data->latex); |
1374 | 1 | p = isl_printer_print_str(p, " = "); |
1375 | 1 | } |
1376 | 5.67k | pos += 1 + isl_space_offset(data->space, data->type); |
1377 | 5.67k | p = print_affine_of_len(data->space, NULL, p, eq->eq[j], pos); |
1378 | 6.76k | } else { |
1379 | 6.76k | p = print_name(data->space, p, data->type, pos, data->latex); |
1380 | 6.76k | } |
1381 | 12.4k | |
1382 | 12.4k | return p; |
1383 | 12.4k | } |
1384 | | |
1385 | | static __isl_give isl_printer *print_split_map(__isl_take isl_printer *p, |
1386 | | struct isl_aff_split *split, int n, __isl_keep isl_space *space) |
1387 | 6.94k | { |
1388 | 6.94k | struct isl_print_space_data data = { 0 }; |
1389 | 6.94k | int i; |
1390 | 6.94k | int rational; |
1391 | 6.94k | |
1392 | 6.94k | data.print_dim = &print_dim_eq; |
1393 | 14.1k | for (i = 0; i < n; ++i7.19k ) { |
1394 | 7.60k | if (!split[i].map) |
1395 | 413 | break; |
1396 | 7.19k | rational = split[i].map->n > 0 && |
1397 | 7.19k | ISL_F_ISSET(split[i].map->p[0], ISL_BASIC_MAP_RATIONAL); |
1398 | 7.19k | if (i) |
1399 | 254 | p = isl_printer_print_str(p, "; "); |
1400 | 7.19k | data.user = split[i].aff; |
1401 | 7.19k | p = isl_print_space(space, p, rational, &data); |
1402 | 7.19k | p = print_disjuncts_map(split[i].map, space, p, 0); |
1403 | 7.19k | } |
1404 | 6.94k | |
1405 | 6.94k | return p; |
1406 | 6.94k | } |
1407 | | |
1408 | | static __isl_give isl_printer *isl_map_print_isl_body(__isl_keep isl_map *map, |
1409 | | __isl_take isl_printer *p) |
1410 | 7.31k | { |
1411 | 7.31k | struct isl_print_space_data data = { 0 }; |
1412 | 7.31k | struct isl_aff_split *split = NULL; |
1413 | 7.31k | int rational; |
1414 | 7.31k | |
1415 | 7.31k | if (!p || !map) |
1416 | 0 | return isl_printer_free(p); |
1417 | 7.31k | if (!p->dump && map->n > 0) |
1418 | 6.94k | split = split_aff(map); |
1419 | 7.31k | if (split) { |
1420 | 6.94k | p = print_split_map(p, split, map->n, map->dim); |
1421 | 6.94k | } else { |
1422 | 371 | rational = map->n > 0 && |
1423 | 371 | ISL_F_ISSET(map->p[0], ISL_BASIC_MAP_RATIONAL); |
1424 | 371 | p = isl_print_space(map->dim, p, rational, &data); |
1425 | 371 | p = print_disjuncts_map(map, map->dim, p, 0); |
1426 | 371 | } |
1427 | 7.31k | free_split(split, map->n); |
1428 | 7.31k | return p; |
1429 | 7.31k | } |
1430 | | |
1431 | | static __isl_give isl_printer *isl_map_print_isl(__isl_keep isl_map *map, |
1432 | | __isl_take isl_printer *p) |
1433 | 6.95k | { |
1434 | 6.95k | struct isl_print_space_data data = { 0 }; |
1435 | 6.95k | |
1436 | 6.95k | p = print_param_tuple(p, map->dim, &data); |
1437 | 6.95k | p = isl_printer_print_str(p, s_open_set[0]); |
1438 | 6.95k | p = isl_map_print_isl_body(map, p); |
1439 | 6.95k | p = isl_printer_print_str(p, s_close_set[0]); |
1440 | 6.95k | return p; |
1441 | 6.95k | } |
1442 | | |
1443 | | static __isl_give isl_printer *print_latex_map(__isl_keep isl_map *map, |
1444 | | __isl_take isl_printer *p, __isl_keep isl_basic_map *aff) |
1445 | 0 | { |
1446 | 0 | struct isl_print_space_data data = { 0 }; |
1447 | 0 |
|
1448 | 0 | data.latex = 1; |
1449 | 0 | p = print_param_tuple(p, map->dim, &data); |
1450 | 0 | p = isl_printer_print_str(p, s_open_set[1]); |
1451 | 0 | data.print_dim = &print_dim_eq; |
1452 | 0 | data.user = aff; |
1453 | 0 | p = isl_print_space(map->dim, p, 0, &data); |
1454 | 0 | p = print_disjuncts_map(map, map->dim, p, 1); |
1455 | 0 | p = isl_printer_print_str(p, s_close_set[1]); |
1456 | 0 |
|
1457 | 0 | return p; |
1458 | 0 | } |
1459 | | |
1460 | | static __isl_give isl_printer *isl_map_print_latex(__isl_keep isl_map *map, |
1461 | | __isl_take isl_printer *p) |
1462 | 0 | { |
1463 | 0 | int i; |
1464 | 0 | struct isl_aff_split *split = NULL; |
1465 | 0 |
|
1466 | 0 | if (map->n > 0) |
1467 | 0 | split = split_aff(map); |
1468 | 0 |
|
1469 | 0 | if (!split) |
1470 | 0 | return print_latex_map(map, p, NULL); |
1471 | 0 | |
1472 | 0 | for (i = 0; i < map->n; ++i) { |
1473 | 0 | if (!split[i].map) |
1474 | 0 | break; |
1475 | 0 | if (i) |
1476 | 0 | p = isl_printer_print_str(p, " \\cup "); |
1477 | 0 | p = print_latex_map(split[i].map, p, split[i].aff); |
1478 | 0 | } |
1479 | 0 |
|
1480 | 0 | free_split(split, map->n); |
1481 | 0 | return p; |
1482 | 0 | } |
1483 | | |
1484 | | __isl_give isl_printer *isl_printer_print_basic_map(__isl_take isl_printer *p, |
1485 | | __isl_keep isl_basic_map *bmap) |
1486 | 0 | { |
1487 | 0 | if (!p || !bmap) |
1488 | 0 | goto error; |
1489 | 0 | if (p->output_format == ISL_FORMAT_ISL) |
1490 | 0 | return isl_basic_map_print_isl(bmap, p, 0); |
1491 | 0 | else if (p->output_format == ISL_FORMAT_OMEGA) |
1492 | 0 | return basic_map_print_omega(bmap, p); |
1493 | 0 | isl_assert(bmap->ctx, 0, goto error); |
1494 | 0 | error: |
1495 | 0 | isl_printer_free(p); |
1496 | 0 | return NULL; |
1497 | 0 | } |
1498 | | |
1499 | | __isl_give isl_printer *isl_printer_print_basic_set(__isl_take isl_printer *p, |
1500 | | __isl_keep isl_basic_set *bset) |
1501 | 0 | { |
1502 | 0 | if (!p || !bset) |
1503 | 0 | goto error; |
1504 | 0 | |
1505 | 0 | if (p->output_format == ISL_FORMAT_ISL) |
1506 | 0 | return isl_basic_map_print_isl(bset, p, 0); |
1507 | 0 | else if (p->output_format == ISL_FORMAT_POLYLIB) |
1508 | 0 | return isl_basic_set_print_polylib(bset, p, 0); |
1509 | 0 | else if (p->output_format == ISL_FORMAT_EXT_POLYLIB) |
1510 | 0 | return isl_basic_set_print_polylib(bset, p, 1); |
1511 | 0 | else if (p->output_format == ISL_FORMAT_POLYLIB_CONSTRAINTS) |
1512 | 0 | return bset_print_constraints_polylib(bset, p); |
1513 | 0 | else if (p->output_format == ISL_FORMAT_OMEGA) |
1514 | 0 | return basic_set_print_omega(bset, p); |
1515 | 0 | isl_assert(p->ctx, 0, goto error); |
1516 | 0 | error: |
1517 | 0 | isl_printer_free(p); |
1518 | 0 | return NULL; |
1519 | 0 | } |
1520 | | |
1521 | | __isl_give isl_printer *isl_printer_print_set(__isl_take isl_printer *p, |
1522 | | __isl_keep isl_set *set) |
1523 | 3.18k | { |
1524 | 3.18k | if (!p || !set) |
1525 | 0 | goto error; |
1526 | 3.18k | if (p->output_format == ISL_FORMAT_ISL) |
1527 | 3.18k | return isl_map_print_isl(set_to_map(set), p); |
1528 | 0 | else if (p->output_format == ISL_FORMAT_POLYLIB) |
1529 | 0 | return isl_set_print_polylib(set, p, 0); |
1530 | 0 | else if (p->output_format == ISL_FORMAT_EXT_POLYLIB) |
1531 | 0 | return isl_set_print_polylib(set, p, 1); |
1532 | 0 | else if (p->output_format == ISL_FORMAT_OMEGA) |
1533 | 0 | return isl_set_print_omega(set, p); |
1534 | 0 | else if (p->output_format == ISL_FORMAT_LATEX) |
1535 | 0 | return isl_map_print_latex(set_to_map(set), p); |
1536 | 0 | isl_assert(set->ctx, 0, goto error); |
1537 | 0 | error: |
1538 | 0 | isl_printer_free(p); |
1539 | 0 | return NULL; |
1540 | 0 | } |
1541 | | |
1542 | | __isl_give isl_printer *isl_printer_print_map(__isl_take isl_printer *p, |
1543 | | __isl_keep isl_map *map) |
1544 | 3.77k | { |
1545 | 3.77k | if (!p || !map) |
1546 | 0 | goto error; |
1547 | 3.77k | |
1548 | 3.77k | if (p->output_format == ISL_FORMAT_ISL) |
1549 | 3.77k | return isl_map_print_isl(map, p); |
1550 | 0 | else if (p->output_format == ISL_FORMAT_POLYLIB) |
1551 | 0 | return isl_map_print_polylib(map, p, 0); |
1552 | 0 | else if (p->output_format == ISL_FORMAT_EXT_POLYLIB) |
1553 | 0 | return isl_map_print_polylib(map, p, 1); |
1554 | 0 | else if (p->output_format == ISL_FORMAT_OMEGA) |
1555 | 0 | return isl_map_print_omega(map, p); |
1556 | 0 | else if (p->output_format == ISL_FORMAT_LATEX) |
1557 | 0 | return isl_map_print_latex(map, p); |
1558 | 0 | isl_assert(map->ctx, 0, goto error); |
1559 | 0 | error: |
1560 | 0 | isl_printer_free(p); |
1561 | 0 | return NULL; |
1562 | 0 | } |
1563 | | |
1564 | | struct isl_union_print_data { |
1565 | | isl_printer *p; |
1566 | | int first; |
1567 | | }; |
1568 | | |
1569 | | static isl_stat print_map_body(__isl_take isl_map *map, void *user) |
1570 | 354 | { |
1571 | 354 | struct isl_union_print_data *data; |
1572 | 354 | data = (struct isl_union_print_data *)user; |
1573 | 354 | |
1574 | 354 | if (!data->first) |
1575 | 194 | data->p = isl_printer_print_str(data->p, "; "); |
1576 | 354 | data->first = 0; |
1577 | 354 | |
1578 | 354 | data->p = isl_map_print_isl_body(map, data->p); |
1579 | 354 | isl_map_free(map); |
1580 | 354 | |
1581 | 354 | return isl_stat_ok; |
1582 | 354 | } |
1583 | | |
1584 | | /* Print the body of "umap" (everything except the parameter declarations) |
1585 | | * to "p" in isl format. |
1586 | | */ |
1587 | | static __isl_give isl_printer *isl_printer_print_union_map_isl_body( |
1588 | | __isl_take isl_printer *p, __isl_keep isl_union_map *umap) |
1589 | 274 | { |
1590 | 274 | struct isl_union_print_data data; |
1591 | 274 | |
1592 | 274 | p = isl_printer_print_str(p, s_open_set[0]); |
1593 | 274 | data.p = p; |
1594 | 274 | data.first = 1; |
1595 | 274 | isl_union_map_foreach_map(umap, &print_map_body, &data); |
1596 | 274 | p = data.p; |
1597 | 274 | p = isl_printer_print_str(p, s_close_set[0]); |
1598 | 274 | return p; |
1599 | 274 | } |
1600 | | |
1601 | | /* Print the body of "uset" (everything except the parameter declarations) |
1602 | | * to "p" in isl format. |
1603 | | */ |
1604 | | static __isl_give isl_printer *isl_printer_print_union_set_isl_body( |
1605 | | __isl_take isl_printer *p, __isl_keep isl_union_set *uset) |
1606 | 7 | { |
1607 | 7 | return isl_printer_print_union_map_isl_body(p, uset_to_umap(uset)); |
1608 | 7 | } |
1609 | | |
1610 | | /* Print the isl_union_map "umap" to "p" in isl format. |
1611 | | */ |
1612 | | static __isl_give isl_printer *isl_union_map_print_isl( |
1613 | | __isl_keep isl_union_map *umap, __isl_take isl_printer *p) |
1614 | 267 | { |
1615 | 267 | struct isl_print_space_data space_data = { 0 }; |
1616 | 267 | isl_space *space; |
1617 | 267 | |
1618 | 267 | space = isl_union_map_get_space(umap); |
1619 | 267 | p = print_param_tuple(p, space, &space_data); |
1620 | 267 | isl_space_free(space); |
1621 | 267 | |
1622 | 267 | p = isl_printer_print_union_map_isl_body(p, umap); |
1623 | 267 | |
1624 | 267 | return p; |
1625 | 267 | } |
1626 | | |
1627 | | static isl_stat print_latex_map_body(__isl_take isl_map *map, void *user) |
1628 | 0 | { |
1629 | 0 | struct isl_union_print_data *data; |
1630 | 0 | data = (struct isl_union_print_data *)user; |
1631 | 0 |
|
1632 | 0 | if (!data->first) |
1633 | 0 | data->p = isl_printer_print_str(data->p, " \\cup "); |
1634 | 0 | data->first = 0; |
1635 | 0 |
|
1636 | 0 | data->p = isl_map_print_latex(map, data->p); |
1637 | 0 | isl_map_free(map); |
1638 | 0 |
|
1639 | 0 | return isl_stat_ok; |
1640 | 0 | } |
1641 | | |
1642 | | static __isl_give isl_printer *isl_union_map_print_latex( |
1643 | | __isl_keep isl_union_map *umap, __isl_take isl_printer *p) |
1644 | 0 | { |
1645 | 0 | struct isl_union_print_data data = { p, 1 }; |
1646 | 0 | isl_union_map_foreach_map(umap, &print_latex_map_body, &data); |
1647 | 0 | p = data.p; |
1648 | 0 | return p; |
1649 | 0 | } |
1650 | | |
1651 | | __isl_give isl_printer *isl_printer_print_union_map(__isl_take isl_printer *p, |
1652 | | __isl_keep isl_union_map *umap) |
1653 | 267 | { |
1654 | 267 | if (!p || !umap) |
1655 | 0 | goto error; |
1656 | 267 | |
1657 | 267 | if (p->output_format == ISL_FORMAT_ISL) |
1658 | 267 | return isl_union_map_print_isl(umap, p); |
1659 | 0 | if (p->output_format == ISL_FORMAT_LATEX) |
1660 | 0 | return isl_union_map_print_latex(umap, p); |
1661 | 0 | |
1662 | 0 | isl_die(p->ctx, isl_error_invalid, |
1663 | 0 | "invalid output format for isl_union_map", goto error); |
1664 | 0 | error: |
1665 | 0 | isl_printer_free(p); |
1666 | 0 | return NULL; |
1667 | 0 | } |
1668 | | |
1669 | | __isl_give isl_printer *isl_printer_print_union_set(__isl_take isl_printer *p, |
1670 | | __isl_keep isl_union_set *uset) |
1671 | 0 | { |
1672 | 0 | if (!p || !uset) |
1673 | 0 | goto error; |
1674 | 0 | |
1675 | 0 | if (p->output_format == ISL_FORMAT_ISL) |
1676 | 0 | return isl_union_map_print_isl(uset_to_umap(uset), p); |
1677 | 0 | if (p->output_format == ISL_FORMAT_LATEX) |
1678 | 0 | return isl_union_map_print_latex(uset_to_umap(uset), p); |
1679 | 0 | |
1680 | 0 | isl_die(p->ctx, isl_error_invalid, |
1681 | 0 | "invalid output format for isl_union_set", goto error); |
1682 | 0 | error: |
1683 | 0 | isl_printer_free(p); |
1684 | 0 | return NULL; |
1685 | 0 | } |
1686 | | |
1687 | | static int upoly_rec_n_non_zero(__isl_keep struct isl_upoly_rec *rec) |
1688 | 0 | { |
1689 | 0 | int i; |
1690 | 0 | int n; |
1691 | 0 |
|
1692 | 0 | for (i = 0, n = 0; i < rec->n; ++i) |
1693 | 0 | if (!isl_upoly_is_zero(rec->p[i])) |
1694 | 0 | ++n; |
1695 | 0 |
|
1696 | 0 | return n; |
1697 | 0 | } |
1698 | | |
1699 | | static __isl_give isl_printer *upoly_print_cst(__isl_keep struct isl_upoly *up, |
1700 | | __isl_take isl_printer *p, int first) |
1701 | 0 | { |
1702 | 0 | struct isl_upoly_cst *cst; |
1703 | 0 | int neg; |
1704 | 0 |
|
1705 | 0 | cst = isl_upoly_as_cst(up); |
1706 | 0 | if (!cst) |
1707 | 0 | goto error; |
1708 | 0 | neg = !first && isl_int_is_neg(cst->n); |
1709 | 0 | if (!first) |
1710 | 0 | p = isl_printer_print_str(p, neg ? " - " : " + "); |
1711 | 0 | if (neg) |
1712 | 0 | isl_int_neg(cst->n, cst->n); |
1713 | 0 | if (isl_int_is_zero(cst->d)) { |
1714 | 0 | int sgn = isl_int_sgn(cst->n); |
1715 | 0 | p = isl_printer_print_str(p, sgn < 0 ? "-infty" : |
1716 | 0 | sgn == 0 ? "NaN" : "infty"); |
1717 | 0 | } else |
1718 | 0 | p = isl_printer_print_isl_int(p, cst->n); |
1719 | 0 | if (neg) |
1720 | 0 | isl_int_neg(cst->n, cst->n); |
1721 | 0 | if (!isl_int_is_zero(cst->d) && !isl_int_is_one(cst->d)) { |
1722 | 0 | p = isl_printer_print_str(p, "/"); |
1723 | 0 | p = isl_printer_print_isl_int(p, cst->d); |
1724 | 0 | } |
1725 | 0 | return p; |
1726 | 0 | error: |
1727 | 0 | isl_printer_free(p); |
1728 | 0 | return NULL; |
1729 | 0 | } |
1730 | | |
1731 | | static __isl_give isl_printer *print_base(__isl_take isl_printer *p, |
1732 | | __isl_keep isl_space *dim, __isl_keep isl_mat *div, int var) |
1733 | 0 | { |
1734 | 0 | unsigned total; |
1735 | 0 |
|
1736 | 0 | total = isl_space_dim(dim, isl_dim_all); |
1737 | 0 | if (var < total) |
1738 | 0 | p = print_term(dim, NULL, dim->ctx->one, 1 + var, p, 0); |
1739 | 0 | else |
1740 | 0 | p = print_div(dim, div, var - total, p); |
1741 | 0 | return p; |
1742 | 0 | } |
1743 | | |
1744 | | static __isl_give isl_printer *print_pow(__isl_take isl_printer *p, |
1745 | | __isl_keep isl_space *dim, __isl_keep isl_mat *div, int var, int exp) |
1746 | 0 | { |
1747 | 0 | p = print_base(p, dim, div, var); |
1748 | 0 | if (exp == 1) |
1749 | 0 | return p; |
1750 | 0 | if (p->output_format == ISL_FORMAT_C) { |
1751 | 0 | int i; |
1752 | 0 | for (i = 1; i < exp; ++i) { |
1753 | 0 | p = isl_printer_print_str(p, "*"); |
1754 | 0 | p = print_base(p, dim, div, var); |
1755 | 0 | } |
1756 | 0 | } else { |
1757 | 0 | p = isl_printer_print_str(p, "^"); |
1758 | 0 | p = isl_printer_print_int(p, exp); |
1759 | 0 | } |
1760 | 0 | return p; |
1761 | 0 | } |
1762 | | |
1763 | | /* Print the polynomial "up" defined over the domain space "space" and |
1764 | | * local variables defined by "div" to "p". |
1765 | | */ |
1766 | | static __isl_give isl_printer *upoly_print(__isl_keep struct isl_upoly *up, |
1767 | | __isl_keep isl_space *space, __isl_keep isl_mat *div, |
1768 | | __isl_take isl_printer *p) |
1769 | 0 | { |
1770 | 0 | int i, n, first, print_parens; |
1771 | 0 | struct isl_upoly_rec *rec; |
1772 | 0 |
|
1773 | 0 | if (!p || !up || !space || !div) |
1774 | 0 | goto error; |
1775 | 0 | |
1776 | 0 | if (isl_upoly_is_cst(up)) |
1777 | 0 | return upoly_print_cst(up, p, 1); |
1778 | 0 | |
1779 | 0 | rec = isl_upoly_as_rec(up); |
1780 | 0 | if (!rec) |
1781 | 0 | goto error; |
1782 | 0 | n = upoly_rec_n_non_zero(rec); |
1783 | 0 | print_parens = n > 1; |
1784 | 0 | if (print_parens) |
1785 | 0 | p = isl_printer_print_str(p, "("); |
1786 | 0 | for (i = 0, first = 1; i < rec->n; ++i) { |
1787 | 0 | if (isl_upoly_is_zero(rec->p[i])) |
1788 | 0 | continue; |
1789 | 0 | if (isl_upoly_is_negone(rec->p[i])) { |
1790 | 0 | if (!i) |
1791 | 0 | p = isl_printer_print_str(p, "-1"); |
1792 | 0 | else if (first) |
1793 | 0 | p = isl_printer_print_str(p, "-"); |
1794 | 0 | else |
1795 | 0 | p = isl_printer_print_str(p, " - "); |
1796 | 0 | } else if (isl_upoly_is_cst(rec->p[i]) && |
1797 | 0 | !isl_upoly_is_one(rec->p[i])) |
1798 | 0 | p = upoly_print_cst(rec->p[i], p, first); |
1799 | 0 | else { |
1800 | 0 | if (!first) |
1801 | 0 | p = isl_printer_print_str(p, " + "); |
1802 | 0 | if (i == 0 || !isl_upoly_is_one(rec->p[i])) |
1803 | 0 | p = upoly_print(rec->p[i], space, div, p); |
1804 | 0 | } |
1805 | 0 | first = 0; |
1806 | 0 | if (i == 0) |
1807 | 0 | continue; |
1808 | 0 | if (!isl_upoly_is_one(rec->p[i]) && |
1809 | 0 | !isl_upoly_is_negone(rec->p[i])) |
1810 | 0 | p = isl_printer_print_str(p, " * "); |
1811 | 0 | p = print_pow(p, space, div, rec->up.var, i); |
1812 | 0 | } |
1813 | 0 | if (print_parens) |
1814 | 0 | p = isl_printer_print_str(p, ")"); |
1815 | 0 | return p; |
1816 | 0 | error: |
1817 | 0 | isl_printer_free(p); |
1818 | 0 | return NULL; |
1819 | 0 | } |
1820 | | |
1821 | | static __isl_give isl_printer *print_qpolynomial(__isl_take isl_printer *p, |
1822 | | __isl_keep isl_qpolynomial *qp) |
1823 | 0 | { |
1824 | 0 | if (!p || !qp) |
1825 | 0 | goto error; |
1826 | 0 | p = upoly_print(qp->upoly, qp->dim, qp->div, p); |
1827 | 0 | return p; |
1828 | 0 | error: |
1829 | 0 | isl_printer_free(p); |
1830 | 0 | return NULL; |
1831 | 0 | } |
1832 | | |
1833 | | static __isl_give isl_printer *print_qpolynomial_isl(__isl_take isl_printer *p, |
1834 | | __isl_keep isl_qpolynomial *qp) |
1835 | 0 | { |
1836 | 0 | struct isl_print_space_data data = { 0 }; |
1837 | 0 |
|
1838 | 0 | if (!p || !qp) |
1839 | 0 | goto error; |
1840 | 0 | |
1841 | 0 | p = print_param_tuple(p, qp->dim, &data); |
1842 | 0 | p = isl_printer_print_str(p, "{ "); |
1843 | 0 | if (!isl_space_is_params(qp->dim)) { |
1844 | 0 | p = isl_print_space(qp->dim, p, 0, &data); |
1845 | 0 | p = isl_printer_print_str(p, " -> "); |
1846 | 0 | } |
1847 | 0 | p = print_qpolynomial(p, qp); |
1848 | 0 | p = isl_printer_print_str(p, " }"); |
1849 | 0 | return p; |
1850 | 0 | error: |
1851 | 0 | isl_printer_free(p); |
1852 | 0 | return NULL; |
1853 | 0 | } |
1854 | | |
1855 | | /* Print the quasi-polynomial "qp" to "p" in C format, with the variable names |
1856 | | * taken from the domain space "space". |
1857 | | */ |
1858 | | static __isl_give isl_printer *print_qpolynomial_c(__isl_take isl_printer *p, |
1859 | | __isl_keep isl_space *space, __isl_keep isl_qpolynomial *qp) |
1860 | 0 | { |
1861 | 0 | isl_int den; |
1862 | 0 |
|
1863 | 0 | isl_int_init(den); |
1864 | 0 | isl_qpolynomial_get_den(qp, &den); |
1865 | 0 | if (!isl_int_is_one(den)) { |
1866 | 0 | isl_qpolynomial *f; |
1867 | 0 | p = isl_printer_print_str(p, "("); |
1868 | 0 | qp = isl_qpolynomial_copy(qp); |
1869 | 0 | f = isl_qpolynomial_rat_cst_on_domain(isl_space_copy(qp->dim), |
1870 | 0 | den, qp->dim->ctx->one); |
1871 | 0 | qp = isl_qpolynomial_mul(qp, f); |
1872 | 0 | } |
1873 | 0 | if (qp) |
1874 | 0 | p = upoly_print(qp->upoly, space, qp->div, p); |
1875 | 0 | else |
1876 | 0 | p = isl_printer_free(p); |
1877 | 0 | if (!isl_int_is_one(den)) { |
1878 | 0 | p = isl_printer_print_str(p, ")/"); |
1879 | 0 | p = isl_printer_print_isl_int(p, den); |
1880 | 0 | isl_qpolynomial_free(qp); |
1881 | 0 | } |
1882 | 0 | isl_int_clear(den); |
1883 | 0 | return p; |
1884 | 0 | } |
1885 | | |
1886 | | __isl_give isl_printer *isl_printer_print_qpolynomial( |
1887 | | __isl_take isl_printer *p, __isl_keep isl_qpolynomial *qp) |
1888 | 0 | { |
1889 | 0 | if (!p || !qp) |
1890 | 0 | goto error; |
1891 | 0 | |
1892 | 0 | if (p->output_format == ISL_FORMAT_ISL) |
1893 | 0 | return print_qpolynomial_isl(p, qp); |
1894 | 0 | else if (p->output_format == ISL_FORMAT_C) |
1895 | 0 | return print_qpolynomial_c(p, qp->dim, qp); |
1896 | 0 | else |
1897 | 0 | isl_die(qp->dim->ctx, isl_error_unsupported, |
1898 | 0 | "output format not supported for isl_qpolynomials", |
1899 | 0 | goto error); |
1900 | 0 | error: |
1901 | 0 | isl_printer_free(p); |
1902 | 0 | return NULL; |
1903 | 0 | } |
1904 | | |
1905 | | void isl_qpolynomial_print(__isl_keep isl_qpolynomial *qp, FILE *out, |
1906 | | unsigned output_format) |
1907 | 0 | { |
1908 | 0 | isl_printer *p; |
1909 | 0 |
|
1910 | 0 | if (!qp) |
1911 | 0 | return; |
1912 | 0 | |
1913 | 0 | isl_assert(qp->dim->ctx, output_format == ISL_FORMAT_ISL, return); |
1914 | 0 | p = isl_printer_to_file(qp->dim->ctx, out); |
1915 | 0 | p = isl_printer_print_qpolynomial(p, qp); |
1916 | 0 | isl_printer_free(p); |
1917 | 0 | } |
1918 | | |
1919 | | static __isl_give isl_printer *qpolynomial_fold_print( |
1920 | | __isl_keep isl_qpolynomial_fold *fold, __isl_take isl_printer *p) |
1921 | 0 | { |
1922 | 0 | int i; |
1923 | 0 |
|
1924 | 0 | if (fold->type == isl_fold_min) |
1925 | 0 | p = isl_printer_print_str(p, "min"); |
1926 | 0 | else if (fold->type == isl_fold_max) |
1927 | 0 | p = isl_printer_print_str(p, "max"); |
1928 | 0 | p = isl_printer_print_str(p, "("); |
1929 | 0 | for (i = 0; i < fold->n; ++i) { |
1930 | 0 | if (i) |
1931 | 0 | p = isl_printer_print_str(p, ", "); |
1932 | 0 | p = print_qpolynomial(p, fold->qp[i]); |
1933 | 0 | } |
1934 | 0 | p = isl_printer_print_str(p, ")"); |
1935 | 0 | return p; |
1936 | 0 | } |
1937 | | |
1938 | | void isl_qpolynomial_fold_print(__isl_keep isl_qpolynomial_fold *fold, |
1939 | | FILE *out, unsigned output_format) |
1940 | 0 | { |
1941 | 0 | isl_printer *p; |
1942 | 0 |
|
1943 | 0 | if (!fold) |
1944 | 0 | return; |
1945 | 0 | |
1946 | 0 | isl_assert(fold->dim->ctx, output_format == ISL_FORMAT_ISL, return); |
1947 | 0 |
|
1948 | 0 | p = isl_printer_to_file(fold->dim->ctx, out); |
1949 | 0 | p = isl_printer_print_qpolynomial_fold(p, fold); |
1950 | 0 |
|
1951 | 0 | isl_printer_free(p); |
1952 | 0 | } |
1953 | | |
1954 | | static __isl_give isl_printer *isl_pwqp_print_isl_body( |
1955 | | __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp) |
1956 | 0 | { |
1957 | 0 | struct isl_print_space_data data = { 0 }; |
1958 | 0 | int i = 0; |
1959 | 0 |
|
1960 | 0 | for (i = 0; i < pwqp->n; ++i) { |
1961 | 0 | isl_space *space; |
1962 | 0 |
|
1963 | 0 | if (i) |
1964 | 0 | p = isl_printer_print_str(p, "; "); |
1965 | 0 | space = isl_qpolynomial_get_domain_space(pwqp->p[i].qp); |
1966 | 0 | if (!isl_space_is_params(space)) { |
1967 | 0 | p = isl_print_space(space, p, 0, &data); |
1968 | 0 | p = isl_printer_print_str(p, " -> "); |
1969 | 0 | } |
1970 | 0 | p = print_qpolynomial(p, pwqp->p[i].qp); |
1971 | 0 | p = print_disjuncts(set_to_map(pwqp->p[i].set), space, p, 0); |
1972 | 0 | isl_space_free(space); |
1973 | 0 | } |
1974 | 0 |
|
1975 | 0 | return p; |
1976 | 0 | } |
1977 | | |
1978 | | static __isl_give isl_printer *print_pw_qpolynomial_isl( |
1979 | | __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp) |
1980 | 0 | { |
1981 | 0 | struct isl_print_space_data data = { 0 }; |
1982 | 0 |
|
1983 | 0 | if (!p || !pwqp) |
1984 | 0 | goto error; |
1985 | 0 | |
1986 | 0 | p = print_param_tuple(p, pwqp->dim, &data); |
1987 | 0 | p = isl_printer_print_str(p, "{ "); |
1988 | 0 | if (pwqp->n == 0) { |
1989 | 0 | if (!isl_space_is_set(pwqp->dim)) { |
1990 | 0 | p = print_tuple(pwqp->dim, p, isl_dim_in, &data); |
1991 | 0 | p = isl_printer_print_str(p, " -> "); |
1992 | 0 | } |
1993 | 0 | p = isl_printer_print_str(p, "0"); |
1994 | 0 | } |
1995 | 0 | p = isl_pwqp_print_isl_body(p, pwqp); |
1996 | 0 | p = isl_printer_print_str(p, " }"); |
1997 | 0 | return p; |
1998 | 0 | error: |
1999 | 0 | isl_printer_free(p); |
2000 | 0 | return NULL; |
2001 | 0 | } |
2002 | | |
2003 | | void isl_pw_qpolynomial_print(__isl_keep isl_pw_qpolynomial *pwqp, FILE *out, |
2004 | | unsigned output_format) |
2005 | 0 | { |
2006 | 0 | isl_printer *p; |
2007 | 0 |
|
2008 | 0 | if (!pwqp) |
2009 | 0 | return; |
2010 | 0 | |
2011 | 0 | p = isl_printer_to_file(pwqp->dim->ctx, out); |
2012 | 0 | p = isl_printer_set_output_format(p, output_format); |
2013 | 0 | p = isl_printer_print_pw_qpolynomial(p, pwqp); |
2014 | 0 |
|
2015 | 0 | isl_printer_free(p); |
2016 | 0 | } |
2017 | | |
2018 | | static __isl_give isl_printer *isl_pwf_print_isl_body( |
2019 | | __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf) |
2020 | 0 | { |
2021 | 0 | struct isl_print_space_data data = { 0 }; |
2022 | 0 | int i = 0; |
2023 | 0 |
|
2024 | 0 | for (i = 0; i < pwf->n; ++i) { |
2025 | 0 | isl_space *space; |
2026 | 0 |
|
2027 | 0 | if (i) |
2028 | 0 | p = isl_printer_print_str(p, "; "); |
2029 | 0 | space = isl_qpolynomial_fold_get_domain_space(pwf->p[i].fold); |
2030 | 0 | if (!isl_space_is_params(space)) { |
2031 | 0 | p = isl_print_space(space, p, 0, &data); |
2032 | 0 | p = isl_printer_print_str(p, " -> "); |
2033 | 0 | } |
2034 | 0 | p = qpolynomial_fold_print(pwf->p[i].fold, p); |
2035 | 0 | p = print_disjuncts(set_to_map(pwf->p[i].set), space, p, 0); |
2036 | 0 | isl_space_free(space); |
2037 | 0 | } |
2038 | 0 |
|
2039 | 0 | return p; |
2040 | 0 | } |
2041 | | |
2042 | | static __isl_give isl_printer *print_pw_qpolynomial_fold_isl( |
2043 | | __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf) |
2044 | 0 | { |
2045 | 0 | struct isl_print_space_data data = { 0 }; |
2046 | 0 |
|
2047 | 0 | p = print_param_tuple(p, pwf->dim, &data); |
2048 | 0 | p = isl_printer_print_str(p, "{ "); |
2049 | 0 | if (pwf->n == 0) { |
2050 | 0 | if (!isl_space_is_set(pwf->dim)) { |
2051 | 0 | p = print_tuple(pwf->dim, p, isl_dim_in, &data); |
2052 | 0 | p = isl_printer_print_str(p, " -> "); |
2053 | 0 | } |
2054 | 0 | p = isl_printer_print_str(p, "0"); |
2055 | 0 | } |
2056 | 0 | p = isl_pwf_print_isl_body(p, pwf); |
2057 | 0 | p = isl_printer_print_str(p, " }"); |
2058 | 0 | return p; |
2059 | 0 | } |
2060 | | |
2061 | | static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p, |
2062 | | __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset, isl_int *c); |
2063 | | |
2064 | | static __isl_give isl_printer *print_name_c(__isl_take isl_printer *p, |
2065 | | __isl_keep isl_space *dim, |
2066 | | __isl_keep isl_basic_set *bset, enum isl_dim_type type, unsigned pos) |
2067 | 0 | { |
2068 | 0 | if (type == isl_dim_div) { |
2069 | 0 | p = isl_printer_print_str(p, "floord("); |
2070 | 0 | p = print_affine_c(p, dim, bset, bset->div[pos] + 1); |
2071 | 0 | p = isl_printer_print_str(p, ", "); |
2072 | 0 | p = isl_printer_print_isl_int(p, bset->div[pos][0]); |
2073 | 0 | p = isl_printer_print_str(p, ")"); |
2074 | 0 | } else { |
2075 | 0 | const char *name; |
2076 | 0 |
|
2077 | 0 | name = isl_space_get_dim_name(dim, type, pos); |
2078 | 0 | if (!name) |
2079 | 0 | name = "UNNAMED"; |
2080 | 0 | p = isl_printer_print_str(p, name); |
2081 | 0 | } |
2082 | 0 | return p; |
2083 | 0 | } |
2084 | | |
2085 | | static __isl_give isl_printer *print_term_c(__isl_take isl_printer *p, |
2086 | | __isl_keep isl_space *space, |
2087 | | __isl_keep isl_basic_set *bset, isl_int c, unsigned pos) |
2088 | 0 | { |
2089 | 0 | enum isl_dim_type type; |
2090 | 0 |
|
2091 | 0 | if (!p || !space) |
2092 | 0 | return isl_printer_free(p); |
2093 | 0 | |
2094 | 0 | if (pos == 0) |
2095 | 0 | return isl_printer_print_isl_int(p, c); |
2096 | 0 | |
2097 | 0 | if (isl_int_is_one(c)) |
2098 | 0 | ; |
2099 | 0 | else if (isl_int_is_negone(c)) |
2100 | 0 | p = isl_printer_print_str(p, "-"); |
2101 | 0 | else { |
2102 | 0 | p = isl_printer_print_isl_int(p, c); |
2103 | 0 | p = isl_printer_print_str(p, "*"); |
2104 | 0 | } |
2105 | 0 | type = pos2type(space, &pos); |
2106 | 0 | p = print_name_c(p, space, bset, type, pos); |
2107 | 0 | return p; |
2108 | 0 | } |
2109 | | |
2110 | | static __isl_give isl_printer *print_partial_affine_c(__isl_take isl_printer *p, |
2111 | | __isl_keep isl_space *dim, |
2112 | | __isl_keep isl_basic_set *bset, isl_int *c, unsigned len) |
2113 | 0 | { |
2114 | 0 | int i; |
2115 | 0 | int first; |
2116 | 0 |
|
2117 | 0 | for (i = 0, first = 1; i < len; ++i) { |
2118 | 0 | int flip = 0; |
2119 | 0 | if (isl_int_is_zero(c[i])) |
2120 | 0 | continue; |
2121 | 0 | if (!first) { |
2122 | 0 | if (isl_int_is_neg(c[i])) { |
2123 | 0 | flip = 1; |
2124 | 0 | isl_int_neg(c[i], c[i]); |
2125 | 0 | p = isl_printer_print_str(p, " - "); |
2126 | 0 | } else |
2127 | 0 | p = isl_printer_print_str(p, " + "); |
2128 | 0 | } |
2129 | 0 | first = 0; |
2130 | 0 | p = print_term_c(p, dim, bset, c[i], i); |
2131 | 0 | if (flip) |
2132 | 0 | isl_int_neg(c[i], c[i]); |
2133 | 0 | } |
2134 | 0 | if (first) |
2135 | 0 | p = isl_printer_print_str(p, "0"); |
2136 | 0 | return p; |
2137 | 0 | } |
2138 | | |
2139 | | static __isl_give isl_printer *print_affine_c(__isl_take isl_printer *p, |
2140 | | __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset, isl_int *c) |
2141 | 0 | { |
2142 | 0 | unsigned len = 1 + isl_basic_set_total_dim(bset); |
2143 | 0 | return print_partial_affine_c(p, dim, bset, c, len); |
2144 | 0 | } |
2145 | | |
2146 | | /* We skip the constraint if it is implied by the div expression. |
2147 | | * |
2148 | | * *first indicates whether this is the first constraint in the conjunction and |
2149 | | * is updated if the constraint is actually printed. |
2150 | | */ |
2151 | | static __isl_give isl_printer *print_constraint_c(__isl_take isl_printer *p, |
2152 | | __isl_keep isl_space *dim, |
2153 | | __isl_keep isl_basic_set *bset, isl_int *c, const char *op, int *first) |
2154 | 0 | { |
2155 | 0 | unsigned o_div; |
2156 | 0 | unsigned n_div; |
2157 | 0 | int div; |
2158 | 0 |
|
2159 | 0 | o_div = isl_basic_set_offset(bset, isl_dim_div); |
2160 | 0 | n_div = isl_basic_set_dim(bset, isl_dim_div); |
2161 | 0 | div = isl_seq_last_non_zero(c + o_div, n_div); |
2162 | 0 | if (div >= 0) { |
2163 | 0 | isl_bool is_div = isl_basic_set_is_div_constraint(bset, c, div); |
2164 | 0 | if (is_div < 0) |
2165 | 0 | return isl_printer_free(p); |
2166 | 0 | if (is_div) |
2167 | 0 | return p; |
2168 | 0 | } |
2169 | 0 | |
2170 | 0 | if (!*first) |
2171 | 0 | p = isl_printer_print_str(p, " && "); |
2172 | 0 |
|
2173 | 0 | p = print_affine_c(p, dim, bset, c); |
2174 | 0 | p = isl_printer_print_str(p, " "); |
2175 | 0 | p = isl_printer_print_str(p, op); |
2176 | 0 | p = isl_printer_print_str(p, " 0"); |
2177 | 0 |
|
2178 | 0 | *first = 0; |
2179 | 0 |
|
2180 | 0 | return p; |
2181 | 0 | } |
2182 | | |
2183 | | static __isl_give isl_printer *print_basic_set_c(__isl_take isl_printer *p, |
2184 | | __isl_keep isl_space *dim, __isl_keep isl_basic_set *bset) |
2185 | 0 | { |
2186 | 0 | int i, j; |
2187 | 0 | int first = 1; |
2188 | 0 | unsigned n_div = isl_basic_set_dim(bset, isl_dim_div); |
2189 | 0 | unsigned total = isl_basic_set_total_dim(bset) - n_div; |
2190 | 0 |
|
2191 | 0 | for (i = 0; i < bset->n_eq; ++i) { |
2192 | 0 | j = isl_seq_last_non_zero(bset->eq[i] + 1 + total, n_div); |
2193 | 0 | if (j < 0) |
2194 | 0 | p = print_constraint_c(p, dim, bset, |
2195 | 0 | bset->eq[i], "==", &first); |
2196 | 0 | else { |
2197 | 0 | if (i) |
2198 | 0 | p = isl_printer_print_str(p, " && "); |
2199 | 0 | p = isl_printer_print_str(p, "("); |
2200 | 0 | p = print_partial_affine_c(p, dim, bset, bset->eq[i], |
2201 | 0 | 1 + total + j); |
2202 | 0 | p = isl_printer_print_str(p, ") % "); |
2203 | 0 | p = isl_printer_print_isl_int(p, |
2204 | 0 | bset->eq[i][1 + total + j]); |
2205 | 0 | p = isl_printer_print_str(p, " == 0"); |
2206 | 0 | first = 0; |
2207 | 0 | } |
2208 | 0 | } |
2209 | 0 | for (i = 0; i < bset->n_ineq; ++i) |
2210 | 0 | p = print_constraint_c(p, dim, bset, bset->ineq[i], ">=", |
2211 | 0 | &first); |
2212 | 0 | return p; |
2213 | 0 | } |
2214 | | |
2215 | | static __isl_give isl_printer *print_set_c(__isl_take isl_printer *p, |
2216 | | __isl_keep isl_space *dim, __isl_keep isl_set *set) |
2217 | 0 | { |
2218 | 0 | int i; |
2219 | 0 |
|
2220 | 0 | if (!set) |
2221 | 0 | return isl_printer_free(p); |
2222 | 0 | |
2223 | 0 | if (set->n == 0) |
2224 | 0 | p = isl_printer_print_str(p, "0"); |
2225 | 0 |
|
2226 | 0 | for (i = 0; i < set->n; ++i) { |
2227 | 0 | if (i) |
2228 | 0 | p = isl_printer_print_str(p, " || "); |
2229 | 0 | if (set->n > 1) |
2230 | 0 | p = isl_printer_print_str(p, "("); |
2231 | 0 | p = print_basic_set_c(p, dim, set->p[i]); |
2232 | 0 | if (set->n > 1) |
2233 | 0 | p = isl_printer_print_str(p, ")"); |
2234 | 0 | } |
2235 | 0 | return p; |
2236 | 0 | } |
2237 | | |
2238 | | /* Print the piecewise quasi-polynomial "pwqp" to "p" in C format. |
2239 | | */ |
2240 | | static __isl_give isl_printer *print_pw_qpolynomial_c( |
2241 | | __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp) |
2242 | 0 | { |
2243 | 0 | int i; |
2244 | 0 | isl_space *space; |
2245 | 0 |
|
2246 | 0 | space = isl_pw_qpolynomial_get_domain_space(pwqp); |
2247 | 0 | if (pwqp->n == 1 && isl_set_plain_is_universe(pwqp->p[0].set)) { |
2248 | 0 | p = print_qpolynomial_c(p, space, pwqp->p[0].qp); |
2249 | 0 | isl_space_free(space); |
2250 | 0 | return p; |
2251 | 0 | } |
2252 | 0 | |
2253 | 0 | for (i = 0; i < pwqp->n; ++i) { |
2254 | 0 | p = isl_printer_print_str(p, "("); |
2255 | 0 | p = print_set_c(p, space, pwqp->p[i].set); |
2256 | 0 | p = isl_printer_print_str(p, ") ? ("); |
2257 | 0 | p = print_qpolynomial_c(p, space, pwqp->p[i].qp); |
2258 | 0 | p = isl_printer_print_str(p, ") : "); |
2259 | 0 | } |
2260 | 0 |
|
2261 | 0 | isl_space_free(space); |
2262 | 0 | p = isl_printer_print_str(p, "0"); |
2263 | 0 | return p; |
2264 | 0 | } |
2265 | | |
2266 | | __isl_give isl_printer *isl_printer_print_pw_qpolynomial( |
2267 | | __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial *pwqp) |
2268 | 0 | { |
2269 | 0 | if (!p || !pwqp) |
2270 | 0 | goto error; |
2271 | 0 | |
2272 | 0 | if (p->output_format == ISL_FORMAT_ISL) |
2273 | 0 | return print_pw_qpolynomial_isl(p, pwqp); |
2274 | 0 | else if (p->output_format == ISL_FORMAT_C) |
2275 | 0 | return print_pw_qpolynomial_c(p, pwqp); |
2276 | 0 | isl_assert(p->ctx, 0, goto error); |
2277 | 0 | error: |
2278 | 0 | isl_printer_free(p); |
2279 | 0 | return NULL; |
2280 | 0 | } |
2281 | | |
2282 | | static isl_stat print_pwqp_body(__isl_take isl_pw_qpolynomial *pwqp, void *user) |
2283 | 0 | { |
2284 | 0 | struct isl_union_print_data *data; |
2285 | 0 | data = (struct isl_union_print_data *)user; |
2286 | 0 |
|
2287 | 0 | if (!data->first) |
2288 | 0 | data->p = isl_printer_print_str(data->p, "; "); |
2289 | 0 | data->first = 0; |
2290 | 0 |
|
2291 | 0 | data->p = isl_pwqp_print_isl_body(data->p, pwqp); |
2292 | 0 | isl_pw_qpolynomial_free(pwqp); |
2293 | 0 |
|
2294 | 0 | return isl_stat_ok; |
2295 | 0 | } |
2296 | | |
2297 | | static __isl_give isl_printer *print_union_pw_qpolynomial_isl( |
2298 | | __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp) |
2299 | 0 | { |
2300 | 0 | struct isl_union_print_data data; |
2301 | 0 | struct isl_print_space_data space_data = { 0 }; |
2302 | 0 | isl_space *space; |
2303 | 0 |
|
2304 | 0 | space = isl_union_pw_qpolynomial_get_space(upwqp); |
2305 | 0 | p = print_param_tuple(p, space, &space_data); |
2306 | 0 | isl_space_free(space); |
2307 | 0 | p = isl_printer_print_str(p, "{ "); |
2308 | 0 | data.p = p; |
2309 | 0 | data.first = 1; |
2310 | 0 | isl_union_pw_qpolynomial_foreach_pw_qpolynomial(upwqp, &print_pwqp_body, |
2311 | 0 | &data); |
2312 | 0 | p = data.p; |
2313 | 0 | p = isl_printer_print_str(p, " }"); |
2314 | 0 | return p; |
2315 | 0 | } |
2316 | | |
2317 | | __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial( |
2318 | | __isl_take isl_printer *p, __isl_keep isl_union_pw_qpolynomial *upwqp) |
2319 | 0 | { |
2320 | 0 | if (!p || !upwqp) |
2321 | 0 | goto error; |
2322 | 0 | |
2323 | 0 | if (p->output_format == ISL_FORMAT_ISL) |
2324 | 0 | return print_union_pw_qpolynomial_isl(p, upwqp); |
2325 | 0 | isl_die(p->ctx, isl_error_invalid, |
2326 | 0 | "invalid output format for isl_union_pw_qpolynomial", |
2327 | 0 | goto error); |
2328 | 0 | error: |
2329 | 0 | isl_printer_free(p); |
2330 | 0 | return NULL; |
2331 | 0 | } |
2332 | | |
2333 | | /* Print the quasi-polynomial reduction "fold" to "p" in C format, |
2334 | | * with the variable names taken from the domain space "space". |
2335 | | */ |
2336 | | static __isl_give isl_printer *print_qpolynomial_fold_c( |
2337 | | __isl_take isl_printer *p, __isl_keep isl_space *space, |
2338 | | __isl_keep isl_qpolynomial_fold *fold) |
2339 | 0 | { |
2340 | 0 | int i; |
2341 | 0 |
|
2342 | 0 | for (i = 0; i < fold->n - 1; ++i) |
2343 | 0 | if (fold->type == isl_fold_min) |
2344 | 0 | p = isl_printer_print_str(p, "min("); |
2345 | 0 | else if (fold->type == isl_fold_max) |
2346 | 0 | p = isl_printer_print_str(p, "max("); |
2347 | 0 |
|
2348 | 0 | for (i = 0; i < fold->n; ++i) { |
2349 | 0 | if (i) |
2350 | 0 | p = isl_printer_print_str(p, ", "); |
2351 | 0 | p = print_qpolynomial_c(p, space, fold->qp[i]); |
2352 | 0 | if (i) |
2353 | 0 | p = isl_printer_print_str(p, ")"); |
2354 | 0 | } |
2355 | 0 | return p; |
2356 | 0 | } |
2357 | | |
2358 | | __isl_give isl_printer *isl_printer_print_qpolynomial_fold( |
2359 | | __isl_take isl_printer *p, __isl_keep isl_qpolynomial_fold *fold) |
2360 | 0 | { |
2361 | 0 | if (!p || !fold) |
2362 | 0 | goto error; |
2363 | 0 | if (p->output_format == ISL_FORMAT_ISL) |
2364 | 0 | return qpolynomial_fold_print(fold, p); |
2365 | 0 | else if (p->output_format == ISL_FORMAT_C) |
2366 | 0 | return print_qpolynomial_fold_c(p, fold->dim, fold); |
2367 | 0 | isl_die(p->ctx, isl_error_unsupported, "unsupported output format", |
2368 | 0 | goto error); |
2369 | 0 | error: |
2370 | 0 | isl_printer_free(p); |
2371 | 0 | return NULL; |
2372 | 0 | } |
2373 | | |
2374 | | /* Print the piecewise quasi-polynomial reduction "pwf" to "p" in C format. |
2375 | | */ |
2376 | | static __isl_give isl_printer *print_pw_qpolynomial_fold_c( |
2377 | | __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf) |
2378 | 0 | { |
2379 | 0 | int i; |
2380 | 0 | isl_space *space; |
2381 | 0 |
|
2382 | 0 | space = isl_pw_qpolynomial_fold_get_domain_space(pwf); |
2383 | 0 | if (pwf->n == 1 && isl_set_plain_is_universe(pwf->p[0].set)) { |
2384 | 0 | p = print_qpolynomial_fold_c(p, space, pwf->p[0].fold); |
2385 | 0 | isl_space_free(space); |
2386 | 0 | return p; |
2387 | 0 | } |
2388 | 0 | |
2389 | 0 | for (i = 0; i < pwf->n; ++i) { |
2390 | 0 | p = isl_printer_print_str(p, "("); |
2391 | 0 | p = print_set_c(p, space, pwf->p[i].set); |
2392 | 0 | p = isl_printer_print_str(p, ") ? ("); |
2393 | 0 | p = print_qpolynomial_fold_c(p, space, pwf->p[i].fold); |
2394 | 0 | p = isl_printer_print_str(p, ") : "); |
2395 | 0 | } |
2396 | 0 |
|
2397 | 0 | isl_space_free(space); |
2398 | 0 | p = isl_printer_print_str(p, "0"); |
2399 | 0 | return p; |
2400 | 0 | } |
2401 | | |
2402 | | __isl_give isl_printer *isl_printer_print_pw_qpolynomial_fold( |
2403 | | __isl_take isl_printer *p, __isl_keep isl_pw_qpolynomial_fold *pwf) |
2404 | 0 | { |
2405 | 0 | if (!p || !pwf) |
2406 | 0 | goto error; |
2407 | 0 | |
2408 | 0 | if (p->output_format == ISL_FORMAT_ISL) |
2409 | 0 | return print_pw_qpolynomial_fold_isl(p, pwf); |
2410 | 0 | else if (p->output_format == ISL_FORMAT_C) |
2411 | 0 | return print_pw_qpolynomial_fold_c(p, pwf); |
2412 | 0 | isl_assert(p->ctx, 0, goto error); |
2413 | 0 | error: |
2414 | 0 | isl_printer_free(p); |
2415 | 0 | return NULL; |
2416 | 0 | } |
2417 | | |
2418 | | void isl_pw_qpolynomial_fold_print(__isl_keep isl_pw_qpolynomial_fold *pwf, |
2419 | | FILE *out, unsigned output_format) |
2420 | 0 | { |
2421 | 0 | isl_printer *p; |
2422 | 0 |
|
2423 | 0 | if (!pwf) |
2424 | 0 | return; |
2425 | 0 | |
2426 | 0 | p = isl_printer_to_file(pwf->dim->ctx, out); |
2427 | 0 | p = isl_printer_set_output_format(p, output_format); |
2428 | 0 | p = isl_printer_print_pw_qpolynomial_fold(p, pwf); |
2429 | 0 |
|
2430 | 0 | isl_printer_free(p); |
2431 | 0 | } |
2432 | | |
2433 | | static isl_stat print_pwf_body(__isl_take isl_pw_qpolynomial_fold *pwf, |
2434 | | void *user) |
2435 | 0 | { |
2436 | 0 | struct isl_union_print_data *data; |
2437 | 0 | data = (struct isl_union_print_data *)user; |
2438 | 0 |
|
2439 | 0 | if (!data->first) |
2440 | 0 | data->p = isl_printer_print_str(data->p, "; "); |
2441 | 0 | data->first = 0; |
2442 | 0 |
|
2443 | 0 | data->p = isl_pwf_print_isl_body(data->p, pwf); |
2444 | 0 | isl_pw_qpolynomial_fold_free(pwf); |
2445 | 0 |
|
2446 | 0 | return isl_stat_ok; |
2447 | 0 | } |
2448 | | |
2449 | | static __isl_give isl_printer *print_union_pw_qpolynomial_fold_isl( |
2450 | | __isl_take isl_printer *p, |
2451 | | __isl_keep isl_union_pw_qpolynomial_fold *upwf) |
2452 | 0 | { |
2453 | 0 | struct isl_union_print_data data; |
2454 | 0 | struct isl_print_space_data space_data = { 0 }; |
2455 | 0 | isl_space *space; |
2456 | 0 |
|
2457 | 0 | space = isl_union_pw_qpolynomial_fold_get_space(upwf); |
2458 | 0 | p = print_param_tuple(p, space, &space_data); |
2459 | 0 | isl_space_free(space); |
2460 | 0 | p = isl_printer_print_str(p, "{ "); |
2461 | 0 | data.p = p; |
2462 | 0 | data.first = 1; |
2463 | 0 | isl_union_pw_qpolynomial_fold_foreach_pw_qpolynomial_fold(upwf, |
2464 | 0 | &print_pwf_body, &data); |
2465 | 0 | p = data.p; |
2466 | 0 | p = isl_printer_print_str(p, " }"); |
2467 | 0 | return p; |
2468 | 0 | } |
2469 | | |
2470 | | __isl_give isl_printer *isl_printer_print_union_pw_qpolynomial_fold( |
2471 | | __isl_take isl_printer *p, |
2472 | | __isl_keep isl_union_pw_qpolynomial_fold *upwf) |
2473 | 0 | { |
2474 | 0 | if (!p || !upwf) |
2475 | 0 | goto error; |
2476 | 0 | |
2477 | 0 | if (p->output_format == ISL_FORMAT_ISL) |
2478 | 0 | return print_union_pw_qpolynomial_fold_isl(p, upwf); |
2479 | 0 | isl_die(p->ctx, isl_error_invalid, |
2480 | 0 | "invalid output format for isl_union_pw_qpolynomial_fold", |
2481 | 0 | goto error); |
2482 | 0 | error: |
2483 | 0 | isl_printer_free(p); |
2484 | 0 | return NULL; |
2485 | 0 | } |
2486 | | |
2487 | | /* Print the isl_constraint "c" to "p". |
2488 | | */ |
2489 | | __isl_give isl_printer *isl_printer_print_constraint(__isl_take isl_printer *p, |
2490 | | __isl_keep isl_constraint *c) |
2491 | 0 | { |
2492 | 0 | struct isl_print_space_data data = { 0 }; |
2493 | 0 | isl_local_space *ls; |
2494 | 0 | isl_space *space; |
2495 | 0 | isl_bool exists; |
2496 | 0 |
|
2497 | 0 | if (!p || !c) |
2498 | 0 | goto error; |
2499 | 0 | |
2500 | 0 | ls = isl_constraint_get_local_space(c); |
2501 | 0 | if (!ls) |
2502 | 0 | return isl_printer_free(p); |
2503 | 0 | space = isl_local_space_get_space(ls); |
2504 | 0 | p = print_param_tuple(p, space, &data); |
2505 | 0 | p = isl_printer_print_str(p, "{ "); |
2506 | 0 | p = isl_print_space(space, p, 0, &data); |
2507 | 0 | p = isl_printer_print_str(p, " : "); |
2508 | 0 | exists = need_exists(p, ls->div); |
2509 | 0 | if (exists < 0) |
2510 | 0 | p = isl_printer_free(p); |
2511 | 0 | if (exists >= 0 && exists) |
2512 | 0 | p = open_exists(p, space, ls->div, 0); |
2513 | 0 | p = print_affine_of_len(space, ls->div, p, c->v->el, c->v->size); |
2514 | 0 | if (isl_constraint_is_equality(c)) |
2515 | 0 | p = isl_printer_print_str(p, " = 0"); |
2516 | 0 | else |
2517 | 0 | p = isl_printer_print_str(p, " >= 0"); |
2518 | 0 | if (exists >= 0 && exists) |
2519 | 0 | p = isl_printer_print_str(p, s_close_exists[0]); |
2520 | 0 | p = isl_printer_print_str(p, " }"); |
2521 | 0 | isl_space_free(space); |
2522 | 0 | isl_local_space_free(ls); |
2523 | 0 |
|
2524 | 0 | return p; |
2525 | 0 | error: |
2526 | 0 | isl_printer_free(p); |
2527 | 0 | return NULL; |
2528 | 0 | } |
2529 | | |
2530 | | static __isl_give isl_printer *isl_printer_print_space_isl( |
2531 | | __isl_take isl_printer *p, __isl_keep isl_space *space) |
2532 | 2 | { |
2533 | 2 | struct isl_print_space_data data = { 0 }; |
2534 | 2 | |
2535 | 2 | if (!space) |
2536 | 0 | goto error; |
2537 | 2 | |
2538 | 2 | p = print_param_tuple(p, space, &data); |
2539 | 2 | |
2540 | 2 | p = isl_printer_print_str(p, "{ "); |
2541 | 2 | if (isl_space_is_params(space)) |
2542 | 2 | p = isl_printer_print_str(p, s_such_that[0]); |
2543 | 0 | else |
2544 | 0 | p = isl_print_space(space, p, 0, &data); |
2545 | 2 | p = isl_printer_print_str(p, " }"); |
2546 | 2 | |
2547 | 2 | return p; |
2548 | 0 | error: |
2549 | 0 | isl_printer_free(p); |
2550 | 0 | return NULL; |
2551 | 2 | } |
2552 | | |
2553 | | __isl_give isl_printer *isl_printer_print_space(__isl_take isl_printer *p, |
2554 | | __isl_keep isl_space *space) |
2555 | 2 | { |
2556 | 2 | if (!p || !space) |
2557 | 0 | return isl_printer_free(p); |
2558 | 2 | if (p->output_format == ISL_FORMAT_ISL) |
2559 | 2 | return isl_printer_print_space_isl(p, space); |
2560 | 0 | else if (p->output_format == ISL_FORMAT_OMEGA) |
2561 | 0 | return print_omega_parameters(space, p); |
2562 | 0 | |
2563 | 0 | isl_die(isl_space_get_ctx(space), isl_error_unsupported, |
2564 | 0 | "output format not supported for space", |
2565 | 0 | return isl_printer_free(p)); |
2566 | 0 | } |
2567 | | |
2568 | | __isl_give isl_printer *isl_printer_print_local_space(__isl_take isl_printer *p, |
2569 | | __isl_keep isl_local_space *ls) |
2570 | 0 | { |
2571 | 0 | struct isl_print_space_data data = { 0 }; |
2572 | 0 | unsigned n_div; |
2573 | 0 |
|
2574 | 0 | if (!ls) |
2575 | 0 | goto error; |
2576 | 0 | |
2577 | 0 | p = print_param_tuple(p, ls->dim, &data); |
2578 | 0 | p = isl_printer_print_str(p, "{ "); |
2579 | 0 | p = isl_print_space(ls->dim, p, 0, &data); |
2580 | 0 | n_div = isl_local_space_dim(ls, isl_dim_div); |
2581 | 0 | if (n_div > 0) { |
2582 | 0 | p = isl_printer_print_str(p, " : "); |
2583 | 0 | p = isl_printer_print_str(p, s_open_exists[0]); |
2584 | 0 | p = print_div_list(p, ls->dim, ls->div, 0, 1); |
2585 | 0 | p = isl_printer_print_str(p, s_close_exists[0]); |
2586 | 0 | } else if (isl_space_is_params(ls->dim)) |
2587 | 0 | p = isl_printer_print_str(p, s_such_that[0]); |
2588 | 0 | p = isl_printer_print_str(p, " }"); |
2589 | 0 | return p; |
2590 | 0 | error: |
2591 | 0 | isl_printer_free(p); |
2592 | 0 | return NULL; |
2593 | 0 | } |
2594 | | |
2595 | | /* Print the (potentially rational) affine expression "aff" to "p", |
2596 | | * with the variable names taken from "space". |
2597 | | */ |
2598 | | static __isl_give isl_printer *print_aff_body(__isl_take isl_printer *p, |
2599 | | __isl_keep isl_space *space, __isl_keep isl_aff *aff) |
2600 | 1.03k | { |
2601 | 1.03k | unsigned total; |
2602 | 1.03k | |
2603 | 1.03k | if (isl_aff_is_nan(aff)) |
2604 | 0 | return isl_printer_print_str(p, "NaN"); |
2605 | 1.03k | |
2606 | 1.03k | total = isl_local_space_dim(aff->ls, isl_dim_all); |
2607 | 1.03k | p = isl_printer_print_str(p, "("); |
2608 | 1.03k | p = print_affine_of_len(space, aff->ls->div, p, |
2609 | 1.03k | aff->v->el + 1, 1 + total); |
2610 | 1.03k | if (isl_int_is_one(aff->v->el[0])) |
2611 | 1.03k | p = isl_printer_print_str(p, ")"); |
2612 | 0 | else { |
2613 | 0 | p = isl_printer_print_str(p, ")/"); |
2614 | 0 | p = isl_printer_print_isl_int(p, aff->v->el[0]); |
2615 | 0 | } |
2616 | 1.03k | |
2617 | 1.03k | return p; |
2618 | 1.03k | } |
2619 | | |
2620 | | static __isl_give isl_printer *print_aff(__isl_take isl_printer *p, |
2621 | | __isl_keep isl_aff *aff) |
2622 | 330 | { |
2623 | 330 | struct isl_print_space_data data = { 0 }; |
2624 | 330 | |
2625 | 330 | if (isl_space_is_params(aff->ls->dim)) |
2626 | 0 | ; |
2627 | 330 | else { |
2628 | 330 | p = print_tuple(aff->ls->dim, p, isl_dim_set, &data); |
2629 | 330 | p = isl_printer_print_str(p, " -> "); |
2630 | 330 | } |
2631 | 330 | p = isl_printer_print_str(p, "["); |
2632 | 330 | p = print_aff_body(p, aff->ls->dim, aff); |
2633 | 330 | p = isl_printer_print_str(p, "]"); |
2634 | 330 | |
2635 | 330 | return p; |
2636 | 330 | } |
2637 | | |
2638 | | static __isl_give isl_printer *print_aff_isl(__isl_take isl_printer *p, |
2639 | | __isl_keep isl_aff *aff) |
2640 | 0 | { |
2641 | 0 | struct isl_print_space_data data = { 0 }; |
2642 | 0 |
|
2643 | 0 | if (!aff) |
2644 | 0 | goto error; |
2645 | 0 | |
2646 | 0 | p = print_param_tuple(p, aff->ls->dim, &data); |
2647 | 0 | p = isl_printer_print_str(p, "{ "); |
2648 | 0 | p = print_aff(p, aff); |
2649 | 0 | p = isl_printer_print_str(p, " }"); |
2650 | 0 | return p; |
2651 | 0 | error: |
2652 | 0 | isl_printer_free(p); |
2653 | 0 | return NULL; |
2654 | 0 | } |
2655 | | |
2656 | | /* Print the body of an isl_pw_aff, i.e., a semicolon delimited |
2657 | | * sequence of affine expressions, each followed by constraints. |
2658 | | */ |
2659 | | static __isl_give isl_printer *print_pw_aff_body( |
2660 | | __isl_take isl_printer *p, __isl_keep isl_pw_aff *pa) |
2661 | 330 | { |
2662 | 330 | int i; |
2663 | 330 | |
2664 | 330 | if (!pa) |
2665 | 0 | return isl_printer_free(p); |
2666 | 330 | |
2667 | 660 | for (i = 0; 330 i < pa->n; ++i330 ) { |
2668 | 330 | isl_space *space; |
2669 | 330 | |
2670 | 330 | if (i) |
2671 | 0 | p = isl_printer_print_str(p, "; "); |
2672 | 330 | p = print_aff(p, pa->p[i].aff); |
2673 | 330 | space = isl_aff_get_domain_space(pa->p[i].aff); |
2674 | 330 | p = print_disjuncts(set_to_map(pa->p[i].set), space, p, 0); |
2675 | 330 | isl_space_free(space); |
2676 | 330 | } |
2677 | 330 | |
2678 | 330 | return p; |
2679 | 330 | } |
2680 | | |
2681 | | static __isl_give isl_printer *print_pw_aff_isl(__isl_take isl_printer *p, |
2682 | | __isl_keep isl_pw_aff *pwaff) |
2683 | 326 | { |
2684 | 326 | struct isl_print_space_data data = { 0 }; |
2685 | 326 | |
2686 | 326 | if (!pwaff) |
2687 | 0 | goto error; |
2688 | 326 | |
2689 | 326 | p = print_param_tuple(p, pwaff->dim, &data); |
2690 | 326 | p = isl_printer_print_str(p, "{ "); |
2691 | 326 | p = print_pw_aff_body(p, pwaff); |
2692 | 326 | p = isl_printer_print_str(p, " }"); |
2693 | 326 | return p; |
2694 | 0 | error: |
2695 | 0 | isl_printer_free(p); |
2696 | 0 | return NULL; |
2697 | 326 | } |
2698 | | |
2699 | | static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p, |
2700 | | __isl_keep isl_local_space *ls, isl_int *c); |
2701 | | |
2702 | | static __isl_give isl_printer *print_ls_name_c(__isl_take isl_printer *p, |
2703 | | __isl_keep isl_local_space *ls, enum isl_dim_type type, unsigned pos) |
2704 | 0 | { |
2705 | 0 | if (type == isl_dim_div) { |
2706 | 0 | p = isl_printer_print_str(p, "floord("); |
2707 | 0 | p = print_ls_affine_c(p, ls, ls->div->row[pos] + 1); |
2708 | 0 | p = isl_printer_print_str(p, ", "); |
2709 | 0 | p = isl_printer_print_isl_int(p, ls->div->row[pos][0]); |
2710 | 0 | p = isl_printer_print_str(p, ")"); |
2711 | 0 | } else { |
2712 | 0 | const char *name; |
2713 | 0 |
|
2714 | 0 | name = isl_space_get_dim_name(ls->dim, type, pos); |
2715 | 0 | if (!name) |
2716 | 0 | name = "UNNAMED"; |
2717 | 0 | p = isl_printer_print_str(p, name); |
2718 | 0 | } |
2719 | 0 | return p; |
2720 | 0 | } |
2721 | | |
2722 | | static __isl_give isl_printer *print_ls_term_c(__isl_take isl_printer *p, |
2723 | | __isl_keep isl_local_space *ls, isl_int c, unsigned pos) |
2724 | 0 | { |
2725 | 0 | enum isl_dim_type type; |
2726 | 0 |
|
2727 | 0 | if (!p || !ls) |
2728 | 0 | return isl_printer_free(p); |
2729 | 0 | |
2730 | 0 | if (pos == 0) |
2731 | 0 | return isl_printer_print_isl_int(p, c); |
2732 | 0 | |
2733 | 0 | if (isl_int_is_one(c)) |
2734 | 0 | ; |
2735 | 0 | else if (isl_int_is_negone(c)) |
2736 | 0 | p = isl_printer_print_str(p, "-"); |
2737 | 0 | else { |
2738 | 0 | p = isl_printer_print_isl_int(p, c); |
2739 | 0 | p = isl_printer_print_str(p, "*"); |
2740 | 0 | } |
2741 | 0 | type = pos2type(ls->dim, &pos); |
2742 | 0 | p = print_ls_name_c(p, ls, type, pos); |
2743 | 0 | return p; |
2744 | 0 | } |
2745 | | |
2746 | | static __isl_give isl_printer *print_ls_partial_affine_c( |
2747 | | __isl_take isl_printer *p, __isl_keep isl_local_space *ls, |
2748 | | isl_int *c, unsigned len) |
2749 | 0 | { |
2750 | 0 | int i; |
2751 | 0 | int first; |
2752 | 0 |
|
2753 | 0 | for (i = 0, first = 1; i < len; ++i) { |
2754 | 0 | int flip = 0; |
2755 | 0 | if (isl_int_is_zero(c[i])) |
2756 | 0 | continue; |
2757 | 0 | if (!first) { |
2758 | 0 | if (isl_int_is_neg(c[i])) { |
2759 | 0 | flip = 1; |
2760 | 0 | isl_int_neg(c[i], c[i]); |
2761 | 0 | p = isl_printer_print_str(p, " - "); |
2762 | 0 | } else |
2763 | 0 | p = isl_printer_print_str(p, " + "); |
2764 | 0 | } |
2765 | 0 | first = 0; |
2766 | 0 | p = print_ls_term_c(p, ls, c[i], i); |
2767 | 0 | if (flip) |
2768 | 0 | isl_int_neg(c[i], c[i]); |
2769 | 0 | } |
2770 | 0 | if (first) |
2771 | 0 | p = isl_printer_print_str(p, "0"); |
2772 | 0 | return p; |
2773 | 0 | } |
2774 | | |
2775 | | static __isl_give isl_printer *print_ls_affine_c(__isl_take isl_printer *p, |
2776 | | __isl_keep isl_local_space *ls, isl_int *c) |
2777 | 0 | { |
2778 | 0 | unsigned len = 1 + isl_local_space_dim(ls, isl_dim_all); |
2779 | 0 | return print_ls_partial_affine_c(p, ls, c, len); |
2780 | 0 | } |
2781 | | |
2782 | | static __isl_give isl_printer *print_aff_c(__isl_take isl_printer *p, |
2783 | | __isl_keep isl_aff *aff) |
2784 | 0 | { |
2785 | 0 | unsigned total; |
2786 | 0 |
|
2787 | 0 | total = isl_local_space_dim(aff->ls, isl_dim_all); |
2788 | 0 | if (!isl_int_is_one(aff->v->el[0])) |
2789 | 0 | p = isl_printer_print_str(p, "("); |
2790 | 0 | p = print_ls_partial_affine_c(p, aff->ls, aff->v->el + 1, 1 + total); |
2791 | 0 | if (!isl_int_is_one(aff->v->el[0])) { |
2792 | 0 | p = isl_printer_print_str(p, ")/"); |
2793 | 0 | p = isl_printer_print_isl_int(p, aff->v->el[0]); |
2794 | 0 | } |
2795 | 0 | return p; |
2796 | 0 | } |
2797 | | |
2798 | | /* In the C format, we cannot express that "pwaff" may be undefined |
2799 | | * on parts of the domain space. We therefore assume that the expression |
2800 | | * will only be evaluated on its definition domain and compute the gist |
2801 | | * of each cell with respect to this domain. |
2802 | | */ |
2803 | | static __isl_give isl_printer *print_pw_aff_c(__isl_take isl_printer *p, |
2804 | | __isl_keep isl_pw_aff *pwaff) |
2805 | 43 | { |
2806 | 43 | isl_set *domain; |
2807 | 43 | isl_ast_build *build; |
2808 | 43 | isl_ast_expr *expr; |
2809 | 43 | |
2810 | 43 | if (pwaff->n < 1) |
2811 | 43 | isl_die0 (p->ctx, isl_error_unsupported, |
2812 | 43 | "cannot print empty isl_pw_aff in C format", |
2813 | 43 | return isl_printer_free(p)); |
2814 | 43 | |
2815 | 43 | domain = isl_pw_aff_domain(isl_pw_aff_copy(pwaff)); |
2816 | 43 | build = isl_ast_build_from_context(domain); |
2817 | 43 | expr = isl_ast_build_expr_from_pw_aff(build, isl_pw_aff_copy(pwaff)); |
2818 | 43 | p = isl_printer_print_ast_expr(p, expr); |
2819 | 43 | isl_ast_expr_free(expr); |
2820 | 43 | isl_ast_build_free(build); |
2821 | 43 | |
2822 | 43 | return p; |
2823 | 43 | } |
2824 | | |
2825 | | __isl_give isl_printer *isl_printer_print_aff(__isl_take isl_printer *p, |
2826 | | __isl_keep isl_aff *aff) |
2827 | 0 | { |
2828 | 0 | if (!p || !aff) |
2829 | 0 | goto error; |
2830 | 0 | |
2831 | 0 | if (p->output_format == ISL_FORMAT_ISL) |
2832 | 0 | return print_aff_isl(p, aff); |
2833 | 0 | else if (p->output_format == ISL_FORMAT_C) |
2834 | 0 | return print_aff_c(p, aff); |
2835 | 0 | isl_die(p->ctx, isl_error_unsupported, "unsupported output format", |
2836 | 0 | goto error); |
2837 | 0 | error: |
2838 | 0 | isl_printer_free(p); |
2839 | 0 | return NULL; |
2840 | 0 | } |
2841 | | |
2842 | | __isl_give isl_printer *isl_printer_print_pw_aff(__isl_take isl_printer *p, |
2843 | | __isl_keep isl_pw_aff *pwaff) |
2844 | 369 | { |
2845 | 369 | if (!p || !pwaff) |
2846 | 0 | goto error; |
2847 | 369 | |
2848 | 369 | if (p->output_format == ISL_FORMAT_ISL) |
2849 | 369 | return print_pw_aff_isl(p, pwaff)326 ; |
2850 | 43 | else if (p->output_format == ISL_FORMAT_C) |
2851 | 43 | return print_pw_aff_c(p, pwaff); |
2852 | 0 | isl_die(p->ctx, isl_error_unsupported, "unsupported output format", |
2853 | 0 | goto error); |
2854 | 0 | error: |
2855 | 0 | isl_printer_free(p); |
2856 | 0 | return NULL; |
2857 | 0 | } |
2858 | | |
2859 | | /* Print "pa" in a sequence of isl_pw_affs delimited by semicolons. |
2860 | | * Each isl_pw_aff itself is also printed as semicolon delimited |
2861 | | * sequence of pieces. |
2862 | | * If data->first = 1, then this is the first in the sequence. |
2863 | | * Update data->first to tell the next element that it is not the first. |
2864 | | */ |
2865 | | static isl_stat print_pw_aff_body_wrap(__isl_take isl_pw_aff *pa, |
2866 | | void *user) |
2867 | 4 | { |
2868 | 4 | struct isl_union_print_data *data; |
2869 | 4 | data = (struct isl_union_print_data *) user; |
2870 | 4 | |
2871 | 4 | if (!data->first) |
2872 | 2 | data->p = isl_printer_print_str(data->p, "; "); |
2873 | 4 | data->first = 0; |
2874 | 4 | |
2875 | 4 | data->p = print_pw_aff_body(data->p, pa); |
2876 | 4 | isl_pw_aff_free(pa); |
2877 | 4 | |
2878 | 4 | return data->p ? isl_stat_ok : isl_stat_error0 ; |
2879 | 4 | } |
2880 | | |
2881 | | /* Print the body of an isl_union_pw_aff, i.e., a semicolon delimited |
2882 | | * sequence of affine expressions, each followed by constraints, |
2883 | | * with the sequence enclosed in braces. |
2884 | | */ |
2885 | | static __isl_give isl_printer *print_union_pw_aff_body( |
2886 | | __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa) |
2887 | 2 | { |
2888 | 2 | struct isl_union_print_data data = { p, 1 }; |
2889 | 2 | |
2890 | 2 | p = isl_printer_print_str(p, s_open_set[0]); |
2891 | 2 | data.p = p; |
2892 | 2 | if (isl_union_pw_aff_foreach_pw_aff(upa, |
2893 | 2 | &print_pw_aff_body_wrap, &data) < 0) |
2894 | 0 | data.p = isl_printer_free(p); |
2895 | 2 | p = data.p; |
2896 | 2 | p = isl_printer_print_str(p, s_close_set[0]); |
2897 | 2 | |
2898 | 2 | return p; |
2899 | 2 | } |
2900 | | |
2901 | | /* Print the isl_union_pw_aff "upa" to "p" in isl format. |
2902 | | * |
2903 | | * The individual isl_pw_affs are delimited by a semicolon. |
2904 | | */ |
2905 | | static __isl_give isl_printer *print_union_pw_aff_isl( |
2906 | | __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa) |
2907 | 0 | { |
2908 | 0 | struct isl_print_space_data data = { 0 }; |
2909 | 0 | isl_space *space; |
2910 | 0 |
|
2911 | 0 | space = isl_union_pw_aff_get_space(upa); |
2912 | 0 | p = print_param_tuple(p, space, &data); |
2913 | 0 | isl_space_free(space); |
2914 | 0 | p = print_union_pw_aff_body(p, upa); |
2915 | 0 | return p; |
2916 | 0 | } |
2917 | | |
2918 | | /* Print the isl_union_pw_aff "upa" to "p". |
2919 | | * |
2920 | | * We currently only support an isl format. |
2921 | | */ |
2922 | | __isl_give isl_printer *isl_printer_print_union_pw_aff( |
2923 | | __isl_take isl_printer *p, __isl_keep isl_union_pw_aff *upa) |
2924 | 0 | { |
2925 | 0 | if (!p || !upa) |
2926 | 0 | return isl_printer_free(p); |
2927 | 0 | |
2928 | 0 | if (p->output_format == ISL_FORMAT_ISL) |
2929 | 0 | return print_union_pw_aff_isl(p, upa); |
2930 | 0 | isl_die(isl_printer_get_ctx(p), isl_error_unsupported, |
2931 | 0 | "unsupported output format", return isl_printer_free(p)); |
2932 | 0 | } |
2933 | | |
2934 | | /* Print dimension "pos" of data->space to "p". |
2935 | | * |
2936 | | * data->user is assumed to be an isl_multi_aff. |
2937 | | * |
2938 | | * If the current dimension is an output dimension, then print |
2939 | | * the corresponding expression. Otherwise, print the name of the dimension. |
2940 | | */ |
2941 | | static __isl_give isl_printer *print_dim_ma(__isl_take isl_printer *p, |
2942 | | struct isl_print_space_data *data, unsigned pos) |
2943 | 692 | { |
2944 | 692 | isl_multi_aff *ma = data->user; |
2945 | 692 | |
2946 | 692 | if (data->type == isl_dim_out) { |
2947 | 690 | isl_space *space; |
2948 | 690 | |
2949 | 690 | space = isl_multi_aff_get_domain_space(ma); |
2950 | 690 | p = print_aff_body(p, space, ma->u.p[pos]); |
2951 | 690 | isl_space_free(space); |
2952 | 690 | } else { |
2953 | 2 | p = print_name(data->space, p, data->type, pos, data->latex); |
2954 | 2 | } |
2955 | 692 | |
2956 | 692 | return p; |
2957 | 692 | } |
2958 | | |
2959 | | static __isl_give isl_printer *print_multi_aff(__isl_take isl_printer *p, |
2960 | | __isl_keep isl_multi_aff *maff) |
2961 | 576 | { |
2962 | 576 | struct isl_print_space_data data = { 0 }; |
2963 | 576 | |
2964 | 576 | data.print_dim = &print_dim_ma; |
2965 | 576 | data.user = maff; |
2966 | 576 | return isl_print_space(maff->space, p, 0, &data); |
2967 | 576 | } |
2968 | | |
2969 | | static __isl_give isl_printer *print_multi_aff_isl(__isl_take isl_printer *p, |
2970 | | __isl_keep isl_multi_aff *maff) |
2971 | 1 | { |
2972 | 1 | struct isl_print_space_data data = { 0 }; |
2973 | 1 | |
2974 | 1 | if (!maff) |
2975 | 0 | goto error; |
2976 | 1 | |
2977 | 1 | p = print_param_tuple(p, maff->space, &data); |
2978 | 1 | p = isl_printer_print_str(p, "{ "); |
2979 | 1 | p = print_multi_aff(p, maff); |
2980 | 1 | p = isl_printer_print_str(p, " }"); |
2981 | 1 | return p; |
2982 | 0 | error: |
2983 | 0 | isl_printer_free(p); |
2984 | 0 | return NULL; |
2985 | 1 | } |
2986 | | |
2987 | | __isl_give isl_printer *isl_printer_print_multi_aff(__isl_take isl_printer *p, |
2988 | | __isl_keep isl_multi_aff *maff) |
2989 | 1 | { |
2990 | 1 | if (!p || !maff) |
2991 | 0 | goto error; |
2992 | 1 | |
2993 | 1 | if (p->output_format == ISL_FORMAT_ISL) |
2994 | 1 | return print_multi_aff_isl(p, maff); |
2995 | 0 | isl_die(p->ctx, isl_error_unsupported, "unsupported output format", |
2996 | 0 | goto error); |
2997 | 0 | error: |
2998 | 0 | isl_printer_free(p); |
2999 | 0 | return NULL; |
3000 | 0 | } |
3001 | | |
3002 | | static __isl_give isl_printer *print_pw_multi_aff_body( |
3003 | | __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma) |
3004 | 540 | { |
3005 | 540 | int i; |
3006 | 540 | |
3007 | 540 | if (!pma) |
3008 | 0 | goto error; |
3009 | 540 | |
3010 | 1.11k | for (i = 0; 540 i < pma->n; ++i575 ) { |
3011 | 575 | isl_space *space; |
3012 | 575 | |
3013 | 575 | if (i) |
3014 | 35 | p = isl_printer_print_str(p, "; "); |
3015 | 575 | p = print_multi_aff(p, pma->p[i].maff); |
3016 | 575 | space = isl_multi_aff_get_domain_space(pma->p[i].maff); |
3017 | 575 | p = print_disjuncts(set_to_map(pma->p[i].set), space, p, 0); |
3018 | 575 | isl_space_free(space); |
3019 | 575 | } |
3020 | 540 | return p; |
3021 | 0 | error: |
3022 | 0 | isl_printer_free(p); |
3023 | 0 | return NULL; |
3024 | 540 | } |
3025 | | |
3026 | | static __isl_give isl_printer *print_pw_multi_aff_isl(__isl_take isl_printer *p, |
3027 | | __isl_keep isl_pw_multi_aff *pma) |
3028 | 540 | { |
3029 | 540 | struct isl_print_space_data data = { 0 }; |
3030 | 540 | |
3031 | 540 | if (!pma) |
3032 | 0 | goto error; |
3033 | 540 | |
3034 | 540 | p = print_param_tuple(p, pma->dim, &data); |
3035 | 540 | p = isl_printer_print_str(p, "{ "); |
3036 | 540 | p = print_pw_multi_aff_body(p, pma); |
3037 | 540 | p = isl_printer_print_str(p, " }"); |
3038 | 540 | return p; |
3039 | 0 | error: |
3040 | 0 | isl_printer_free(p); |
3041 | 0 | return NULL; |
3042 | 540 | } |
3043 | | |
3044 | | /* Print the unnamed, single-dimensional piecewise multi affine expression "pma" |
3045 | | * to "p". |
3046 | | */ |
3047 | | static __isl_give isl_printer *print_unnamed_pw_multi_aff_c( |
3048 | | __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma) |
3049 | 0 | { |
3050 | 0 | int i; |
3051 | 0 | isl_space *space; |
3052 | 0 |
|
3053 | 0 | space = isl_pw_multi_aff_get_domain_space(pma); |
3054 | 0 | for (i = 0; i < pma->n - 1; ++i) { |
3055 | 0 | p = isl_printer_print_str(p, "("); |
3056 | 0 | p = print_set_c(p, space, pma->p[i].set); |
3057 | 0 | p = isl_printer_print_str(p, ") ? ("); |
3058 | 0 | p = print_aff_c(p, pma->p[i].maff->u.p[0]); |
3059 | 0 | p = isl_printer_print_str(p, ") : "); |
3060 | 0 | } |
3061 | 0 | isl_space_free(space); |
3062 | 0 |
|
3063 | 0 | return print_aff_c(p, pma->p[pma->n - 1].maff->u.p[0]); |
3064 | 0 | } |
3065 | | |
3066 | | static __isl_give isl_printer *print_pw_multi_aff_c(__isl_take isl_printer *p, |
3067 | | __isl_keep isl_pw_multi_aff *pma) |
3068 | 0 | { |
3069 | 0 | int n; |
3070 | 0 | const char *name; |
3071 | 0 |
|
3072 | 0 | if (!pma) |
3073 | 0 | goto error; |
3074 | 0 | if (pma->n < 1) |
3075 | 0 | isl_die(p->ctx, isl_error_unsupported, |
3076 | 0 | "cannot print empty isl_pw_multi_aff in C format", |
3077 | 0 | goto error); |
3078 | 0 | name = isl_pw_multi_aff_get_tuple_name(pma, isl_dim_out); |
3079 | 0 | if (!name && isl_pw_multi_aff_dim(pma, isl_dim_out) == 1) |
3080 | 0 | return print_unnamed_pw_multi_aff_c(p, pma); |
3081 | 0 | if (!name) |
3082 | 0 | isl_die(p->ctx, isl_error_unsupported, |
3083 | 0 | "cannot print unnamed isl_pw_multi_aff in C format", |
3084 | 0 | goto error); |
3085 | 0 |
|
3086 | 0 | p = isl_printer_print_str(p, name); |
3087 | 0 | n = isl_pw_multi_aff_dim(pma, isl_dim_out); |
3088 | 0 | if (n != 0) |
3089 | 0 | isl_die(p->ctx, isl_error_unsupported, |
3090 | 0 | "not supported yet", goto error); |
3091 | 0 |
|
3092 | 0 | return p; |
3093 | 0 | error: |
3094 | 0 | isl_printer_free(p); |
3095 | 0 | return NULL; |
3096 | 0 | } |
3097 | | |
3098 | | __isl_give isl_printer *isl_printer_print_pw_multi_aff( |
3099 | | __isl_take isl_printer *p, __isl_keep isl_pw_multi_aff *pma) |
3100 | 540 | { |
3101 | 540 | if (!p || !pma) |
3102 | 0 | goto error; |
3103 | 540 | |
3104 | 540 | if (p->output_format == ISL_FORMAT_ISL) |
3105 | 540 | return print_pw_multi_aff_isl(p, pma); |
3106 | 0 | if (p->output_format == ISL_FORMAT_C) |
3107 | 0 | return print_pw_multi_aff_c(p, pma); |
3108 | 0 | isl_die(p->ctx, isl_error_unsupported, "unsupported output format", |
3109 | 0 | goto error); |
3110 | 0 | error: |
3111 | 0 | isl_printer_free(p); |
3112 | 0 | return NULL; |
3113 | 0 | } |
3114 | | |
3115 | | static isl_stat print_pw_multi_aff_body_wrap(__isl_take isl_pw_multi_aff *pma, |
3116 | | void *user) |
3117 | 0 | { |
3118 | 0 | struct isl_union_print_data *data; |
3119 | 0 | data = (struct isl_union_print_data *) user; |
3120 | 0 |
|
3121 | 0 | if (!data->first) |
3122 | 0 | data->p = isl_printer_print_str(data->p, "; "); |
3123 | 0 | data->first = 0; |
3124 | 0 |
|
3125 | 0 | data->p = print_pw_multi_aff_body(data->p, pma); |
3126 | 0 | isl_pw_multi_aff_free(pma); |
3127 | 0 |
|
3128 | 0 | return isl_stat_ok; |
3129 | 0 | } |
3130 | | |
3131 | | static __isl_give isl_printer *print_union_pw_multi_aff_isl( |
3132 | | __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma) |
3133 | 0 | { |
3134 | 0 | struct isl_union_print_data data; |
3135 | 0 | struct isl_print_space_data space_data = { 0 }; |
3136 | 0 | isl_space *space; |
3137 | 0 |
|
3138 | 0 | space = isl_union_pw_multi_aff_get_space(upma); |
3139 | 0 | p = print_param_tuple(p, space, &space_data); |
3140 | 0 | isl_space_free(space); |
3141 | 0 | p = isl_printer_print_str(p, s_open_set[0]); |
3142 | 0 | data.p = p; |
3143 | 0 | data.first = 1; |
3144 | 0 | isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, |
3145 | 0 | &print_pw_multi_aff_body_wrap, &data); |
3146 | 0 | p = data.p; |
3147 | 0 | p = isl_printer_print_str(p, s_close_set[0]); |
3148 | 0 | return p; |
3149 | 0 | } |
3150 | | |
3151 | | __isl_give isl_printer *isl_printer_print_union_pw_multi_aff( |
3152 | | __isl_take isl_printer *p, __isl_keep isl_union_pw_multi_aff *upma) |
3153 | 0 | { |
3154 | 0 | if (!p || !upma) |
3155 | 0 | goto error; |
3156 | 0 | |
3157 | 0 | if (p->output_format == ISL_FORMAT_ISL) |
3158 | 0 | return print_union_pw_multi_aff_isl(p, upma); |
3159 | 0 | isl_die(p->ctx, isl_error_unsupported, "unsupported output format", |
3160 | 0 | goto error); |
3161 | 0 | error: |
3162 | 0 | isl_printer_free(p); |
3163 | 0 | return NULL; |
3164 | 0 | } |
3165 | | |
3166 | | /* Print dimension "pos" of data->space to "p". |
3167 | | * |
3168 | | * data->user is assumed to be an isl_multi_pw_aff. |
3169 | | * |
3170 | | * If the current dimension is an output dimension, then print |
3171 | | * the corresponding piecewise affine expression. |
3172 | | * Otherwise, print the name of the dimension. |
3173 | | */ |
3174 | | static __isl_give isl_printer *print_dim_mpa(__isl_take isl_printer *p, |
3175 | | struct isl_print_space_data *data, unsigned pos) |
3176 | 26 | { |
3177 | 26 | int i; |
3178 | 26 | int need_parens; |
3179 | 26 | isl_space *space; |
3180 | 26 | isl_multi_pw_aff *mpa = data->user; |
3181 | 26 | isl_pw_aff *pa; |
3182 | 26 | |
3183 | 26 | if (data->type != isl_dim_out) |
3184 | 14 | return print_name(data->space, p, data->type, pos, data->latex); |
3185 | 12 | |
3186 | 12 | pa = mpa->u.p[pos]; |
3187 | 12 | if (pa->n == 0) |
3188 | 0 | return isl_printer_print_str(p, "(0 : false)"); |
3189 | 12 | |
3190 | 12 | need_parens = pa->n != 1 || !isl_set_plain_is_universe(pa->p[0].set); |
3191 | 12 | if (need_parens) |
3192 | 11 | p = isl_printer_print_str(p, "("); |
3193 | 12 | space = isl_multi_pw_aff_get_domain_space(mpa); |
3194 | 24 | for (i = 0; i < pa->n; ++i12 ) { |
3195 | 12 | |
3196 | 12 | if (i) |
3197 | 0 | p = isl_printer_print_str(p, "; "); |
3198 | 12 | p = print_aff_body(p, space, pa->p[i].aff); |
3199 | 12 | p = print_disjuncts(pa->p[i].set, space, p, 0); |
3200 | 12 | } |
3201 | 12 | isl_space_free(space); |
3202 | 12 | if (need_parens) |
3203 | 11 | p = isl_printer_print_str(p, ")"); |
3204 | 12 | |
3205 | 12 | return p; |
3206 | 12 | } |
3207 | | |
3208 | | /* Print "mpa" to "p" in isl format. |
3209 | | * |
3210 | | * If "mpa" is zero-dimensional and has a non-trivial explicit domain, |
3211 | | * then it is printed after the tuple of affine expressions. |
3212 | | */ |
3213 | | static __isl_give isl_printer *print_multi_pw_aff_isl(__isl_take isl_printer *p, |
3214 | | __isl_keep isl_multi_pw_aff *mpa) |
3215 | 14 | { |
3216 | 14 | struct isl_print_space_data data = { 0 }; |
3217 | 14 | isl_bool has_domain; |
3218 | 14 | |
3219 | 14 | if (!mpa) |
3220 | 0 | return isl_printer_free(p); |
3221 | 14 | |
3222 | 14 | p = print_param_tuple(p, mpa->space, &data); |
3223 | 14 | p = isl_printer_print_str(p, "{ "); |
3224 | 14 | data.print_dim = &print_dim_mpa; |
3225 | 14 | data.user = mpa; |
3226 | 14 | p = isl_print_space(mpa->space, p, 0, &data); |
3227 | 14 | has_domain = isl_multi_pw_aff_has_non_trivial_domain(mpa); |
3228 | 14 | if (has_domain < 0) |
3229 | 0 | return isl_printer_free(p); |
3230 | 14 | if (has_domain) { |
3231 | 5 | isl_space *space; |
3232 | 5 | |
3233 | 5 | space = isl_space_domain(isl_space_copy(mpa->space)); |
3234 | 5 | p = print_disjuncts_set(mpa->u.dom, space, p, 0); |
3235 | 5 | isl_space_free(space); |
3236 | 5 | } |
3237 | 14 | p = isl_printer_print_str(p, " }"); |
3238 | 14 | return p; |
3239 | 14 | } |
3240 | | |
3241 | | __isl_give isl_printer *isl_printer_print_multi_pw_aff( |
3242 | | __isl_take isl_printer *p, __isl_keep isl_multi_pw_aff *mpa) |
3243 | 14 | { |
3244 | 14 | if (!p || !mpa) |
3245 | 0 | return isl_printer_free(p); |
3246 | 14 | |
3247 | 14 | if (p->output_format == ISL_FORMAT_ISL) |
3248 | 14 | return print_multi_pw_aff_isl(p, mpa); |
3249 | 0 | isl_die(p->ctx, isl_error_unsupported, "unsupported output format", |
3250 | 0 | return isl_printer_free(p)); |
3251 | 0 | } |
3252 | | |
3253 | | /* Print dimension "pos" of data->space to "p". |
3254 | | * |
3255 | | * data->user is assumed to be an isl_multi_val. |
3256 | | * |
3257 | | * If the current dimension is an output dimension, then print |
3258 | | * the corresponding value. Otherwise, print the name of the dimension. |
3259 | | */ |
3260 | | static __isl_give isl_printer *print_dim_mv(__isl_take isl_printer *p, |
3261 | | struct isl_print_space_data *data, unsigned pos) |
3262 | 0 | { |
3263 | 0 | isl_multi_val *mv = data->user; |
3264 | 0 |
|
3265 | 0 | if (data->type == isl_dim_out) |
3266 | 0 | return isl_printer_print_val(p, mv->u.p[pos]); |
3267 | 0 | else |
3268 | 0 | return print_name(data->space, p, data->type, pos, data->latex); |
3269 | 0 | } |
3270 | | |
3271 | | /* Print the isl_multi_val "mv" to "p" in isl format. |
3272 | | */ |
3273 | | static __isl_give isl_printer *print_multi_val_isl(__isl_take isl_printer *p, |
3274 | | __isl_keep isl_multi_val *mv) |
3275 | 0 | { |
3276 | 0 | struct isl_print_space_data data = { 0 }; |
3277 | 0 |
|
3278 | 0 | if (!mv) |
3279 | 0 | return isl_printer_free(p); |
3280 | 0 | |
3281 | 0 | p = print_param_tuple(p, mv->space, &data); |
3282 | 0 | p = isl_printer_print_str(p, "{ "); |
3283 | 0 | data.print_dim = &print_dim_mv; |
3284 | 0 | data.user = mv; |
3285 | 0 | p = isl_print_space(mv->space, p, 0, &data); |
3286 | 0 | p = isl_printer_print_str(p, " }"); |
3287 | 0 | return p; |
3288 | 0 | } |
3289 | | |
3290 | | /* Print the isl_multi_val "mv" to "p". |
3291 | | * |
3292 | | * Currently only supported in isl format. |
3293 | | */ |
3294 | | __isl_give isl_printer *isl_printer_print_multi_val( |
3295 | | __isl_take isl_printer *p, __isl_keep isl_multi_val *mv) |
3296 | 0 | { |
3297 | 0 | if (!p || !mv) |
3298 | 0 | return isl_printer_free(p); |
3299 | 0 | |
3300 | 0 | if (p->output_format == ISL_FORMAT_ISL) |
3301 | 0 | return print_multi_val_isl(p, mv); |
3302 | 0 | isl_die(p->ctx, isl_error_unsupported, "unsupported output format", |
3303 | 0 | return isl_printer_free(p)); |
3304 | 0 | } |
3305 | | |
3306 | | /* Print dimension "pos" of data->space to "p". |
3307 | | * |
3308 | | * data->user is assumed to be an isl_multi_union_pw_aff. |
3309 | | * |
3310 | | * The current dimension is necessarily a set dimension, so |
3311 | | * we print the corresponding isl_union_pw_aff, including |
3312 | | * the braces. |
3313 | | */ |
3314 | | static __isl_give isl_printer *print_union_pw_aff_dim(__isl_take isl_printer *p, |
3315 | | struct isl_print_space_data *data, unsigned pos) |
3316 | 2 | { |
3317 | 2 | isl_multi_union_pw_aff *mupa = data->user; |
3318 | 2 | isl_union_pw_aff *upa; |
3319 | 2 | |
3320 | 2 | upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, pos); |
3321 | 2 | p = print_union_pw_aff_body(p, upa); |
3322 | 2 | isl_union_pw_aff_free(upa); |
3323 | 2 | |
3324 | 2 | return p; |
3325 | 2 | } |
3326 | | |
3327 | | /* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format. |
3328 | | * |
3329 | | * If "mupa" is zero-dimensional and has a non-trivial explicit domain, |
3330 | | * then it is printed after the tuple of affine expressions. |
3331 | | * In order to clarify that this domain belongs to the expression, |
3332 | | * the tuple along with the domain are placed inside parentheses. |
3333 | | * If "mupa" has any parameters, then the opening parenthesis |
3334 | | * appears after the parameter declarations. |
3335 | | */ |
3336 | | static __isl_give isl_printer *print_multi_union_pw_aff_isl( |
3337 | | __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa) |
3338 | 13 | { |
3339 | 13 | struct isl_print_space_data data = { 0 }; |
3340 | 13 | isl_bool has_domain; |
3341 | 13 | isl_space *space; |
3342 | 13 | |
3343 | 13 | if (!mupa) |
3344 | 0 | return isl_printer_free(p); |
3345 | 13 | has_domain = isl_multi_union_pw_aff_has_non_trivial_domain(mupa); |
3346 | 13 | if (has_domain < 0) |
3347 | 0 | return isl_printer_free(p); |
3348 | 13 | |
3349 | 13 | space = isl_multi_union_pw_aff_get_space(mupa); |
3350 | 13 | p = print_param_tuple(p, space, &data); |
3351 | 13 | |
3352 | 13 | if (has_domain) |
3353 | 7 | p = isl_printer_print_str(p, "("); |
3354 | 13 | |
3355 | 13 | data.print_dim = &print_union_pw_aff_dim; |
3356 | 13 | data.user = mupa; |
3357 | 13 | |
3358 | 13 | p = isl_print_space(space, p, 0, &data); |
3359 | 13 | isl_space_free(space); |
3360 | 13 | |
3361 | 13 | if (has_domain) { |
3362 | 7 | p = isl_printer_print_str(p, " : "); |
3363 | 7 | p = isl_printer_print_union_set_isl_body(p, mupa->u.dom); |
3364 | 7 | p = isl_printer_print_str(p, ")"); |
3365 | 7 | } |
3366 | 13 | |
3367 | 13 | return p; |
3368 | 13 | } |
3369 | | |
3370 | | /* Print the isl_multi_union_pw_aff "mupa" to "p" in isl format. |
3371 | | * |
3372 | | * We currently only support an isl format. |
3373 | | */ |
3374 | | __isl_give isl_printer *isl_printer_print_multi_union_pw_aff( |
3375 | | __isl_take isl_printer *p, __isl_keep isl_multi_union_pw_aff *mupa) |
3376 | 13 | { |
3377 | 13 | if (!p || !mupa) |
3378 | 0 | return isl_printer_free(p); |
3379 | 13 | |
3380 | 13 | if (p->output_format == ISL_FORMAT_ISL) |
3381 | 13 | return print_multi_union_pw_aff_isl(p, mupa); |
3382 | 0 | isl_die(isl_printer_get_ctx(p), isl_error_unsupported, |
3383 | 0 | "unsupported output format", return isl_printer_free(p)); |
3384 | 0 | } |