| 1 | /* |
| 2 | * Copyright 2017 Sven Verdoolaege |
| 3 | * |
| 4 | * Use of this software is governed by the MIT license |
| 5 | * |
| 6 | * Written by Sven Verdoolaege. |
| 7 | */ |
| 8 | |
| 9 | #include <isl_multi_macro.h> |
| 10 | |
| 11 | /* Compute the sum of "multi1" and "multi2" on the union of their domains, |
| 12 | * with the actual sum on the shared domain and |
| 13 | * the defined expression on the symmetric difference of the domains. |
| 14 | * |
| 15 | * We simply iterate over the elements in both arguments and |
| 16 | * call isl_union_pw_aff_union_add on each of them, if there is |
| 17 | * at least one element. |
| 18 | * |
| 19 | * Otherwise, the two expressions have an explicit domain and |
| 20 | * the union of these explicit domains is computed. |
| 21 | * This assumes that the explicit domains are either both in terms |
| 22 | * of specific domains elements or both in terms of parameters. |
| 23 | * However, if one of the expressions does not have any constraints |
| 24 | * on its explicit domain, then this is allowed as well and the result |
| 25 | * is the expression with no constraints on its explicit domain. |
| 26 | */ |
| 27 | __isl_give MULTI(BASE) *FN(MULTI(BASE),union_add)( |
| 28 | __isl_take MULTI(BASE) *multi1, __isl_take MULTI(BASE) *multi2) |
| 29 | { |
| 30 | isl_bool has_domain, is_params1, is_params2; |
| 31 | |
| 32 | if (!multi1) |
| 33 | goto error; |
| 34 | if (multi1->n > 0) |
| 35 | return FN(MULTI(BASE),bin_op)(multi1, multi2, |
| 36 | fn: &FN(EL,union_add)); |
| 37 | FN(MULTI(BASE),align_params_bin)(obj1: &multi1, obj2: &multi2); |
| 38 | if (FN(MULTI(BASE),check_equal_space)(obj1: multi1, obj2: multi2) < 0) |
| 39 | goto error; |
| 40 | if (FN(MULTI(BASE),check_has_explicit_domain)(multi: multi1) < 0 || |
| 41 | FN(MULTI(BASE),check_has_explicit_domain)(multi: multi2) < 0) |
| 42 | goto error; |
| 43 | |
| 44 | has_domain = FN(MULTI(BASE),has_non_trivial_domain)(multi: multi1); |
| 45 | if (has_domain < 0) |
| 46 | goto error; |
| 47 | if (!has_domain) { |
| 48 | FN(MULTI(BASE),free)(multi: multi2); |
| 49 | return multi1; |
| 50 | } |
| 51 | has_domain = FN(MULTI(BASE),has_non_trivial_domain)(multi: multi2); |
| 52 | if (has_domain < 0) |
| 53 | goto error; |
| 54 | if (!has_domain) { |
| 55 | FN(MULTI(BASE),free)(multi: multi1); |
| 56 | return multi2; |
| 57 | } |
| 58 | |
| 59 | is_params1 = FN(DOM,is_params)(map: multi1->u.dom); |
| 60 | is_params2 = FN(DOM,is_params)(map: multi2->u.dom); |
| 61 | if (is_params1 < 0 || is_params2 < 0) |
| 62 | goto error; |
| 63 | if (is_params1 != is_params2) |
| 64 | isl_die(FN(MULTI(BASE),get_ctx)(multi1), |
| 65 | isl_error_invalid, |
| 66 | "cannot compute union of concrete domain and " |
| 67 | "parameter constraints" , goto error); |
| 68 | multi1 = FN(MULTI(BASE),cow)(multi: multi1); |
| 69 | if (!multi1) |
| 70 | goto error; |
| 71 | multi1->u.dom = FN(DOM,union)(map1: multi1->u.dom, |
| 72 | FN(DOM,copy)(map: multi2->u.dom)); |
| 73 | if (!multi1->u.dom) |
| 74 | goto error; |
| 75 | FN(MULTI(BASE),free)(multi: multi2); |
| 76 | return multi1; |
| 77 | error: |
| 78 | FN(MULTI(BASE),free)(multi: multi1); |
| 79 | FN(MULTI(BASE),free)(multi: multi2); |
| 80 | return NULL; |
| 81 | } |
| 82 | |