| 1 | /* |
| 2 | * Copyright 2010 INRIA Saclay |
| 3 | * |
| 4 | * Use of this software is governed by the MIT license |
| 5 | * |
| 6 | * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, |
| 7 | * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, |
| 8 | * 91893 Orsay, France |
| 9 | */ |
| 10 | |
| 11 | #include <isl_union_macro.h> |
| 12 | |
| 13 | /* Evaluate "u" in the void point "pnt". |
| 14 | * In particular, return the value NaN. |
| 15 | */ |
| 16 | static __isl_give isl_val *FN(UNION,eval_void)(__isl_take UNION *u, |
| 17 | __isl_take isl_point *pnt) |
| 18 | { |
| 19 | isl_ctx *ctx; |
| 20 | |
| 21 | ctx = isl_point_get_ctx(pnt); |
| 22 | FN(UNION,free)(u); |
| 23 | isl_point_free(pnt); |
| 24 | return isl_val_nan(ctx); |
| 25 | } |
| 26 | |
| 27 | /* Internal data structure for isl_union_*_eval. |
| 28 | * |
| 29 | * "pnt" is the point in which the function is evaluated. |
| 30 | * "v" stores the result and is initialized to zero. |
| 31 | */ |
| 32 | S(UNION,eval_data) { |
| 33 | isl_point *pnt; |
| 34 | isl_val *v; |
| 35 | }; |
| 36 | |
| 37 | /* Update the evaluation in data->v based on the evaluation of "part". |
| 38 | * |
| 39 | * Only (at most) a single part on which this function is called |
| 40 | * is assumed to evaluate to anything other than zero. |
| 41 | * Since the value is initialized to zero, the evaluation of "part" |
| 42 | * can simply be added. |
| 43 | */ |
| 44 | static isl_stat FN(UNION,eval_entry)(__isl_take PART *part, void *user) |
| 45 | { |
| 46 | S(UNION,eval_data) *data = user; |
| 47 | isl_val *v; |
| 48 | |
| 49 | v = FN(PART,eval)(pw: part, pnt: isl_point_copy(pnt: data->pnt)); |
| 50 | data->v = isl_val_add(v1: data->v, v2: v); |
| 51 | |
| 52 | return isl_stat_non_null(obj: data->v); |
| 53 | } |
| 54 | |
| 55 | /* Evaluate "u" in the point "pnt". |
| 56 | */ |
| 57 | __isl_give isl_val *FN(UNION,eval)(__isl_take UNION *u, |
| 58 | __isl_take isl_point *pnt) |
| 59 | { |
| 60 | S(UNION,eval_data) data = { pnt }; |
| 61 | isl_bool is_void; |
| 62 | isl_space *space; |
| 63 | |
| 64 | is_void = isl_point_is_void(pnt); |
| 65 | if (is_void < 0) |
| 66 | goto error; |
| 67 | if (is_void) |
| 68 | return FN(UNION,eval_void)(u, pnt); |
| 69 | |
| 70 | data.v = isl_val_zero(ctx: isl_point_get_ctx(pnt)); |
| 71 | space = isl_point_peek_space(pnt); |
| 72 | if (FN(UNION,foreach_on_domain)(u, space, |
| 73 | fn: &FN(UNION,eval_entry), user: &data) < 0) |
| 74 | data.v = isl_val_free(v: data.v); |
| 75 | FN(UNION,free)(u); |
| 76 | isl_point_free(pnt); |
| 77 | return data.v; |
| 78 | error: |
| 79 | FN(UNION,free)(u); |
| 80 | isl_point_free(pnt); |
| 81 | return NULL; |
| 82 | } |
| 83 | |