/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/polly/lib/External/isl/isl_val.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2013 Ecole Normale Superieure |
3 | | * |
4 | | * Use of this software is governed by the MIT license |
5 | | * |
6 | | * Written by Sven Verdoolaege, |
7 | | * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France |
8 | | */ |
9 | | |
10 | | #include <isl_int.h> |
11 | | #include <isl_ctx_private.h> |
12 | | #include <isl_val_private.h> |
13 | | |
14 | | #undef BASE |
15 | | #define BASE val |
16 | | |
17 | | #include <isl_list_templ.c> |
18 | | |
19 | | /* Allocate an isl_val object with indeterminate value. |
20 | | */ |
21 | | __isl_give isl_val *isl_val_alloc(isl_ctx *ctx) |
22 | 177k | { |
23 | 177k | isl_val *v; |
24 | 177k | |
25 | 177k | v = isl_alloc_type(ctx, struct isl_val); |
26 | 177k | if (!v) |
27 | 0 | return NULL; |
28 | 177k | |
29 | 177k | v->ctx = ctx; |
30 | 177k | isl_ctx_ref(ctx); |
31 | 177k | v->ref = 1; |
32 | 177k | isl_int_init(v->n); |
33 | 177k | isl_int_init(v->d); |
34 | 177k | |
35 | 177k | return v; |
36 | 177k | } |
37 | | |
38 | | /* Return a reference to an isl_val representing zero. |
39 | | */ |
40 | | __isl_give isl_val *isl_val_zero(isl_ctx *ctx) |
41 | 10.1k | { |
42 | 10.1k | return isl_val_int_from_si(ctx, 0); |
43 | 10.1k | } |
44 | | |
45 | | /* Return a reference to an isl_val representing one. |
46 | | */ |
47 | | __isl_give isl_val *isl_val_one(isl_ctx *ctx) |
48 | 6.26k | { |
49 | 6.26k | return isl_val_int_from_si(ctx, 1); |
50 | 6.26k | } |
51 | | |
52 | | /* Return a reference to an isl_val representing negative one. |
53 | | */ |
54 | | __isl_give isl_val *isl_val_negone(isl_ctx *ctx) |
55 | 0 | { |
56 | 0 | return isl_val_int_from_si(ctx, -1); |
57 | 0 | } |
58 | | |
59 | | /* Return a reference to an isl_val representing NaN. |
60 | | */ |
61 | | __isl_give isl_val *isl_val_nan(isl_ctx *ctx) |
62 | 1.08k | { |
63 | 1.08k | isl_val *v; |
64 | 1.08k | |
65 | 1.08k | v = isl_val_alloc(ctx); |
66 | 1.08k | if (!v) |
67 | 0 | return NULL; |
68 | 1.08k | |
69 | 1.08k | isl_int_set_si(v->n, 0); |
70 | 1.08k | isl_int_set_si(v->d, 0); |
71 | 1.08k | |
72 | 1.08k | return v; |
73 | 1.08k | } |
74 | | |
75 | | /* Change "v" into a NaN. |
76 | | */ |
77 | | __isl_give isl_val *isl_val_set_nan(__isl_take isl_val *v) |
78 | 13 | { |
79 | 13 | if (!v) |
80 | 0 | return NULL; |
81 | 13 | if (isl_val_is_nan(v)) |
82 | 0 | return v; |
83 | 13 | v = isl_val_cow(v); |
84 | 13 | if (!v) |
85 | 0 | return NULL; |
86 | 13 | |
87 | 13 | isl_int_set_si(v->n, 0); |
88 | 13 | isl_int_set_si(v->d, 0); |
89 | 13 | |
90 | 13 | return v; |
91 | 13 | } |
92 | | |
93 | | /* Return a reference to an isl_val representing +infinity. |
94 | | */ |
95 | | __isl_give isl_val *isl_val_infty(isl_ctx *ctx) |
96 | 254 | { |
97 | 254 | isl_val *v; |
98 | 254 | |
99 | 254 | v = isl_val_alloc(ctx); |
100 | 254 | if (!v) |
101 | 0 | return NULL; |
102 | 254 | |
103 | 254 | isl_int_set_si(v->n, 1); |
104 | 254 | isl_int_set_si(v->d, 0); |
105 | 254 | |
106 | 254 | return v; |
107 | 254 | } |
108 | | |
109 | | /* Return a reference to an isl_val representing -infinity. |
110 | | */ |
111 | | __isl_give isl_val *isl_val_neginfty(isl_ctx *ctx) |
112 | 32 | { |
113 | 32 | isl_val *v; |
114 | 32 | |
115 | 32 | v = isl_val_alloc(ctx); |
116 | 32 | if (!v) |
117 | 0 | return NULL; |
118 | 32 | |
119 | 32 | isl_int_set_si(v->n, -1); |
120 | 32 | isl_int_set_si(v->d, 0); |
121 | 32 | |
122 | 32 | return v; |
123 | 32 | } |
124 | | |
125 | | /* Return a reference to an isl_val representing the integer "i". |
126 | | */ |
127 | | __isl_give isl_val *isl_val_int_from_si(isl_ctx *ctx, long i) |
128 | 38.0k | { |
129 | 38.0k | isl_val *v; |
130 | 38.0k | |
131 | 38.0k | v = isl_val_alloc(ctx); |
132 | 38.0k | if (!v) |
133 | 0 | return NULL; |
134 | 38.0k | |
135 | 38.0k | isl_int_set_si(v->n, i); |
136 | 38.0k | isl_int_set_si(v->d, 1); |
137 | 38.0k | |
138 | 38.0k | return v; |
139 | 38.0k | } |
140 | | |
141 | | /* Change the value of "v" to be equal to the integer "i". |
142 | | */ |
143 | | __isl_give isl_val *isl_val_set_si(__isl_take isl_val *v, long i) |
144 | 6 | { |
145 | 6 | if (!v) |
146 | 0 | return NULL; |
147 | 6 | if (isl_val_is_int(v) && isl_int_cmp_si(v->n, i) == 0) |
148 | 0 | return v; |
149 | 6 | v = isl_val_cow(v); |
150 | 6 | if (!v) |
151 | 0 | return NULL; |
152 | 6 | |
153 | 6 | isl_int_set_si(v->n, i); |
154 | 6 | isl_int_set_si(v->d, 1); |
155 | 6 | |
156 | 6 | return v; |
157 | 6 | } |
158 | | |
159 | | /* Change the value of "v" to be equal to zero. |
160 | | */ |
161 | | __isl_give isl_val *isl_val_set_zero(__isl_take isl_val *v) |
162 | 4 | { |
163 | 4 | return isl_val_set_si(v, 0); |
164 | 4 | } |
165 | | |
166 | | /* Return a reference to an isl_val representing the unsigned integer "u". |
167 | | */ |
168 | | __isl_give isl_val *isl_val_int_from_ui(isl_ctx *ctx, unsigned long u) |
169 | 6.42k | { |
170 | 6.42k | isl_val *v; |
171 | 6.42k | |
172 | 6.42k | v = isl_val_alloc(ctx); |
173 | 6.42k | if (!v) |
174 | 0 | return NULL; |
175 | 6.42k | |
176 | 6.42k | isl_int_set_ui(v->n, u); |
177 | 6.42k | isl_int_set_si(v->d, 1); |
178 | 6.42k | |
179 | 6.42k | return v; |
180 | 6.42k | } |
181 | | |
182 | | /* Return a reference to an isl_val representing the integer "n". |
183 | | */ |
184 | | __isl_give isl_val *isl_val_int_from_isl_int(isl_ctx *ctx, isl_int n) |
185 | 28.2k | { |
186 | 28.2k | isl_val *v; |
187 | 28.2k | |
188 | 28.2k | v = isl_val_alloc(ctx); |
189 | 28.2k | if (!v) |
190 | 0 | return NULL; |
191 | 28.2k | |
192 | 28.2k | isl_int_set(v->n, n); |
193 | 28.2k | isl_int_set_si(v->d, 1); |
194 | 28.2k | |
195 | 28.2k | return v; |
196 | 28.2k | } |
197 | | |
198 | | /* Return a reference to an isl_val representing the rational value "n"/"d". |
199 | | * Normalizing the isl_val (if needed) is left to the caller. |
200 | | */ |
201 | | __isl_give isl_val *isl_val_rat_from_isl_int(isl_ctx *ctx, |
202 | | isl_int n, isl_int d) |
203 | 64.1k | { |
204 | 64.1k | isl_val *v; |
205 | 64.1k | |
206 | 64.1k | v = isl_val_alloc(ctx); |
207 | 64.1k | if (!v) |
208 | 0 | return NULL; |
209 | 64.1k | |
210 | 64.1k | isl_int_set(v->n, n); |
211 | 64.1k | isl_int_set(v->d, d); |
212 | 64.1k | |
213 | 64.1k | return v; |
214 | 64.1k | } |
215 | | |
216 | | /* Return a new reference to "v". |
217 | | */ |
218 | | __isl_give isl_val *isl_val_copy(__isl_keep isl_val *v) |
219 | 68.7k | { |
220 | 68.7k | if (!v) |
221 | 0 | return NULL; |
222 | 68.7k | |
223 | 68.7k | v->ref++; |
224 | 68.7k | return v; |
225 | 68.7k | } |
226 | | |
227 | | /* Return a fresh copy of "val". |
228 | | */ |
229 | | __isl_give isl_val *isl_val_dup(__isl_keep isl_val *val) |
230 | 13.8k | { |
231 | 13.8k | isl_val *dup; |
232 | 13.8k | |
233 | 13.8k | if (!val) |
234 | 0 | return NULL; |
235 | 13.8k | |
236 | 13.8k | dup = isl_val_alloc(isl_val_get_ctx(val)); |
237 | 13.8k | if (!dup) |
238 | 0 | return NULL; |
239 | 13.8k | |
240 | 13.8k | isl_int_set(dup->n, val->n); |
241 | 13.8k | isl_int_set(dup->d, val->d); |
242 | 13.8k | |
243 | 13.8k | return dup; |
244 | 13.8k | } |
245 | | |
246 | | /* Return an isl_val that is equal to "val" and that has only |
247 | | * a single reference. |
248 | | */ |
249 | | __isl_give isl_val *isl_val_cow(__isl_take isl_val *val) |
250 | 20.6k | { |
251 | 20.6k | if (!val) |
252 | 0 | return NULL; |
253 | 20.6k | |
254 | 20.6k | if (val->ref == 1) |
255 | 6.87k | return val; |
256 | 13.8k | val->ref--; |
257 | 13.8k | return isl_val_dup(val); |
258 | 13.8k | } |
259 | | |
260 | | /* Free "v" and return NULL. |
261 | | */ |
262 | | __isl_null isl_val *isl_val_free(__isl_take isl_val *v) |
263 | 240k | { |
264 | 240k | if (!v) |
265 | 8.54k | return NULL; |
266 | 232k | |
267 | 232k | if (--v->ref > 0) |
268 | 54.9k | return NULL; |
269 | 177k | |
270 | 177k | isl_ctx_deref(v->ctx); |
271 | 177k | isl_int_clear(v->n); |
272 | 177k | isl_int_clear(v->d); |
273 | 177k | free(v); |
274 | 177k | return NULL; |
275 | 177k | } |
276 | | |
277 | | /* Extract the numerator of a rational value "v" as an integer. |
278 | | * |
279 | | * If "v" is not a rational value, then the result is undefined. |
280 | | */ |
281 | | long isl_val_get_num_si(__isl_keep isl_val *v) |
282 | 2.50k | { |
283 | 2.50k | if (!v) |
284 | 0 | return 0; |
285 | 2.50k | if (!isl_val_is_rat(v)) |
286 | 2.50k | isl_die0 (isl_val_get_ctx(v), isl_error_invalid, |
287 | 2.50k | "expecting rational value", return 0); |
288 | 2.50k | if (!isl_int_fits_slong(v->n)) |
289 | 2.50k | isl_die0 (isl_val_get_ctx(v), isl_error_invalid, |
290 | 2.50k | "numerator too large", return 0); |
291 | 2.50k | return isl_int_get_si(v->n); |
292 | 2.50k | } |
293 | | |
294 | | /* Extract the numerator of a rational value "v" as an isl_int. |
295 | | * |
296 | | * If "v" is not a rational value, then the result is undefined. |
297 | | */ |
298 | | int isl_val_get_num_isl_int(__isl_keep isl_val *v, isl_int *n) |
299 | 3 | { |
300 | 3 | if (!v) |
301 | 0 | return -1; |
302 | 3 | if (!isl_val_is_rat(v)) |
303 | 3 | isl_die0 (isl_val_get_ctx(v), isl_error_invalid, |
304 | 3 | "expecting rational value", return -1); |
305 | 3 | isl_int_set(*n, v->n); |
306 | 3 | return 0; |
307 | 3 | } |
308 | | |
309 | | /* Extract the denominator of a rational value "v" as an integer. |
310 | | * |
311 | | * If "v" is not a rational value, then the result is undefined. |
312 | | */ |
313 | | long isl_val_get_den_si(__isl_keep isl_val *v) |
314 | 0 | { |
315 | 0 | if (!v) |
316 | 0 | return 0; |
317 | 0 | if (!isl_val_is_rat(v)) |
318 | 0 | isl_die(isl_val_get_ctx(v), isl_error_invalid, |
319 | 0 | "expecting rational value", return 0); |
320 | 0 | if (!isl_int_fits_slong(v->d)) |
321 | 0 | isl_die(isl_val_get_ctx(v), isl_error_invalid, |
322 | 0 | "denominator too large", return 0); |
323 | 0 | return isl_int_get_si(v->d); |
324 | 0 | } |
325 | | |
326 | | /* Extract the denominator of a rational value "v" as an isl_val. |
327 | | * |
328 | | * If "v" is not a rational value, then the result is undefined. |
329 | | */ |
330 | | __isl_give isl_val *isl_val_get_den_val(__isl_keep isl_val *v) |
331 | 0 | { |
332 | 0 | if (!v) |
333 | 0 | return NULL; |
334 | 0 | if (!isl_val_is_rat(v)) |
335 | 0 | isl_die(isl_val_get_ctx(v), isl_error_invalid, |
336 | 0 | "expecting rational value", return NULL); |
337 | 0 | return isl_val_int_from_isl_int(isl_val_get_ctx(v), v->d); |
338 | 0 | } |
339 | | |
340 | | /* Return an approximation of "v" as a double. |
341 | | */ |
342 | | double isl_val_get_d(__isl_keep isl_val *v) |
343 | 0 | { |
344 | 0 | if (!v) |
345 | 0 | return 0; |
346 | 0 | if (!isl_val_is_rat(v)) |
347 | 0 | isl_die(isl_val_get_ctx(v), isl_error_invalid, |
348 | 0 | "expecting rational value", return 0); |
349 | 0 | return isl_int_get_d(v->n) / isl_int_get_d(v->d); |
350 | 0 | } |
351 | | |
352 | | /* Return the isl_ctx to which "val" belongs. |
353 | | */ |
354 | | isl_ctx *isl_val_get_ctx(__isl_keep isl_val *val) |
355 | 30.3k | { |
356 | 30.3k | return val ? val->ctx : NULL; |
357 | 30.3k | } |
358 | | |
359 | | /* Return a hash value that digests "val". |
360 | | */ |
361 | | uint32_t isl_val_get_hash(__isl_keep isl_val *val) |
362 | 0 | { |
363 | 0 | uint32_t hash; |
364 | 0 |
|
365 | 0 | if (!val) |
366 | 0 | return 0; |
367 | 0 | |
368 | 0 | hash = isl_hash_init(); |
369 | 0 | hash = isl_int_hash(val->n, hash); |
370 | 0 | hash = isl_int_hash(val->d, hash); |
371 | 0 |
|
372 | 0 | return hash; |
373 | 0 | } |
374 | | |
375 | | /* Normalize "v". |
376 | | * |
377 | | * In particular, make sure that the denominator of a rational value |
378 | | * is positive and the numerator and denominator do not have any |
379 | | * common divisors. |
380 | | * |
381 | | * This function should not be called by an external user |
382 | | * since it will only be given normalized values. |
383 | | */ |
384 | | __isl_give isl_val *isl_val_normalize(__isl_take isl_val *v) |
385 | 72.2k | { |
386 | 72.2k | isl_ctx *ctx; |
387 | 72.2k | |
388 | 72.2k | if (!v) |
389 | 0 | return NULL; |
390 | 72.2k | if (isl_val_is_int(v)) |
391 | 72.0k | return v; |
392 | 192 | if (!isl_val_is_rat(v)) |
393 | 0 | return v; |
394 | 192 | if (isl_int_is_neg(v->d)) { |
395 | 4 | isl_int_neg(v->d, v->d); |
396 | 4 | isl_int_neg(v->n, v->n); |
397 | 4 | } |
398 | 192 | ctx = isl_val_get_ctx(v); |
399 | 192 | isl_int_gcd(ctx->normalize_gcd, v->n, v->d); |
400 | 192 | if (isl_int_is_one(ctx->normalize_gcd)) |
401 | 192 | return v91 ; |
402 | 101 | isl_int_divexact(v->n, v->n, ctx->normalize_gcd); |
403 | 101 | isl_int_divexact(v->d, v->d, ctx->normalize_gcd); |
404 | 101 | return v; |
405 | 101 | } |
406 | | |
407 | | /* Return the opposite of "v". |
408 | | */ |
409 | | __isl_give isl_val *isl_val_neg(__isl_take isl_val *v) |
410 | 3.52k | { |
411 | 3.52k | if (!v) |
412 | 0 | return NULL; |
413 | 3.52k | if (isl_val_is_nan(v)) |
414 | 1 | return v; |
415 | 3.52k | if (isl_val_is_zero(v)) |
416 | 210 | return v; |
417 | 3.31k | |
418 | 3.31k | v = isl_val_cow(v); |
419 | 3.31k | if (!v) |
420 | 0 | return NULL; |
421 | 3.31k | isl_int_neg(v->n, v->n); |
422 | 3.31k | |
423 | 3.31k | return v; |
424 | 3.31k | } |
425 | | |
426 | | /* Return the inverse of "v". |
427 | | */ |
428 | | __isl_give isl_val *isl_val_inv(__isl_take isl_val *v) |
429 | 9 | { |
430 | 9 | if (!v) |
431 | 0 | return NULL; |
432 | 9 | if (isl_val_is_nan(v)) |
433 | 1 | return v; |
434 | 8 | if (isl_val_is_zero(v)) { |
435 | 1 | isl_ctx *ctx = isl_val_get_ctx(v); |
436 | 1 | isl_val_free(v); |
437 | 1 | return isl_val_nan(ctx); |
438 | 1 | } |
439 | 7 | if (isl_val_is_infty(v) || isl_val_is_neginfty(v)6 ) { |
440 | 2 | isl_ctx *ctx = isl_val_get_ctx(v); |
441 | 2 | isl_val_free(v); |
442 | 2 | return isl_val_zero(ctx); |
443 | 2 | } |
444 | 5 | |
445 | 5 | v = isl_val_cow(v); |
446 | 5 | if (!v) |
447 | 0 | return NULL; |
448 | 5 | isl_int_swap(v->n, v->d); |
449 | 5 | |
450 | 5 | return isl_val_normalize(v); |
451 | 5 | } |
452 | | |
453 | | /* Return the absolute value of "v". |
454 | | */ |
455 | | __isl_give isl_val *isl_val_abs(__isl_take isl_val *v) |
456 | 958 | { |
457 | 958 | if (!v) |
458 | 0 | return NULL; |
459 | 958 | if (isl_val_is_nan(v)) |
460 | 1 | return v; |
461 | 957 | if (isl_val_is_nonneg(v)) |
462 | 622 | return v; |
463 | 335 | return isl_val_neg(v); |
464 | 335 | } |
465 | | |
466 | | /* Return the "floor" (greatest integer part) of "v". |
467 | | * That is, return the result of rounding towards -infinity. |
468 | | */ |
469 | | __isl_give isl_val *isl_val_floor(__isl_take isl_val *v) |
470 | 12 | { |
471 | 12 | if (!v) |
472 | 0 | return NULL; |
473 | 12 | if (isl_val_is_int(v)) |
474 | 3 | return v; |
475 | 9 | if (!isl_val_is_rat(v)) |
476 | 3 | return v; |
477 | 6 | |
478 | 6 | v = isl_val_cow(v); |
479 | 6 | if (!v) |
480 | 0 | return NULL; |
481 | 6 | isl_int_fdiv_q(v->n, v->n, v->d); |
482 | 6 | isl_int_set_si(v->d, 1); |
483 | 6 | |
484 | 6 | return v; |
485 | 6 | } |
486 | | |
487 | | /* Return the "ceiling" of "v". |
488 | | * That is, return the result of rounding towards +infinity. |
489 | | */ |
490 | | __isl_give isl_val *isl_val_ceil(__isl_take isl_val *v) |
491 | 64 | { |
492 | 64 | if (!v) |
493 | 0 | return NULL; |
494 | 64 | if (isl_val_is_int(v)) |
495 | 40 | return v; |
496 | 24 | if (!isl_val_is_rat(v)) |
497 | 3 | return v; |
498 | 21 | |
499 | 21 | v = isl_val_cow(v); |
500 | 21 | if (!v) |
501 | 0 | return NULL; |
502 | 21 | isl_int_cdiv_q(v->n, v->n, v->d); |
503 | 21 | isl_int_set_si(v->d, 1); |
504 | 21 | |
505 | 21 | return v; |
506 | 21 | } |
507 | | |
508 | | /* Truncate "v". |
509 | | * That is, return the result of rounding towards zero. |
510 | | */ |
511 | | __isl_give isl_val *isl_val_trunc(__isl_take isl_val *v) |
512 | 0 | { |
513 | 0 | if (!v) |
514 | 0 | return NULL; |
515 | 0 | if (isl_val_is_int(v)) |
516 | 0 | return v; |
517 | 0 | if (!isl_val_is_rat(v)) |
518 | 0 | return v; |
519 | 0 | |
520 | 0 | v = isl_val_cow(v); |
521 | 0 | if (!v) |
522 | 0 | return NULL; |
523 | 0 | isl_int_tdiv_q(v->n, v->n, v->d); |
524 | 0 | isl_int_set_si(v->d, 1); |
525 | 0 |
|
526 | 0 | return v; |
527 | 0 | } |
528 | | |
529 | | /* Return 2^v, where v is an integer (that is not too large). |
530 | | */ |
531 | | __isl_give isl_val *isl_val_2exp(__isl_take isl_val *v) |
532 | 6.09k | { |
533 | 6.09k | unsigned long exp; |
534 | 6.09k | int neg; |
535 | 6.09k | |
536 | 6.09k | v = isl_val_cow(v); |
537 | 6.09k | if (!v) |
538 | 0 | return NULL; |
539 | 6.09k | if (!isl_val_is_int(v)) |
540 | 6.09k | isl_die0 (isl_val_get_ctx(v), isl_error_invalid, |
541 | 6.09k | "can only compute integer powers", |
542 | 6.09k | return isl_val_free(v)); |
543 | 6.09k | neg = isl_val_is_neg(v); |
544 | 6.09k | if (neg) |
545 | 6.09k | isl_int_neg2 (v->n, v->n); |
546 | 6.09k | if (!isl_int_fits_ulong(v->n)) |
547 | 6.09k | isl_die0 (isl_val_get_ctx(v), isl_error_invalid, |
548 | 6.09k | "exponent too large", return isl_val_free(v)); |
549 | 6.09k | exp = isl_int_get_ui(v->n); |
550 | 6.09k | if (neg) { |
551 | 2 | isl_int_mul_2exp(v->d, v->d, exp); |
552 | 2 | isl_int_set_si(v->n, 1); |
553 | 6.09k | } else { |
554 | 6.09k | isl_int_mul_2exp(v->n, v->d, exp); |
555 | 6.09k | } |
556 | 6.09k | |
557 | 6.09k | return v; |
558 | 6.09k | } |
559 | | |
560 | | /* Return the minimum of "v1" and "v2". |
561 | | */ |
562 | | __isl_give isl_val *isl_val_min(__isl_take isl_val *v1, __isl_take isl_val *v2) |
563 | 6 | { |
564 | 6 | if (!v1 || !v2) |
565 | 0 | goto error; |
566 | 6 | |
567 | 6 | if (isl_val_is_nan(v1)) { |
568 | 0 | isl_val_free(v2); |
569 | 0 | return v1; |
570 | 0 | } |
571 | 6 | if (isl_val_is_nan(v2)) { |
572 | 1 | isl_val_free(v1); |
573 | 1 | return v2; |
574 | 1 | } |
575 | 5 | if (isl_val_le(v1, v2)) { |
576 | 2 | isl_val_free(v2); |
577 | 2 | return v1; |
578 | 3 | } else { |
579 | 3 | isl_val_free(v1); |
580 | 3 | return v2; |
581 | 3 | } |
582 | 0 | error: |
583 | 0 | isl_val_free(v1); |
584 | 0 | isl_val_free(v2); |
585 | 0 | return NULL; |
586 | 5 | } |
587 | | |
588 | | /* Return the maximum of "v1" and "v2". |
589 | | */ |
590 | | __isl_give isl_val *isl_val_max(__isl_take isl_val *v1, __isl_take isl_val *v2) |
591 | 6 | { |
592 | 6 | if (!v1 || !v2) |
593 | 0 | goto error; |
594 | 6 | |
595 | 6 | if (isl_val_is_nan(v1)) { |
596 | 0 | isl_val_free(v2); |
597 | 0 | return v1; |
598 | 0 | } |
599 | 6 | if (isl_val_is_nan(v2)) { |
600 | 1 | isl_val_free(v1); |
601 | 1 | return v2; |
602 | 1 | } |
603 | 5 | if (isl_val_ge(v1, v2)) { |
604 | 3 | isl_val_free(v2); |
605 | 3 | return v1; |
606 | 3 | } else { |
607 | 2 | isl_val_free(v1); |
608 | 2 | return v2; |
609 | 2 | } |
610 | 0 | error: |
611 | 0 | isl_val_free(v1); |
612 | 0 | isl_val_free(v2); |
613 | 0 | return NULL; |
614 | 5 | } |
615 | | |
616 | | /* Return the sum of "v1" and "v2". |
617 | | */ |
618 | | __isl_give isl_val *isl_val_add(__isl_take isl_val *v1, __isl_take isl_val *v2) |
619 | 495 | { |
620 | 495 | if (!v1 || !v2) |
621 | 0 | goto error; |
622 | 495 | if (isl_val_is_nan(v1)) { |
623 | 0 | isl_val_free(v2); |
624 | 0 | return v1; |
625 | 0 | } |
626 | 495 | if (isl_val_is_nan(v2)) { |
627 | 0 | isl_val_free(v1); |
628 | 0 | return v2; |
629 | 0 | } |
630 | 495 | if ((isl_val_is_infty(v1) && isl_val_is_neginfty(v2)3 ) || |
631 | 495 | (494 isl_val_is_neginfty(v1)494 && isl_val_is_infty(v2)0 )) { |
632 | 1 | isl_val_free(v2); |
633 | 1 | return isl_val_set_nan(v1); |
634 | 1 | } |
635 | 494 | if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)492 ) { |
636 | 2 | isl_val_free(v2); |
637 | 2 | return v1; |
638 | 2 | } |
639 | 492 | if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)491 ) { |
640 | 1 | isl_val_free(v1); |
641 | 1 | return v2; |
642 | 1 | } |
643 | 491 | if (isl_val_is_zero(v1)) { |
644 | 384 | isl_val_free(v1); |
645 | 384 | return v2; |
646 | 384 | } |
647 | 107 | if (isl_val_is_zero(v2)) { |
648 | 3 | isl_val_free(v2); |
649 | 3 | return v1; |
650 | 3 | } |
651 | 104 | |
652 | 104 | v1 = isl_val_cow(v1); |
653 | 104 | if (!v1) |
654 | 0 | goto error; |
655 | 104 | if (isl_val_is_int(v1) && isl_val_is_int(v2)102 ) |
656 | 104 | isl_int_add102 (v1->n, v1->n, v2->n); |
657 | 104 | else { |
658 | 2 | if (isl_int_eq(v1->d, v2->d)) |
659 | 2 | isl_int_add1 (v1->n, v1->n, v2->n); |
660 | 2 | else { |
661 | 1 | isl_int_mul(v1->n, v1->n, v2->d); |
662 | 1 | isl_int_addmul(v1->n, v2->n, v1->d); |
663 | 1 | isl_int_mul(v1->d, v1->d, v2->d); |
664 | 1 | } |
665 | 2 | v1 = isl_val_normalize(v1); |
666 | 2 | } |
667 | 104 | isl_val_free(v2); |
668 | 104 | return v1; |
669 | 0 | error: |
670 | 0 | isl_val_free(v1); |
671 | 0 | isl_val_free(v2); |
672 | 0 | return NULL; |
673 | 104 | } |
674 | | |
675 | | /* Return the sum of "v1" and "v2". |
676 | | */ |
677 | | __isl_give isl_val *isl_val_add_ui(__isl_take isl_val *v1, unsigned long v2) |
678 | 5.34k | { |
679 | 5.34k | if (!v1) |
680 | 0 | return NULL; |
681 | 5.34k | if (!isl_val_is_rat(v1)) |
682 | 0 | return v1; |
683 | 5.34k | if (v2 == 0) |
684 | 0 | return v1; |
685 | 5.34k | v1 = isl_val_cow(v1); |
686 | 5.34k | if (!v1) |
687 | 0 | return NULL; |
688 | 5.34k | |
689 | 5.34k | isl_int_addmul_ui(v1->n, v1->d, v2); |
690 | 5.34k | |
691 | 5.34k | return v1; |
692 | 5.34k | } |
693 | | |
694 | | /* Subtract "v2" from "v1". |
695 | | */ |
696 | | __isl_give isl_val *isl_val_sub(__isl_take isl_val *v1, __isl_take isl_val *v2) |
697 | 165 | { |
698 | 165 | if (!v1 || !v2) |
699 | 0 | goto error; |
700 | 165 | if (isl_val_is_nan(v1)) { |
701 | 0 | isl_val_free(v2); |
702 | 0 | return v1; |
703 | 0 | } |
704 | 165 | if (isl_val_is_nan(v2)) { |
705 | 0 | isl_val_free(v1); |
706 | 0 | return v2; |
707 | 0 | } |
708 | 165 | if ((isl_val_is_infty(v1) && isl_val_is_infty(v2)1 ) || |
709 | 165 | (164 isl_val_is_neginfty(v1)164 && isl_val_is_neginfty(v2)0 )) { |
710 | 1 | isl_val_free(v2); |
711 | 1 | return isl_val_set_nan(v1); |
712 | 1 | } |
713 | 164 | if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) { |
714 | 0 | isl_val_free(v2); |
715 | 0 | return v1; |
716 | 0 | } |
717 | 164 | if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)163 ) { |
718 | 1 | isl_val_free(v1); |
719 | 1 | return isl_val_neg(v2); |
720 | 1 | } |
721 | 163 | if (isl_val_is_zero(v2)) { |
722 | 113 | isl_val_free(v2); |
723 | 113 | return v1; |
724 | 113 | } |
725 | 50 | if (isl_val_is_zero(v1)) { |
726 | 0 | isl_val_free(v1); |
727 | 0 | return isl_val_neg(v2); |
728 | 0 | } |
729 | 50 | |
730 | 50 | v1 = isl_val_cow(v1); |
731 | 50 | if (!v1) |
732 | 0 | goto error; |
733 | 50 | if (isl_val_is_int(v1) && isl_val_is_int(v2)48 ) |
734 | 50 | isl_int_sub47 (v1->n, v1->n, v2->n); |
735 | 50 | else { |
736 | 3 | if (isl_int_eq(v1->d, v2->d)) |
737 | 3 | isl_int_sub1 (v1->n, v1->n, v2->n); |
738 | 3 | else { |
739 | 2 | isl_int_mul(v1->n, v1->n, v2->d); |
740 | 2 | isl_int_submul(v1->n, v2->n, v1->d); |
741 | 2 | isl_int_mul(v1->d, v1->d, v2->d); |
742 | 2 | } |
743 | 3 | v1 = isl_val_normalize(v1); |
744 | 3 | } |
745 | 50 | isl_val_free(v2); |
746 | 50 | return v1; |
747 | 0 | error: |
748 | 0 | isl_val_free(v1); |
749 | 0 | isl_val_free(v2); |
750 | 0 | return NULL; |
751 | 50 | } |
752 | | |
753 | | /* Subtract "v2" from "v1". |
754 | | */ |
755 | | __isl_give isl_val *isl_val_sub_ui(__isl_take isl_val *v1, unsigned long v2) |
756 | 184 | { |
757 | 184 | if (!v1) |
758 | 0 | return NULL; |
759 | 184 | if (!isl_val_is_rat(v1)) |
760 | 0 | return v1; |
761 | 184 | if (v2 == 0) |
762 | 0 | return v1; |
763 | 184 | v1 = isl_val_cow(v1); |
764 | 184 | if (!v1) |
765 | 0 | return NULL; |
766 | 184 | |
767 | 184 | isl_int_submul_ui(v1->n, v1->d, v2); |
768 | 184 | |
769 | 184 | return v1; |
770 | 184 | } |
771 | | |
772 | | /* Return the product of "v1" and "v2". |
773 | | */ |
774 | | __isl_give isl_val *isl_val_mul(__isl_take isl_val *v1, __isl_take isl_val *v2) |
775 | 17 | { |
776 | 17 | if (!v1 || !v2) |
777 | 0 | goto error; |
778 | 17 | if (isl_val_is_nan(v1)) { |
779 | 0 | isl_val_free(v2); |
780 | 0 | return v1; |
781 | 0 | } |
782 | 17 | if (isl_val_is_nan(v2)) { |
783 | 0 | isl_val_free(v1); |
784 | 0 | return v2; |
785 | 0 | } |
786 | 17 | if ((!isl_val_is_rat(v1) && isl_val_is_zero(v2)6 ) || |
787 | 17 | (16 isl_val_is_zero(v1)16 && !isl_val_is_rat(v2)1 )) { |
788 | 2 | isl_val_free(v2); |
789 | 2 | return isl_val_set_nan(v1); |
790 | 2 | } |
791 | 15 | if (isl_val_is_zero(v1)) { |
792 | 0 | isl_val_free(v2); |
793 | 0 | return v1; |
794 | 0 | } |
795 | 15 | if (isl_val_is_zero(v2)) { |
796 | 0 | isl_val_free(v1); |
797 | 0 | return v2; |
798 | 0 | } |
799 | 15 | if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)12 ) { |
800 | 5 | if (isl_val_is_neg(v2)) |
801 | 2 | v1 = isl_val_neg(v1); |
802 | 5 | isl_val_free(v2); |
803 | 5 | return v1; |
804 | 5 | } |
805 | 10 | if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)9 ) { |
806 | 1 | if (isl_val_is_neg(v1)) |
807 | 0 | v2 = isl_val_neg(v2); |
808 | 1 | isl_val_free(v1); |
809 | 1 | return v2; |
810 | 1 | } |
811 | 9 | |
812 | 9 | v1 = isl_val_cow(v1); |
813 | 9 | if (!v1) |
814 | 0 | goto error; |
815 | 9 | if (isl_val_is_int(v1) && isl_val_is_int(v2)7 ) |
816 | 9 | isl_int_mul5 (v1->n, v1->n, v2->n); |
817 | 9 | else { |
818 | 4 | isl_int_mul(v1->n, v1->n, v2->n); |
819 | 4 | isl_int_mul(v1->d, v1->d, v2->d); |
820 | 4 | v1 = isl_val_normalize(v1); |
821 | 4 | } |
822 | 9 | isl_val_free(v2); |
823 | 9 | return v1; |
824 | 0 | error: |
825 | 0 | isl_val_free(v1); |
826 | 0 | isl_val_free(v2); |
827 | 0 | return NULL; |
828 | 9 | } |
829 | | |
830 | | /* Return the product of "v1" and "v2". |
831 | | * |
832 | | * This is a private copy of isl_val_mul for use in the generic |
833 | | * isl_multi_*_scale_val instantiated for isl_val. |
834 | | */ |
835 | | __isl_give isl_val *isl_val_scale_val(__isl_take isl_val *v1, |
836 | | __isl_take isl_val *v2) |
837 | 0 | { |
838 | 0 | return isl_val_mul(v1, v2); |
839 | 0 | } |
840 | | |
841 | | /* Return the product of "v1" and "v2". |
842 | | */ |
843 | | __isl_give isl_val *isl_val_mul_ui(__isl_take isl_val *v1, unsigned long v2) |
844 | 0 | { |
845 | 0 | if (!v1) |
846 | 0 | return NULL; |
847 | 0 | if (isl_val_is_nan(v1)) |
848 | 0 | return v1; |
849 | 0 | if (!isl_val_is_rat(v1)) { |
850 | 0 | if (v2 == 0) |
851 | 0 | v1 = isl_val_set_nan(v1); |
852 | 0 | return v1; |
853 | 0 | } |
854 | 0 | if (v2 == 1) |
855 | 0 | return v1; |
856 | 0 | v1 = isl_val_cow(v1); |
857 | 0 | if (!v1) |
858 | 0 | return NULL; |
859 | 0 | |
860 | 0 | isl_int_mul_ui(v1->n, v1->n, v2); |
861 | 0 |
|
862 | 0 | return isl_val_normalize(v1); |
863 | 0 | } |
864 | | |
865 | | /* Divide "v1" by "v2". |
866 | | */ |
867 | | __isl_give isl_val *isl_val_div(__isl_take isl_val *v1, __isl_take isl_val *v2) |
868 | 10.8k | { |
869 | 10.8k | if (!v1 || !v2) |
870 | 0 | goto error; |
871 | 10.8k | if (isl_val_is_nan(v1)) { |
872 | 4 | isl_val_free(v2); |
873 | 4 | return v1; |
874 | 4 | } |
875 | 10.8k | if (isl_val_is_nan(v2)) { |
876 | 5 | isl_val_free(v1); |
877 | 5 | return v2; |
878 | 5 | } |
879 | 10.8k | if (isl_val_is_zero(v2) || |
880 | 10.8k | (10.8k !isl_val_is_rat(v1)10.8k && !isl_val_is_rat(v2)4 )) { |
881 | 9 | isl_val_free(v2); |
882 | 9 | return isl_val_set_nan(v1); |
883 | 9 | } |
884 | 10.7k | if (isl_val_is_zero(v1)) { |
885 | 5.34k | isl_val_free(v2); |
886 | 5.34k | return v1; |
887 | 5.34k | } |
888 | 5.45k | if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) { |
889 | 0 | if (isl_val_is_neg(v2)) |
890 | 0 | v1 = isl_val_neg(v1); |
891 | 0 | isl_val_free(v2); |
892 | 0 | return v1; |
893 | 0 | } |
894 | 5.45k | if (isl_val_is_infty(v2) || isl_val_is_neginfty(v2)5.44k ) { |
895 | 4 | isl_val_free(v2); |
896 | 4 | return isl_val_set_zero(v1); |
897 | 4 | } |
898 | 5.44k | |
899 | 5.44k | v1 = isl_val_cow(v1); |
900 | 5.44k | if (!v1) |
901 | 0 | goto error; |
902 | 5.44k | if (isl_val_is_int(v2)) { |
903 | 5.44k | isl_int_mul(v1->d, v1->d, v2->n); |
904 | 5.44k | v1 = isl_val_normalize(v1); |
905 | 5.44k | } else { |
906 | 6 | isl_int_mul(v1->d, v1->d, v2->n); |
907 | 6 | isl_int_mul(v1->n, v1->n, v2->d); |
908 | 6 | v1 = isl_val_normalize(v1); |
909 | 6 | } |
910 | 5.44k | isl_val_free(v2); |
911 | 5.44k | return v1; |
912 | 0 | error: |
913 | 0 | isl_val_free(v1); |
914 | 0 | isl_val_free(v2); |
915 | 0 | return NULL; |
916 | 5.44k | } |
917 | | |
918 | | /* Divide "v1" by "v2". |
919 | | */ |
920 | | __isl_give isl_val *isl_val_div_ui(__isl_take isl_val *v1, unsigned long v2) |
921 | 20 | { |
922 | 20 | if (!v1) |
923 | 0 | return NULL; |
924 | 20 | if (isl_val_is_nan(v1)) |
925 | 0 | return v1; |
926 | 20 | if (v2 == 0) |
927 | 0 | return isl_val_set_nan(v1); |
928 | 20 | if (v2 == 1) |
929 | 0 | return v1; |
930 | 20 | if (isl_val_is_zero(v1)) |
931 | 0 | return v1; |
932 | 20 | if (isl_val_is_infty(v1) || isl_val_is_neginfty(v1)) |
933 | 0 | return v1; |
934 | 20 | v1 = isl_val_cow(v1); |
935 | 20 | if (!v1) |
936 | 0 | return NULL; |
937 | 20 | |
938 | 20 | isl_int_mul_ui(v1->d, v1->d, v2); |
939 | 20 | |
940 | 20 | return isl_val_normalize(v1); |
941 | 20 | } |
942 | | |
943 | | /* Divide "v1" by "v2". |
944 | | * |
945 | | * This is a private copy of isl_val_div for use in the generic |
946 | | * isl_multi_*_scale_down_val instantiated for isl_val. |
947 | | */ |
948 | | __isl_give isl_val *isl_val_scale_down_val(__isl_take isl_val *v1, |
949 | | __isl_take isl_val *v2) |
950 | 0 | { |
951 | 0 | return isl_val_div(v1, v2); |
952 | 0 | } |
953 | | |
954 | | /* Given two integer values "v1" and "v2", check if "v1" is divisible by "v2". |
955 | | */ |
956 | | isl_bool isl_val_is_divisible_by(__isl_keep isl_val *v1, __isl_keep isl_val *v2) |
957 | 540 | { |
958 | 540 | if (!v1 || !v2) |
959 | 0 | return isl_bool_error; |
960 | 540 | |
961 | 540 | if (!isl_val_is_int(v1) || !isl_val_is_int(v2)) |
962 | 540 | isl_die0 (isl_val_get_ctx(v1), isl_error_invalid, |
963 | 540 | "expecting two integers", return isl_bool_error); |
964 | 540 | |
965 | 540 | return isl_int_is_divisible_by(v1->n, v2->n); |
966 | 540 | } |
967 | | |
968 | | /* Given two integer values "v1" and "v2", return the residue of "v1" |
969 | | * modulo "v2". |
970 | | */ |
971 | | __isl_give isl_val *isl_val_mod(__isl_take isl_val *v1, __isl_take isl_val *v2) |
972 | 45 | { |
973 | 45 | if (!v1 || !v2) |
974 | 0 | goto error; |
975 | 45 | if (!isl_val_is_int(v1) || !isl_val_is_int(v2)) |
976 | 45 | isl_die0 (isl_val_get_ctx(v1), isl_error_invalid, |
977 | 45 | "expecting two integers", goto error); |
978 | 45 | if (isl_val_is_nonneg(v1) && isl_val_lt(v1, v2)41 ) { |
979 | 15 | isl_val_free(v2); |
980 | 15 | return v1; |
981 | 15 | } |
982 | 30 | v1 = isl_val_cow(v1); |
983 | 30 | if (!v1) |
984 | 0 | goto error; |
985 | 30 | isl_int_fdiv_r(v1->n, v1->n, v2->n); |
986 | 30 | isl_val_free(v2); |
987 | 30 | return v1; |
988 | 0 | error: |
989 | 0 | isl_val_free(v1); |
990 | 0 | isl_val_free(v2); |
991 | 0 | return NULL; |
992 | 30 | } |
993 | | |
994 | | /* Given two integer values "v1" and "v2", return the residue of "v1" |
995 | | * modulo "v2". |
996 | | * |
997 | | * This is a private copy of isl_val_mod for use in the generic |
998 | | * isl_multi_*_mod_multi_val instantiated for isl_val. |
999 | | */ |
1000 | | __isl_give isl_val *isl_val_mod_val(__isl_take isl_val *v1, |
1001 | | __isl_take isl_val *v2) |
1002 | 0 | { |
1003 | 0 | return isl_val_mod(v1, v2); |
1004 | 0 | } |
1005 | | |
1006 | | /* Given two integer values, return their greatest common divisor. |
1007 | | */ |
1008 | | __isl_give isl_val *isl_val_gcd(__isl_take isl_val *v1, __isl_take isl_val *v2) |
1009 | 5.42k | { |
1010 | 5.42k | if (!v1 || !v2) |
1011 | 0 | goto error; |
1012 | 5.42k | if (!isl_val_is_int(v1) || !isl_val_is_int(v2)) |
1013 | 5.42k | isl_die0 (isl_val_get_ctx(v1), isl_error_invalid, |
1014 | 5.42k | "expecting two integers", goto error); |
1015 | 5.42k | if (isl_val_eq(v1, v2)) { |
1016 | 75 | isl_val_free(v2); |
1017 | 75 | return v1; |
1018 | 75 | } |
1019 | 5.35k | if (isl_val_is_one(v1)) { |
1020 | 0 | isl_val_free(v2); |
1021 | 0 | return v1; |
1022 | 0 | } |
1023 | 5.35k | if (isl_val_is_one(v2)) { |
1024 | 5.32k | isl_val_free(v1); |
1025 | 5.32k | return v2; |
1026 | 5.32k | } |
1027 | 30 | v1 = isl_val_cow(v1); |
1028 | 30 | if (!v1) |
1029 | 0 | goto error; |
1030 | 30 | isl_int_gcd(v1->n, v1->n, v2->n); |
1031 | 30 | isl_val_free(v2); |
1032 | 30 | return v1; |
1033 | 0 | error: |
1034 | 0 | isl_val_free(v1); |
1035 | 0 | isl_val_free(v2); |
1036 | 0 | return NULL; |
1037 | 30 | } |
1038 | | |
1039 | | /* Compute x, y and g such that g = gcd(a,b) and a*x+b*y = g. |
1040 | | */ |
1041 | | static void isl_int_gcdext(isl_int *g, isl_int *x, isl_int *y, |
1042 | | isl_int a, isl_int b) |
1043 | 14 | { |
1044 | 14 | isl_int d, tmp; |
1045 | 14 | isl_int a_copy, b_copy; |
1046 | 14 | |
1047 | 14 | isl_int_init(a_copy); |
1048 | 14 | isl_int_init(b_copy); |
1049 | 14 | isl_int_init(d); |
1050 | 14 | isl_int_init(tmp); |
1051 | 14 | isl_int_set(a_copy, a); |
1052 | 14 | isl_int_set(b_copy, b); |
1053 | 14 | isl_int_abs(*g, a_copy); |
1054 | 14 | isl_int_abs(d, b_copy); |
1055 | 14 | isl_int_set_si(*x, 1); |
1056 | 14 | isl_int_set_si(*y, 0); |
1057 | 42 | while (isl_int_is_pos(d)) { |
1058 | 28 | isl_int_fdiv_q(tmp, *g, d); |
1059 | 28 | isl_int_submul(*x, tmp, *y); |
1060 | 28 | isl_int_submul(*g, tmp, d); |
1061 | 28 | isl_int_swap(*g, d); |
1062 | 28 | isl_int_swap(*x, *y); |
1063 | 28 | } |
1064 | 14 | if (isl_int_is_zero(a_copy)) |
1065 | 14 | isl_int_set_si0 (*x, 0); |
1066 | 14 | else if (isl_int_is_neg(a_copy)) |
1067 | 14 | isl_int_neg(*x, *x); |
1068 | 14 | if (isl_int_is_zero(b_copy)) |
1069 | 14 | isl_int_set_si0 (*y, 0); |
1070 | 14 | else { |
1071 | 14 | isl_int_mul(tmp, a_copy, *x); |
1072 | 14 | isl_int_sub(tmp, *g, tmp); |
1073 | 14 | isl_int_divexact(*y, tmp, b_copy); |
1074 | 14 | } |
1075 | 14 | isl_int_clear(d); |
1076 | 14 | isl_int_clear(tmp); |
1077 | 14 | isl_int_clear(a_copy); |
1078 | 14 | isl_int_clear(b_copy); |
1079 | 14 | } |
1080 | | |
1081 | | /* Given two integer values v1 and v2, return their greatest common divisor g, |
1082 | | * as well as two integers x and y such that x * v1 + y * v2 = g. |
1083 | | */ |
1084 | | __isl_give isl_val *isl_val_gcdext(__isl_take isl_val *v1, |
1085 | | __isl_take isl_val *v2, __isl_give isl_val **x, __isl_give isl_val **y) |
1086 | 14 | { |
1087 | 14 | isl_ctx *ctx; |
1088 | 14 | isl_val *a = NULL, *b = NULL; |
1089 | 14 | |
1090 | 14 | if (!x && !y0 ) |
1091 | 0 | return isl_val_gcd(v1, v2); |
1092 | 14 | |
1093 | 14 | if (!v1 || !v2) |
1094 | 0 | goto error; |
1095 | 14 | |
1096 | 14 | ctx = isl_val_get_ctx(v1); |
1097 | 14 | if (!isl_val_is_int(v1) || !isl_val_is_int(v2)) |
1098 | 14 | isl_die0 (ctx, isl_error_invalid, |
1099 | 14 | "expecting two integers", goto error); |
1100 | 14 | |
1101 | 14 | v1 = isl_val_cow(v1); |
1102 | 14 | a = isl_val_alloc(ctx); |
1103 | 14 | b = isl_val_alloc(ctx); |
1104 | 14 | if (!v1 || !a || !b) |
1105 | 0 | goto error; |
1106 | 14 | isl_int_gcdext(&v1->n, &a->n, &b->n, v1->n, v2->n); |
1107 | 14 | if (x) { |
1108 | 14 | isl_int_set_si(a->d, 1); |
1109 | 14 | *x = a; |
1110 | 14 | } else |
1111 | 0 | isl_val_free(a); |
1112 | 14 | if (y) { |
1113 | 14 | isl_int_set_si(b->d, 1); |
1114 | 14 | *y = b; |
1115 | 14 | } else |
1116 | 0 | isl_val_free(b); |
1117 | 14 | isl_val_free(v2); |
1118 | 14 | return v1; |
1119 | 0 | error: |
1120 | 0 | isl_val_free(v1); |
1121 | 0 | isl_val_free(v2); |
1122 | 0 | isl_val_free(a); |
1123 | 0 | isl_val_free(b); |
1124 | 0 | if (x) |
1125 | 0 | *x = NULL; |
1126 | 0 | if (y) |
1127 | 0 | *y = NULL; |
1128 | 0 | return NULL; |
1129 | 14 | } |
1130 | | |
1131 | | /* Does "v" represent an integer value? |
1132 | | */ |
1133 | | isl_bool isl_val_is_int(__isl_keep isl_val *v) |
1134 | 124k | { |
1135 | 124k | if (!v) |
1136 | 0 | return isl_bool_error; |
1137 | 124k | |
1138 | 124k | return isl_int_is_one(v->d); |
1139 | 124k | } |
1140 | | |
1141 | | /* Does "v" represent a rational value? |
1142 | | */ |
1143 | | isl_bool isl_val_is_rat(__isl_keep isl_val *v) |
1144 | 56.0k | { |
1145 | 56.0k | if (!v) |
1146 | 0 | return isl_bool_error; |
1147 | 56.0k | |
1148 | 56.0k | return !isl_int_is_zero(v->d); |
1149 | 56.0k | } |
1150 | | |
1151 | | /* Does "v" represent NaN? |
1152 | | */ |
1153 | | isl_bool isl_val_is_nan(__isl_keep isl_val *v) |
1154 | 91.3k | { |
1155 | 91.3k | if (!v) |
1156 | 0 | return isl_bool_error; |
1157 | 91.3k | |
1158 | 91.3k | return isl_int_is_zero(v->n) && isl_int_is_zero19.2k (v->d); |
1159 | 91.3k | } |
1160 | | |
1161 | | /* Does "v" represent +infinity? |
1162 | | */ |
1163 | | isl_bool isl_val_is_infty(__isl_keep isl_val *v) |
1164 | 15.3k | { |
1165 | 15.3k | if (!v) |
1166 | 0 | return isl_bool_error; |
1167 | 15.3k | |
1168 | 15.3k | return isl_int_is_pos(v->n) && isl_int_is_zero13.8k (v->d); |
1169 | 15.3k | } |
1170 | | |
1171 | | /* Does "v" represent -infinity? |
1172 | | */ |
1173 | | isl_bool isl_val_is_neginfty(__isl_keep isl_val *v) |
1174 | 12.9k | { |
1175 | 12.9k | if (!v) |
1176 | 0 | return isl_bool_error; |
1177 | 12.9k | |
1178 | 12.9k | return isl_int_is_neg(v->n) && isl_int_is_zero194 (v->d); |
1179 | 12.9k | } |
1180 | | |
1181 | | /* Does "v" represent the integer zero? |
1182 | | */ |
1183 | | isl_bool isl_val_is_zero(__isl_keep isl_val *v) |
1184 | 111k | { |
1185 | 111k | if (!v) |
1186 | 0 | return isl_bool_error; |
1187 | 111k | |
1188 | 111k | return isl_int_is_zero(v->n) && !72.8k isl_int_is_zero72.8k (v->d); |
1189 | 111k | } |
1190 | | |
1191 | | /* Does "v" represent the integer one? |
1192 | | */ |
1193 | | isl_bool isl_val_is_one(__isl_keep isl_val *v) |
1194 | 49.4k | { |
1195 | 49.4k | if (!v) |
1196 | 0 | return isl_bool_error; |
1197 | 49.4k | |
1198 | 49.4k | if (isl_val_is_nan(v)) |
1199 | 0 | return isl_bool_false; |
1200 | 49.4k | |
1201 | 49.4k | return isl_int_eq(v->n, v->d); |
1202 | 49.4k | } |
1203 | | |
1204 | | /* Does "v" represent the integer negative one? |
1205 | | */ |
1206 | | isl_bool isl_val_is_negone(__isl_keep isl_val *v) |
1207 | 5.23k | { |
1208 | 5.23k | if (!v) |
1209 | 0 | return isl_bool_error; |
1210 | 5.23k | |
1211 | 5.23k | return isl_int_is_neg(v->n) && isl_int_abs_eq149 (v->n, v->d); |
1212 | 5.23k | } |
1213 | | |
1214 | | /* Is "v" (strictly) positive? |
1215 | | */ |
1216 | | isl_bool isl_val_is_pos(__isl_keep isl_val *v) |
1217 | 1.85k | { |
1218 | 1.85k | if (!v) |
1219 | 0 | return isl_bool_error; |
1220 | 1.85k | |
1221 | 1.85k | return isl_int_is_pos(v->n); |
1222 | 1.85k | } |
1223 | | |
1224 | | /* Is "v" (strictly) negative? |
1225 | | */ |
1226 | | isl_bool isl_val_is_neg(__isl_keep isl_val *v) |
1227 | 23.5k | { |
1228 | 23.5k | if (!v) |
1229 | 0 | return isl_bool_error; |
1230 | 23.5k | |
1231 | 23.5k | return isl_int_is_neg(v->n); |
1232 | 23.5k | } |
1233 | | |
1234 | | /* Is "v" non-negative? |
1235 | | */ |
1236 | | isl_bool isl_val_is_nonneg(__isl_keep isl_val *v) |
1237 | 1.00k | { |
1238 | 1.00k | if (!v) |
1239 | 0 | return isl_bool_error; |
1240 | 1.00k | |
1241 | 1.00k | if (isl_val_is_nan(v)) |
1242 | 0 | return isl_bool_false; |
1243 | 1.00k | |
1244 | 1.00k | return isl_int_is_nonneg(v->n); |
1245 | 1.00k | } |
1246 | | |
1247 | | /* Is "v" non-positive? |
1248 | | */ |
1249 | | isl_bool isl_val_is_nonpos(__isl_keep isl_val *v) |
1250 | 0 | { |
1251 | 0 | if (!v) |
1252 | 0 | return isl_bool_error; |
1253 | 0 | |
1254 | 0 | if (isl_val_is_nan(v)) |
1255 | 0 | return isl_bool_false; |
1256 | 0 | |
1257 | 0 | return isl_int_is_nonpos(v->n); |
1258 | 0 | } |
1259 | | |
1260 | | /* Return the sign of "v". |
1261 | | * |
1262 | | * The sign of NaN is undefined. |
1263 | | */ |
1264 | | int isl_val_sgn(__isl_keep isl_val *v) |
1265 | 3.48k | { |
1266 | 3.48k | if (!v) |
1267 | 0 | return 0; |
1268 | 3.48k | if (isl_val_is_zero(v)) |
1269 | 2.04k | return 0; |
1270 | 1.44k | if (isl_val_is_pos(v)) |
1271 | 818 | return 1; |
1272 | 629 | return -1; |
1273 | 629 | } |
1274 | | |
1275 | | /* Is "v1" (strictly) less than "v2"? |
1276 | | */ |
1277 | | isl_bool isl_val_lt(__isl_keep isl_val *v1, __isl_keep isl_val *v2) |
1278 | 46 | { |
1279 | 46 | isl_int t; |
1280 | 46 | isl_bool lt; |
1281 | 46 | |
1282 | 46 | if (!v1 || !v2) |
1283 | 0 | return isl_bool_error; |
1284 | 46 | if (isl_val_is_int(v1) && isl_val_is_int(v2)) |
1285 | 46 | return isl_int_lt(v1->n, v2->n); |
1286 | 0 | if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) |
1287 | 0 | return isl_bool_false; |
1288 | 0 | if (isl_val_eq(v1, v2)) |
1289 | 0 | return isl_bool_false; |
1290 | 0 | if (isl_val_is_infty(v2)) |
1291 | 0 | return isl_bool_true; |
1292 | 0 | if (isl_val_is_infty(v1)) |
1293 | 0 | return isl_bool_false; |
1294 | 0 | if (isl_val_is_neginfty(v1)) |
1295 | 0 | return isl_bool_true; |
1296 | 0 | if (isl_val_is_neginfty(v2)) |
1297 | 0 | return isl_bool_false; |
1298 | 0 | |
1299 | 0 | isl_int_init(t); |
1300 | 0 | isl_int_mul(t, v1->n, v2->d); |
1301 | 0 | isl_int_submul(t, v2->n, v1->d); |
1302 | 0 | lt = isl_int_is_neg(t); |
1303 | 0 | isl_int_clear(t); |
1304 | 0 |
|
1305 | 0 | return lt; |
1306 | 0 | } |
1307 | | |
1308 | | /* Is "v1" (strictly) greater than "v2"? |
1309 | | */ |
1310 | | isl_bool isl_val_gt(__isl_keep isl_val *v1, __isl_keep isl_val *v2) |
1311 | 0 | { |
1312 | 0 | return isl_val_lt(v2, v1); |
1313 | 0 | } |
1314 | | |
1315 | | /* Is "v" (strictly) greater than "i"? |
1316 | | */ |
1317 | | isl_bool isl_val_gt_si(__isl_keep isl_val *v, long i) |
1318 | 5.32k | { |
1319 | 5.32k | isl_val *vi; |
1320 | 5.32k | isl_bool res; |
1321 | 5.32k | |
1322 | 5.32k | if (!v) |
1323 | 0 | return isl_bool_error; |
1324 | 5.32k | if (isl_val_is_int(v)) |
1325 | 5.32k | return isl_int_cmp_si(v->n, i) > 0; |
1326 | 0 | if (isl_val_is_nan(v)) |
1327 | 0 | return isl_bool_false; |
1328 | 0 | if (isl_val_is_infty(v)) |
1329 | 0 | return isl_bool_true; |
1330 | 0 | if (isl_val_is_neginfty(v)) |
1331 | 0 | return isl_bool_false; |
1332 | 0 | |
1333 | 0 | vi = isl_val_int_from_si(isl_val_get_ctx(v), i); |
1334 | 0 | res = isl_val_gt(v, vi); |
1335 | 0 | isl_val_free(vi); |
1336 | 0 |
|
1337 | 0 | return res; |
1338 | 0 | } |
1339 | | |
1340 | | /* Is "v1" less than or equal to "v2"? |
1341 | | */ |
1342 | | isl_bool isl_val_le(__isl_keep isl_val *v1, __isl_keep isl_val *v2) |
1343 | 10 | { |
1344 | 10 | isl_int t; |
1345 | 10 | isl_bool le; |
1346 | 10 | |
1347 | 10 | if (!v1 || !v2) |
1348 | 0 | return isl_bool_error; |
1349 | 10 | if (isl_val_is_int(v1) && isl_val_is_int(v2)6 ) |
1350 | 4 | return isl_int_le(v1->n, v2->n); |
1351 | 6 | if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) |
1352 | 0 | return isl_bool_false; |
1353 | 6 | if (isl_val_eq(v1, v2)) |
1354 | 0 | return isl_bool_true; |
1355 | 6 | if (isl_val_is_infty(v2)) |
1356 | 2 | return isl_bool_true; |
1357 | 4 | if (isl_val_is_infty(v1)) |
1358 | 2 | return isl_bool_false; |
1359 | 2 | if (isl_val_is_neginfty(v1)) |
1360 | 1 | return isl_bool_true; |
1361 | 1 | if (isl_val_is_neginfty(v2)) |
1362 | 1 | return isl_bool_false; |
1363 | 0 | |
1364 | 0 | isl_int_init(t); |
1365 | 0 | isl_int_mul(t, v1->n, v2->d); |
1366 | 0 | isl_int_submul(t, v2->n, v1->d); |
1367 | 0 | le = isl_int_is_nonpos(t); |
1368 | 0 | isl_int_clear(t); |
1369 | 0 |
|
1370 | 0 | return le; |
1371 | 0 | } |
1372 | | |
1373 | | /* Is "v1" greater than or equal to "v2"? |
1374 | | */ |
1375 | | isl_bool isl_val_ge(__isl_keep isl_val *v1, __isl_keep isl_val *v2) |
1376 | 5 | { |
1377 | 5 | return isl_val_le(v2, v1); |
1378 | 5 | } |
1379 | | |
1380 | | /* How does "v" compare to "i"? |
1381 | | * |
1382 | | * Return 1 if v is greater, -1 if v is smaller and 0 if v is equal to i. |
1383 | | * |
1384 | | * If v is NaN (or NULL), then the result is undefined. |
1385 | | */ |
1386 | | int isl_val_cmp_si(__isl_keep isl_val *v, long i) |
1387 | 2.62k | { |
1388 | 2.62k | isl_int t; |
1389 | 2.62k | int cmp; |
1390 | 2.62k | |
1391 | 2.62k | if (!v) |
1392 | 0 | return 0; |
1393 | 2.62k | if (isl_val_is_int(v)) |
1394 | 2.62k | return isl_int_cmp_si(v->n, i); |
1395 | 0 | if (isl_val_is_nan(v)) |
1396 | 0 | return 0; |
1397 | 0 | if (isl_val_is_infty(v)) |
1398 | 0 | return 1; |
1399 | 0 | if (isl_val_is_neginfty(v)) |
1400 | 0 | return -1; |
1401 | 0 | |
1402 | 0 | isl_int_init(t); |
1403 | 0 | isl_int_mul_si(t, v->d, i); |
1404 | 0 | isl_int_sub(t, v->n, t); |
1405 | 0 | cmp = isl_int_sgn(t); |
1406 | 0 | isl_int_clear(t); |
1407 | 0 |
|
1408 | 0 | return cmp; |
1409 | 0 | } |
1410 | | |
1411 | | /* Is "v1" equal to "v2"? |
1412 | | */ |
1413 | | isl_bool isl_val_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2) |
1414 | 5.55k | { |
1415 | 5.55k | if (!v1 || !v2) |
1416 | 0 | return isl_bool_error; |
1417 | 5.55k | if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) |
1418 | 0 | return isl_bool_false; |
1419 | 5.55k | |
1420 | 5.55k | return isl_int_eq(v1->n, v2->n) && isl_int_eq193 (v1->d, v2->d); |
1421 | 5.55k | } |
1422 | | |
1423 | | /* Is "v1" equal to "v2" in absolute value? |
1424 | | */ |
1425 | | isl_bool isl_val_abs_eq(__isl_keep isl_val *v1, __isl_keep isl_val *v2) |
1426 | 17 | { |
1427 | 17 | if (!v1 || !v2) |
1428 | 0 | return isl_bool_error; |
1429 | 17 | if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) |
1430 | 0 | return isl_bool_false; |
1431 | 17 | |
1432 | 17 | return isl_int_abs_eq(v1->n, v2->n) && isl_int_eq(v1->d, v2->d); |
1433 | 17 | } |
1434 | | |
1435 | | /* Is "v1" different from "v2"? |
1436 | | */ |
1437 | | isl_bool isl_val_ne(__isl_keep isl_val *v1, __isl_keep isl_val *v2) |
1438 | 5 | { |
1439 | 5 | if (!v1 || !v2) |
1440 | 0 | return isl_bool_error; |
1441 | 5 | if (isl_val_is_nan(v1) || isl_val_is_nan(v2)) |
1442 | 0 | return isl_bool_false; |
1443 | 5 | |
1444 | 5 | return isl_int_ne(v1->n, v2->n) || isl_int_ne1 (v1->d, v2->d); |
1445 | 5 | } |
1446 | | |
1447 | | /* Print a textual representation of "v" onto "p". |
1448 | | */ |
1449 | | __isl_give isl_printer *isl_printer_print_val(__isl_take isl_printer *p, |
1450 | | __isl_keep isl_val *v) |
1451 | 9.25k | { |
1452 | 9.25k | int neg; |
1453 | 9.25k | |
1454 | 9.25k | if (!p || !v) |
1455 | 0 | return isl_printer_free(p); |
1456 | 9.25k | |
1457 | 9.25k | neg = isl_int_is_neg(v->n); |
1458 | 9.25k | if (neg) { |
1459 | 55 | p = isl_printer_print_str(p, "-"); |
1460 | 55 | isl_int_neg(v->n, v->n); |
1461 | 55 | } |
1462 | 9.25k | if (isl_int_is_zero(v->d)) { |
1463 | 0 | int sgn = isl_int_sgn(v->n); |
1464 | 0 | p = isl_printer_print_str(p, sgn < 0 ? "-infty" : |
1465 | 0 | sgn == 0 ? "NaN" : "infty"); |
1466 | 0 | } else |
1467 | 9.25k | p = isl_printer_print_isl_int(p, v->n); |
1468 | 9.25k | if (neg) |
1469 | 9.25k | isl_int_neg55 (v->n, v->n); |
1470 | 9.25k | if (!isl_int_is_zero(v->d) && !isl_int_is_one(v->d)) { |
1471 | 0 | p = isl_printer_print_str(p, "/"); |
1472 | 0 | p = isl_printer_print_isl_int(p, v->d); |
1473 | 0 | } |
1474 | 9.25k | |
1475 | 9.25k | return p; |
1476 | 9.25k | } |
1477 | | |
1478 | | /* Is "val1" (obviously) equal to "val2"? |
1479 | | * |
1480 | | * This is a private copy of isl_val_eq for use in the generic |
1481 | | * isl_multi_*_plain_is_equal instantiated for isl_val. |
1482 | | */ |
1483 | | int isl_val_plain_is_equal(__isl_keep isl_val *val1, __isl_keep isl_val *val2) |
1484 | 0 | { |
1485 | 0 | return isl_val_eq(val1, val2); |
1486 | 0 | } |
1487 | | |
1488 | | /* Does "v" have any non-zero coefficients |
1489 | | * for any dimension in the given range? |
1490 | | * |
1491 | | * This function is only meant to be used in the generic isl_multi_* |
1492 | | * functions which have to deal with base objects that have an associated |
1493 | | * space. Since an isl_val does not have any coefficients, this function |
1494 | | * always return 0. |
1495 | | */ |
1496 | | int isl_val_involves_dims(__isl_keep isl_val *v, enum isl_dim_type type, |
1497 | | unsigned first, unsigned n) |
1498 | 0 | { |
1499 | 0 | if (!v) |
1500 | 0 | return -1; |
1501 | 0 | |
1502 | 0 | return 0; |
1503 | 0 | } |
1504 | | |
1505 | | /* Insert "n" dimensions of type "type" at position "first". |
1506 | | * |
1507 | | * This function is only meant to be used in the generic isl_multi_* |
1508 | | * functions which have to deal with base objects that have an associated |
1509 | | * space. Since an isl_val does not have an associated space, this function |
1510 | | * does not do anything. |
1511 | | */ |
1512 | | __isl_give isl_val *isl_val_insert_dims(__isl_take isl_val *v, |
1513 | | enum isl_dim_type type, unsigned first, unsigned n) |
1514 | 0 | { |
1515 | 0 | return v; |
1516 | 0 | } |
1517 | | |
1518 | | /* Drop the "n" first dimensions of type "type" at position "first". |
1519 | | * |
1520 | | * This function is only meant to be used in the generic isl_multi_* |
1521 | | * functions which have to deal with base objects that have an associated |
1522 | | * space. Since an isl_val does not have an associated space, this function |
1523 | | * does not do anything. |
1524 | | */ |
1525 | | __isl_give isl_val *isl_val_drop_dims(__isl_take isl_val *v, |
1526 | | enum isl_dim_type type, unsigned first, unsigned n) |
1527 | 0 | { |
1528 | 0 | return v; |
1529 | 0 | } |
1530 | | |
1531 | | /* Change the name of the dimension of type "type" at position "pos" to "s". |
1532 | | * |
1533 | | * This function is only meant to be used in the generic isl_multi_* |
1534 | | * functions which have to deal with base objects that have an associated |
1535 | | * space. Since an isl_val does not have an associated space, this function |
1536 | | * does not do anything. |
1537 | | */ |
1538 | | __isl_give isl_val *isl_val_set_dim_name(__isl_take isl_val *v, |
1539 | | enum isl_dim_type type, unsigned pos, const char *s) |
1540 | 0 | { |
1541 | 0 | return v; |
1542 | 0 | } |
1543 | | |
1544 | | /* Return the space of "v". |
1545 | | * |
1546 | | * This function is only meant to be used in the generic isl_multi_* |
1547 | | * functions which have to deal with base objects that have an associated |
1548 | | * space. The conditions surrounding the call to this function make sure |
1549 | | * that this function will never actually get called. We return a valid |
1550 | | * space anyway, just in case. |
1551 | | */ |
1552 | | __isl_give isl_space *isl_val_get_space(__isl_keep isl_val *v) |
1553 | 0 | { |
1554 | 0 | if (!v) |
1555 | 0 | return NULL; |
1556 | 0 | |
1557 | 0 | return isl_space_params_alloc(isl_val_get_ctx(v), 0); |
1558 | 0 | } |
1559 | | |
1560 | | /* Reset the domain space of "v" to "space". |
1561 | | * |
1562 | | * This function is only meant to be used in the generic isl_multi_* |
1563 | | * functions which have to deal with base objects that have an associated |
1564 | | * space. Since an isl_val does not have an associated space, this function |
1565 | | * does not do anything, apart from error handling and cleaning up memory. |
1566 | | */ |
1567 | | __isl_give isl_val *isl_val_reset_domain_space(__isl_take isl_val *v, |
1568 | | __isl_take isl_space *space) |
1569 | 3.07k | { |
1570 | 3.07k | if (!space) |
1571 | 0 | return isl_val_free(v); |
1572 | 3.07k | isl_space_free(space); |
1573 | 3.07k | return v; |
1574 | 3.07k | } |
1575 | | |
1576 | | /* Align the parameters of "v" to those of "space". |
1577 | | * |
1578 | | * This function is only meant to be used in the generic isl_multi_* |
1579 | | * functions which have to deal with base objects that have an associated |
1580 | | * space. Since an isl_val does not have an associated space, this function |
1581 | | * does not do anything, apart from error handling and cleaning up memory. |
1582 | | * Note that the conditions surrounding the call to this function make sure |
1583 | | * that this function will never actually get called. |
1584 | | */ |
1585 | | __isl_give isl_val *isl_val_align_params(__isl_take isl_val *v, |
1586 | | __isl_take isl_space *space) |
1587 | 0 | { |
1588 | 0 | if (!space) |
1589 | 0 | return isl_val_free(v); |
1590 | 0 | isl_space_free(space); |
1591 | 0 | return v; |
1592 | 0 | } |
1593 | | |
1594 | | /* Reorder the dimensions of the domain of "v" according |
1595 | | * to the given reordering. |
1596 | | * |
1597 | | * This function is only meant to be used in the generic isl_multi_* |
1598 | | * functions which have to deal with base objects that have an associated |
1599 | | * space. Since an isl_val does not have an associated space, this function |
1600 | | * does not do anything, apart from error handling and cleaning up memory. |
1601 | | */ |
1602 | | __isl_give isl_val *isl_val_realign_domain(__isl_take isl_val *v, |
1603 | | __isl_take isl_reordering *r) |
1604 | 3.07k | { |
1605 | 3.07k | if (!r) |
1606 | 0 | return isl_val_free(v); |
1607 | 3.07k | isl_reordering_free(r); |
1608 | 3.07k | return v; |
1609 | 3.07k | } |
1610 | | |
1611 | | /* Return an isl_val that is zero on "ls". |
1612 | | * |
1613 | | * This function is only meant to be used in the generic isl_multi_* |
1614 | | * functions which have to deal with base objects that have an associated |
1615 | | * space. Since an isl_val does not have an associated space, this function |
1616 | | * simply returns a zero isl_val in the same context as "ls". |
1617 | | */ |
1618 | | __isl_give isl_val *isl_val_zero_on_domain(__isl_take isl_local_space *ls) |
1619 | 3.52k | { |
1620 | 3.52k | isl_ctx *ctx; |
1621 | 3.52k | |
1622 | 3.52k | if (!ls) |
1623 | 0 | return NULL; |
1624 | 3.52k | ctx = isl_local_space_get_ctx(ls); |
1625 | 3.52k | isl_local_space_free(ls); |
1626 | 3.52k | return isl_val_zero(ctx); |
1627 | 3.52k | } |
1628 | | |
1629 | | /* Do the parameters of "v" match those of "space"? |
1630 | | * |
1631 | | * This function is only meant to be used in the generic isl_multi_* |
1632 | | * functions which have to deal with base objects that have an associated |
1633 | | * space. Since an isl_val does not have an associated space, this function |
1634 | | * simply returns true, except if "v" or "space" are NULL. |
1635 | | */ |
1636 | | isl_bool isl_val_matching_params(__isl_keep isl_val *v, |
1637 | | __isl_keep isl_space *space) |
1638 | 14.4k | { |
1639 | 14.4k | if (!v || !space) |
1640 | 0 | return isl_bool_error; |
1641 | 14.4k | return isl_bool_true; |
1642 | 14.4k | } |
1643 | | |
1644 | | /* Check that the domain space of "v" matches "space". |
1645 | | * |
1646 | | * This function is only meant to be used in the generic isl_multi_* |
1647 | | * functions which have to deal with base objects that have an associated |
1648 | | * space. Since an isl_val does not have an associated space, this function |
1649 | | * simply returns 0, except if "v" or "space" are NULL. |
1650 | | */ |
1651 | | isl_stat isl_val_check_match_domain_space(__isl_keep isl_val *v, |
1652 | | __isl_keep isl_space *space) |
1653 | 14.4k | { |
1654 | 14.4k | if (!v || !space) |
1655 | 0 | return isl_stat_error; |
1656 | 14.4k | return isl_stat_ok; |
1657 | 14.4k | } |
1658 | | |
1659 | 0 | #define isl_val_involves_nan isl_val_is_nan |
1660 | | |
1661 | | #undef BASE |
1662 | | #define BASE val |
1663 | | |
1664 | | #define NO_DOMAIN |
1665 | | #define NO_IDENTITY |
1666 | | #define NO_FROM_BASE |
1667 | | #define NO_MOVE_DIMS |
1668 | | #include <isl_multi_no_explicit_domain.c> |
1669 | | #include <isl_multi_templ.c> |
1670 | | #include <isl_multi_dims.c> |
1671 | | |
1672 | | /* Apply "fn" to each of the elements of "mv" with as second argument "v". |
1673 | | */ |
1674 | | static __isl_give isl_multi_val *isl_multi_val_fn_val( |
1675 | | __isl_take isl_multi_val *mv, |
1676 | | __isl_give isl_val *(*fn)(__isl_take isl_val *v1, |
1677 | | __isl_take isl_val *v2), |
1678 | | __isl_take isl_val *v) |
1679 | 4 | { |
1680 | 4 | int i; |
1681 | 4 | |
1682 | 4 | mv = isl_multi_val_cow(mv); |
1683 | 4 | if (!mv || !v) |
1684 | 0 | goto error; |
1685 | 4 | |
1686 | 16 | for (i = 0; 4 i < mv->n; ++i12 ) { |
1687 | 12 | mv->u.p[i] = fn(mv->u.p[i], isl_val_copy(v)); |
1688 | 12 | if (!mv->u.p[i]) |
1689 | 0 | goto error; |
1690 | 12 | } |
1691 | 4 | |
1692 | 4 | isl_val_free(v); |
1693 | 4 | return mv; |
1694 | 0 | error: |
1695 | 0 | isl_val_free(v); |
1696 | 0 | isl_multi_val_free(mv); |
1697 | 0 | return NULL; |
1698 | 4 | } |
1699 | | |
1700 | | /* Add "v" to each of the elements of "mv". |
1701 | | */ |
1702 | | __isl_give isl_multi_val *isl_multi_val_add_val(__isl_take isl_multi_val *mv, |
1703 | | __isl_take isl_val *v) |
1704 | 3 | { |
1705 | 3 | if (!v) |
1706 | 0 | return isl_multi_val_free(mv); |
1707 | 3 | if (isl_val_is_zero(v)) { |
1708 | 2 | isl_val_free(v); |
1709 | 2 | return mv; |
1710 | 2 | } |
1711 | 1 | return isl_multi_val_fn_val(mv, &isl_val_add, v); |
1712 | 1 | } |
1713 | | |
1714 | | /* Reduce the elements of "mv" modulo "v". |
1715 | | */ |
1716 | | __isl_give isl_multi_val *isl_multi_val_mod_val(__isl_take isl_multi_val *mv, |
1717 | | __isl_take isl_val *v) |
1718 | 3 | { |
1719 | 3 | return isl_multi_val_fn_val(mv, &isl_val_mod, v); |
1720 | 3 | } |