Home | History | Annotate | Line # | Download | only in dist
      1  1.1  mrg /*
      2  1.1  mrg  * Copyright 2017      Sven Verdoolaege
      3  1.1  mrg  *
      4  1.1  mrg  * Use of this software is governed by the MIT license
      5  1.1  mrg  *
      6  1.1  mrg  * Written by Sven Verdoolaege.
      7  1.1  mrg  */
      8  1.1  mrg 
      9  1.1  mrg /* These versions of the explicit domain functions are used
     10  1.1  mrg  * when the multi expression may have an explicit domain.
     11  1.1  mrg  */
     12  1.1  mrg 
     13  1.1  mrg #include <isl_multi_macro.h>
     14  1.1  mrg 
     15  1.1  mrg __isl_give MULTI(BASE) *FN(MULTI(BASE),cow)(__isl_take MULTI(BASE) *multi);
     16  1.1  mrg 
     17  1.1  mrg /* Does "multi" have an explicit domain?
     18  1.1  mrg  *
     19  1.1  mrg  * An explicit domain is only available if "multi" is zero-dimensional.
     20  1.1  mrg  */
     21  1.1  mrg static int FN(MULTI(BASE),has_explicit_domain)(__isl_keep MULTI(BASE) *multi)
     22  1.1  mrg {
     23  1.1  mrg 	return multi && multi->n == 0;
     24  1.1  mrg }
     25  1.1  mrg 
     26  1.1  mrg /* Check that "multi" has an explicit domain.
     27  1.1  mrg  */
     28  1.1  mrg static isl_stat FN(MULTI(BASE),check_has_explicit_domain)(
     29  1.1  mrg 	__isl_keep MULTI(BASE) *multi)
     30  1.1  mrg {
     31  1.1  mrg 	if (!multi)
     32  1.1  mrg 		return isl_stat_error;
     33  1.1  mrg 	if (!FN(MULTI(BASE),has_explicit_domain)(multi))
     34  1.1  mrg 		isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_internal,
     35  1.1  mrg 			"expression does not have an explicit domain",
     36  1.1  mrg 			return isl_stat_error);
     37  1.1  mrg 	return isl_stat_ok;
     38  1.1  mrg }
     39  1.1  mrg 
     40  1.1  mrg /* Return the explicit domain of "multi", assuming it has one.
     41  1.1  mrg  */
     42  1.1  mrg static __isl_keep DOM *FN(MULTI(BASE),peek_explicit_domain)(
     43  1.1  mrg 	__isl_keep MULTI(BASE) *multi)
     44  1.1  mrg {
     45  1.1  mrg 	if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)
     46  1.1  mrg 		return NULL;
     47  1.1  mrg 	return multi->u.dom;
     48  1.1  mrg }
     49  1.1  mrg 
     50  1.1  mrg /* Return a copy of the explicit domain of "multi", assuming it has one.
     51  1.1  mrg  */
     52  1.1  mrg static __isl_give DOM *FN(MULTI(BASE),get_explicit_domain)(
     53  1.1  mrg 	__isl_keep MULTI(BASE) *multi)
     54  1.1  mrg {
     55  1.1  mrg 	return FN(DOM,copy)(FN(MULTI(BASE),peek_explicit_domain)(multi));
     56  1.1  mrg }
     57  1.1  mrg 
     58  1.1  mrg /* Replace the explicit domain of "multi" by "dom", assuming it has one.
     59  1.1  mrg  */
     60  1.1  mrg static __isl_give MULTI(BASE) *FN(MULTI(BASE),set_explicit_domain)(
     61  1.1  mrg 	__isl_take MULTI(BASE) *multi, __isl_take DOM *dom)
     62  1.1  mrg {
     63  1.1  mrg 	if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)
     64  1.1  mrg 		goto error;
     65  1.1  mrg 	multi = FN(MULTI(BASE),cow)(multi);
     66  1.1  mrg 	if (!multi || !dom)
     67  1.1  mrg 		goto error;
     68  1.1  mrg 	FN(DOM,free)(multi->u.dom);
     69  1.1  mrg 	multi->u.dom = dom;
     70  1.1  mrg 	if (!multi->u.dom)
     71  1.1  mrg 		return FN(MULTI(BASE),free)(multi);
     72  1.1  mrg 	return multi;
     73  1.1  mrg error:
     74  1.1  mrg 	FN(MULTI(BASE),free)(multi);
     75  1.1  mrg 	FN(DOM,free)(dom);
     76  1.1  mrg 	return NULL;
     77  1.1  mrg }
     78  1.1  mrg 
     79  1.1  mrg /* Intersect the domain of "dst" with the explicit domain of "src".
     80  1.1  mrg  *
     81  1.1  mrg  * In the case of isl_multi_union_pw_aff objects, the explicit domain
     82  1.1  mrg  * of "src" is allowed to have only constraints on the parameters, even
     83  1.1  mrg  * if the domain of "dst" contains actual domain elements.  In this case,
     84  1.1  mrg  * the domain of "dst" is intersected with those parameter constraints.
     85  1.1  mrg  */
     86  1.1  mrg static __isl_give MULTI(BASE) *FN(MULTI(BASE),intersect_explicit_domain)(
     87  1.1  mrg 	__isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src)
     88  1.1  mrg {
     89  1.1  mrg 	isl_bool is_params;
     90  1.1  mrg 	DOM *dom;
     91  1.1  mrg 
     92  1.1  mrg 	dom = FN(MULTI(BASE),peek_explicit_domain)(src);
     93  1.1  mrg 	is_params = FN(DOM,is_params)(dom);
     94  1.1  mrg 	if (is_params < 0)
     95  1.1  mrg 		return FN(MULTI(BASE),free)(dst);
     96  1.1  mrg 
     97  1.1  mrg 	dom = FN(DOM,copy)(dom);
     98  1.1  mrg 	if (!is_params) {
     99  1.1  mrg 		dst = FN(MULTI(BASE),intersect_domain)(dst, dom);
    100  1.1  mrg 	} else {
    101  1.1  mrg 		isl_set *params;
    102  1.1  mrg 
    103  1.1  mrg 		params = FN(DOM,params)(dom);
    104  1.1  mrg 		dst = FN(MULTI(BASE),intersect_params)(dst, params);
    105  1.1  mrg 	}
    106  1.1  mrg 
    107  1.1  mrg 	return dst;
    108  1.1  mrg }
    109  1.1  mrg 
    110  1.1  mrg /* Set the explicit domain of "dst" to that of "src".
    111  1.1  mrg  */
    112  1.1  mrg static __isl_give MULTI(BASE) *FN(MULTI(BASE),copy_explicit_domain)(
    113  1.1  mrg 	__isl_take MULTI(BASE) *dst, __isl_keep MULTI(BASE) *src)
    114  1.1  mrg {
    115  1.1  mrg 	DOM *dom;
    116  1.1  mrg 
    117  1.1  mrg 	dom = FN(MULTI(BASE),get_explicit_domain)(src);
    118  1.1  mrg 	dst = FN(MULTI(BASE),set_explicit_domain)(dst, dom);
    119  1.1  mrg 
    120  1.1  mrg 	return dst;
    121  1.1  mrg }
    122  1.1  mrg 
    123  1.1  mrg /* Align the parameters of the explicit domain of "multi" to those of "space".
    124  1.1  mrg  */
    125  1.1  mrg static __isl_give MULTI(BASE) *FN(MULTI(BASE),align_explicit_domain_params)(
    126  1.1  mrg 	__isl_take MULTI(BASE) *multi, __isl_take isl_space *space)
    127  1.1  mrg {
    128  1.1  mrg 	DOM *dom;
    129  1.1  mrg 
    130  1.1  mrg 	dom = FN(MULTI(BASE),get_explicit_domain)(multi);
    131  1.1  mrg 	dom = FN(DOM,align_params)(dom, space);
    132  1.1  mrg 	multi = FN(MULTI(BASE),set_explicit_domain)(multi, dom);
    133  1.1  mrg 
    134  1.1  mrg 	return multi;
    135  1.1  mrg }
    136  1.1  mrg 
    137  1.1  mrg /* Replace the space of the explicit domain of "multi" by "space",
    138  1.1  mrg  * without modifying its dimension.
    139  1.1  mrg  */
    140  1.1  mrg static __isl_give MULTI(BASE) *FN(MULTI(BASE),reset_explicit_domain_space)(
    141  1.1  mrg 	__isl_take MULTI(BASE) *multi, __isl_take isl_space *space)
    142  1.1  mrg {
    143  1.1  mrg 	DOM *dom;
    144  1.1  mrg 
    145  1.1  mrg 	dom = FN(MULTI(BASE),get_explicit_domain)(multi);
    146  1.1  mrg 	dom = FN(DOM,reset_equal_dim_space)(dom, space);
    147  1.1  mrg 	multi = FN(MULTI(BASE),set_explicit_domain)(multi, dom);
    148  1.1  mrg 
    149  1.1  mrg 	return multi;
    150  1.1  mrg }
    151  1.1  mrg 
    152  1.1  mrg /* Free the explicit domain of "multi".
    153  1.1  mrg  */
    154  1.1  mrg static void FN(MULTI(BASE),free_explicit_domain)(__isl_keep MULTI(BASE) *multi)
    155  1.1  mrg {
    156  1.1  mrg 	if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)
    157  1.1  mrg 		return;
    158  1.1  mrg 	FN(DOM,free)(multi->u.dom);
    159  1.1  mrg }
    160  1.1  mrg 
    161  1.1  mrg /* Do "multi1" and "multi2" have the same explicit domain?
    162  1.1  mrg  */
    163  1.1  mrg static isl_bool FN(MULTI(BASE),equal_explicit_domain)(
    164  1.1  mrg 	__isl_keep MULTI(BASE) *multi1, __isl_keep MULTI(BASE) *multi2)
    165  1.1  mrg {
    166  1.1  mrg 	DOM *dom1, *dom2;
    167  1.1  mrg 	isl_bool equal;
    168  1.1  mrg 
    169  1.1  mrg 	if (FN(MULTI(BASE),check_has_explicit_domain)(multi1) < 0 ||
    170  1.1  mrg 	    FN(MULTI(BASE),check_has_explicit_domain)(multi2) < 0)
    171  1.1  mrg 		return isl_bool_error;
    172  1.1  mrg 	dom1 = FN(MULTI(BASE),get_explicit_domain)(multi1);
    173  1.1  mrg 	dom2 = FN(MULTI(BASE),get_explicit_domain)(multi2);
    174  1.1  mrg 	equal = FN(DOM,is_equal)(dom1, dom2);
    175  1.1  mrg 	FN(DOM,free)(dom1);
    176  1.1  mrg 	FN(DOM,free)(dom2);
    177  1.1  mrg 
    178  1.1  mrg 	return equal;
    179  1.1  mrg }
    180  1.1  mrg 
    181  1.1  mrg static isl_stat FN(MULTI(BASE),check_explicit_domain)(
    182  1.1  mrg 	__isl_keep MULTI(BASE) *multi) __attribute__ ((unused));
    183  1.1  mrg 
    184  1.1  mrg /* Debugging function to check that the explicit domain of "multi"
    185  1.1  mrg  * has the correct space.
    186  1.1  mrg  */
    187  1.1  mrg isl_stat FN(MULTI(BASE),check_explicit_domain)(__isl_keep MULTI(BASE) *multi)
    188  1.1  mrg {
    189  1.1  mrg 	isl_space *space1, *space2;
    190  1.1  mrg 	isl_bool equal;
    191  1.1  mrg 
    192  1.1  mrg 	if (FN(MULTI(BASE),check_has_explicit_domain)(multi) < 0)
    193  1.1  mrg 		return isl_stat_error;
    194  1.1  mrg 	space1 = isl_space_domain(isl_space_copy(multi->space));
    195  1.1  mrg 	space2 = FN(DOM,get_space)(multi->u.dom);
    196  1.1  mrg 	equal = isl_space_is_equal(space1, space2);
    197  1.1  mrg 	isl_space_free(space1);
    198  1.1  mrg 	isl_space_free(space2);
    199  1.1  mrg 	if (equal < 0)
    200  1.1  mrg 		return isl_stat_error;
    201  1.1  mrg 	if (!equal)
    202  1.1  mrg 		isl_die(FN(MULTI(BASE),get_ctx)(multi), isl_error_internal,
    203  1.1  mrg 			"check failed", return isl_stat_error);
    204  1.1  mrg 	return isl_stat_ok;
    205  1.1  mrg }
    206