Home | History | Annotate | Line # | Download | only in dist
      1  1.1  mrg /*
      2  1.1  mrg  * Copyright 2011      INRIA Saclay
      3  1.1  mrg  * Copyright 2011      Sven Verdoolaege
      4  1.1  mrg  * Copyright 2012-2014 Ecole Normale Superieure
      5  1.1  mrg  * Copyright 2014      INRIA Rocquencourt
      6  1.1  mrg  * Copyright 2016      Sven Verdoolaege
      7  1.1  mrg  * Copyright 2018,2020 Cerebras Systems
      8  1.1  mrg  * Copyright 2021      Sven Verdoolaege
      9  1.1  mrg  * Copyright 2022      Cerebras Systems
     10  1.1  mrg  *
     11  1.1  mrg  * Use of this software is governed by the MIT license
     12  1.1  mrg  *
     13  1.1  mrg  * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
     14  1.1  mrg  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
     15  1.1  mrg  * 91893 Orsay, France
     16  1.1  mrg  * and Ecole Normale Superieure, 45 rue dUlm, 75230 Paris, France
     17  1.1  mrg  * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
     18  1.1  mrg  * B.P. 105 - 78153 Le Chesnay, France
     19  1.1  mrg  * and Cerebras Systems, 175 S San Antonio Rd, Los Altos, CA, USA
     20  1.1  mrg  * and Cerebras Systems, 1237 E Arques Ave, Sunnyvale, CA, USA
     21  1.1  mrg  */
     22  1.1  mrg 
     23  1.1  mrg #include <isl_ctx_private.h>
     24  1.1  mrg #include <isl_map_private.h>
     25  1.1  mrg #include <isl_union_map_private.h>
     26  1.1  mrg #include <isl_aff_private.h>
     27  1.1  mrg #include <isl_space_private.h>
     28  1.1  mrg #include <isl_local_space_private.h>
     29  1.1  mrg #include <isl_vec_private.h>
     30  1.1  mrg #include <isl_mat_private.h>
     31  1.1  mrg #include <isl_id_private.h>
     32  1.1  mrg #include <isl/constraint.h>
     33  1.1  mrg #include <isl_seq.h>
     34  1.1  mrg #include <isl/set.h>
     35  1.1  mrg #include <isl_val_private.h>
     36  1.1  mrg #include <isl_point_private.h>
     37  1.1  mrg #include <isl_config.h>
     38  1.1  mrg 
     39  1.1  mrg #undef EL_BASE
     40  1.1  mrg #define EL_BASE aff
     41  1.1  mrg 
     42  1.1  mrg #include <isl_list_templ.c>
     43  1.1  mrg #include <isl_list_read_templ.c>
     44  1.1  mrg 
     45  1.1  mrg #undef EL_BASE
     46  1.1  mrg #define EL_BASE pw_aff
     47  1.1  mrg 
     48  1.1  mrg #include <isl_list_templ.c>
     49  1.1  mrg #include <isl_list_read_templ.c>
     50  1.1  mrg 
     51  1.1  mrg #undef EL_BASE
     52  1.1  mrg #define EL_BASE pw_multi_aff
     53  1.1  mrg 
     54  1.1  mrg #include <isl_list_templ.c>
     55  1.1  mrg #include <isl_list_read_templ.c>
     56  1.1  mrg 
     57  1.1  mrg #undef EL_BASE
     58  1.1  mrg #define EL_BASE union_pw_aff
     59  1.1  mrg 
     60  1.1  mrg #include <isl_list_templ.c>
     61  1.1  mrg #include <isl_list_read_templ.c>
     62  1.1  mrg 
     63  1.1  mrg #undef EL_BASE
     64  1.1  mrg #define EL_BASE union_pw_multi_aff
     65  1.1  mrg 
     66  1.1  mrg #include <isl_list_templ.c>
     67  1.1  mrg 
     68  1.1  mrg /* Construct an isl_aff from the given domain local space "ls" and
     69  1.1  mrg  * coefficients "v", where the local space is known to be valid
     70  1.1  mrg  * for an affine expression.
     71  1.1  mrg  */
     72  1.1  mrg static __isl_give isl_aff *isl_aff_alloc_vec_validated(
     73  1.1  mrg 	__isl_take isl_local_space *ls, __isl_take isl_vec *v)
     74  1.1  mrg {
     75  1.1  mrg 	isl_aff *aff;
     76  1.1  mrg 
     77  1.1  mrg 	if (!ls || !v)
     78  1.1  mrg 		goto error;
     79  1.1  mrg 
     80  1.1  mrg 	aff = isl_calloc_type(v->ctx, struct isl_aff);
     81  1.1  mrg 	if (!aff)
     82  1.1  mrg 		goto error;
     83  1.1  mrg 
     84  1.1  mrg 	aff->ref = 1;
     85  1.1  mrg 	aff->ls = ls;
     86  1.1  mrg 	aff->v = v;
     87  1.1  mrg 
     88  1.1  mrg 	return aff;
     89  1.1  mrg error:
     90  1.1  mrg 	isl_local_space_free(ls);
     91  1.1  mrg 	isl_vec_free(v);
     92  1.1  mrg 	return NULL;
     93  1.1  mrg }
     94  1.1  mrg 
     95  1.1  mrg /* Construct an isl_aff from the given domain local space "ls" and
     96  1.1  mrg  * coefficients "v".
     97  1.1  mrg  *
     98  1.1  mrg  * First check that "ls" is a valid domain local space
     99  1.1  mrg  * for an affine expression.
    100  1.1  mrg  */
    101  1.1  mrg __isl_give isl_aff *isl_aff_alloc_vec(__isl_take isl_local_space *ls,
    102  1.1  mrg 	__isl_take isl_vec *v)
    103  1.1  mrg {
    104  1.1  mrg 	isl_ctx *ctx;
    105  1.1  mrg 
    106  1.1  mrg 	if (!ls)
    107  1.1  mrg 		return NULL;
    108  1.1  mrg 
    109  1.1  mrg 	ctx = isl_local_space_get_ctx(ls);
    110  1.1  mrg 	if (!isl_local_space_divs_known(ls))
    111  1.1  mrg 		isl_die(ctx, isl_error_invalid, "local space has unknown divs",
    112  1.1  mrg 			goto error);
    113  1.1  mrg 	if (!isl_local_space_is_set(ls))
    114  1.1  mrg 		isl_die(ctx, isl_error_invalid,
    115  1.1  mrg 			"domain of affine expression should be a set",
    116  1.1  mrg 			goto error);
    117  1.1  mrg 	return isl_aff_alloc_vec_validated(ls, v);
    118  1.1  mrg error:
    119  1.1  mrg 	isl_local_space_free(ls);
    120  1.1  mrg 	isl_vec_free(v);
    121  1.1  mrg 	return NULL;
    122  1.1  mrg }
    123  1.1  mrg 
    124  1.1  mrg __isl_give isl_aff *isl_aff_alloc(__isl_take isl_local_space *ls)
    125  1.1  mrg {
    126  1.1  mrg 	isl_ctx *ctx;
    127  1.1  mrg 	isl_vec *v;
    128  1.1  mrg 	isl_size total;
    129  1.1  mrg 
    130  1.1  mrg 	if (!ls)
    131  1.1  mrg 		return NULL;
    132  1.1  mrg 
    133  1.1  mrg 	ctx = isl_local_space_get_ctx(ls);
    134  1.1  mrg 
    135  1.1  mrg 	total = isl_local_space_dim(ls, isl_dim_all);
    136  1.1  mrg 	if (total < 0)
    137  1.1  mrg 		goto error;
    138  1.1  mrg 	v = isl_vec_alloc(ctx, 1 + 1 + total);
    139  1.1  mrg 	return isl_aff_alloc_vec(ls, v);
    140  1.1  mrg error:
    141  1.1  mrg 	isl_local_space_free(ls);
    142  1.1  mrg 	return NULL;
    143  1.1  mrg }
    144  1.1  mrg 
    145  1.1  mrg __isl_give isl_aff *isl_aff_copy(__isl_keep isl_aff *aff)
    146  1.1  mrg {
    147  1.1  mrg 	if (!aff)
    148  1.1  mrg 		return NULL;
    149  1.1  mrg 
    150  1.1  mrg 	aff->ref++;
    151  1.1  mrg 	return aff;
    152  1.1  mrg }
    153  1.1  mrg 
    154  1.1  mrg __isl_give isl_aff *isl_aff_dup(__isl_keep isl_aff *aff)
    155  1.1  mrg {
    156  1.1  mrg 	if (!aff)
    157  1.1  mrg 		return NULL;
    158  1.1  mrg 
    159  1.1  mrg 	return isl_aff_alloc_vec_validated(isl_local_space_copy(aff->ls),
    160  1.1  mrg 					    isl_vec_copy(aff->v));
    161  1.1  mrg }
    162  1.1  mrg 
    163  1.1  mrg __isl_give isl_aff *isl_aff_cow(__isl_take isl_aff *aff)
    164  1.1  mrg {
    165  1.1  mrg 	if (!aff)
    166  1.1  mrg 		return NULL;
    167  1.1  mrg 
    168  1.1  mrg 	if (aff->ref == 1)
    169  1.1  mrg 		return aff;
    170  1.1  mrg 	aff->ref--;
    171  1.1  mrg 	return isl_aff_dup(aff);
    172  1.1  mrg }
    173  1.1  mrg 
    174  1.1  mrg /* Return a copy of the rational affine expression of "aff".
    175  1.1  mrg  */
    176  1.1  mrg static __isl_give isl_vec *isl_aff_get_rat_aff(__isl_keep isl_aff *aff)
    177  1.1  mrg {
    178  1.1  mrg 	if (!aff)
    179  1.1  mrg 		return NULL;
    180  1.1  mrg 	return isl_vec_copy(aff->v);
    181  1.1  mrg }
    182  1.1  mrg 
    183  1.1  mrg /* Return the rational affine expression of "aff".
    184  1.1  mrg  * This may be either a copy or the expression itself
    185  1.1  mrg  * if there is only one reference to "aff".
    186  1.1  mrg  * This allows the expression to be modified inplace
    187  1.1  mrg  * if both the "aff" and its expression have only a single reference.
    188  1.1  mrg  * The caller is not allowed to modify "aff" between this call and
    189  1.1  mrg  * a subsequent call to isl_aff_restore_rat_aff.
    190  1.1  mrg  * The only exception is that isl_aff_free can be called instead.
    191  1.1  mrg  */
    192  1.1  mrg static __isl_give isl_vec *isl_aff_take_rat_aff(__isl_keep isl_aff *aff)
    193  1.1  mrg {
    194  1.1  mrg 	isl_vec *v;
    195  1.1  mrg 
    196  1.1  mrg 	if (!aff)
    197  1.1  mrg 		return NULL;
    198  1.1  mrg 	if (aff->ref != 1)
    199  1.1  mrg 		return isl_aff_get_rat_aff(aff);
    200  1.1  mrg 	v = aff->v;
    201  1.1  mrg 	aff->v = NULL;
    202  1.1  mrg 	return v;
    203  1.1  mrg }
    204  1.1  mrg 
    205  1.1  mrg /* Set the rational affine expression of "aff" to "v",
    206  1.1  mrg  * where the rational affine expression of "aff" may be missing
    207  1.1  mrg  * due to a preceding call to isl_aff_take_rat_aff.
    208  1.1  mrg  * However, in this case, "aff" only has a single reference and
    209  1.1  mrg  * then the call to isl_aff_cow has no effect.
    210  1.1  mrg  */
    211  1.1  mrg static __isl_give isl_aff *isl_aff_restore_rat_aff(__isl_keep isl_aff *aff,
    212  1.1  mrg 	__isl_take isl_vec *v)
    213  1.1  mrg {
    214  1.1  mrg 	if (!aff || !v)
    215  1.1  mrg 		goto error;
    216  1.1  mrg 
    217  1.1  mrg 	if (aff->v == v) {
    218  1.1  mrg 		isl_vec_free(v);
    219  1.1  mrg 		return aff;
    220  1.1  mrg 	}
    221  1.1  mrg 
    222  1.1  mrg 	aff = isl_aff_cow(aff);
    223  1.1  mrg 	if (!aff)
    224  1.1  mrg 		goto error;
    225  1.1  mrg 	isl_vec_free(aff->v);
    226  1.1  mrg 	aff->v = v;
    227  1.1  mrg 
    228  1.1  mrg 	return aff;
    229  1.1  mrg error:
    230  1.1  mrg 	isl_aff_free(aff);
    231  1.1  mrg 	isl_vec_free(v);
    232  1.1  mrg 	return NULL;
    233  1.1  mrg }
    234  1.1  mrg 
    235  1.1  mrg __isl_give isl_aff *isl_aff_zero_on_domain(__isl_take isl_local_space *ls)
    236  1.1  mrg {
    237  1.1  mrg 	isl_aff *aff;
    238  1.1  mrg 
    239  1.1  mrg 	aff = isl_aff_alloc(ls);
    240  1.1  mrg 	if (!aff)
    241  1.1  mrg 		return NULL;
    242  1.1  mrg 
    243  1.1  mrg 	isl_int_set_si(aff->v->el[0], 1);
    244  1.1  mrg 	isl_seq_clr(aff->v->el + 1, aff->v->size - 1);
    245  1.1  mrg 
    246  1.1  mrg 	return aff;
    247  1.1  mrg }
    248  1.1  mrg 
    249  1.1  mrg /* Return an affine expression that is equal to zero on domain space "space".
    250  1.1  mrg  */
    251  1.1  mrg __isl_give isl_aff *isl_aff_zero_on_domain_space(__isl_take isl_space *space)
    252  1.1  mrg {
    253  1.1  mrg 	return isl_aff_zero_on_domain(isl_local_space_from_space(space));
    254  1.1  mrg }
    255  1.1  mrg 
    256  1.1  mrg /* This function performs the same operation as isl_aff_zero_on_domain_space,
    257  1.1  mrg  * but is considered as a function on an isl_space when exported.
    258  1.1  mrg  */
    259  1.1  mrg __isl_give isl_aff *isl_space_zero_aff_on_domain(__isl_take isl_space *space)
    260  1.1  mrg {
    261  1.1  mrg 	return isl_aff_zero_on_domain_space(space);
    262  1.1  mrg }
    263  1.1  mrg 
    264  1.1  mrg /* Return a piecewise affine expression defined on the specified domain
    265  1.1  mrg  * that is equal to zero.
    266  1.1  mrg  */
    267  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_zero_on_domain(__isl_take isl_local_space *ls)
    268  1.1  mrg {
    269  1.1  mrg 	return isl_pw_aff_from_aff(isl_aff_zero_on_domain(ls));
    270  1.1  mrg }
    271  1.1  mrg 
    272  1.1  mrg /* Change "aff" into a NaN.
    273  1.1  mrg  *
    274  1.1  mrg  * Note that this function gets called from isl_aff_nan_on_domain,
    275  1.1  mrg  * so "aff" may not have been initialized yet.
    276  1.1  mrg  */
    277  1.1  mrg static __isl_give isl_aff *isl_aff_set_nan(__isl_take isl_aff *aff)
    278  1.1  mrg {
    279  1.1  mrg 	isl_vec *v;
    280  1.1  mrg 
    281  1.1  mrg 	v = isl_aff_take_rat_aff(aff);
    282  1.1  mrg 	v = isl_vec_clr(v);
    283  1.1  mrg 	aff = isl_aff_restore_rat_aff(aff, v);
    284  1.1  mrg 
    285  1.1  mrg 	return aff;
    286  1.1  mrg }
    287  1.1  mrg 
    288  1.1  mrg /* Return an affine expression defined on the specified domain
    289  1.1  mrg  * that represents NaN.
    290  1.1  mrg  */
    291  1.1  mrg __isl_give isl_aff *isl_aff_nan_on_domain(__isl_take isl_local_space *ls)
    292  1.1  mrg {
    293  1.1  mrg 	isl_aff *aff;
    294  1.1  mrg 
    295  1.1  mrg 	aff = isl_aff_alloc(ls);
    296  1.1  mrg 	return isl_aff_set_nan(aff);
    297  1.1  mrg }
    298  1.1  mrg 
    299  1.1  mrg /* Return an affine expression defined on the specified domain space
    300  1.1  mrg  * that represents NaN.
    301  1.1  mrg  */
    302  1.1  mrg __isl_give isl_aff *isl_aff_nan_on_domain_space(__isl_take isl_space *space)
    303  1.1  mrg {
    304  1.1  mrg 	return isl_aff_nan_on_domain(isl_local_space_from_space(space));
    305  1.1  mrg }
    306  1.1  mrg 
    307  1.1  mrg /* Return a piecewise affine expression defined on the specified domain space
    308  1.1  mrg  * that represents NaN.
    309  1.1  mrg  */
    310  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_nan_on_domain_space(
    311  1.1  mrg 	__isl_take isl_space *space)
    312  1.1  mrg {
    313  1.1  mrg 	return isl_pw_aff_from_aff(isl_aff_nan_on_domain_space(space));
    314  1.1  mrg }
    315  1.1  mrg 
    316  1.1  mrg /* Return a piecewise affine expression defined on the specified domain
    317  1.1  mrg  * that represents NaN.
    318  1.1  mrg  */
    319  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_nan_on_domain(__isl_take isl_local_space *ls)
    320  1.1  mrg {
    321  1.1  mrg 	return isl_pw_aff_from_aff(isl_aff_nan_on_domain(ls));
    322  1.1  mrg }
    323  1.1  mrg 
    324  1.1  mrg /* Return an affine expression that is equal to "val" on
    325  1.1  mrg  * domain local space "ls".
    326  1.1  mrg  *
    327  1.1  mrg  * Note that the encoding for the special value NaN
    328  1.1  mrg  * is the same in isl_val and isl_aff, so this does not need
    329  1.1  mrg  * to be treated in any special way.
    330  1.1  mrg  */
    331  1.1  mrg __isl_give isl_aff *isl_aff_val_on_domain(__isl_take isl_local_space *ls,
    332  1.1  mrg 	__isl_take isl_val *val)
    333  1.1  mrg {
    334  1.1  mrg 	isl_aff *aff;
    335  1.1  mrg 
    336  1.1  mrg 	if (!ls || !val)
    337  1.1  mrg 		goto error;
    338  1.1  mrg 	if (!isl_val_is_rat(val) && !isl_val_is_nan(val))
    339  1.1  mrg 		isl_die(isl_val_get_ctx(val), isl_error_invalid,
    340  1.1  mrg 			"expecting rational value or NaN", goto error);
    341  1.1  mrg 
    342  1.1  mrg 	aff = isl_aff_alloc(isl_local_space_copy(ls));
    343  1.1  mrg 	if (!aff)
    344  1.1  mrg 		goto error;
    345  1.1  mrg 
    346  1.1  mrg 	isl_seq_clr(aff->v->el + 2, aff->v->size - 2);
    347  1.1  mrg 	isl_int_set(aff->v->el[1], val->n);
    348  1.1  mrg 	isl_int_set(aff->v->el[0], val->d);
    349  1.1  mrg 
    350  1.1  mrg 	isl_local_space_free(ls);
    351  1.1  mrg 	isl_val_free(val);
    352  1.1  mrg 	return aff;
    353  1.1  mrg error:
    354  1.1  mrg 	isl_local_space_free(ls);
    355  1.1  mrg 	isl_val_free(val);
    356  1.1  mrg 	return NULL;
    357  1.1  mrg }
    358  1.1  mrg 
    359  1.1  mrg /* Return an affine expression that is equal to "val" on domain space "space".
    360  1.1  mrg  */
    361  1.1  mrg __isl_give isl_aff *isl_aff_val_on_domain_space(__isl_take isl_space *space,
    362  1.1  mrg 	__isl_take isl_val *val)
    363  1.1  mrg {
    364  1.1  mrg 	return isl_aff_val_on_domain(isl_local_space_from_space(space), val);
    365  1.1  mrg }
    366  1.1  mrg 
    367  1.1  mrg /* Return an affine expression that is equal to the specified dimension
    368  1.1  mrg  * in "ls".
    369  1.1  mrg  */
    370  1.1  mrg __isl_give isl_aff *isl_aff_var_on_domain(__isl_take isl_local_space *ls,
    371  1.1  mrg 	enum isl_dim_type type, unsigned pos)
    372  1.1  mrg {
    373  1.1  mrg 	isl_space *space;
    374  1.1  mrg 	isl_aff *aff;
    375  1.1  mrg 
    376  1.1  mrg 	if (!ls)
    377  1.1  mrg 		return NULL;
    378  1.1  mrg 
    379  1.1  mrg 	space = isl_local_space_get_space(ls);
    380  1.1  mrg 	if (!space)
    381  1.1  mrg 		goto error;
    382  1.1  mrg 	if (isl_space_is_map(space))
    383  1.1  mrg 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
    384  1.1  mrg 			"expecting (parameter) set space", goto error);
    385  1.1  mrg 	if (isl_local_space_check_range(ls, type, pos, 1) < 0)
    386  1.1  mrg 		goto error;
    387  1.1  mrg 
    388  1.1  mrg 	isl_space_free(space);
    389  1.1  mrg 	aff = isl_aff_alloc(ls);
    390  1.1  mrg 	if (!aff)
    391  1.1  mrg 		return NULL;
    392  1.1  mrg 
    393  1.1  mrg 	pos += isl_local_space_offset(aff->ls, type);
    394  1.1  mrg 
    395  1.1  mrg 	isl_int_set_si(aff->v->el[0], 1);
    396  1.1  mrg 	isl_seq_clr(aff->v->el + 1, aff->v->size - 1);
    397  1.1  mrg 	isl_int_set_si(aff->v->el[1 + pos], 1);
    398  1.1  mrg 
    399  1.1  mrg 	return aff;
    400  1.1  mrg error:
    401  1.1  mrg 	isl_local_space_free(ls);
    402  1.1  mrg 	isl_space_free(space);
    403  1.1  mrg 	return NULL;
    404  1.1  mrg }
    405  1.1  mrg 
    406  1.1  mrg /* Return a piecewise affine expression that is equal to
    407  1.1  mrg  * the specified dimension in "ls".
    408  1.1  mrg  */
    409  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_var_on_domain(__isl_take isl_local_space *ls,
    410  1.1  mrg 	enum isl_dim_type type, unsigned pos)
    411  1.1  mrg {
    412  1.1  mrg 	return isl_pw_aff_from_aff(isl_aff_var_on_domain(ls, type, pos));
    413  1.1  mrg }
    414  1.1  mrg 
    415  1.1  mrg /* Return an affine expression that is equal to the parameter
    416  1.1  mrg  * in the domain space "space" with identifier "id".
    417  1.1  mrg  */
    418  1.1  mrg __isl_give isl_aff *isl_aff_param_on_domain_space_id(
    419  1.1  mrg 	__isl_take isl_space *space, __isl_take isl_id *id)
    420  1.1  mrg {
    421  1.1  mrg 	int pos;
    422  1.1  mrg 	isl_local_space *ls;
    423  1.1  mrg 
    424  1.1  mrg 	if (!space || !id)
    425  1.1  mrg 		goto error;
    426  1.1  mrg 	pos = isl_space_find_dim_by_id(space, isl_dim_param, id);
    427  1.1  mrg 	if (pos < 0)
    428  1.1  mrg 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
    429  1.1  mrg 			"parameter not found in space", goto error);
    430  1.1  mrg 	isl_id_free(id);
    431  1.1  mrg 	ls = isl_local_space_from_space(space);
    432  1.1  mrg 	return isl_aff_var_on_domain(ls, isl_dim_param, pos);
    433  1.1  mrg error:
    434  1.1  mrg 	isl_space_free(space);
    435  1.1  mrg 	isl_id_free(id);
    436  1.1  mrg 	return NULL;
    437  1.1  mrg }
    438  1.1  mrg 
    439  1.1  mrg /* This function performs the same operation as
    440  1.1  mrg  * isl_aff_param_on_domain_space_id,
    441  1.1  mrg  * but is considered as a function on an isl_space when exported.
    442  1.1  mrg  */
    443  1.1  mrg __isl_give isl_aff *isl_space_param_aff_on_domain_id(
    444  1.1  mrg 	__isl_take isl_space *space, __isl_take isl_id *id)
    445  1.1  mrg {
    446  1.1  mrg 	return isl_aff_param_on_domain_space_id(space, id);
    447  1.1  mrg }
    448  1.1  mrg 
    449  1.1  mrg __isl_null isl_aff *isl_aff_free(__isl_take isl_aff *aff)
    450  1.1  mrg {
    451  1.1  mrg 	if (!aff)
    452  1.1  mrg 		return NULL;
    453  1.1  mrg 
    454  1.1  mrg 	if (--aff->ref > 0)
    455  1.1  mrg 		return NULL;
    456  1.1  mrg 
    457  1.1  mrg 	isl_local_space_free(aff->ls);
    458  1.1  mrg 	isl_vec_free(aff->v);
    459  1.1  mrg 
    460  1.1  mrg 	free(aff);
    461  1.1  mrg 
    462  1.1  mrg 	return NULL;
    463  1.1  mrg }
    464  1.1  mrg 
    465  1.1  mrg isl_ctx *isl_aff_get_ctx(__isl_keep isl_aff *aff)
    466  1.1  mrg {
    467  1.1  mrg 	return aff ? isl_local_space_get_ctx(aff->ls) : NULL;
    468  1.1  mrg }
    469  1.1  mrg 
    470  1.1  mrg /* Return a hash value that digests "aff".
    471  1.1  mrg  */
    472  1.1  mrg uint32_t isl_aff_get_hash(__isl_keep isl_aff *aff)
    473  1.1  mrg {
    474  1.1  mrg 	uint32_t hash, ls_hash, v_hash;
    475  1.1  mrg 
    476  1.1  mrg 	if (!aff)
    477  1.1  mrg 		return 0;
    478  1.1  mrg 
    479  1.1  mrg 	hash = isl_hash_init();
    480  1.1  mrg 	ls_hash = isl_local_space_get_hash(aff->ls);
    481  1.1  mrg 	isl_hash_hash(hash, ls_hash);
    482  1.1  mrg 	v_hash = isl_vec_get_hash(aff->v);
    483  1.1  mrg 	isl_hash_hash(hash, v_hash);
    484  1.1  mrg 
    485  1.1  mrg 	return hash;
    486  1.1  mrg }
    487  1.1  mrg 
    488  1.1  mrg /* Return the domain local space of "aff".
    489  1.1  mrg  */
    490  1.1  mrg static __isl_keep isl_local_space *isl_aff_peek_domain_local_space(
    491  1.1  mrg 	__isl_keep isl_aff *aff)
    492  1.1  mrg {
    493  1.1  mrg 	return aff ? aff->ls : NULL;
    494  1.1  mrg }
    495  1.1  mrg 
    496  1.1  mrg /* Return the number of variables of the given type in the domain of "aff".
    497  1.1  mrg  */
    498  1.1  mrg isl_size isl_aff_domain_dim(__isl_keep isl_aff *aff, enum isl_dim_type type)
    499  1.1  mrg {
    500  1.1  mrg 	isl_local_space *ls;
    501  1.1  mrg 
    502  1.1  mrg 	ls = isl_aff_peek_domain_local_space(aff);
    503  1.1  mrg 	return isl_local_space_dim(ls, type);
    504  1.1  mrg }
    505  1.1  mrg 
    506  1.1  mrg /* Externally, an isl_aff has a map space, but internally, the
    507  1.1  mrg  * ls field corresponds to the domain of that space.
    508  1.1  mrg  */
    509  1.1  mrg isl_size isl_aff_dim(__isl_keep isl_aff *aff, enum isl_dim_type type)
    510  1.1  mrg {
    511  1.1  mrg 	if (!aff)
    512  1.1  mrg 		return isl_size_error;
    513  1.1  mrg 	if (type == isl_dim_out)
    514  1.1  mrg 		return 1;
    515  1.1  mrg 	if (type == isl_dim_in)
    516  1.1  mrg 		type = isl_dim_set;
    517  1.1  mrg 	return isl_aff_domain_dim(aff, type);
    518  1.1  mrg }
    519  1.1  mrg 
    520  1.1  mrg /* Return the offset of the first coefficient of type "type" in
    521  1.1  mrg  * the domain of "aff".
    522  1.1  mrg  */
    523  1.1  mrg isl_size isl_aff_domain_offset(__isl_keep isl_aff *aff, enum isl_dim_type type)
    524  1.1  mrg {
    525  1.1  mrg 	isl_local_space *ls;
    526  1.1  mrg 
    527  1.1  mrg 	ls = isl_aff_peek_domain_local_space(aff);
    528  1.1  mrg 	return isl_local_space_offset(ls, type);
    529  1.1  mrg }
    530  1.1  mrg 
    531  1.1  mrg /* Return the position of the dimension of the given type and name
    532  1.1  mrg  * in "aff".
    533  1.1  mrg  * Return -1 if no such dimension can be found.
    534  1.1  mrg  */
    535  1.1  mrg int isl_aff_find_dim_by_name(__isl_keep isl_aff *aff, enum isl_dim_type type,
    536  1.1  mrg 	const char *name)
    537  1.1  mrg {
    538  1.1  mrg 	if (!aff)
    539  1.1  mrg 		return -1;
    540  1.1  mrg 	if (type == isl_dim_out)
    541  1.1  mrg 		return -1;
    542  1.1  mrg 	if (type == isl_dim_in)
    543  1.1  mrg 		type = isl_dim_set;
    544  1.1  mrg 	return isl_local_space_find_dim_by_name(aff->ls, type, name);
    545  1.1  mrg }
    546  1.1  mrg 
    547  1.1  mrg /* Return the domain space of "aff".
    548  1.1  mrg  */
    549  1.1  mrg static __isl_keep isl_space *isl_aff_peek_domain_space(__isl_keep isl_aff *aff)
    550  1.1  mrg {
    551  1.1  mrg 	return aff ? isl_local_space_peek_space(aff->ls) : NULL;
    552  1.1  mrg }
    553  1.1  mrg 
    554  1.1  mrg __isl_give isl_space *isl_aff_get_domain_space(__isl_keep isl_aff *aff)
    555  1.1  mrg {
    556  1.1  mrg 	return isl_space_copy(isl_aff_peek_domain_space(aff));
    557  1.1  mrg }
    558  1.1  mrg 
    559  1.1  mrg __isl_give isl_space *isl_aff_get_space(__isl_keep isl_aff *aff)
    560  1.1  mrg {
    561  1.1  mrg 	isl_space *space;
    562  1.1  mrg 	if (!aff)
    563  1.1  mrg 		return NULL;
    564  1.1  mrg 	space = isl_local_space_get_space(aff->ls);
    565  1.1  mrg 	space = isl_space_from_domain(space);
    566  1.1  mrg 	space = isl_space_add_dims(space, isl_dim_out, 1);
    567  1.1  mrg 	return space;
    568  1.1  mrg }
    569  1.1  mrg 
    570  1.1  mrg /* Return a copy of the domain space of "aff".
    571  1.1  mrg  */
    572  1.1  mrg __isl_give isl_local_space *isl_aff_get_domain_local_space(
    573  1.1  mrg 	__isl_keep isl_aff *aff)
    574  1.1  mrg {
    575  1.1  mrg 	return isl_local_space_copy(isl_aff_peek_domain_local_space(aff));
    576  1.1  mrg }
    577  1.1  mrg 
    578  1.1  mrg __isl_give isl_local_space *isl_aff_get_local_space(__isl_keep isl_aff *aff)
    579  1.1  mrg {
    580  1.1  mrg 	isl_local_space *ls;
    581  1.1  mrg 	if (!aff)
    582  1.1  mrg 		return NULL;
    583  1.1  mrg 	ls = isl_local_space_copy(aff->ls);
    584  1.1  mrg 	ls = isl_local_space_from_domain(ls);
    585  1.1  mrg 	ls = isl_local_space_add_dims(ls, isl_dim_out, 1);
    586  1.1  mrg 	return ls;
    587  1.1  mrg }
    588  1.1  mrg 
    589  1.1  mrg /* Return the local space of the domain of "aff".
    590  1.1  mrg  * This may be either a copy or the local space itself
    591  1.1  mrg  * if there is only one reference to "aff".
    592  1.1  mrg  * This allows the local space to be modified inplace
    593  1.1  mrg  * if both the expression and its local space have only a single reference.
    594  1.1  mrg  * The caller is not allowed to modify "aff" between this call and
    595  1.1  mrg  * a subsequent call to isl_aff_restore_domain_local_space.
    596  1.1  mrg  * The only exception is that isl_aff_free can be called instead.
    597  1.1  mrg  */
    598  1.1  mrg __isl_give isl_local_space *isl_aff_take_domain_local_space(
    599  1.1  mrg 	__isl_keep isl_aff *aff)
    600  1.1  mrg {
    601  1.1  mrg 	isl_local_space *ls;
    602  1.1  mrg 
    603  1.1  mrg 	if (!aff)
    604  1.1  mrg 		return NULL;
    605  1.1  mrg 	if (aff->ref != 1)
    606  1.1  mrg 		return isl_aff_get_domain_local_space(aff);
    607  1.1  mrg 	ls = aff->ls;
    608  1.1  mrg 	aff->ls = NULL;
    609  1.1  mrg 	return ls;
    610  1.1  mrg }
    611  1.1  mrg 
    612  1.1  mrg /* Set the local space of the domain of "aff" to "ls",
    613  1.1  mrg  * where the local space of "aff" may be missing
    614  1.1  mrg  * due to a preceding call to isl_aff_take_domain_local_space.
    615  1.1  mrg  * However, in this case, "aff" only has a single reference and
    616  1.1  mrg  * then the call to isl_aff_cow has no effect.
    617  1.1  mrg  */
    618  1.1  mrg __isl_give isl_aff *isl_aff_restore_domain_local_space(
    619  1.1  mrg 	__isl_keep isl_aff *aff, __isl_take isl_local_space *ls)
    620  1.1  mrg {
    621  1.1  mrg 	if (!aff || !ls)
    622  1.1  mrg 		goto error;
    623  1.1  mrg 
    624  1.1  mrg 	if (aff->ls == ls) {
    625  1.1  mrg 		isl_local_space_free(ls);
    626  1.1  mrg 		return aff;
    627  1.1  mrg 	}
    628  1.1  mrg 
    629  1.1  mrg 	aff = isl_aff_cow(aff);
    630  1.1  mrg 	if (!aff)
    631  1.1  mrg 		goto error;
    632  1.1  mrg 	isl_local_space_free(aff->ls);
    633  1.1  mrg 	aff->ls = ls;
    634  1.1  mrg 
    635  1.1  mrg 	return aff;
    636  1.1  mrg error:
    637  1.1  mrg 	isl_aff_free(aff);
    638  1.1  mrg 	isl_local_space_free(ls);
    639  1.1  mrg 	return NULL;
    640  1.1  mrg }
    641  1.1  mrg 
    642  1.1  mrg /* Externally, an isl_aff has a map space, but internally, the
    643  1.1  mrg  * ls field corresponds to the domain of that space.
    644  1.1  mrg  */
    645  1.1  mrg const char *isl_aff_get_dim_name(__isl_keep isl_aff *aff,
    646  1.1  mrg 	enum isl_dim_type type, unsigned pos)
    647  1.1  mrg {
    648  1.1  mrg 	if (!aff)
    649  1.1  mrg 		return NULL;
    650  1.1  mrg 	if (type == isl_dim_out)
    651  1.1  mrg 		return NULL;
    652  1.1  mrg 	if (type == isl_dim_in)
    653  1.1  mrg 		type = isl_dim_set;
    654  1.1  mrg 	return isl_local_space_get_dim_name(aff->ls, type, pos);
    655  1.1  mrg }
    656  1.1  mrg 
    657  1.1  mrg __isl_give isl_aff *isl_aff_reset_domain_space(__isl_take isl_aff *aff,
    658  1.1  mrg 	__isl_take isl_space *space)
    659  1.1  mrg {
    660  1.1  mrg 	aff = isl_aff_cow(aff);
    661  1.1  mrg 	if (!aff || !space)
    662  1.1  mrg 		goto error;
    663  1.1  mrg 
    664  1.1  mrg 	aff->ls = isl_local_space_reset_space(aff->ls, space);
    665  1.1  mrg 	if (!aff->ls)
    666  1.1  mrg 		return isl_aff_free(aff);
    667  1.1  mrg 
    668  1.1  mrg 	return aff;
    669  1.1  mrg error:
    670  1.1  mrg 	isl_aff_free(aff);
    671  1.1  mrg 	isl_space_free(space);
    672  1.1  mrg 	return NULL;
    673  1.1  mrg }
    674  1.1  mrg 
    675  1.1  mrg /* Reset the space of "aff".  This function is called from isl_pw_templ.c
    676  1.1  mrg  * and doesn't know if the space of an element object is represented
    677  1.1  mrg  * directly or through its domain.  It therefore passes along both.
    678  1.1  mrg  */
    679  1.1  mrg __isl_give isl_aff *isl_aff_reset_space_and_domain(__isl_take isl_aff *aff,
    680  1.1  mrg 	__isl_take isl_space *space, __isl_take isl_space *domain)
    681  1.1  mrg {
    682  1.1  mrg 	isl_space_free(space);
    683  1.1  mrg 	return isl_aff_reset_domain_space(aff, domain);
    684  1.1  mrg }
    685  1.1  mrg 
    686  1.1  mrg /* Reorder the dimensions of the domain of "aff" according
    687  1.1  mrg  * to the given reordering.
    688  1.1  mrg  */
    689  1.1  mrg __isl_give isl_aff *isl_aff_realign_domain(__isl_take isl_aff *aff,
    690  1.1  mrg 	__isl_take isl_reordering *r)
    691  1.1  mrg {
    692  1.1  mrg 	aff = isl_aff_cow(aff);
    693  1.1  mrg 	if (!aff)
    694  1.1  mrg 		goto error;
    695  1.1  mrg 
    696  1.1  mrg 	r = isl_reordering_extend(r, aff->ls->div->n_row);
    697  1.1  mrg 	aff->v = isl_vec_reorder(aff->v, 2, isl_reordering_copy(r));
    698  1.1  mrg 	aff->ls = isl_local_space_realign(aff->ls, r);
    699  1.1  mrg 
    700  1.1  mrg 	if (!aff->v || !aff->ls)
    701  1.1  mrg 		return isl_aff_free(aff);
    702  1.1  mrg 
    703  1.1  mrg 	return aff;
    704  1.1  mrg error:
    705  1.1  mrg 	isl_aff_free(aff);
    706  1.1  mrg 	isl_reordering_free(r);
    707  1.1  mrg 	return NULL;
    708  1.1  mrg }
    709  1.1  mrg 
    710  1.1  mrg __isl_give isl_aff *isl_aff_align_params(__isl_take isl_aff *aff,
    711  1.1  mrg 	__isl_take isl_space *model)
    712  1.1  mrg {
    713  1.1  mrg 	isl_space *domain_space;
    714  1.1  mrg 	isl_bool equal_params;
    715  1.1  mrg 
    716  1.1  mrg 	domain_space = isl_aff_peek_domain_space(aff);
    717  1.1  mrg 	equal_params = isl_space_has_equal_params(domain_space, model);
    718  1.1  mrg 	if (equal_params < 0)
    719  1.1  mrg 		goto error;
    720  1.1  mrg 	if (!equal_params) {
    721  1.1  mrg 		isl_reordering *exp;
    722  1.1  mrg 
    723  1.1  mrg 		exp = isl_parameter_alignment_reordering(domain_space, model);
    724  1.1  mrg 		aff = isl_aff_realign_domain(aff, exp);
    725  1.1  mrg 	}
    726  1.1  mrg 
    727  1.1  mrg 	isl_space_free(model);
    728  1.1  mrg 	return aff;
    729  1.1  mrg error:
    730  1.1  mrg 	isl_space_free(model);
    731  1.1  mrg 	isl_aff_free(aff);
    732  1.1  mrg 	return NULL;
    733  1.1  mrg }
    734  1.1  mrg 
    735  1.1  mrg #undef TYPE
    736  1.1  mrg #define TYPE isl_aff
    737  1.1  mrg #include "isl_unbind_params_templ.c"
    738  1.1  mrg 
    739  1.1  mrg /* Is "aff" obviously equal to zero?
    740  1.1  mrg  *
    741  1.1  mrg  * If the denominator is zero, then "aff" is not equal to zero.
    742  1.1  mrg  */
    743  1.1  mrg isl_bool isl_aff_plain_is_zero(__isl_keep isl_aff *aff)
    744  1.1  mrg {
    745  1.1  mrg 	int pos;
    746  1.1  mrg 
    747  1.1  mrg 	if (!aff)
    748  1.1  mrg 		return isl_bool_error;
    749  1.1  mrg 
    750  1.1  mrg 	if (isl_int_is_zero(aff->v->el[0]))
    751  1.1  mrg 		return isl_bool_false;
    752  1.1  mrg 	pos = isl_seq_first_non_zero(aff->v->el + 1, aff->v->size - 1);
    753  1.1  mrg 	return isl_bool_ok(pos < 0);
    754  1.1  mrg }
    755  1.1  mrg 
    756  1.1  mrg /* Does "aff" represent NaN?
    757  1.1  mrg  */
    758  1.1  mrg isl_bool isl_aff_is_nan(__isl_keep isl_aff *aff)
    759  1.1  mrg {
    760  1.1  mrg 	if (!aff)
    761  1.1  mrg 		return isl_bool_error;
    762  1.1  mrg 
    763  1.1  mrg 	return isl_bool_ok(isl_seq_first_non_zero(aff->v->el, 2) < 0);
    764  1.1  mrg }
    765  1.1  mrg 
    766  1.1  mrg /* Are "aff1" and "aff2" obviously equal?
    767  1.1  mrg  *
    768  1.1  mrg  * NaN is not equal to anything, not even to another NaN.
    769  1.1  mrg  */
    770  1.1  mrg isl_bool isl_aff_plain_is_equal(__isl_keep isl_aff *aff1,
    771  1.1  mrg 	__isl_keep isl_aff *aff2)
    772  1.1  mrg {
    773  1.1  mrg 	isl_bool equal;
    774  1.1  mrg 
    775  1.1  mrg 	if (!aff1 || !aff2)
    776  1.1  mrg 		return isl_bool_error;
    777  1.1  mrg 
    778  1.1  mrg 	if (isl_aff_is_nan(aff1) || isl_aff_is_nan(aff2))
    779  1.1  mrg 		return isl_bool_false;
    780  1.1  mrg 
    781  1.1  mrg 	equal = isl_local_space_is_equal(aff1->ls, aff2->ls);
    782  1.1  mrg 	if (equal < 0 || !equal)
    783  1.1  mrg 		return equal;
    784  1.1  mrg 
    785  1.1  mrg 	return isl_vec_is_equal(aff1->v, aff2->v);
    786  1.1  mrg }
    787  1.1  mrg 
    788  1.1  mrg /* Return the common denominator of "aff" in "v".
    789  1.1  mrg  *
    790  1.1  mrg  * We cannot return anything meaningful in case of a NaN.
    791  1.1  mrg  */
    792  1.1  mrg isl_stat isl_aff_get_denominator(__isl_keep isl_aff *aff, isl_int *v)
    793  1.1  mrg {
    794  1.1  mrg 	if (!aff)
    795  1.1  mrg 		return isl_stat_error;
    796  1.1  mrg 	if (isl_aff_is_nan(aff))
    797  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
    798  1.1  mrg 			"cannot get denominator of NaN", return isl_stat_error);
    799  1.1  mrg 	isl_int_set(*v, aff->v->el[0]);
    800  1.1  mrg 	return isl_stat_ok;
    801  1.1  mrg }
    802  1.1  mrg 
    803  1.1  mrg /* Return the common denominator of "aff".
    804  1.1  mrg  */
    805  1.1  mrg __isl_give isl_val *isl_aff_get_denominator_val(__isl_keep isl_aff *aff)
    806  1.1  mrg {
    807  1.1  mrg 	isl_ctx *ctx;
    808  1.1  mrg 
    809  1.1  mrg 	if (!aff)
    810  1.1  mrg 		return NULL;
    811  1.1  mrg 
    812  1.1  mrg 	ctx = isl_aff_get_ctx(aff);
    813  1.1  mrg 	if (isl_aff_is_nan(aff))
    814  1.1  mrg 		return isl_val_nan(ctx);
    815  1.1  mrg 	return isl_val_int_from_isl_int(ctx, aff->v->el[0]);
    816  1.1  mrg }
    817  1.1  mrg 
    818  1.1  mrg /* Return the constant term of "aff".
    819  1.1  mrg  */
    820  1.1  mrg __isl_give isl_val *isl_aff_get_constant_val(__isl_keep isl_aff *aff)
    821  1.1  mrg {
    822  1.1  mrg 	isl_ctx *ctx;
    823  1.1  mrg 	isl_val *v;
    824  1.1  mrg 
    825  1.1  mrg 	if (!aff)
    826  1.1  mrg 		return NULL;
    827  1.1  mrg 
    828  1.1  mrg 	ctx = isl_aff_get_ctx(aff);
    829  1.1  mrg 	if (isl_aff_is_nan(aff))
    830  1.1  mrg 		return isl_val_nan(ctx);
    831  1.1  mrg 	v = isl_val_rat_from_isl_int(ctx, aff->v->el[1], aff->v->el[0]);
    832  1.1  mrg 	return isl_val_normalize(v);
    833  1.1  mrg }
    834  1.1  mrg 
    835  1.1  mrg /* Return the coefficient of the variable of type "type" at position "pos"
    836  1.1  mrg  * of "aff".
    837  1.1  mrg  */
    838  1.1  mrg __isl_give isl_val *isl_aff_get_coefficient_val(__isl_keep isl_aff *aff,
    839  1.1  mrg 	enum isl_dim_type type, int pos)
    840  1.1  mrg {
    841  1.1  mrg 	isl_ctx *ctx;
    842  1.1  mrg 	isl_val *v;
    843  1.1  mrg 
    844  1.1  mrg 	if (!aff)
    845  1.1  mrg 		return NULL;
    846  1.1  mrg 
    847  1.1  mrg 	ctx = isl_aff_get_ctx(aff);
    848  1.1  mrg 	if (type == isl_dim_out)
    849  1.1  mrg 		isl_die(ctx, isl_error_invalid,
    850  1.1  mrg 			"output/set dimension does not have a coefficient",
    851  1.1  mrg 			return NULL);
    852  1.1  mrg 	if (type == isl_dim_in)
    853  1.1  mrg 		type = isl_dim_set;
    854  1.1  mrg 
    855  1.1  mrg 	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
    856  1.1  mrg 		return NULL;
    857  1.1  mrg 
    858  1.1  mrg 	if (isl_aff_is_nan(aff))
    859  1.1  mrg 		return isl_val_nan(ctx);
    860  1.1  mrg 	pos += isl_local_space_offset(aff->ls, type);
    861  1.1  mrg 	v = isl_val_rat_from_isl_int(ctx, aff->v->el[1 + pos], aff->v->el[0]);
    862  1.1  mrg 	return isl_val_normalize(v);
    863  1.1  mrg }
    864  1.1  mrg 
    865  1.1  mrg /* Return the sign of the coefficient of the variable of type "type"
    866  1.1  mrg  * at position "pos" of "aff".
    867  1.1  mrg  */
    868  1.1  mrg int isl_aff_coefficient_sgn(__isl_keep isl_aff *aff, enum isl_dim_type type,
    869  1.1  mrg 	int pos)
    870  1.1  mrg {
    871  1.1  mrg 	isl_ctx *ctx;
    872  1.1  mrg 
    873  1.1  mrg 	if (!aff)
    874  1.1  mrg 		return 0;
    875  1.1  mrg 
    876  1.1  mrg 	ctx = isl_aff_get_ctx(aff);
    877  1.1  mrg 	if (type == isl_dim_out)
    878  1.1  mrg 		isl_die(ctx, isl_error_invalid,
    879  1.1  mrg 			"output/set dimension does not have a coefficient",
    880  1.1  mrg 			return 0);
    881  1.1  mrg 	if (type == isl_dim_in)
    882  1.1  mrg 		type = isl_dim_set;
    883  1.1  mrg 
    884  1.1  mrg 	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
    885  1.1  mrg 		return 0;
    886  1.1  mrg 
    887  1.1  mrg 	pos += isl_local_space_offset(aff->ls, type);
    888  1.1  mrg 	return isl_int_sgn(aff->v->el[1 + pos]);
    889  1.1  mrg }
    890  1.1  mrg 
    891  1.1  mrg /* Replace the numerator of the constant term of "aff" by "v".
    892  1.1  mrg  *
    893  1.1  mrg  * A NaN is unaffected by this operation.
    894  1.1  mrg  */
    895  1.1  mrg __isl_give isl_aff *isl_aff_set_constant(__isl_take isl_aff *aff, isl_int v)
    896  1.1  mrg {
    897  1.1  mrg 	if (!aff)
    898  1.1  mrg 		return NULL;
    899  1.1  mrg 	if (isl_aff_is_nan(aff))
    900  1.1  mrg 		return aff;
    901  1.1  mrg 	aff = isl_aff_cow(aff);
    902  1.1  mrg 	if (!aff)
    903  1.1  mrg 		return NULL;
    904  1.1  mrg 
    905  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
    906  1.1  mrg 	if (!aff->v)
    907  1.1  mrg 		return isl_aff_free(aff);
    908  1.1  mrg 
    909  1.1  mrg 	isl_int_set(aff->v->el[1], v);
    910  1.1  mrg 
    911  1.1  mrg 	return aff;
    912  1.1  mrg }
    913  1.1  mrg 
    914  1.1  mrg /* Replace the constant term of "aff" by "v".
    915  1.1  mrg  *
    916  1.1  mrg  * A NaN is unaffected by this operation.
    917  1.1  mrg  */
    918  1.1  mrg __isl_give isl_aff *isl_aff_set_constant_val(__isl_take isl_aff *aff,
    919  1.1  mrg 	__isl_take isl_val *v)
    920  1.1  mrg {
    921  1.1  mrg 	if (!aff || !v)
    922  1.1  mrg 		goto error;
    923  1.1  mrg 
    924  1.1  mrg 	if (isl_aff_is_nan(aff)) {
    925  1.1  mrg 		isl_val_free(v);
    926  1.1  mrg 		return aff;
    927  1.1  mrg 	}
    928  1.1  mrg 
    929  1.1  mrg 	if (!isl_val_is_rat(v))
    930  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
    931  1.1  mrg 			"expecting rational value", goto error);
    932  1.1  mrg 
    933  1.1  mrg 	if (isl_int_eq(aff->v->el[1], v->n) &&
    934  1.1  mrg 	    isl_int_eq(aff->v->el[0], v->d)) {
    935  1.1  mrg 		isl_val_free(v);
    936  1.1  mrg 		return aff;
    937  1.1  mrg 	}
    938  1.1  mrg 
    939  1.1  mrg 	aff = isl_aff_cow(aff);
    940  1.1  mrg 	if (!aff)
    941  1.1  mrg 		goto error;
    942  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
    943  1.1  mrg 	if (!aff->v)
    944  1.1  mrg 		goto error;
    945  1.1  mrg 
    946  1.1  mrg 	if (isl_int_eq(aff->v->el[0], v->d)) {
    947  1.1  mrg 		isl_int_set(aff->v->el[1], v->n);
    948  1.1  mrg 	} else if (isl_int_is_one(v->d)) {
    949  1.1  mrg 		isl_int_mul(aff->v->el[1], aff->v->el[0], v->n);
    950  1.1  mrg 	} else {
    951  1.1  mrg 		isl_seq_scale(aff->v->el + 1,
    952  1.1  mrg 				aff->v->el + 1, v->d, aff->v->size - 1);
    953  1.1  mrg 		isl_int_mul(aff->v->el[1], aff->v->el[0], v->n);
    954  1.1  mrg 		isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
    955  1.1  mrg 		aff->v = isl_vec_normalize(aff->v);
    956  1.1  mrg 		if (!aff->v)
    957  1.1  mrg 			goto error;
    958  1.1  mrg 	}
    959  1.1  mrg 
    960  1.1  mrg 	isl_val_free(v);
    961  1.1  mrg 	return aff;
    962  1.1  mrg error:
    963  1.1  mrg 	isl_aff_free(aff);
    964  1.1  mrg 	isl_val_free(v);
    965  1.1  mrg 	return NULL;
    966  1.1  mrg }
    967  1.1  mrg 
    968  1.1  mrg /* Add "v" to the constant term of "aff".
    969  1.1  mrg  *
    970  1.1  mrg  * A NaN is unaffected by this operation.
    971  1.1  mrg  */
    972  1.1  mrg __isl_give isl_aff *isl_aff_add_constant(__isl_take isl_aff *aff, isl_int v)
    973  1.1  mrg {
    974  1.1  mrg 	if (isl_int_is_zero(v))
    975  1.1  mrg 		return aff;
    976  1.1  mrg 
    977  1.1  mrg 	if (!aff)
    978  1.1  mrg 		return NULL;
    979  1.1  mrg 	if (isl_aff_is_nan(aff))
    980  1.1  mrg 		return aff;
    981  1.1  mrg 	aff = isl_aff_cow(aff);
    982  1.1  mrg 	if (!aff)
    983  1.1  mrg 		return NULL;
    984  1.1  mrg 
    985  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
    986  1.1  mrg 	if (!aff->v)
    987  1.1  mrg 		return isl_aff_free(aff);
    988  1.1  mrg 
    989  1.1  mrg 	isl_int_addmul(aff->v->el[1], aff->v->el[0], v);
    990  1.1  mrg 
    991  1.1  mrg 	return aff;
    992  1.1  mrg }
    993  1.1  mrg 
    994  1.1  mrg /* Add "v" to the constant term of "aff",
    995  1.1  mrg  * in case "aff" is a rational expression.
    996  1.1  mrg  */
    997  1.1  mrg static __isl_give isl_aff *isl_aff_add_rat_constant_val(__isl_take isl_aff *aff,
    998  1.1  mrg 	__isl_take isl_val *v)
    999  1.1  mrg {
   1000  1.1  mrg 	aff = isl_aff_cow(aff);
   1001  1.1  mrg 	if (!aff)
   1002  1.1  mrg 		goto error;
   1003  1.1  mrg 
   1004  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   1005  1.1  mrg 	if (!aff->v)
   1006  1.1  mrg 		goto error;
   1007  1.1  mrg 
   1008  1.1  mrg 	if (isl_int_is_one(v->d)) {
   1009  1.1  mrg 		isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n);
   1010  1.1  mrg 	} else if (isl_int_eq(aff->v->el[0], v->d)) {
   1011  1.1  mrg 		isl_int_add(aff->v->el[1], aff->v->el[1], v->n);
   1012  1.1  mrg 		aff->v = isl_vec_normalize(aff->v);
   1013  1.1  mrg 		if (!aff->v)
   1014  1.1  mrg 			goto error;
   1015  1.1  mrg 	} else {
   1016  1.1  mrg 		isl_seq_scale(aff->v->el + 1,
   1017  1.1  mrg 				aff->v->el + 1, v->d, aff->v->size - 1);
   1018  1.1  mrg 		isl_int_addmul(aff->v->el[1], aff->v->el[0], v->n);
   1019  1.1  mrg 		isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
   1020  1.1  mrg 		aff->v = isl_vec_normalize(aff->v);
   1021  1.1  mrg 		if (!aff->v)
   1022  1.1  mrg 			goto error;
   1023  1.1  mrg 	}
   1024  1.1  mrg 
   1025  1.1  mrg 	isl_val_free(v);
   1026  1.1  mrg 	return aff;
   1027  1.1  mrg error:
   1028  1.1  mrg 	isl_aff_free(aff);
   1029  1.1  mrg 	isl_val_free(v);
   1030  1.1  mrg 	return NULL;
   1031  1.1  mrg }
   1032  1.1  mrg 
   1033  1.1  mrg /* Return the first argument and free the second.
   1034  1.1  mrg  */
   1035  1.1  mrg static __isl_give isl_aff *pick_free(__isl_take isl_aff *aff,
   1036  1.1  mrg 	__isl_take isl_val *v)
   1037  1.1  mrg {
   1038  1.1  mrg 	isl_val_free(v);
   1039  1.1  mrg 	return aff;
   1040  1.1  mrg }
   1041  1.1  mrg 
   1042  1.1  mrg /* Replace the first argument by NaN and free the second argument.
   1043  1.1  mrg  */
   1044  1.1  mrg static __isl_give isl_aff *set_nan_free_val(__isl_take isl_aff *aff,
   1045  1.1  mrg 	__isl_take isl_val *v)
   1046  1.1  mrg {
   1047  1.1  mrg 	isl_val_free(v);
   1048  1.1  mrg 	return isl_aff_set_nan(aff);
   1049  1.1  mrg }
   1050  1.1  mrg 
   1051  1.1  mrg /* Add "v" to the constant term of "aff".
   1052  1.1  mrg  *
   1053  1.1  mrg  * A NaN is unaffected by this operation.
   1054  1.1  mrg  * Conversely, adding a NaN turns "aff" into a NaN.
   1055  1.1  mrg  */
   1056  1.1  mrg __isl_give isl_aff *isl_aff_add_constant_val(__isl_take isl_aff *aff,
   1057  1.1  mrg 	__isl_take isl_val *v)
   1058  1.1  mrg {
   1059  1.1  mrg 	isl_bool is_nan, is_zero, is_rat;
   1060  1.1  mrg 
   1061  1.1  mrg 	is_nan = isl_aff_is_nan(aff);
   1062  1.1  mrg 	is_zero = isl_val_is_zero(v);
   1063  1.1  mrg 	if (is_nan < 0 || is_zero < 0)
   1064  1.1  mrg 		goto error;
   1065  1.1  mrg 	if (is_nan || is_zero)
   1066  1.1  mrg 		return pick_free(aff, v);
   1067  1.1  mrg 
   1068  1.1  mrg 	is_nan = isl_val_is_nan(v);
   1069  1.1  mrg 	is_rat = isl_val_is_rat(v);
   1070  1.1  mrg 	if (is_nan < 0 || is_rat < 0)
   1071  1.1  mrg 		goto error;
   1072  1.1  mrg 	if (is_nan)
   1073  1.1  mrg 		return set_nan_free_val(aff, v);
   1074  1.1  mrg 	if (!is_rat)
   1075  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   1076  1.1  mrg 			"expecting rational value or NaN", goto error);
   1077  1.1  mrg 
   1078  1.1  mrg 	return isl_aff_add_rat_constant_val(aff, v);
   1079  1.1  mrg error:
   1080  1.1  mrg 	isl_aff_free(aff);
   1081  1.1  mrg 	isl_val_free(v);
   1082  1.1  mrg 	return NULL;
   1083  1.1  mrg }
   1084  1.1  mrg 
   1085  1.1  mrg __isl_give isl_aff *isl_aff_add_constant_si(__isl_take isl_aff *aff, int v)
   1086  1.1  mrg {
   1087  1.1  mrg 	isl_int t;
   1088  1.1  mrg 
   1089  1.1  mrg 	isl_int_init(t);
   1090  1.1  mrg 	isl_int_set_si(t, v);
   1091  1.1  mrg 	aff = isl_aff_add_constant(aff, t);
   1092  1.1  mrg 	isl_int_clear(t);
   1093  1.1  mrg 
   1094  1.1  mrg 	return aff;
   1095  1.1  mrg }
   1096  1.1  mrg 
   1097  1.1  mrg /* Add "v" to the numerator of the constant term of "aff".
   1098  1.1  mrg  *
   1099  1.1  mrg  * A NaN is unaffected by this operation.
   1100  1.1  mrg  */
   1101  1.1  mrg __isl_give isl_aff *isl_aff_add_constant_num(__isl_take isl_aff *aff, isl_int v)
   1102  1.1  mrg {
   1103  1.1  mrg 	if (isl_int_is_zero(v))
   1104  1.1  mrg 		return aff;
   1105  1.1  mrg 
   1106  1.1  mrg 	if (!aff)
   1107  1.1  mrg 		return NULL;
   1108  1.1  mrg 	if (isl_aff_is_nan(aff))
   1109  1.1  mrg 		return aff;
   1110  1.1  mrg 	aff = isl_aff_cow(aff);
   1111  1.1  mrg 	if (!aff)
   1112  1.1  mrg 		return NULL;
   1113  1.1  mrg 
   1114  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   1115  1.1  mrg 	if (!aff->v)
   1116  1.1  mrg 		return isl_aff_free(aff);
   1117  1.1  mrg 
   1118  1.1  mrg 	isl_int_add(aff->v->el[1], aff->v->el[1], v);
   1119  1.1  mrg 
   1120  1.1  mrg 	return aff;
   1121  1.1  mrg }
   1122  1.1  mrg 
   1123  1.1  mrg /* Add "v" to the numerator of the constant term of "aff".
   1124  1.1  mrg  *
   1125  1.1  mrg  * A NaN is unaffected by this operation.
   1126  1.1  mrg  */
   1127  1.1  mrg __isl_give isl_aff *isl_aff_add_constant_num_si(__isl_take isl_aff *aff, int v)
   1128  1.1  mrg {
   1129  1.1  mrg 	isl_int t;
   1130  1.1  mrg 
   1131  1.1  mrg 	if (v == 0)
   1132  1.1  mrg 		return aff;
   1133  1.1  mrg 
   1134  1.1  mrg 	isl_int_init(t);
   1135  1.1  mrg 	isl_int_set_si(t, v);
   1136  1.1  mrg 	aff = isl_aff_add_constant_num(aff, t);
   1137  1.1  mrg 	isl_int_clear(t);
   1138  1.1  mrg 
   1139  1.1  mrg 	return aff;
   1140  1.1  mrg }
   1141  1.1  mrg 
   1142  1.1  mrg /* Replace the numerator of the constant term of "aff" by "v".
   1143  1.1  mrg  *
   1144  1.1  mrg  * A NaN is unaffected by this operation.
   1145  1.1  mrg  */
   1146  1.1  mrg __isl_give isl_aff *isl_aff_set_constant_si(__isl_take isl_aff *aff, int v)
   1147  1.1  mrg {
   1148  1.1  mrg 	if (!aff)
   1149  1.1  mrg 		return NULL;
   1150  1.1  mrg 	if (isl_aff_is_nan(aff))
   1151  1.1  mrg 		return aff;
   1152  1.1  mrg 	aff = isl_aff_cow(aff);
   1153  1.1  mrg 	if (!aff)
   1154  1.1  mrg 		return NULL;
   1155  1.1  mrg 
   1156  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   1157  1.1  mrg 	if (!aff->v)
   1158  1.1  mrg 		return isl_aff_free(aff);
   1159  1.1  mrg 
   1160  1.1  mrg 	isl_int_set_si(aff->v->el[1], v);
   1161  1.1  mrg 
   1162  1.1  mrg 	return aff;
   1163  1.1  mrg }
   1164  1.1  mrg 
   1165  1.1  mrg /* Replace the numerator of the coefficient of the variable of type "type"
   1166  1.1  mrg  * at position "pos" of "aff" by "v".
   1167  1.1  mrg  *
   1168  1.1  mrg  * A NaN is unaffected by this operation.
   1169  1.1  mrg  */
   1170  1.1  mrg __isl_give isl_aff *isl_aff_set_coefficient(__isl_take isl_aff *aff,
   1171  1.1  mrg 	enum isl_dim_type type, int pos, isl_int v)
   1172  1.1  mrg {
   1173  1.1  mrg 	if (!aff)
   1174  1.1  mrg 		return NULL;
   1175  1.1  mrg 
   1176  1.1  mrg 	if (type == isl_dim_out)
   1177  1.1  mrg 		isl_die(aff->v->ctx, isl_error_invalid,
   1178  1.1  mrg 			"output/set dimension does not have a coefficient",
   1179  1.1  mrg 			return isl_aff_free(aff));
   1180  1.1  mrg 	if (type == isl_dim_in)
   1181  1.1  mrg 		type = isl_dim_set;
   1182  1.1  mrg 
   1183  1.1  mrg 	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
   1184  1.1  mrg 		return isl_aff_free(aff);
   1185  1.1  mrg 
   1186  1.1  mrg 	if (isl_aff_is_nan(aff))
   1187  1.1  mrg 		return aff;
   1188  1.1  mrg 	aff = isl_aff_cow(aff);
   1189  1.1  mrg 	if (!aff)
   1190  1.1  mrg 		return NULL;
   1191  1.1  mrg 
   1192  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   1193  1.1  mrg 	if (!aff->v)
   1194  1.1  mrg 		return isl_aff_free(aff);
   1195  1.1  mrg 
   1196  1.1  mrg 	pos += isl_local_space_offset(aff->ls, type);
   1197  1.1  mrg 	isl_int_set(aff->v->el[1 + pos], v);
   1198  1.1  mrg 
   1199  1.1  mrg 	return aff;
   1200  1.1  mrg }
   1201  1.1  mrg 
   1202  1.1  mrg /* Replace the numerator of the coefficient of the variable of type "type"
   1203  1.1  mrg  * at position "pos" of "aff" by "v".
   1204  1.1  mrg  *
   1205  1.1  mrg  * A NaN is unaffected by this operation.
   1206  1.1  mrg  */
   1207  1.1  mrg __isl_give isl_aff *isl_aff_set_coefficient_si(__isl_take isl_aff *aff,
   1208  1.1  mrg 	enum isl_dim_type type, int pos, int v)
   1209  1.1  mrg {
   1210  1.1  mrg 	if (!aff)
   1211  1.1  mrg 		return NULL;
   1212  1.1  mrg 
   1213  1.1  mrg 	if (type == isl_dim_out)
   1214  1.1  mrg 		isl_die(aff->v->ctx, isl_error_invalid,
   1215  1.1  mrg 			"output/set dimension does not have a coefficient",
   1216  1.1  mrg 			return isl_aff_free(aff));
   1217  1.1  mrg 	if (type == isl_dim_in)
   1218  1.1  mrg 		type = isl_dim_set;
   1219  1.1  mrg 
   1220  1.1  mrg 	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
   1221  1.1  mrg 		return isl_aff_free(aff);
   1222  1.1  mrg 
   1223  1.1  mrg 	if (isl_aff_is_nan(aff))
   1224  1.1  mrg 		return aff;
   1225  1.1  mrg 	pos += isl_local_space_offset(aff->ls, type);
   1226  1.1  mrg 	if (isl_int_cmp_si(aff->v->el[1 + pos], v) == 0)
   1227  1.1  mrg 		return aff;
   1228  1.1  mrg 
   1229  1.1  mrg 	aff = isl_aff_cow(aff);
   1230  1.1  mrg 	if (!aff)
   1231  1.1  mrg 		return NULL;
   1232  1.1  mrg 
   1233  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   1234  1.1  mrg 	if (!aff->v)
   1235  1.1  mrg 		return isl_aff_free(aff);
   1236  1.1  mrg 
   1237  1.1  mrg 	isl_int_set_si(aff->v->el[1 + pos], v);
   1238  1.1  mrg 
   1239  1.1  mrg 	return aff;
   1240  1.1  mrg }
   1241  1.1  mrg 
   1242  1.1  mrg /* Replace the coefficient of the variable of type "type" at position "pos"
   1243  1.1  mrg  * of "aff" by "v".
   1244  1.1  mrg  *
   1245  1.1  mrg  * A NaN is unaffected by this operation.
   1246  1.1  mrg  */
   1247  1.1  mrg __isl_give isl_aff *isl_aff_set_coefficient_val(__isl_take isl_aff *aff,
   1248  1.1  mrg 	enum isl_dim_type type, int pos, __isl_take isl_val *v)
   1249  1.1  mrg {
   1250  1.1  mrg 	if (!aff || !v)
   1251  1.1  mrg 		goto error;
   1252  1.1  mrg 
   1253  1.1  mrg 	if (type == isl_dim_out)
   1254  1.1  mrg 		isl_die(aff->v->ctx, isl_error_invalid,
   1255  1.1  mrg 			"output/set dimension does not have a coefficient",
   1256  1.1  mrg 			goto error);
   1257  1.1  mrg 	if (type == isl_dim_in)
   1258  1.1  mrg 		type = isl_dim_set;
   1259  1.1  mrg 
   1260  1.1  mrg 	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
   1261  1.1  mrg 		return isl_aff_free(aff);
   1262  1.1  mrg 
   1263  1.1  mrg 	if (isl_aff_is_nan(aff)) {
   1264  1.1  mrg 		isl_val_free(v);
   1265  1.1  mrg 		return aff;
   1266  1.1  mrg 	}
   1267  1.1  mrg 	if (!isl_val_is_rat(v))
   1268  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   1269  1.1  mrg 			"expecting rational value", goto error);
   1270  1.1  mrg 
   1271  1.1  mrg 	pos += isl_local_space_offset(aff->ls, type);
   1272  1.1  mrg 	if (isl_int_eq(aff->v->el[1 + pos], v->n) &&
   1273  1.1  mrg 	    isl_int_eq(aff->v->el[0], v->d)) {
   1274  1.1  mrg 		isl_val_free(v);
   1275  1.1  mrg 		return aff;
   1276  1.1  mrg 	}
   1277  1.1  mrg 
   1278  1.1  mrg 	aff = isl_aff_cow(aff);
   1279  1.1  mrg 	if (!aff)
   1280  1.1  mrg 		goto error;
   1281  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   1282  1.1  mrg 	if (!aff->v)
   1283  1.1  mrg 		goto error;
   1284  1.1  mrg 
   1285  1.1  mrg 	if (isl_int_eq(aff->v->el[0], v->d)) {
   1286  1.1  mrg 		isl_int_set(aff->v->el[1 + pos], v->n);
   1287  1.1  mrg 	} else if (isl_int_is_one(v->d)) {
   1288  1.1  mrg 		isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n);
   1289  1.1  mrg 	} else {
   1290  1.1  mrg 		isl_seq_scale(aff->v->el + 1,
   1291  1.1  mrg 				aff->v->el + 1, v->d, aff->v->size - 1);
   1292  1.1  mrg 		isl_int_mul(aff->v->el[1 + pos], aff->v->el[0], v->n);
   1293  1.1  mrg 		isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
   1294  1.1  mrg 		aff->v = isl_vec_normalize(aff->v);
   1295  1.1  mrg 		if (!aff->v)
   1296  1.1  mrg 			goto error;
   1297  1.1  mrg 	}
   1298  1.1  mrg 
   1299  1.1  mrg 	isl_val_free(v);
   1300  1.1  mrg 	return aff;
   1301  1.1  mrg error:
   1302  1.1  mrg 	isl_aff_free(aff);
   1303  1.1  mrg 	isl_val_free(v);
   1304  1.1  mrg 	return NULL;
   1305  1.1  mrg }
   1306  1.1  mrg 
   1307  1.1  mrg /* Add "v" to the coefficient of the variable of type "type"
   1308  1.1  mrg  * at position "pos" of "aff".
   1309  1.1  mrg  *
   1310  1.1  mrg  * A NaN is unaffected by this operation.
   1311  1.1  mrg  */
   1312  1.1  mrg __isl_give isl_aff *isl_aff_add_coefficient(__isl_take isl_aff *aff,
   1313  1.1  mrg 	enum isl_dim_type type, int pos, isl_int v)
   1314  1.1  mrg {
   1315  1.1  mrg 	if (!aff)
   1316  1.1  mrg 		return NULL;
   1317  1.1  mrg 
   1318  1.1  mrg 	if (type == isl_dim_out)
   1319  1.1  mrg 		isl_die(aff->v->ctx, isl_error_invalid,
   1320  1.1  mrg 			"output/set dimension does not have a coefficient",
   1321  1.1  mrg 			return isl_aff_free(aff));
   1322  1.1  mrg 	if (type == isl_dim_in)
   1323  1.1  mrg 		type = isl_dim_set;
   1324  1.1  mrg 
   1325  1.1  mrg 	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
   1326  1.1  mrg 		return isl_aff_free(aff);
   1327  1.1  mrg 
   1328  1.1  mrg 	if (isl_aff_is_nan(aff))
   1329  1.1  mrg 		return aff;
   1330  1.1  mrg 	aff = isl_aff_cow(aff);
   1331  1.1  mrg 	if (!aff)
   1332  1.1  mrg 		return NULL;
   1333  1.1  mrg 
   1334  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   1335  1.1  mrg 	if (!aff->v)
   1336  1.1  mrg 		return isl_aff_free(aff);
   1337  1.1  mrg 
   1338  1.1  mrg 	pos += isl_local_space_offset(aff->ls, type);
   1339  1.1  mrg 	isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v);
   1340  1.1  mrg 
   1341  1.1  mrg 	return aff;
   1342  1.1  mrg }
   1343  1.1  mrg 
   1344  1.1  mrg /* Add "v" to the coefficient of the variable of type "type"
   1345  1.1  mrg  * at position "pos" of "aff".
   1346  1.1  mrg  *
   1347  1.1  mrg  * A NaN is unaffected by this operation.
   1348  1.1  mrg  */
   1349  1.1  mrg __isl_give isl_aff *isl_aff_add_coefficient_val(__isl_take isl_aff *aff,
   1350  1.1  mrg 	enum isl_dim_type type, int pos, __isl_take isl_val *v)
   1351  1.1  mrg {
   1352  1.1  mrg 	if (!aff || !v)
   1353  1.1  mrg 		goto error;
   1354  1.1  mrg 
   1355  1.1  mrg 	if (isl_val_is_zero(v)) {
   1356  1.1  mrg 		isl_val_free(v);
   1357  1.1  mrg 		return aff;
   1358  1.1  mrg 	}
   1359  1.1  mrg 
   1360  1.1  mrg 	if (type == isl_dim_out)
   1361  1.1  mrg 		isl_die(aff->v->ctx, isl_error_invalid,
   1362  1.1  mrg 			"output/set dimension does not have a coefficient",
   1363  1.1  mrg 			goto error);
   1364  1.1  mrg 	if (type == isl_dim_in)
   1365  1.1  mrg 		type = isl_dim_set;
   1366  1.1  mrg 
   1367  1.1  mrg 	if (isl_local_space_check_range(aff->ls, type, pos, 1) < 0)
   1368  1.1  mrg 		goto error;
   1369  1.1  mrg 
   1370  1.1  mrg 	if (isl_aff_is_nan(aff)) {
   1371  1.1  mrg 		isl_val_free(v);
   1372  1.1  mrg 		return aff;
   1373  1.1  mrg 	}
   1374  1.1  mrg 	if (!isl_val_is_rat(v))
   1375  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   1376  1.1  mrg 			"expecting rational value", goto error);
   1377  1.1  mrg 
   1378  1.1  mrg 	aff = isl_aff_cow(aff);
   1379  1.1  mrg 	if (!aff)
   1380  1.1  mrg 		goto error;
   1381  1.1  mrg 
   1382  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   1383  1.1  mrg 	if (!aff->v)
   1384  1.1  mrg 		goto error;
   1385  1.1  mrg 
   1386  1.1  mrg 	pos += isl_local_space_offset(aff->ls, type);
   1387  1.1  mrg 	if (isl_int_is_one(v->d)) {
   1388  1.1  mrg 		isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n);
   1389  1.1  mrg 	} else if (isl_int_eq(aff->v->el[0], v->d)) {
   1390  1.1  mrg 		isl_int_add(aff->v->el[1 + pos], aff->v->el[1 + pos], v->n);
   1391  1.1  mrg 		aff->v = isl_vec_normalize(aff->v);
   1392  1.1  mrg 		if (!aff->v)
   1393  1.1  mrg 			goto error;
   1394  1.1  mrg 	} else {
   1395  1.1  mrg 		isl_seq_scale(aff->v->el + 1,
   1396  1.1  mrg 				aff->v->el + 1, v->d, aff->v->size - 1);
   1397  1.1  mrg 		isl_int_addmul(aff->v->el[1 + pos], aff->v->el[0], v->n);
   1398  1.1  mrg 		isl_int_mul(aff->v->el[0], aff->v->el[0], v->d);
   1399  1.1  mrg 		aff->v = isl_vec_normalize(aff->v);
   1400  1.1  mrg 		if (!aff->v)
   1401  1.1  mrg 			goto error;
   1402  1.1  mrg 	}
   1403  1.1  mrg 
   1404  1.1  mrg 	isl_val_free(v);
   1405  1.1  mrg 	return aff;
   1406  1.1  mrg error:
   1407  1.1  mrg 	isl_aff_free(aff);
   1408  1.1  mrg 	isl_val_free(v);
   1409  1.1  mrg 	return NULL;
   1410  1.1  mrg }
   1411  1.1  mrg 
   1412  1.1  mrg __isl_give isl_aff *isl_aff_add_coefficient_si(__isl_take isl_aff *aff,
   1413  1.1  mrg 	enum isl_dim_type type, int pos, int v)
   1414  1.1  mrg {
   1415  1.1  mrg 	isl_int t;
   1416  1.1  mrg 
   1417  1.1  mrg 	isl_int_init(t);
   1418  1.1  mrg 	isl_int_set_si(t, v);
   1419  1.1  mrg 	aff = isl_aff_add_coefficient(aff, type, pos, t);
   1420  1.1  mrg 	isl_int_clear(t);
   1421  1.1  mrg 
   1422  1.1  mrg 	return aff;
   1423  1.1  mrg }
   1424  1.1  mrg 
   1425  1.1  mrg __isl_give isl_aff *isl_aff_get_div(__isl_keep isl_aff *aff, int pos)
   1426  1.1  mrg {
   1427  1.1  mrg 	if (!aff)
   1428  1.1  mrg 		return NULL;
   1429  1.1  mrg 
   1430  1.1  mrg 	return isl_local_space_get_div(aff->ls, pos);
   1431  1.1  mrg }
   1432  1.1  mrg 
   1433  1.1  mrg /* Return the negation of "aff".
   1434  1.1  mrg  *
   1435  1.1  mrg  * As a special case, -NaN = NaN.
   1436  1.1  mrg  */
   1437  1.1  mrg __isl_give isl_aff *isl_aff_neg(__isl_take isl_aff *aff)
   1438  1.1  mrg {
   1439  1.1  mrg 	if (!aff)
   1440  1.1  mrg 		return NULL;
   1441  1.1  mrg 	if (isl_aff_is_nan(aff))
   1442  1.1  mrg 		return aff;
   1443  1.1  mrg 	aff = isl_aff_cow(aff);
   1444  1.1  mrg 	if (!aff)
   1445  1.1  mrg 		return NULL;
   1446  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   1447  1.1  mrg 	if (!aff->v)
   1448  1.1  mrg 		return isl_aff_free(aff);
   1449  1.1  mrg 
   1450  1.1  mrg 	isl_seq_neg(aff->v->el + 1, aff->v->el + 1, aff->v->size - 1);
   1451  1.1  mrg 
   1452  1.1  mrg 	return aff;
   1453  1.1  mrg }
   1454  1.1  mrg 
   1455  1.1  mrg /* Remove divs from the local space that do not appear in the affine
   1456  1.1  mrg  * expression.
   1457  1.1  mrg  * We currently only remove divs at the end.
   1458  1.1  mrg  * Some intermediate divs may also not appear directly in the affine
   1459  1.1  mrg  * expression, but we would also need to check that no other divs are
   1460  1.1  mrg  * defined in terms of them.
   1461  1.1  mrg  */
   1462  1.1  mrg __isl_give isl_aff *isl_aff_remove_unused_divs(__isl_take isl_aff *aff)
   1463  1.1  mrg {
   1464  1.1  mrg 	int pos;
   1465  1.1  mrg 	isl_size off;
   1466  1.1  mrg 	isl_size n;
   1467  1.1  mrg 
   1468  1.1  mrg 	n = isl_aff_domain_dim(aff, isl_dim_div);
   1469  1.1  mrg 	off = isl_aff_domain_offset(aff, isl_dim_div);
   1470  1.1  mrg 	if (n < 0 || off < 0)
   1471  1.1  mrg 		return isl_aff_free(aff);
   1472  1.1  mrg 
   1473  1.1  mrg 	pos = isl_seq_last_non_zero(aff->v->el + 1 + off, n) + 1;
   1474  1.1  mrg 	if (pos == n)
   1475  1.1  mrg 		return aff;
   1476  1.1  mrg 
   1477  1.1  mrg 	aff = isl_aff_cow(aff);
   1478  1.1  mrg 	if (!aff)
   1479  1.1  mrg 		return NULL;
   1480  1.1  mrg 
   1481  1.1  mrg 	aff->ls = isl_local_space_drop_dims(aff->ls, isl_dim_div, pos, n - pos);
   1482  1.1  mrg 	aff->v = isl_vec_drop_els(aff->v, 1 + off + pos, n - pos);
   1483  1.1  mrg 	if (!aff->ls || !aff->v)
   1484  1.1  mrg 		return isl_aff_free(aff);
   1485  1.1  mrg 
   1486  1.1  mrg 	return aff;
   1487  1.1  mrg }
   1488  1.1  mrg 
   1489  1.1  mrg /* Look for any divs in the aff->ls with a denominator equal to one
   1490  1.1  mrg  * and plug them into the affine expression and any subsequent divs
   1491  1.1  mrg  * that may reference the div.
   1492  1.1  mrg  */
   1493  1.1  mrg static __isl_give isl_aff *plug_in_integral_divs(__isl_take isl_aff *aff)
   1494  1.1  mrg {
   1495  1.1  mrg 	int i;
   1496  1.1  mrg 	isl_size n;
   1497  1.1  mrg 	int len;
   1498  1.1  mrg 	isl_int v;
   1499  1.1  mrg 	isl_vec *vec;
   1500  1.1  mrg 	isl_local_space *ls;
   1501  1.1  mrg 	isl_size off;
   1502  1.1  mrg 
   1503  1.1  mrg 	n = isl_aff_domain_dim(aff, isl_dim_div);
   1504  1.1  mrg 	off = isl_aff_domain_offset(aff, isl_dim_div);
   1505  1.1  mrg 	if (n < 0 || off < 0)
   1506  1.1  mrg 		return isl_aff_free(aff);
   1507  1.1  mrg 	len = aff->v->size;
   1508  1.1  mrg 	for (i = 0; i < n; ++i) {
   1509  1.1  mrg 		if (!isl_int_is_one(aff->ls->div->row[i][0]))
   1510  1.1  mrg 			continue;
   1511  1.1  mrg 		ls = isl_local_space_copy(aff->ls);
   1512  1.1  mrg 		ls = isl_local_space_substitute_seq(ls, isl_dim_div, i,
   1513  1.1  mrg 				aff->ls->div->row[i], len, i + 1, n - (i + 1));
   1514  1.1  mrg 		vec = isl_vec_copy(aff->v);
   1515  1.1  mrg 		vec = isl_vec_cow(vec);
   1516  1.1  mrg 		if (!ls || !vec)
   1517  1.1  mrg 			goto error;
   1518  1.1  mrg 
   1519  1.1  mrg 		isl_int_init(v);
   1520  1.1  mrg 
   1521  1.1  mrg 		isl_seq_substitute(vec->el, off + i, aff->ls->div->row[i],
   1522  1.1  mrg 					len, len, v);
   1523  1.1  mrg 
   1524  1.1  mrg 		isl_int_clear(v);
   1525  1.1  mrg 
   1526  1.1  mrg 		isl_vec_free(aff->v);
   1527  1.1  mrg 		aff->v = vec;
   1528  1.1  mrg 		isl_local_space_free(aff->ls);
   1529  1.1  mrg 		aff->ls = ls;
   1530  1.1  mrg 	}
   1531  1.1  mrg 
   1532  1.1  mrg 	return aff;
   1533  1.1  mrg error:
   1534  1.1  mrg 	isl_vec_free(vec);
   1535  1.1  mrg 	isl_local_space_free(ls);
   1536  1.1  mrg 	return isl_aff_free(aff);
   1537  1.1  mrg }
   1538  1.1  mrg 
   1539  1.1  mrg /* Look for any divs j that appear with a unit coefficient inside
   1540  1.1  mrg  * the definitions of other divs i and plug them into the definitions
   1541  1.1  mrg  * of the divs i.
   1542  1.1  mrg  *
   1543  1.1  mrg  * In particular, an expression of the form
   1544  1.1  mrg  *
   1545  1.1  mrg  *	floor((f(..) + floor(g(..)/n))/m)
   1546  1.1  mrg  *
   1547  1.1  mrg  * is simplified to
   1548  1.1  mrg  *
   1549  1.1  mrg  *	floor((n * f(..) + g(..))/(n * m))
   1550  1.1  mrg  *
   1551  1.1  mrg  * This simplification is correct because we can move the expression
   1552  1.1  mrg  * f(..) into the inner floor in the original expression to obtain
   1553  1.1  mrg  *
   1554  1.1  mrg  *	floor(floor((n * f(..) + g(..))/n)/m)
   1555  1.1  mrg  *
   1556  1.1  mrg  * from which we can derive the simplified expression.
   1557  1.1  mrg  */
   1558  1.1  mrg static __isl_give isl_aff *plug_in_unit_divs(__isl_take isl_aff *aff)
   1559  1.1  mrg {
   1560  1.1  mrg 	int i, j;
   1561  1.1  mrg 	isl_size n;
   1562  1.1  mrg 	isl_size off;
   1563  1.1  mrg 
   1564  1.1  mrg 	n = isl_aff_domain_dim(aff, isl_dim_div);
   1565  1.1  mrg 	off = isl_aff_domain_offset(aff, isl_dim_div);
   1566  1.1  mrg 	if (n < 0 || off < 0)
   1567  1.1  mrg 		return isl_aff_free(aff);
   1568  1.1  mrg 	for (i = 1; i < n; ++i) {
   1569  1.1  mrg 		for (j = 0; j < i; ++j) {
   1570  1.1  mrg 			if (!isl_int_is_one(aff->ls->div->row[i][1 + off + j]))
   1571  1.1  mrg 				continue;
   1572  1.1  mrg 			aff->ls = isl_local_space_substitute_seq(aff->ls,
   1573  1.1  mrg 				isl_dim_div, j, aff->ls->div->row[j],
   1574  1.1  mrg 				aff->v->size, i, 1);
   1575  1.1  mrg 			if (!aff->ls)
   1576  1.1  mrg 				return isl_aff_free(aff);
   1577  1.1  mrg 		}
   1578  1.1  mrg 	}
   1579  1.1  mrg 
   1580  1.1  mrg 	return aff;
   1581  1.1  mrg }
   1582  1.1  mrg 
   1583  1.1  mrg /* Swap divs "a" and "b" in "aff", which is assumed to be non-NULL.
   1584  1.1  mrg  *
   1585  1.1  mrg  * Even though this function is only called on isl_affs with a single
   1586  1.1  mrg  * reference, we are careful to only change aff->v and aff->ls together.
   1587  1.1  mrg  */
   1588  1.1  mrg static __isl_give isl_aff *swap_div(__isl_take isl_aff *aff, int a, int b)
   1589  1.1  mrg {
   1590  1.1  mrg 	isl_size off = isl_aff_domain_offset(aff, isl_dim_div);
   1591  1.1  mrg 	isl_local_space *ls;
   1592  1.1  mrg 	isl_vec *v;
   1593  1.1  mrg 
   1594  1.1  mrg 	if (off < 0)
   1595  1.1  mrg 		return isl_aff_free(aff);
   1596  1.1  mrg 
   1597  1.1  mrg 	ls = isl_local_space_copy(aff->ls);
   1598  1.1  mrg 	ls = isl_local_space_swap_div(ls, a, b);
   1599  1.1  mrg 	v = isl_vec_copy(aff->v);
   1600  1.1  mrg 	v = isl_vec_cow(v);
   1601  1.1  mrg 	if (!ls || !v)
   1602  1.1  mrg 		goto error;
   1603  1.1  mrg 
   1604  1.1  mrg 	isl_int_swap(v->el[1 + off + a], v->el[1 + off + b]);
   1605  1.1  mrg 	isl_vec_free(aff->v);
   1606  1.1  mrg 	aff->v = v;
   1607  1.1  mrg 	isl_local_space_free(aff->ls);
   1608  1.1  mrg 	aff->ls = ls;
   1609  1.1  mrg 
   1610  1.1  mrg 	return aff;
   1611  1.1  mrg error:
   1612  1.1  mrg 	isl_vec_free(v);
   1613  1.1  mrg 	isl_local_space_free(ls);
   1614  1.1  mrg 	return isl_aff_free(aff);
   1615  1.1  mrg }
   1616  1.1  mrg 
   1617  1.1  mrg /* Merge divs "a" and "b" in "aff", which is assumed to be non-NULL.
   1618  1.1  mrg  *
   1619  1.1  mrg  * We currently do not actually remove div "b", but simply add its
   1620  1.1  mrg  * coefficient to that of "a" and then zero it out.
   1621  1.1  mrg  */
   1622  1.1  mrg static __isl_give isl_aff *merge_divs(__isl_take isl_aff *aff, int a, int b)
   1623  1.1  mrg {
   1624  1.1  mrg 	isl_size off = isl_aff_domain_offset(aff, isl_dim_div);
   1625  1.1  mrg 
   1626  1.1  mrg 	if (off < 0)
   1627  1.1  mrg 		return isl_aff_free(aff);
   1628  1.1  mrg 
   1629  1.1  mrg 	if (isl_int_is_zero(aff->v->el[1 + off + b]))
   1630  1.1  mrg 		return aff;
   1631  1.1  mrg 
   1632  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   1633  1.1  mrg 	if (!aff->v)
   1634  1.1  mrg 		return isl_aff_free(aff);
   1635  1.1  mrg 
   1636  1.1  mrg 	isl_int_add(aff->v->el[1 + off + a],
   1637  1.1  mrg 		    aff->v->el[1 + off + a], aff->v->el[1 + off + b]);
   1638  1.1  mrg 	isl_int_set_si(aff->v->el[1 + off + b], 0);
   1639  1.1  mrg 
   1640  1.1  mrg 	return aff;
   1641  1.1  mrg }
   1642  1.1  mrg 
   1643  1.1  mrg /* Sort the divs in the local space of "aff" according to
   1644  1.1  mrg  * the comparison function "cmp_row" in isl_local_space.c,
   1645  1.1  mrg  * combining the coefficients of identical divs.
   1646  1.1  mrg  *
   1647  1.1  mrg  * Reordering divs does not change the semantics of "aff",
   1648  1.1  mrg  * so there is no need to call isl_aff_cow.
   1649  1.1  mrg  * Moreover, this function is currently only called on isl_affs
   1650  1.1  mrg  * with a single reference.
   1651  1.1  mrg  */
   1652  1.1  mrg static __isl_give isl_aff *sort_divs(__isl_take isl_aff *aff)
   1653  1.1  mrg {
   1654  1.1  mrg 	isl_size n;
   1655  1.1  mrg 	int i, j;
   1656  1.1  mrg 
   1657  1.1  mrg 	n = isl_aff_dim(aff, isl_dim_div);
   1658  1.1  mrg 	if (n < 0)
   1659  1.1  mrg 		return isl_aff_free(aff);
   1660  1.1  mrg 	for (i = 1; i < n; ++i) {
   1661  1.1  mrg 		for (j = i - 1; j >= 0; --j) {
   1662  1.1  mrg 			int cmp = isl_mat_cmp_div(aff->ls->div, j, j + 1);
   1663  1.1  mrg 			if (cmp < 0)
   1664  1.1  mrg 				break;
   1665  1.1  mrg 			if (cmp == 0)
   1666  1.1  mrg 				aff = merge_divs(aff, j, j + 1);
   1667  1.1  mrg 			else
   1668  1.1  mrg 				aff = swap_div(aff, j, j + 1);
   1669  1.1  mrg 			if (!aff)
   1670  1.1  mrg 				return NULL;
   1671  1.1  mrg 		}
   1672  1.1  mrg 	}
   1673  1.1  mrg 
   1674  1.1  mrg 	return aff;
   1675  1.1  mrg }
   1676  1.1  mrg 
   1677  1.1  mrg /* Normalize the representation of "aff".
   1678  1.1  mrg  *
   1679  1.1  mrg  * This function should only be called on "new" isl_affs, i.e.,
   1680  1.1  mrg  * with only a single reference.  We therefore do not need to
   1681  1.1  mrg  * worry about affecting other instances.
   1682  1.1  mrg  */
   1683  1.1  mrg __isl_give isl_aff *isl_aff_normalize(__isl_take isl_aff *aff)
   1684  1.1  mrg {
   1685  1.1  mrg 	if (!aff)
   1686  1.1  mrg 		return NULL;
   1687  1.1  mrg 	aff->v = isl_vec_normalize(aff->v);
   1688  1.1  mrg 	if (!aff->v)
   1689  1.1  mrg 		return isl_aff_free(aff);
   1690  1.1  mrg 	aff = plug_in_integral_divs(aff);
   1691  1.1  mrg 	aff = plug_in_unit_divs(aff);
   1692  1.1  mrg 	aff = sort_divs(aff);
   1693  1.1  mrg 	aff = isl_aff_remove_unused_divs(aff);
   1694  1.1  mrg 	return aff;
   1695  1.1  mrg }
   1696  1.1  mrg 
   1697  1.1  mrg /* Given f, return floor(f).
   1698  1.1  mrg  * If f is an integer expression, then just return f.
   1699  1.1  mrg  * If f is a constant, then return the constant floor(f).
   1700  1.1  mrg  * Otherwise, if f = g/m, write g = q m + r,
   1701  1.1  mrg  * create a new div d = [r/m] and return the expression q + d.
   1702  1.1  mrg  * The coefficients in r are taken to lie between -m/2 and m/2.
   1703  1.1  mrg  *
   1704  1.1  mrg  * reduce_div_coefficients performs the same normalization.
   1705  1.1  mrg  *
   1706  1.1  mrg  * As a special case, floor(NaN) = NaN.
   1707  1.1  mrg  */
   1708  1.1  mrg __isl_give isl_aff *isl_aff_floor(__isl_take isl_aff *aff)
   1709  1.1  mrg {
   1710  1.1  mrg 	int i;
   1711  1.1  mrg 	int size;
   1712  1.1  mrg 	isl_ctx *ctx;
   1713  1.1  mrg 	isl_vec *div;
   1714  1.1  mrg 
   1715  1.1  mrg 	if (!aff)
   1716  1.1  mrg 		return NULL;
   1717  1.1  mrg 
   1718  1.1  mrg 	if (isl_aff_is_nan(aff))
   1719  1.1  mrg 		return aff;
   1720  1.1  mrg 	if (isl_int_is_one(aff->v->el[0]))
   1721  1.1  mrg 		return aff;
   1722  1.1  mrg 
   1723  1.1  mrg 	aff = isl_aff_cow(aff);
   1724  1.1  mrg 	if (!aff)
   1725  1.1  mrg 		return NULL;
   1726  1.1  mrg 
   1727  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   1728  1.1  mrg 	if (!aff->v)
   1729  1.1  mrg 		return isl_aff_free(aff);
   1730  1.1  mrg 
   1731  1.1  mrg 	if (isl_aff_is_cst(aff)) {
   1732  1.1  mrg 		isl_int_fdiv_q(aff->v->el[1], aff->v->el[1], aff->v->el[0]);
   1733  1.1  mrg 		isl_int_set_si(aff->v->el[0], 1);
   1734  1.1  mrg 		return aff;
   1735  1.1  mrg 	}
   1736  1.1  mrg 
   1737  1.1  mrg 	div = isl_vec_copy(aff->v);
   1738  1.1  mrg 	div = isl_vec_cow(div);
   1739  1.1  mrg 	if (!div)
   1740  1.1  mrg 		return isl_aff_free(aff);
   1741  1.1  mrg 
   1742  1.1  mrg 	ctx = isl_aff_get_ctx(aff);
   1743  1.1  mrg 	isl_int_fdiv_q(aff->v->el[0], aff->v->el[0], ctx->two);
   1744  1.1  mrg 	for (i = 1; i < aff->v->size; ++i) {
   1745  1.1  mrg 		isl_int_fdiv_r(div->el[i], div->el[i], div->el[0]);
   1746  1.1  mrg 		isl_int_fdiv_q(aff->v->el[i], aff->v->el[i], div->el[0]);
   1747  1.1  mrg 		if (isl_int_gt(div->el[i], aff->v->el[0])) {
   1748  1.1  mrg 			isl_int_sub(div->el[i], div->el[i], div->el[0]);
   1749  1.1  mrg 			isl_int_add_ui(aff->v->el[i], aff->v->el[i], 1);
   1750  1.1  mrg 		}
   1751  1.1  mrg 	}
   1752  1.1  mrg 
   1753  1.1  mrg 	aff->ls = isl_local_space_add_div(aff->ls, div);
   1754  1.1  mrg 	if (!aff->ls)
   1755  1.1  mrg 		return isl_aff_free(aff);
   1756  1.1  mrg 
   1757  1.1  mrg 	size = aff->v->size;
   1758  1.1  mrg 	aff->v = isl_vec_extend(aff->v, size + 1);
   1759  1.1  mrg 	if (!aff->v)
   1760  1.1  mrg 		return isl_aff_free(aff);
   1761  1.1  mrg 	isl_int_set_si(aff->v->el[0], 1);
   1762  1.1  mrg 	isl_int_set_si(aff->v->el[size], 1);
   1763  1.1  mrg 
   1764  1.1  mrg 	aff = isl_aff_normalize(aff);
   1765  1.1  mrg 
   1766  1.1  mrg 	return aff;
   1767  1.1  mrg }
   1768  1.1  mrg 
   1769  1.1  mrg /* Compute
   1770  1.1  mrg  *
   1771  1.1  mrg  *	aff mod m = aff - m * floor(aff/m)
   1772  1.1  mrg  *
   1773  1.1  mrg  * with m an integer value.
   1774  1.1  mrg  */
   1775  1.1  mrg __isl_give isl_aff *isl_aff_mod_val(__isl_take isl_aff *aff,
   1776  1.1  mrg 	__isl_take isl_val *m)
   1777  1.1  mrg {
   1778  1.1  mrg 	isl_aff *res;
   1779  1.1  mrg 
   1780  1.1  mrg 	if (!aff || !m)
   1781  1.1  mrg 		goto error;
   1782  1.1  mrg 
   1783  1.1  mrg 	if (!isl_val_is_int(m))
   1784  1.1  mrg 		isl_die(isl_val_get_ctx(m), isl_error_invalid,
   1785  1.1  mrg 			"expecting integer modulo", goto error);
   1786  1.1  mrg 
   1787  1.1  mrg 	res = isl_aff_copy(aff);
   1788  1.1  mrg 	aff = isl_aff_scale_down_val(aff, isl_val_copy(m));
   1789  1.1  mrg 	aff = isl_aff_floor(aff);
   1790  1.1  mrg 	aff = isl_aff_scale_val(aff, m);
   1791  1.1  mrg 	res = isl_aff_sub(res, aff);
   1792  1.1  mrg 
   1793  1.1  mrg 	return res;
   1794  1.1  mrg error:
   1795  1.1  mrg 	isl_aff_free(aff);
   1796  1.1  mrg 	isl_val_free(m);
   1797  1.1  mrg 	return NULL;
   1798  1.1  mrg }
   1799  1.1  mrg 
   1800  1.1  mrg /* Compute
   1801  1.1  mrg  *
   1802  1.1  mrg  *	pwaff mod m = pwaff - m * floor(pwaff/m)
   1803  1.1  mrg  */
   1804  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_mod(__isl_take isl_pw_aff *pwaff, isl_int m)
   1805  1.1  mrg {
   1806  1.1  mrg 	isl_pw_aff *res;
   1807  1.1  mrg 
   1808  1.1  mrg 	res = isl_pw_aff_copy(pwaff);
   1809  1.1  mrg 	pwaff = isl_pw_aff_scale_down(pwaff, m);
   1810  1.1  mrg 	pwaff = isl_pw_aff_floor(pwaff);
   1811  1.1  mrg 	pwaff = isl_pw_aff_scale(pwaff, m);
   1812  1.1  mrg 	res = isl_pw_aff_sub(res, pwaff);
   1813  1.1  mrg 
   1814  1.1  mrg 	return res;
   1815  1.1  mrg }
   1816  1.1  mrg 
   1817  1.1  mrg /* Compute
   1818  1.1  mrg  *
   1819  1.1  mrg  *	pa mod m = pa - m * floor(pa/m)
   1820  1.1  mrg  *
   1821  1.1  mrg  * with m an integer value.
   1822  1.1  mrg  */
   1823  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_mod_val(__isl_take isl_pw_aff *pa,
   1824  1.1  mrg 	__isl_take isl_val *m)
   1825  1.1  mrg {
   1826  1.1  mrg 	if (!pa || !m)
   1827  1.1  mrg 		goto error;
   1828  1.1  mrg 	if (!isl_val_is_int(m))
   1829  1.1  mrg 		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
   1830  1.1  mrg 			"expecting integer modulo", goto error);
   1831  1.1  mrg 	pa = isl_pw_aff_mod(pa, m->n);
   1832  1.1  mrg 	isl_val_free(m);
   1833  1.1  mrg 	return pa;
   1834  1.1  mrg error:
   1835  1.1  mrg 	isl_pw_aff_free(pa);
   1836  1.1  mrg 	isl_val_free(m);
   1837  1.1  mrg 	return NULL;
   1838  1.1  mrg }
   1839  1.1  mrg 
   1840  1.1  mrg /* Given f, return ceil(f).
   1841  1.1  mrg  * If f is an integer expression, then just return f.
   1842  1.1  mrg  * Otherwise, let f be the expression
   1843  1.1  mrg  *
   1844  1.1  mrg  *	e/m
   1845  1.1  mrg  *
   1846  1.1  mrg  * then return
   1847  1.1  mrg  *
   1848  1.1  mrg  *	floor((e + m - 1)/m)
   1849  1.1  mrg  *
   1850  1.1  mrg  * As a special case, ceil(NaN) = NaN.
   1851  1.1  mrg  */
   1852  1.1  mrg __isl_give isl_aff *isl_aff_ceil(__isl_take isl_aff *aff)
   1853  1.1  mrg {
   1854  1.1  mrg 	if (!aff)
   1855  1.1  mrg 		return NULL;
   1856  1.1  mrg 
   1857  1.1  mrg 	if (isl_aff_is_nan(aff))
   1858  1.1  mrg 		return aff;
   1859  1.1  mrg 	if (isl_int_is_one(aff->v->el[0]))
   1860  1.1  mrg 		return aff;
   1861  1.1  mrg 
   1862  1.1  mrg 	aff = isl_aff_cow(aff);
   1863  1.1  mrg 	if (!aff)
   1864  1.1  mrg 		return NULL;
   1865  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   1866  1.1  mrg 	if (!aff->v)
   1867  1.1  mrg 		return isl_aff_free(aff);
   1868  1.1  mrg 
   1869  1.1  mrg 	isl_int_add(aff->v->el[1], aff->v->el[1], aff->v->el[0]);
   1870  1.1  mrg 	isl_int_sub_ui(aff->v->el[1], aff->v->el[1], 1);
   1871  1.1  mrg 	aff = isl_aff_floor(aff);
   1872  1.1  mrg 
   1873  1.1  mrg 	return aff;
   1874  1.1  mrg }
   1875  1.1  mrg 
   1876  1.1  mrg /* Apply the expansion computed by isl_merge_divs.
   1877  1.1  mrg  * The expansion itself is given by "exp" while the resulting
   1878  1.1  mrg  * list of divs is given by "div".
   1879  1.1  mrg  */
   1880  1.1  mrg __isl_give isl_aff *isl_aff_expand_divs(__isl_take isl_aff *aff,
   1881  1.1  mrg 	__isl_take isl_mat *div, int *exp)
   1882  1.1  mrg {
   1883  1.1  mrg 	isl_size old_n_div;
   1884  1.1  mrg 	isl_size new_n_div;
   1885  1.1  mrg 	isl_size offset;
   1886  1.1  mrg 
   1887  1.1  mrg 	aff = isl_aff_cow(aff);
   1888  1.1  mrg 
   1889  1.1  mrg 	offset = isl_aff_domain_offset(aff, isl_dim_div);
   1890  1.1  mrg 	old_n_div = isl_aff_domain_dim(aff, isl_dim_div);
   1891  1.1  mrg 	new_n_div = isl_mat_rows(div);
   1892  1.1  mrg 	if (offset < 0 || old_n_div < 0 || new_n_div < 0)
   1893  1.1  mrg 		goto error;
   1894  1.1  mrg 
   1895  1.1  mrg 	aff->v = isl_vec_expand(aff->v, 1 + offset, old_n_div, exp, new_n_div);
   1896  1.1  mrg 	aff->ls = isl_local_space_replace_divs(aff->ls, div);
   1897  1.1  mrg 	if (!aff->v || !aff->ls)
   1898  1.1  mrg 		return isl_aff_free(aff);
   1899  1.1  mrg 	return aff;
   1900  1.1  mrg error:
   1901  1.1  mrg 	isl_aff_free(aff);
   1902  1.1  mrg 	isl_mat_free(div);
   1903  1.1  mrg 	return NULL;
   1904  1.1  mrg }
   1905  1.1  mrg 
   1906  1.1  mrg /* Add two affine expressions that live in the same local space.
   1907  1.1  mrg  */
   1908  1.1  mrg static __isl_give isl_aff *add_expanded(__isl_take isl_aff *aff1,
   1909  1.1  mrg 	__isl_take isl_aff *aff2)
   1910  1.1  mrg {
   1911  1.1  mrg 	isl_int gcd, f;
   1912  1.1  mrg 
   1913  1.1  mrg 	aff1 = isl_aff_cow(aff1);
   1914  1.1  mrg 	if (!aff1 || !aff2)
   1915  1.1  mrg 		goto error;
   1916  1.1  mrg 
   1917  1.1  mrg 	aff1->v = isl_vec_cow(aff1->v);
   1918  1.1  mrg 	if (!aff1->v)
   1919  1.1  mrg 		goto error;
   1920  1.1  mrg 
   1921  1.1  mrg 	isl_int_init(gcd);
   1922  1.1  mrg 	isl_int_init(f);
   1923  1.1  mrg 	isl_int_gcd(gcd, aff1->v->el[0], aff2->v->el[0]);
   1924  1.1  mrg 	isl_int_divexact(f, aff2->v->el[0], gcd);
   1925  1.1  mrg 	isl_seq_scale(aff1->v->el + 1, aff1->v->el + 1, f, aff1->v->size - 1);
   1926  1.1  mrg 	isl_int_divexact(f, aff1->v->el[0], gcd);
   1927  1.1  mrg 	isl_seq_addmul(aff1->v->el + 1, f, aff2->v->el + 1, aff1->v->size - 1);
   1928  1.1  mrg 	isl_int_divexact(f, aff2->v->el[0], gcd);
   1929  1.1  mrg 	isl_int_mul(aff1->v->el[0], aff1->v->el[0], f);
   1930  1.1  mrg 	isl_int_clear(f);
   1931  1.1  mrg 	isl_int_clear(gcd);
   1932  1.1  mrg 
   1933  1.1  mrg 	isl_aff_free(aff2);
   1934  1.1  mrg 	aff1 = isl_aff_normalize(aff1);
   1935  1.1  mrg 	return aff1;
   1936  1.1  mrg error:
   1937  1.1  mrg 	isl_aff_free(aff1);
   1938  1.1  mrg 	isl_aff_free(aff2);
   1939  1.1  mrg 	return NULL;
   1940  1.1  mrg }
   1941  1.1  mrg 
   1942  1.1  mrg /* Replace one of the arguments by a NaN and free the other one.
   1943  1.1  mrg  */
   1944  1.1  mrg static __isl_give isl_aff *set_nan_free(__isl_take isl_aff *aff1,
   1945  1.1  mrg 	__isl_take isl_aff *aff2)
   1946  1.1  mrg {
   1947  1.1  mrg 	isl_aff_free(aff2);
   1948  1.1  mrg 	return isl_aff_set_nan(aff1);
   1949  1.1  mrg }
   1950  1.1  mrg 
   1951  1.1  mrg /* Return the sum of "aff1" and "aff2".
   1952  1.1  mrg  *
   1953  1.1  mrg  * If either of the two is NaN, then the result is NaN.
   1954  1.1  mrg  */
   1955  1.1  mrg __isl_give isl_aff *isl_aff_add(__isl_take isl_aff *aff1,
   1956  1.1  mrg 	__isl_take isl_aff *aff2)
   1957  1.1  mrg {
   1958  1.1  mrg 	isl_ctx *ctx;
   1959  1.1  mrg 	int *exp1 = NULL;
   1960  1.1  mrg 	int *exp2 = NULL;
   1961  1.1  mrg 	isl_mat *div;
   1962  1.1  mrg 	isl_size n_div1, n_div2;
   1963  1.1  mrg 
   1964  1.1  mrg 	if (!aff1 || !aff2)
   1965  1.1  mrg 		goto error;
   1966  1.1  mrg 
   1967  1.1  mrg 	ctx = isl_aff_get_ctx(aff1);
   1968  1.1  mrg 	if (!isl_space_is_equal(aff1->ls->dim, aff2->ls->dim))
   1969  1.1  mrg 		isl_die(ctx, isl_error_invalid,
   1970  1.1  mrg 			"spaces don't match", goto error);
   1971  1.1  mrg 
   1972  1.1  mrg 	if (isl_aff_is_nan(aff1)) {
   1973  1.1  mrg 		isl_aff_free(aff2);
   1974  1.1  mrg 		return aff1;
   1975  1.1  mrg 	}
   1976  1.1  mrg 	if (isl_aff_is_nan(aff2)) {
   1977  1.1  mrg 		isl_aff_free(aff1);
   1978  1.1  mrg 		return aff2;
   1979  1.1  mrg 	}
   1980  1.1  mrg 
   1981  1.1  mrg 	n_div1 = isl_aff_dim(aff1, isl_dim_div);
   1982  1.1  mrg 	n_div2 = isl_aff_dim(aff2, isl_dim_div);
   1983  1.1  mrg 	if (n_div1 < 0 || n_div2 < 0)
   1984  1.1  mrg 		goto error;
   1985  1.1  mrg 	if (n_div1 == 0 && n_div2 == 0)
   1986  1.1  mrg 		return add_expanded(aff1, aff2);
   1987  1.1  mrg 
   1988  1.1  mrg 	exp1 = isl_alloc_array(ctx, int, n_div1);
   1989  1.1  mrg 	exp2 = isl_alloc_array(ctx, int, n_div2);
   1990  1.1  mrg 	if ((n_div1 && !exp1) || (n_div2 && !exp2))
   1991  1.1  mrg 		goto error;
   1992  1.1  mrg 
   1993  1.1  mrg 	div = isl_merge_divs(aff1->ls->div, aff2->ls->div, exp1, exp2);
   1994  1.1  mrg 	aff1 = isl_aff_expand_divs(aff1, isl_mat_copy(div), exp1);
   1995  1.1  mrg 	aff2 = isl_aff_expand_divs(aff2, div, exp2);
   1996  1.1  mrg 	free(exp1);
   1997  1.1  mrg 	free(exp2);
   1998  1.1  mrg 
   1999  1.1  mrg 	return add_expanded(aff1, aff2);
   2000  1.1  mrg error:
   2001  1.1  mrg 	free(exp1);
   2002  1.1  mrg 	free(exp2);
   2003  1.1  mrg 	isl_aff_free(aff1);
   2004  1.1  mrg 	isl_aff_free(aff2);
   2005  1.1  mrg 	return NULL;
   2006  1.1  mrg }
   2007  1.1  mrg 
   2008  1.1  mrg __isl_give isl_aff *isl_aff_sub(__isl_take isl_aff *aff1,
   2009  1.1  mrg 	__isl_take isl_aff *aff2)
   2010  1.1  mrg {
   2011  1.1  mrg 	return isl_aff_add(aff1, isl_aff_neg(aff2));
   2012  1.1  mrg }
   2013  1.1  mrg 
   2014  1.1  mrg /* Return the result of scaling "aff" by a factor of "f".
   2015  1.1  mrg  *
   2016  1.1  mrg  * As a special case, f * NaN = NaN.
   2017  1.1  mrg  */
   2018  1.1  mrg __isl_give isl_aff *isl_aff_scale(__isl_take isl_aff *aff, isl_int f)
   2019  1.1  mrg {
   2020  1.1  mrg 	isl_int gcd;
   2021  1.1  mrg 
   2022  1.1  mrg 	if (!aff)
   2023  1.1  mrg 		return NULL;
   2024  1.1  mrg 	if (isl_aff_is_nan(aff))
   2025  1.1  mrg 		return aff;
   2026  1.1  mrg 
   2027  1.1  mrg 	if (isl_int_is_one(f))
   2028  1.1  mrg 		return aff;
   2029  1.1  mrg 
   2030  1.1  mrg 	aff = isl_aff_cow(aff);
   2031  1.1  mrg 	if (!aff)
   2032  1.1  mrg 		return NULL;
   2033  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   2034  1.1  mrg 	if (!aff->v)
   2035  1.1  mrg 		return isl_aff_free(aff);
   2036  1.1  mrg 
   2037  1.1  mrg 	if (isl_int_is_pos(f) && isl_int_is_divisible_by(aff->v->el[0], f)) {
   2038  1.1  mrg 		isl_int_divexact(aff->v->el[0], aff->v->el[0], f);
   2039  1.1  mrg 		return aff;
   2040  1.1  mrg 	}
   2041  1.1  mrg 
   2042  1.1  mrg 	isl_int_init(gcd);
   2043  1.1  mrg 	isl_int_gcd(gcd, aff->v->el[0], f);
   2044  1.1  mrg 	isl_int_divexact(aff->v->el[0], aff->v->el[0], gcd);
   2045  1.1  mrg 	isl_int_divexact(gcd, f, gcd);
   2046  1.1  mrg 	isl_seq_scale(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
   2047  1.1  mrg 	isl_int_clear(gcd);
   2048  1.1  mrg 
   2049  1.1  mrg 	return aff;
   2050  1.1  mrg }
   2051  1.1  mrg 
   2052  1.1  mrg /* Multiple "aff" by "v".
   2053  1.1  mrg  */
   2054  1.1  mrg __isl_give isl_aff *isl_aff_scale_val(__isl_take isl_aff *aff,
   2055  1.1  mrg 	__isl_take isl_val *v)
   2056  1.1  mrg {
   2057  1.1  mrg 	if (!aff || !v)
   2058  1.1  mrg 		goto error;
   2059  1.1  mrg 
   2060  1.1  mrg 	if (isl_val_is_one(v)) {
   2061  1.1  mrg 		isl_val_free(v);
   2062  1.1  mrg 		return aff;
   2063  1.1  mrg 	}
   2064  1.1  mrg 
   2065  1.1  mrg 	if (!isl_val_is_rat(v))
   2066  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2067  1.1  mrg 			"expecting rational factor", goto error);
   2068  1.1  mrg 
   2069  1.1  mrg 	aff = isl_aff_scale(aff, v->n);
   2070  1.1  mrg 	aff = isl_aff_scale_down(aff, v->d);
   2071  1.1  mrg 
   2072  1.1  mrg 	isl_val_free(v);
   2073  1.1  mrg 	return aff;
   2074  1.1  mrg error:
   2075  1.1  mrg 	isl_aff_free(aff);
   2076  1.1  mrg 	isl_val_free(v);
   2077  1.1  mrg 	return NULL;
   2078  1.1  mrg }
   2079  1.1  mrg 
   2080  1.1  mrg /* Return the result of scaling "aff" down by a factor of "f".
   2081  1.1  mrg  *
   2082  1.1  mrg  * As a special case, NaN/f = NaN.
   2083  1.1  mrg  */
   2084  1.1  mrg __isl_give isl_aff *isl_aff_scale_down(__isl_take isl_aff *aff, isl_int f)
   2085  1.1  mrg {
   2086  1.1  mrg 	isl_int gcd;
   2087  1.1  mrg 
   2088  1.1  mrg 	if (!aff)
   2089  1.1  mrg 		return NULL;
   2090  1.1  mrg 	if (isl_aff_is_nan(aff))
   2091  1.1  mrg 		return aff;
   2092  1.1  mrg 
   2093  1.1  mrg 	if (isl_int_is_one(f))
   2094  1.1  mrg 		return aff;
   2095  1.1  mrg 
   2096  1.1  mrg 	aff = isl_aff_cow(aff);
   2097  1.1  mrg 	if (!aff)
   2098  1.1  mrg 		return NULL;
   2099  1.1  mrg 
   2100  1.1  mrg 	if (isl_int_is_zero(f))
   2101  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2102  1.1  mrg 			"cannot scale down by zero", return isl_aff_free(aff));
   2103  1.1  mrg 
   2104  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   2105  1.1  mrg 	if (!aff->v)
   2106  1.1  mrg 		return isl_aff_free(aff);
   2107  1.1  mrg 
   2108  1.1  mrg 	isl_int_init(gcd);
   2109  1.1  mrg 	isl_seq_gcd(aff->v->el + 1, aff->v->size - 1, &gcd);
   2110  1.1  mrg 	isl_int_gcd(gcd, gcd, f);
   2111  1.1  mrg 	isl_seq_scale_down(aff->v->el + 1, aff->v->el + 1, gcd, aff->v->size - 1);
   2112  1.1  mrg 	isl_int_divexact(gcd, f, gcd);
   2113  1.1  mrg 	isl_int_mul(aff->v->el[0], aff->v->el[0], gcd);
   2114  1.1  mrg 	isl_int_clear(gcd);
   2115  1.1  mrg 
   2116  1.1  mrg 	return aff;
   2117  1.1  mrg }
   2118  1.1  mrg 
   2119  1.1  mrg /* Divide "aff" by "v".
   2120  1.1  mrg  */
   2121  1.1  mrg __isl_give isl_aff *isl_aff_scale_down_val(__isl_take isl_aff *aff,
   2122  1.1  mrg 	__isl_take isl_val *v)
   2123  1.1  mrg {
   2124  1.1  mrg 	if (!aff || !v)
   2125  1.1  mrg 		goto error;
   2126  1.1  mrg 
   2127  1.1  mrg 	if (isl_val_is_one(v)) {
   2128  1.1  mrg 		isl_val_free(v);
   2129  1.1  mrg 		return aff;
   2130  1.1  mrg 	}
   2131  1.1  mrg 
   2132  1.1  mrg 	if (!isl_val_is_rat(v))
   2133  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2134  1.1  mrg 			"expecting rational factor", goto error);
   2135  1.1  mrg 	if (!isl_val_is_pos(v))
   2136  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2137  1.1  mrg 			"factor needs to be positive", goto error);
   2138  1.1  mrg 
   2139  1.1  mrg 	aff = isl_aff_scale(aff, v->d);
   2140  1.1  mrg 	aff = isl_aff_scale_down(aff, v->n);
   2141  1.1  mrg 
   2142  1.1  mrg 	isl_val_free(v);
   2143  1.1  mrg 	return aff;
   2144  1.1  mrg error:
   2145  1.1  mrg 	isl_aff_free(aff);
   2146  1.1  mrg 	isl_val_free(v);
   2147  1.1  mrg 	return NULL;
   2148  1.1  mrg }
   2149  1.1  mrg 
   2150  1.1  mrg __isl_give isl_aff *isl_aff_scale_down_ui(__isl_take isl_aff *aff, unsigned f)
   2151  1.1  mrg {
   2152  1.1  mrg 	isl_int v;
   2153  1.1  mrg 
   2154  1.1  mrg 	if (f == 1)
   2155  1.1  mrg 		return aff;
   2156  1.1  mrg 
   2157  1.1  mrg 	isl_int_init(v);
   2158  1.1  mrg 	isl_int_set_ui(v, f);
   2159  1.1  mrg 	aff = isl_aff_scale_down(aff, v);
   2160  1.1  mrg 	isl_int_clear(v);
   2161  1.1  mrg 
   2162  1.1  mrg 	return aff;
   2163  1.1  mrg }
   2164  1.1  mrg 
   2165  1.1  mrg __isl_give isl_aff *isl_aff_set_dim_name(__isl_take isl_aff *aff,
   2166  1.1  mrg 	enum isl_dim_type type, unsigned pos, const char *s)
   2167  1.1  mrg {
   2168  1.1  mrg 	aff = isl_aff_cow(aff);
   2169  1.1  mrg 	if (!aff)
   2170  1.1  mrg 		return NULL;
   2171  1.1  mrg 	if (type == isl_dim_out)
   2172  1.1  mrg 		isl_die(aff->v->ctx, isl_error_invalid,
   2173  1.1  mrg 			"cannot set name of output/set dimension",
   2174  1.1  mrg 			return isl_aff_free(aff));
   2175  1.1  mrg 	if (type == isl_dim_in)
   2176  1.1  mrg 		type = isl_dim_set;
   2177  1.1  mrg 	aff->ls = isl_local_space_set_dim_name(aff->ls, type, pos, s);
   2178  1.1  mrg 	if (!aff->ls)
   2179  1.1  mrg 		return isl_aff_free(aff);
   2180  1.1  mrg 
   2181  1.1  mrg 	return aff;
   2182  1.1  mrg }
   2183  1.1  mrg 
   2184  1.1  mrg __isl_give isl_aff *isl_aff_set_dim_id(__isl_take isl_aff *aff,
   2185  1.1  mrg 	enum isl_dim_type type, unsigned pos, __isl_take isl_id *id)
   2186  1.1  mrg {
   2187  1.1  mrg 	aff = isl_aff_cow(aff);
   2188  1.1  mrg 	if (!aff)
   2189  1.1  mrg 		goto error;
   2190  1.1  mrg 	if (type == isl_dim_out)
   2191  1.1  mrg 		isl_die(aff->v->ctx, isl_error_invalid,
   2192  1.1  mrg 			"cannot set name of output/set dimension",
   2193  1.1  mrg 			goto error);
   2194  1.1  mrg 	if (type == isl_dim_in)
   2195  1.1  mrg 		type = isl_dim_set;
   2196  1.1  mrg 	aff->ls = isl_local_space_set_dim_id(aff->ls, type, pos, id);
   2197  1.1  mrg 	if (!aff->ls)
   2198  1.1  mrg 		return isl_aff_free(aff);
   2199  1.1  mrg 
   2200  1.1  mrg 	return aff;
   2201  1.1  mrg error:
   2202  1.1  mrg 	isl_id_free(id);
   2203  1.1  mrg 	isl_aff_free(aff);
   2204  1.1  mrg 	return NULL;
   2205  1.1  mrg }
   2206  1.1  mrg 
   2207  1.1  mrg /* Replace the identifier of the input tuple of "aff" by "id".
   2208  1.1  mrg  * type is currently required to be equal to isl_dim_in
   2209  1.1  mrg  */
   2210  1.1  mrg __isl_give isl_aff *isl_aff_set_tuple_id(__isl_take isl_aff *aff,
   2211  1.1  mrg 	enum isl_dim_type type, __isl_take isl_id *id)
   2212  1.1  mrg {
   2213  1.1  mrg 	aff = isl_aff_cow(aff);
   2214  1.1  mrg 	if (!aff)
   2215  1.1  mrg 		goto error;
   2216  1.1  mrg 	if (type != isl_dim_in)
   2217  1.1  mrg 		isl_die(aff->v->ctx, isl_error_invalid,
   2218  1.1  mrg 			"cannot only set id of input tuple", goto error);
   2219  1.1  mrg 	aff->ls = isl_local_space_set_tuple_id(aff->ls, isl_dim_set, id);
   2220  1.1  mrg 	if (!aff->ls)
   2221  1.1  mrg 		return isl_aff_free(aff);
   2222  1.1  mrg 
   2223  1.1  mrg 	return aff;
   2224  1.1  mrg error:
   2225  1.1  mrg 	isl_id_free(id);
   2226  1.1  mrg 	isl_aff_free(aff);
   2227  1.1  mrg 	return NULL;
   2228  1.1  mrg }
   2229  1.1  mrg 
   2230  1.1  mrg /* Exploit the equalities in "eq" to simplify the affine expression
   2231  1.1  mrg  * and the expressions of the integer divisions in the local space.
   2232  1.1  mrg  * The integer divisions in this local space are assumed to appear
   2233  1.1  mrg  * as regular dimensions in "eq".
   2234  1.1  mrg  */
   2235  1.1  mrg static __isl_give isl_aff *isl_aff_substitute_equalities_lifted(
   2236  1.1  mrg 	__isl_take isl_aff *aff, __isl_take isl_basic_set *eq)
   2237  1.1  mrg {
   2238  1.1  mrg 	int i, j;
   2239  1.1  mrg 	unsigned o_div;
   2240  1.1  mrg 	unsigned n_div;
   2241  1.1  mrg 
   2242  1.1  mrg 	if (!eq)
   2243  1.1  mrg 		goto error;
   2244  1.1  mrg 	if (eq->n_eq == 0) {
   2245  1.1  mrg 		isl_basic_set_free(eq);
   2246  1.1  mrg 		return aff;
   2247  1.1  mrg 	}
   2248  1.1  mrg 
   2249  1.1  mrg 	aff = isl_aff_cow(aff);
   2250  1.1  mrg 	if (!aff)
   2251  1.1  mrg 		goto error;
   2252  1.1  mrg 
   2253  1.1  mrg 	aff->ls = isl_local_space_substitute_equalities(aff->ls,
   2254  1.1  mrg 							isl_basic_set_copy(eq));
   2255  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   2256  1.1  mrg 	if (!aff->ls || !aff->v)
   2257  1.1  mrg 		goto error;
   2258  1.1  mrg 
   2259  1.1  mrg 	o_div = isl_basic_set_offset(eq, isl_dim_div);
   2260  1.1  mrg 	n_div = eq->n_div;
   2261  1.1  mrg 	for (i = 0; i < eq->n_eq; ++i) {
   2262  1.1  mrg 		j = isl_seq_last_non_zero(eq->eq[i], o_div + n_div);
   2263  1.1  mrg 		if (j < 0 || j == 0 || j >= o_div)
   2264  1.1  mrg 			continue;
   2265  1.1  mrg 
   2266  1.1  mrg 		isl_seq_elim(aff->v->el + 1, eq->eq[i], j, o_div,
   2267  1.1  mrg 				&aff->v->el[0]);
   2268  1.1  mrg 	}
   2269  1.1  mrg 
   2270  1.1  mrg 	isl_basic_set_free(eq);
   2271  1.1  mrg 	aff = isl_aff_normalize(aff);
   2272  1.1  mrg 	return aff;
   2273  1.1  mrg error:
   2274  1.1  mrg 	isl_basic_set_free(eq);
   2275  1.1  mrg 	isl_aff_free(aff);
   2276  1.1  mrg 	return NULL;
   2277  1.1  mrg }
   2278  1.1  mrg 
   2279  1.1  mrg /* Exploit the equalities in "eq" to simplify the affine expression
   2280  1.1  mrg  * and the expressions of the integer divisions in the local space.
   2281  1.1  mrg  */
   2282  1.1  mrg __isl_give isl_aff *isl_aff_substitute_equalities(__isl_take isl_aff *aff,
   2283  1.1  mrg 	__isl_take isl_basic_set *eq)
   2284  1.1  mrg {
   2285  1.1  mrg 	isl_size n_div;
   2286  1.1  mrg 
   2287  1.1  mrg 	n_div = isl_aff_domain_dim(aff, isl_dim_div);
   2288  1.1  mrg 	if (n_div < 0)
   2289  1.1  mrg 		goto error;
   2290  1.1  mrg 	if (n_div > 0)
   2291  1.1  mrg 		eq = isl_basic_set_add_dims(eq, isl_dim_set, n_div);
   2292  1.1  mrg 	return isl_aff_substitute_equalities_lifted(aff, eq);
   2293  1.1  mrg error:
   2294  1.1  mrg 	isl_basic_set_free(eq);
   2295  1.1  mrg 	isl_aff_free(aff);
   2296  1.1  mrg 	return NULL;
   2297  1.1  mrg }
   2298  1.1  mrg 
   2299  1.1  mrg /* Look for equalities among the variables shared by context and aff
   2300  1.1  mrg  * and the integer divisions of aff, if any.
   2301  1.1  mrg  * The equalities are then used to eliminate coefficients and/or integer
   2302  1.1  mrg  * divisions from aff.
   2303  1.1  mrg  */
   2304  1.1  mrg __isl_give isl_aff *isl_aff_gist(__isl_take isl_aff *aff,
   2305  1.1  mrg 	__isl_take isl_set *context)
   2306  1.1  mrg {
   2307  1.1  mrg 	isl_local_space *ls;
   2308  1.1  mrg 	isl_basic_set *hull;
   2309  1.1  mrg 
   2310  1.1  mrg 	ls = isl_aff_get_domain_local_space(aff);
   2311  1.1  mrg 	context = isl_local_space_lift_set(ls, context);
   2312  1.1  mrg 
   2313  1.1  mrg 	hull = isl_set_affine_hull(context);
   2314  1.1  mrg 	return isl_aff_substitute_equalities_lifted(aff, hull);
   2315  1.1  mrg }
   2316  1.1  mrg 
   2317  1.1  mrg __isl_give isl_aff *isl_aff_gist_params(__isl_take isl_aff *aff,
   2318  1.1  mrg 	__isl_take isl_set *context)
   2319  1.1  mrg {
   2320  1.1  mrg 	isl_set *dom_context = isl_set_universe(isl_aff_get_domain_space(aff));
   2321  1.1  mrg 	dom_context = isl_set_intersect_params(dom_context, context);
   2322  1.1  mrg 	return isl_aff_gist(aff, dom_context);
   2323  1.1  mrg }
   2324  1.1  mrg 
   2325  1.1  mrg /* Return a basic set containing those elements in the space
   2326  1.1  mrg  * of aff where it is positive.  "rational" should not be set.
   2327  1.1  mrg  *
   2328  1.1  mrg  * If "aff" is NaN, then it is not positive.
   2329  1.1  mrg  */
   2330  1.1  mrg static __isl_give isl_basic_set *aff_pos_basic_set(__isl_take isl_aff *aff,
   2331  1.1  mrg 	int rational, void *user)
   2332  1.1  mrg {
   2333  1.1  mrg 	isl_constraint *ineq;
   2334  1.1  mrg 	isl_basic_set *bset;
   2335  1.1  mrg 	isl_val *c;
   2336  1.1  mrg 
   2337  1.1  mrg 	if (!aff)
   2338  1.1  mrg 		return NULL;
   2339  1.1  mrg 	if (isl_aff_is_nan(aff)) {
   2340  1.1  mrg 		isl_space *space = isl_aff_get_domain_space(aff);
   2341  1.1  mrg 		isl_aff_free(aff);
   2342  1.1  mrg 		return isl_basic_set_empty(space);
   2343  1.1  mrg 	}
   2344  1.1  mrg 	if (rational)
   2345  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_unsupported,
   2346  1.1  mrg 			"rational sets not supported", goto error);
   2347  1.1  mrg 
   2348  1.1  mrg 	ineq = isl_inequality_from_aff(aff);
   2349  1.1  mrg 	c = isl_constraint_get_constant_val(ineq);
   2350  1.1  mrg 	c = isl_val_sub_ui(c, 1);
   2351  1.1  mrg 	ineq = isl_constraint_set_constant_val(ineq, c);
   2352  1.1  mrg 
   2353  1.1  mrg 	bset = isl_basic_set_from_constraint(ineq);
   2354  1.1  mrg 	bset = isl_basic_set_simplify(bset);
   2355  1.1  mrg 	return bset;
   2356  1.1  mrg error:
   2357  1.1  mrg 	isl_aff_free(aff);
   2358  1.1  mrg 	return NULL;
   2359  1.1  mrg }
   2360  1.1  mrg 
   2361  1.1  mrg /* Return a basic set containing those elements in the space
   2362  1.1  mrg  * of aff where it is non-negative.
   2363  1.1  mrg  * If "rational" is set, then return a rational basic set.
   2364  1.1  mrg  *
   2365  1.1  mrg  * If "aff" is NaN, then it is not non-negative (it's not negative either).
   2366  1.1  mrg  */
   2367  1.1  mrg static __isl_give isl_basic_set *aff_nonneg_basic_set(
   2368  1.1  mrg 	__isl_take isl_aff *aff, int rational, void *user)
   2369  1.1  mrg {
   2370  1.1  mrg 	isl_constraint *ineq;
   2371  1.1  mrg 	isl_basic_set *bset;
   2372  1.1  mrg 
   2373  1.1  mrg 	if (!aff)
   2374  1.1  mrg 		return NULL;
   2375  1.1  mrg 	if (isl_aff_is_nan(aff)) {
   2376  1.1  mrg 		isl_space *space = isl_aff_get_domain_space(aff);
   2377  1.1  mrg 		isl_aff_free(aff);
   2378  1.1  mrg 		return isl_basic_set_empty(space);
   2379  1.1  mrg 	}
   2380  1.1  mrg 
   2381  1.1  mrg 	ineq = isl_inequality_from_aff(aff);
   2382  1.1  mrg 
   2383  1.1  mrg 	bset = isl_basic_set_from_constraint(ineq);
   2384  1.1  mrg 	if (rational)
   2385  1.1  mrg 		bset = isl_basic_set_set_rational(bset);
   2386  1.1  mrg 	bset = isl_basic_set_simplify(bset);
   2387  1.1  mrg 	return bset;
   2388  1.1  mrg }
   2389  1.1  mrg 
   2390  1.1  mrg /* Return a basic set containing those elements in the space
   2391  1.1  mrg  * of aff where it is non-negative.
   2392  1.1  mrg  */
   2393  1.1  mrg __isl_give isl_basic_set *isl_aff_nonneg_basic_set(__isl_take isl_aff *aff)
   2394  1.1  mrg {
   2395  1.1  mrg 	return aff_nonneg_basic_set(aff, 0, NULL);
   2396  1.1  mrg }
   2397  1.1  mrg 
   2398  1.1  mrg /* Return a basic set containing those elements in the domain space
   2399  1.1  mrg  * of "aff" where it is positive.
   2400  1.1  mrg  */
   2401  1.1  mrg __isl_give isl_basic_set *isl_aff_pos_basic_set(__isl_take isl_aff *aff)
   2402  1.1  mrg {
   2403  1.1  mrg 	aff = isl_aff_add_constant_num_si(aff, -1);
   2404  1.1  mrg 	return isl_aff_nonneg_basic_set(aff);
   2405  1.1  mrg }
   2406  1.1  mrg 
   2407  1.1  mrg /* Return a basic set containing those elements in the domain space
   2408  1.1  mrg  * of aff where it is negative.
   2409  1.1  mrg  */
   2410  1.1  mrg __isl_give isl_basic_set *isl_aff_neg_basic_set(__isl_take isl_aff *aff)
   2411  1.1  mrg {
   2412  1.1  mrg 	aff = isl_aff_neg(aff);
   2413  1.1  mrg 	return isl_aff_pos_basic_set(aff);
   2414  1.1  mrg }
   2415  1.1  mrg 
   2416  1.1  mrg /* Return a basic set containing those elements in the space
   2417  1.1  mrg  * of aff where it is zero.
   2418  1.1  mrg  * If "rational" is set, then return a rational basic set.
   2419  1.1  mrg  *
   2420  1.1  mrg  * If "aff" is NaN, then it is not zero.
   2421  1.1  mrg  */
   2422  1.1  mrg static __isl_give isl_basic_set *aff_zero_basic_set(__isl_take isl_aff *aff,
   2423  1.1  mrg 	int rational, void *user)
   2424  1.1  mrg {
   2425  1.1  mrg 	isl_constraint *ineq;
   2426  1.1  mrg 	isl_basic_set *bset;
   2427  1.1  mrg 
   2428  1.1  mrg 	if (!aff)
   2429  1.1  mrg 		return NULL;
   2430  1.1  mrg 	if (isl_aff_is_nan(aff)) {
   2431  1.1  mrg 		isl_space *space = isl_aff_get_domain_space(aff);
   2432  1.1  mrg 		isl_aff_free(aff);
   2433  1.1  mrg 		return isl_basic_set_empty(space);
   2434  1.1  mrg 	}
   2435  1.1  mrg 
   2436  1.1  mrg 	ineq = isl_equality_from_aff(aff);
   2437  1.1  mrg 
   2438  1.1  mrg 	bset = isl_basic_set_from_constraint(ineq);
   2439  1.1  mrg 	if (rational)
   2440  1.1  mrg 		bset = isl_basic_set_set_rational(bset);
   2441  1.1  mrg 	bset = isl_basic_set_simplify(bset);
   2442  1.1  mrg 	return bset;
   2443  1.1  mrg }
   2444  1.1  mrg 
   2445  1.1  mrg /* Return a basic set containing those elements in the space
   2446  1.1  mrg  * of aff where it is zero.
   2447  1.1  mrg  */
   2448  1.1  mrg __isl_give isl_basic_set *isl_aff_zero_basic_set(__isl_take isl_aff *aff)
   2449  1.1  mrg {
   2450  1.1  mrg 	return aff_zero_basic_set(aff, 0, NULL);
   2451  1.1  mrg }
   2452  1.1  mrg 
   2453  1.1  mrg /* Return a basic set containing those elements in the shared space
   2454  1.1  mrg  * of aff1 and aff2 where aff1 is greater than or equal to aff2.
   2455  1.1  mrg  */
   2456  1.1  mrg __isl_give isl_basic_set *isl_aff_ge_basic_set(__isl_take isl_aff *aff1,
   2457  1.1  mrg 	__isl_take isl_aff *aff2)
   2458  1.1  mrg {
   2459  1.1  mrg 	aff1 = isl_aff_sub(aff1, aff2);
   2460  1.1  mrg 
   2461  1.1  mrg 	return isl_aff_nonneg_basic_set(aff1);
   2462  1.1  mrg }
   2463  1.1  mrg 
   2464  1.1  mrg /* Return a basic set containing those elements in the shared domain space
   2465  1.1  mrg  * of "aff1" and "aff2" where "aff1" is greater than "aff2".
   2466  1.1  mrg  */
   2467  1.1  mrg __isl_give isl_basic_set *isl_aff_gt_basic_set(__isl_take isl_aff *aff1,
   2468  1.1  mrg 	__isl_take isl_aff *aff2)
   2469  1.1  mrg {
   2470  1.1  mrg 	aff1 = isl_aff_sub(aff1, aff2);
   2471  1.1  mrg 
   2472  1.1  mrg 	return isl_aff_pos_basic_set(aff1);
   2473  1.1  mrg }
   2474  1.1  mrg 
   2475  1.1  mrg /* Return a set containing those elements in the shared space
   2476  1.1  mrg  * of aff1 and aff2 where aff1 is greater than or equal to aff2.
   2477  1.1  mrg  */
   2478  1.1  mrg __isl_give isl_set *isl_aff_ge_set(__isl_take isl_aff *aff1,
   2479  1.1  mrg 	__isl_take isl_aff *aff2)
   2480  1.1  mrg {
   2481  1.1  mrg 	return isl_set_from_basic_set(isl_aff_ge_basic_set(aff1, aff2));
   2482  1.1  mrg }
   2483  1.1  mrg 
   2484  1.1  mrg /* Return a set containing those elements in the shared domain space
   2485  1.1  mrg  * of aff1 and aff2 where aff1 is greater than aff2.
   2486  1.1  mrg  *
   2487  1.1  mrg  * If either of the two inputs is NaN, then the result is empty,
   2488  1.1  mrg  * as comparisons with NaN always return false.
   2489  1.1  mrg  */
   2490  1.1  mrg __isl_give isl_set *isl_aff_gt_set(__isl_take isl_aff *aff1,
   2491  1.1  mrg 	__isl_take isl_aff *aff2)
   2492  1.1  mrg {
   2493  1.1  mrg 	return isl_set_from_basic_set(isl_aff_gt_basic_set(aff1, aff2));
   2494  1.1  mrg }
   2495  1.1  mrg 
   2496  1.1  mrg /* Return a basic set containing those elements in the shared space
   2497  1.1  mrg  * of aff1 and aff2 where aff1 is smaller than or equal to aff2.
   2498  1.1  mrg  */
   2499  1.1  mrg __isl_give isl_basic_set *isl_aff_le_basic_set(__isl_take isl_aff *aff1,
   2500  1.1  mrg 	__isl_take isl_aff *aff2)
   2501  1.1  mrg {
   2502  1.1  mrg 	return isl_aff_ge_basic_set(aff2, aff1);
   2503  1.1  mrg }
   2504  1.1  mrg 
   2505  1.1  mrg /* Return a basic set containing those elements in the shared domain space
   2506  1.1  mrg  * of "aff1" and "aff2" where "aff1" is smaller than "aff2".
   2507  1.1  mrg  */
   2508  1.1  mrg __isl_give isl_basic_set *isl_aff_lt_basic_set(__isl_take isl_aff *aff1,
   2509  1.1  mrg 	__isl_take isl_aff *aff2)
   2510  1.1  mrg {
   2511  1.1  mrg 	return isl_aff_gt_basic_set(aff2, aff1);
   2512  1.1  mrg }
   2513  1.1  mrg 
   2514  1.1  mrg /* Return a set containing those elements in the shared space
   2515  1.1  mrg  * of aff1 and aff2 where aff1 is smaller than or equal to aff2.
   2516  1.1  mrg  */
   2517  1.1  mrg __isl_give isl_set *isl_aff_le_set(__isl_take isl_aff *aff1,
   2518  1.1  mrg 	__isl_take isl_aff *aff2)
   2519  1.1  mrg {
   2520  1.1  mrg 	return isl_aff_ge_set(aff2, aff1);
   2521  1.1  mrg }
   2522  1.1  mrg 
   2523  1.1  mrg /* Return a set containing those elements in the shared domain space
   2524  1.1  mrg  * of "aff1" and "aff2" where "aff1" is smaller than "aff2".
   2525  1.1  mrg  */
   2526  1.1  mrg __isl_give isl_set *isl_aff_lt_set(__isl_take isl_aff *aff1,
   2527  1.1  mrg 	__isl_take isl_aff *aff2)
   2528  1.1  mrg {
   2529  1.1  mrg 	return isl_set_from_basic_set(isl_aff_lt_basic_set(aff1, aff2));
   2530  1.1  mrg }
   2531  1.1  mrg 
   2532  1.1  mrg /* Return a basic set containing those elements in the shared space
   2533  1.1  mrg  * of aff1 and aff2 where aff1 and aff2 are equal.
   2534  1.1  mrg  */
   2535  1.1  mrg __isl_give isl_basic_set *isl_aff_eq_basic_set(__isl_take isl_aff *aff1,
   2536  1.1  mrg 	__isl_take isl_aff *aff2)
   2537  1.1  mrg {
   2538  1.1  mrg 	aff1 = isl_aff_sub(aff1, aff2);
   2539  1.1  mrg 
   2540  1.1  mrg 	return isl_aff_zero_basic_set(aff1);
   2541  1.1  mrg }
   2542  1.1  mrg 
   2543  1.1  mrg /* Return a set containing those elements in the shared space
   2544  1.1  mrg  * of aff1 and aff2 where aff1 and aff2 are equal.
   2545  1.1  mrg  */
   2546  1.1  mrg __isl_give isl_set *isl_aff_eq_set(__isl_take isl_aff *aff1,
   2547  1.1  mrg 	__isl_take isl_aff *aff2)
   2548  1.1  mrg {
   2549  1.1  mrg 	return isl_set_from_basic_set(isl_aff_eq_basic_set(aff1, aff2));
   2550  1.1  mrg }
   2551  1.1  mrg 
   2552  1.1  mrg /* Return a set containing those elements in the shared domain space
   2553  1.1  mrg  * of aff1 and aff2 where aff1 and aff2 are not equal.
   2554  1.1  mrg  *
   2555  1.1  mrg  * If either of the two inputs is NaN, then the result is empty,
   2556  1.1  mrg  * as comparisons with NaN always return false.
   2557  1.1  mrg  */
   2558  1.1  mrg __isl_give isl_set *isl_aff_ne_set(__isl_take isl_aff *aff1,
   2559  1.1  mrg 	__isl_take isl_aff *aff2)
   2560  1.1  mrg {
   2561  1.1  mrg 	isl_set *set_lt, *set_gt;
   2562  1.1  mrg 
   2563  1.1  mrg 	set_lt = isl_aff_lt_set(isl_aff_copy(aff1),
   2564  1.1  mrg 				isl_aff_copy(aff2));
   2565  1.1  mrg 	set_gt = isl_aff_gt_set(aff1, aff2);
   2566  1.1  mrg 	return isl_set_union_disjoint(set_lt, set_gt);
   2567  1.1  mrg }
   2568  1.1  mrg 
   2569  1.1  mrg __isl_give isl_aff *isl_aff_add_on_domain(__isl_keep isl_set *dom,
   2570  1.1  mrg 	__isl_take isl_aff *aff1, __isl_take isl_aff *aff2)
   2571  1.1  mrg {
   2572  1.1  mrg 	aff1 = isl_aff_add(aff1, aff2);
   2573  1.1  mrg 	aff1 = isl_aff_gist(aff1, isl_set_copy(dom));
   2574  1.1  mrg 	return aff1;
   2575  1.1  mrg }
   2576  1.1  mrg 
   2577  1.1  mrg isl_bool isl_aff_is_empty(__isl_keep isl_aff *aff)
   2578  1.1  mrg {
   2579  1.1  mrg 	if (!aff)
   2580  1.1  mrg 		return isl_bool_error;
   2581  1.1  mrg 
   2582  1.1  mrg 	return isl_bool_false;
   2583  1.1  mrg }
   2584  1.1  mrg 
   2585  1.1  mrg #undef TYPE
   2586  1.1  mrg #define TYPE	isl_aff
   2587  1.1  mrg static
   2588  1.1  mrg #include "check_type_range_templ.c"
   2589  1.1  mrg 
   2590  1.1  mrg /* Check whether the given affine expression has non-zero coefficient
   2591  1.1  mrg  * for any dimension in the given range or if any of these dimensions
   2592  1.1  mrg  * appear with non-zero coefficients in any of the integer divisions
   2593  1.1  mrg  * involved in the affine expression.
   2594  1.1  mrg  */
   2595  1.1  mrg isl_bool isl_aff_involves_dims(__isl_keep isl_aff *aff,
   2596  1.1  mrg 	enum isl_dim_type type, unsigned first, unsigned n)
   2597  1.1  mrg {
   2598  1.1  mrg 	int i;
   2599  1.1  mrg 	int *active = NULL;
   2600  1.1  mrg 	isl_bool involves = isl_bool_false;
   2601  1.1  mrg 
   2602  1.1  mrg 	if (!aff)
   2603  1.1  mrg 		return isl_bool_error;
   2604  1.1  mrg 	if (n == 0)
   2605  1.1  mrg 		return isl_bool_false;
   2606  1.1  mrg 	if (isl_aff_check_range(aff, type, first, n) < 0)
   2607  1.1  mrg 		return isl_bool_error;
   2608  1.1  mrg 
   2609  1.1  mrg 	active = isl_local_space_get_active(aff->ls, aff->v->el + 2);
   2610  1.1  mrg 	if (!active)
   2611  1.1  mrg 		goto error;
   2612  1.1  mrg 
   2613  1.1  mrg 	first += isl_local_space_offset(aff->ls, type) - 1;
   2614  1.1  mrg 	for (i = 0; i < n; ++i)
   2615  1.1  mrg 		if (active[first + i]) {
   2616  1.1  mrg 			involves = isl_bool_true;
   2617  1.1  mrg 			break;
   2618  1.1  mrg 		}
   2619  1.1  mrg 
   2620  1.1  mrg 	free(active);
   2621  1.1  mrg 
   2622  1.1  mrg 	return involves;
   2623  1.1  mrg error:
   2624  1.1  mrg 	free(active);
   2625  1.1  mrg 	return isl_bool_error;
   2626  1.1  mrg }
   2627  1.1  mrg 
   2628  1.1  mrg /* Does "aff" involve any local variables, i.e., integer divisions?
   2629  1.1  mrg  */
   2630  1.1  mrg isl_bool isl_aff_involves_locals(__isl_keep isl_aff *aff)
   2631  1.1  mrg {
   2632  1.1  mrg 	isl_size n;
   2633  1.1  mrg 
   2634  1.1  mrg 	n = isl_aff_dim(aff, isl_dim_div);
   2635  1.1  mrg 	if (n < 0)
   2636  1.1  mrg 		return isl_bool_error;
   2637  1.1  mrg 	return isl_bool_ok(n > 0);
   2638  1.1  mrg }
   2639  1.1  mrg 
   2640  1.1  mrg __isl_give isl_aff *isl_aff_drop_dims(__isl_take isl_aff *aff,
   2641  1.1  mrg 	enum isl_dim_type type, unsigned first, unsigned n)
   2642  1.1  mrg {
   2643  1.1  mrg 	if (!aff)
   2644  1.1  mrg 		return NULL;
   2645  1.1  mrg 	if (type == isl_dim_out)
   2646  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2647  1.1  mrg 			"cannot drop output/set dimension",
   2648  1.1  mrg 			return isl_aff_free(aff));
   2649  1.1  mrg 	if (type == isl_dim_in)
   2650  1.1  mrg 		type = isl_dim_set;
   2651  1.1  mrg 	if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
   2652  1.1  mrg 		return aff;
   2653  1.1  mrg 
   2654  1.1  mrg 	if (isl_local_space_check_range(aff->ls, type, first, n) < 0)
   2655  1.1  mrg 		return isl_aff_free(aff);
   2656  1.1  mrg 
   2657  1.1  mrg 	aff = isl_aff_cow(aff);
   2658  1.1  mrg 	if (!aff)
   2659  1.1  mrg 		return NULL;
   2660  1.1  mrg 
   2661  1.1  mrg 	aff->ls = isl_local_space_drop_dims(aff->ls, type, first, n);
   2662  1.1  mrg 	if (!aff->ls)
   2663  1.1  mrg 		return isl_aff_free(aff);
   2664  1.1  mrg 
   2665  1.1  mrg 	first += 1 + isl_local_space_offset(aff->ls, type);
   2666  1.1  mrg 	aff->v = isl_vec_drop_els(aff->v, first, n);
   2667  1.1  mrg 	if (!aff->v)
   2668  1.1  mrg 		return isl_aff_free(aff);
   2669  1.1  mrg 
   2670  1.1  mrg 	return aff;
   2671  1.1  mrg }
   2672  1.1  mrg 
   2673  1.1  mrg /* Is the domain of "aff" a product?
   2674  1.1  mrg  */
   2675  1.1  mrg static isl_bool isl_aff_domain_is_product(__isl_keep isl_aff *aff)
   2676  1.1  mrg {
   2677  1.1  mrg 	return isl_space_is_product(isl_aff_peek_domain_space(aff));
   2678  1.1  mrg }
   2679  1.1  mrg 
   2680  1.1  mrg #undef TYPE
   2681  1.1  mrg #define TYPE	isl_aff
   2682  1.1  mrg #include <isl_domain_factor_templ.c>
   2683  1.1  mrg 
   2684  1.1  mrg /* Project the domain of the affine expression onto its parameter space.
   2685  1.1  mrg  * The affine expression may not involve any of the domain dimensions.
   2686  1.1  mrg  */
   2687  1.1  mrg __isl_give isl_aff *isl_aff_project_domain_on_params(__isl_take isl_aff *aff)
   2688  1.1  mrg {
   2689  1.1  mrg 	isl_space *space;
   2690  1.1  mrg 	isl_size n;
   2691  1.1  mrg 
   2692  1.1  mrg 	n = isl_aff_dim(aff, isl_dim_in);
   2693  1.1  mrg 	if (n < 0)
   2694  1.1  mrg 		return isl_aff_free(aff);
   2695  1.1  mrg 	aff = isl_aff_drop_domain(aff, 0, n);
   2696  1.1  mrg 	space = isl_aff_get_domain_space(aff);
   2697  1.1  mrg 	space = isl_space_params(space);
   2698  1.1  mrg 	aff = isl_aff_reset_domain_space(aff, space);
   2699  1.1  mrg 	return aff;
   2700  1.1  mrg }
   2701  1.1  mrg 
   2702  1.1  mrg /* Convert an affine expression defined over a parameter domain
   2703  1.1  mrg  * into one that is defined over a zero-dimensional set.
   2704  1.1  mrg  */
   2705  1.1  mrg __isl_give isl_aff *isl_aff_from_range(__isl_take isl_aff *aff)
   2706  1.1  mrg {
   2707  1.1  mrg 	isl_local_space *ls;
   2708  1.1  mrg 
   2709  1.1  mrg 	ls = isl_aff_take_domain_local_space(aff);
   2710  1.1  mrg 	ls = isl_local_space_set_from_params(ls);
   2711  1.1  mrg 	aff = isl_aff_restore_domain_local_space(aff, ls);
   2712  1.1  mrg 
   2713  1.1  mrg 	return aff;
   2714  1.1  mrg }
   2715  1.1  mrg 
   2716  1.1  mrg __isl_give isl_aff *isl_aff_insert_dims(__isl_take isl_aff *aff,
   2717  1.1  mrg 	enum isl_dim_type type, unsigned first, unsigned n)
   2718  1.1  mrg {
   2719  1.1  mrg 	if (!aff)
   2720  1.1  mrg 		return NULL;
   2721  1.1  mrg 	if (type == isl_dim_out)
   2722  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2723  1.1  mrg 			"cannot insert output/set dimensions",
   2724  1.1  mrg 			return isl_aff_free(aff));
   2725  1.1  mrg 	if (type == isl_dim_in)
   2726  1.1  mrg 		type = isl_dim_set;
   2727  1.1  mrg 	if (n == 0 && !isl_local_space_is_named_or_nested(aff->ls, type))
   2728  1.1  mrg 		return aff;
   2729  1.1  mrg 
   2730  1.1  mrg 	if (isl_local_space_check_range(aff->ls, type, first, 0) < 0)
   2731  1.1  mrg 		return isl_aff_free(aff);
   2732  1.1  mrg 
   2733  1.1  mrg 	aff = isl_aff_cow(aff);
   2734  1.1  mrg 	if (!aff)
   2735  1.1  mrg 		return NULL;
   2736  1.1  mrg 
   2737  1.1  mrg 	aff->ls = isl_local_space_insert_dims(aff->ls, type, first, n);
   2738  1.1  mrg 	if (!aff->ls)
   2739  1.1  mrg 		return isl_aff_free(aff);
   2740  1.1  mrg 
   2741  1.1  mrg 	first += 1 + isl_local_space_offset(aff->ls, type);
   2742  1.1  mrg 	aff->v = isl_vec_insert_zero_els(aff->v, first, n);
   2743  1.1  mrg 	if (!aff->v)
   2744  1.1  mrg 		return isl_aff_free(aff);
   2745  1.1  mrg 
   2746  1.1  mrg 	return aff;
   2747  1.1  mrg }
   2748  1.1  mrg 
   2749  1.1  mrg __isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff,
   2750  1.1  mrg 	enum isl_dim_type type, unsigned n)
   2751  1.1  mrg {
   2752  1.1  mrg 	isl_size pos;
   2753  1.1  mrg 
   2754  1.1  mrg 	pos = isl_aff_dim(aff, type);
   2755  1.1  mrg 	if (pos < 0)
   2756  1.1  mrg 		return isl_aff_free(aff);
   2757  1.1  mrg 
   2758  1.1  mrg 	return isl_aff_insert_dims(aff, type, pos, n);
   2759  1.1  mrg }
   2760  1.1  mrg 
   2761  1.1  mrg /* Move the "n" dimensions of "src_type" starting at "src_pos" of "aff"
   2762  1.1  mrg  * to dimensions of "dst_type" at "dst_pos".
   2763  1.1  mrg  *
   2764  1.1  mrg  * We only support moving input dimensions to parameters and vice versa.
   2765  1.1  mrg  */
   2766  1.1  mrg __isl_give isl_aff *isl_aff_move_dims(__isl_take isl_aff *aff,
   2767  1.1  mrg 	enum isl_dim_type dst_type, unsigned dst_pos,
   2768  1.1  mrg 	enum isl_dim_type src_type, unsigned src_pos, unsigned n)
   2769  1.1  mrg {
   2770  1.1  mrg 	unsigned g_dst_pos;
   2771  1.1  mrg 	unsigned g_src_pos;
   2772  1.1  mrg 	isl_size src_off, dst_off;
   2773  1.1  mrg 
   2774  1.1  mrg 	if (!aff)
   2775  1.1  mrg 		return NULL;
   2776  1.1  mrg 	if (n == 0 &&
   2777  1.1  mrg 	    !isl_local_space_is_named_or_nested(aff->ls, src_type) &&
   2778  1.1  mrg 	    !isl_local_space_is_named_or_nested(aff->ls, dst_type))
   2779  1.1  mrg 		return aff;
   2780  1.1  mrg 
   2781  1.1  mrg 	if (dst_type == isl_dim_out || src_type == isl_dim_out)
   2782  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2783  1.1  mrg 			"cannot move output/set dimension",
   2784  1.1  mrg 			return isl_aff_free(aff));
   2785  1.1  mrg 	if (dst_type == isl_dim_div || src_type == isl_dim_div)
   2786  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   2787  1.1  mrg 			"cannot move divs", return isl_aff_free(aff));
   2788  1.1  mrg 	if (dst_type == isl_dim_in)
   2789  1.1  mrg 		dst_type = isl_dim_set;
   2790  1.1  mrg 	if (src_type == isl_dim_in)
   2791  1.1  mrg 		src_type = isl_dim_set;
   2792  1.1  mrg 
   2793  1.1  mrg 	if (isl_local_space_check_range(aff->ls, src_type, src_pos, n) < 0)
   2794  1.1  mrg 		return isl_aff_free(aff);
   2795  1.1  mrg 	if (dst_type == src_type)
   2796  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_unsupported,
   2797  1.1  mrg 			"moving dims within the same type not supported",
   2798  1.1  mrg 			return isl_aff_free(aff));
   2799  1.1  mrg 
   2800  1.1  mrg 	aff = isl_aff_cow(aff);
   2801  1.1  mrg 	src_off = isl_aff_domain_offset(aff, src_type);
   2802  1.1  mrg 	dst_off = isl_aff_domain_offset(aff, dst_type);
   2803  1.1  mrg 	if (src_off < 0 || dst_off < 0)
   2804  1.1  mrg 		return isl_aff_free(aff);
   2805  1.1  mrg 
   2806  1.1  mrg 	g_src_pos = 1 + src_off + src_pos;
   2807  1.1  mrg 	g_dst_pos = 1 + dst_off + dst_pos;
   2808  1.1  mrg 	if (dst_type > src_type)
   2809  1.1  mrg 		g_dst_pos -= n;
   2810  1.1  mrg 
   2811  1.1  mrg 	aff->v = isl_vec_move_els(aff->v, g_dst_pos, g_src_pos, n);
   2812  1.1  mrg 	aff->ls = isl_local_space_move_dims(aff->ls, dst_type, dst_pos,
   2813  1.1  mrg 						src_type, src_pos, n);
   2814  1.1  mrg 	if (!aff->v || !aff->ls)
   2815  1.1  mrg 		return isl_aff_free(aff);
   2816  1.1  mrg 
   2817  1.1  mrg 	aff = sort_divs(aff);
   2818  1.1  mrg 
   2819  1.1  mrg 	return aff;
   2820  1.1  mrg }
   2821  1.1  mrg 
   2822  1.1  mrg /* Given an affine function on a domain (A -> B),
   2823  1.1  mrg  * interchange A and B in the wrapped domain
   2824  1.1  mrg  * to obtain a function on the domain (B -> A).
   2825  1.1  mrg  *
   2826  1.1  mrg  * Since this may change the position of some variables,
   2827  1.1  mrg  * it may also change the normalized order of the local variables.
   2828  1.1  mrg  * Restore this order.  Since sort_divs assumes the input
   2829  1.1  mrg  * has a single reference, an explicit isl_aff_cow is required.
   2830  1.1  mrg  */
   2831  1.1  mrg __isl_give isl_aff *isl_aff_domain_reverse(__isl_take isl_aff *aff)
   2832  1.1  mrg {
   2833  1.1  mrg 	isl_space *space;
   2834  1.1  mrg 	isl_local_space *ls;
   2835  1.1  mrg 	isl_vec *v;
   2836  1.1  mrg 	isl_size n_in, n_out;
   2837  1.1  mrg 	unsigned offset;
   2838  1.1  mrg 
   2839  1.1  mrg 	space = isl_aff_peek_domain_space(aff);
   2840  1.1  mrg 	offset = isl_space_offset(space, isl_dim_set);
   2841  1.1  mrg 	n_in = isl_space_wrapped_dim(space, isl_dim_set, isl_dim_in);
   2842  1.1  mrg 	n_out = isl_space_wrapped_dim(space, isl_dim_set, isl_dim_out);
   2843  1.1  mrg 	if (offset < 0 || n_in < 0 || n_out < 0)
   2844  1.1  mrg 		return isl_aff_free(aff);
   2845  1.1  mrg 
   2846  1.1  mrg 	v = isl_aff_take_rat_aff(aff);
   2847  1.1  mrg 	v = isl_vec_move_els(v, 1 + 1 + offset, 1 + 1 + offset + n_in, n_out);
   2848  1.1  mrg 	aff = isl_aff_restore_rat_aff(aff, v);
   2849  1.1  mrg 
   2850  1.1  mrg 	ls = isl_aff_take_domain_local_space(aff);
   2851  1.1  mrg 	ls = isl_local_space_wrapped_reverse(ls);
   2852  1.1  mrg 	aff = isl_aff_restore_domain_local_space(aff, ls);
   2853  1.1  mrg 
   2854  1.1  mrg 	aff = isl_aff_cow(aff);
   2855  1.1  mrg 	aff = sort_divs(aff);
   2856  1.1  mrg 
   2857  1.1  mrg 	return aff;
   2858  1.1  mrg }
   2859  1.1  mrg 
   2860  1.1  mrg /* Return a zero isl_aff in the given space.
   2861  1.1  mrg  *
   2862  1.1  mrg  * This is a helper function for isl_pw_*_as_* that ensures a uniform
   2863  1.1  mrg  * interface over all piecewise types.
   2864  1.1  mrg  */
   2865  1.1  mrg static __isl_give isl_aff *isl_aff_zero_in_space(__isl_take isl_space *space)
   2866  1.1  mrg {
   2867  1.1  mrg 	isl_local_space *ls;
   2868  1.1  mrg 
   2869  1.1  mrg 	ls = isl_local_space_from_space(isl_space_domain(space));
   2870  1.1  mrg 	return isl_aff_zero_on_domain(ls);
   2871  1.1  mrg }
   2872  1.1  mrg 
   2873  1.1  mrg #define isl_aff_involves_nan isl_aff_is_nan
   2874  1.1  mrg 
   2875  1.1  mrg #undef PW
   2876  1.1  mrg #define PW isl_pw_aff
   2877  1.1  mrg #undef BASE
   2878  1.1  mrg #define BASE aff
   2879  1.1  mrg #undef EL_IS_ZERO
   2880  1.1  mrg #define EL_IS_ZERO is_empty
   2881  1.1  mrg #undef ZERO
   2882  1.1  mrg #define ZERO empty
   2883  1.1  mrg #undef IS_ZERO
   2884  1.1  mrg #define IS_ZERO is_empty
   2885  1.1  mrg #undef FIELD
   2886  1.1  mrg #define FIELD aff
   2887  1.1  mrg #undef DEFAULT_IS_ZERO
   2888  1.1  mrg #define DEFAULT_IS_ZERO 0
   2889  1.1  mrg 
   2890  1.1  mrg #include <isl_pw_templ.c>
   2891  1.1  mrg #include <isl_pw_un_op_templ.c>
   2892  1.1  mrg #include <isl_pw_add_constant_val_templ.c>
   2893  1.1  mrg #include <isl_pw_add_disjoint_templ.c>
   2894  1.1  mrg #include <isl_pw_bind_domain_templ.c>
   2895  1.1  mrg #include <isl_pw_domain_reverse_templ.c>
   2896  1.1  mrg #include <isl_pw_eval.c>
   2897  1.1  mrg #include <isl_pw_hash.c>
   2898  1.1  mrg #include <isl_pw_fix_templ.c>
   2899  1.1  mrg #include <isl_pw_from_range_templ.c>
   2900  1.1  mrg #include <isl_pw_insert_dims_templ.c>
   2901  1.1  mrg #include <isl_pw_insert_domain_templ.c>
   2902  1.1  mrg #include <isl_pw_move_dims_templ.c>
   2903  1.1  mrg #include <isl_pw_neg_templ.c>
   2904  1.1  mrg #include <isl_pw_pullback_templ.c>
   2905  1.1  mrg #include <isl_pw_scale_templ.c>
   2906  1.1  mrg #include <isl_pw_sub_templ.c>
   2907  1.1  mrg #include <isl_pw_union_opt.c>
   2908  1.1  mrg 
   2909  1.1  mrg #undef BASE
   2910  1.1  mrg #define BASE pw_aff
   2911  1.1  mrg 
   2912  1.1  mrg #include <isl_union_single.c>
   2913  1.1  mrg #include <isl_union_neg.c>
   2914  1.1  mrg #include <isl_union_sub_templ.c>
   2915  1.1  mrg 
   2916  1.1  mrg #undef BASE
   2917  1.1  mrg #define BASE aff
   2918  1.1  mrg 
   2919  1.1  mrg #include <isl_union_pw_templ.c>
   2920  1.1  mrg 
   2921  1.1  mrg /* Compute a piecewise quasi-affine expression with a domain that
   2922  1.1  mrg  * is the union of those of pwaff1 and pwaff2 and such that on each
   2923  1.1  mrg  * cell, the quasi-affine expression is the maximum of those of pwaff1
   2924  1.1  mrg  * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
   2925  1.1  mrg  * cell, then the associated expression is the defined one.
   2926  1.1  mrg  */
   2927  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_union_max(__isl_take isl_pw_aff *pwaff1,
   2928  1.1  mrg 	__isl_take isl_pw_aff *pwaff2)
   2929  1.1  mrg {
   2930  1.1  mrg 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   2931  1.1  mrg 	return isl_pw_aff_union_opt_cmp(pwaff1, pwaff2, &isl_aff_ge_set);
   2932  1.1  mrg }
   2933  1.1  mrg 
   2934  1.1  mrg /* Compute a piecewise quasi-affine expression with a domain that
   2935  1.1  mrg  * is the union of those of pwaff1 and pwaff2 and such that on each
   2936  1.1  mrg  * cell, the quasi-affine expression is the minimum of those of pwaff1
   2937  1.1  mrg  * and pwaff2.  If only one of pwaff1 or pwaff2 is defined on a given
   2938  1.1  mrg  * cell, then the associated expression is the defined one.
   2939  1.1  mrg  */
   2940  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_union_min(__isl_take isl_pw_aff *pwaff1,
   2941  1.1  mrg 	__isl_take isl_pw_aff *pwaff2)
   2942  1.1  mrg {
   2943  1.1  mrg 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   2944  1.1  mrg 	return isl_pw_aff_union_opt_cmp(pwaff1, pwaff2, &isl_aff_le_set);
   2945  1.1  mrg }
   2946  1.1  mrg 
   2947  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_union_opt(__isl_take isl_pw_aff *pwaff1,
   2948  1.1  mrg 	__isl_take isl_pw_aff *pwaff2, int max)
   2949  1.1  mrg {
   2950  1.1  mrg 	if (max)
   2951  1.1  mrg 		return isl_pw_aff_union_max(pwaff1, pwaff2);
   2952  1.1  mrg 	else
   2953  1.1  mrg 		return isl_pw_aff_union_min(pwaff1, pwaff2);
   2954  1.1  mrg }
   2955  1.1  mrg 
   2956  1.1  mrg /* Is the domain of "pa" a product?
   2957  1.1  mrg  */
   2958  1.1  mrg static isl_bool isl_pw_aff_domain_is_product(__isl_keep isl_pw_aff *pa)
   2959  1.1  mrg {
   2960  1.1  mrg 	return isl_space_domain_is_wrapping(isl_pw_aff_peek_space(pa));
   2961  1.1  mrg }
   2962  1.1  mrg 
   2963  1.1  mrg #undef TYPE
   2964  1.1  mrg #define TYPE	isl_pw_aff
   2965  1.1  mrg #include <isl_domain_factor_templ.c>
   2966  1.1  mrg 
   2967  1.1  mrg /* Return a set containing those elements in the domain
   2968  1.1  mrg  * of "pwaff" where it satisfies "fn" (if complement is 0) or
   2969  1.1  mrg  * does not satisfy "fn" (if complement is 1).
   2970  1.1  mrg  *
   2971  1.1  mrg  * The pieces with a NaN never belong to the result since
   2972  1.1  mrg  * NaN does not satisfy any property.
   2973  1.1  mrg  */
   2974  1.1  mrg static __isl_give isl_set *pw_aff_locus(__isl_take isl_pw_aff *pwaff,
   2975  1.1  mrg 	__isl_give isl_basic_set *(*fn)(__isl_take isl_aff *aff, int rational,
   2976  1.1  mrg 		void *user),
   2977  1.1  mrg 	int complement, void *user)
   2978  1.1  mrg {
   2979  1.1  mrg 	int i;
   2980  1.1  mrg 	isl_set *set;
   2981  1.1  mrg 
   2982  1.1  mrg 	if (!pwaff)
   2983  1.1  mrg 		return NULL;
   2984  1.1  mrg 
   2985  1.1  mrg 	set = isl_set_empty(isl_pw_aff_get_domain_space(pwaff));
   2986  1.1  mrg 
   2987  1.1  mrg 	for (i = 0; i < pwaff->n; ++i) {
   2988  1.1  mrg 		isl_basic_set *bset;
   2989  1.1  mrg 		isl_set *set_i, *locus;
   2990  1.1  mrg 		isl_bool rational;
   2991  1.1  mrg 
   2992  1.1  mrg 		if (isl_aff_is_nan(pwaff->p[i].aff))
   2993  1.1  mrg 			continue;
   2994  1.1  mrg 
   2995  1.1  mrg 		rational = isl_set_has_rational(pwaff->p[i].set);
   2996  1.1  mrg 		bset = fn(isl_aff_copy(pwaff->p[i].aff), rational, user);
   2997  1.1  mrg 		locus = isl_set_from_basic_set(bset);
   2998  1.1  mrg 		set_i = isl_set_copy(pwaff->p[i].set);
   2999  1.1  mrg 		if (complement)
   3000  1.1  mrg 			set_i = isl_set_subtract(set_i, locus);
   3001  1.1  mrg 		else
   3002  1.1  mrg 			set_i = isl_set_intersect(set_i, locus);
   3003  1.1  mrg 		set = isl_set_union_disjoint(set, set_i);
   3004  1.1  mrg 	}
   3005  1.1  mrg 
   3006  1.1  mrg 	isl_pw_aff_free(pwaff);
   3007  1.1  mrg 
   3008  1.1  mrg 	return set;
   3009  1.1  mrg }
   3010  1.1  mrg 
   3011  1.1  mrg /* Return a set containing those elements in the domain
   3012  1.1  mrg  * of "pa" where it is positive.
   3013  1.1  mrg  */
   3014  1.1  mrg __isl_give isl_set *isl_pw_aff_pos_set(__isl_take isl_pw_aff *pa)
   3015  1.1  mrg {
   3016  1.1  mrg 	return pw_aff_locus(pa, &aff_pos_basic_set, 0, NULL);
   3017  1.1  mrg }
   3018  1.1  mrg 
   3019  1.1  mrg /* Return a set containing those elements in the domain
   3020  1.1  mrg  * of pwaff where it is non-negative.
   3021  1.1  mrg  */
   3022  1.1  mrg __isl_give isl_set *isl_pw_aff_nonneg_set(__isl_take isl_pw_aff *pwaff)
   3023  1.1  mrg {
   3024  1.1  mrg 	return pw_aff_locus(pwaff, &aff_nonneg_basic_set, 0, NULL);
   3025  1.1  mrg }
   3026  1.1  mrg 
   3027  1.1  mrg /* Return a set containing those elements in the domain
   3028  1.1  mrg  * of pwaff where it is zero.
   3029  1.1  mrg  */
   3030  1.1  mrg __isl_give isl_set *isl_pw_aff_zero_set(__isl_take isl_pw_aff *pwaff)
   3031  1.1  mrg {
   3032  1.1  mrg 	return pw_aff_locus(pwaff, &aff_zero_basic_set, 0, NULL);
   3033  1.1  mrg }
   3034  1.1  mrg 
   3035  1.1  mrg /* Return a set containing those elements in the domain
   3036  1.1  mrg  * of pwaff where it is not zero.
   3037  1.1  mrg  */
   3038  1.1  mrg __isl_give isl_set *isl_pw_aff_non_zero_set(__isl_take isl_pw_aff *pwaff)
   3039  1.1  mrg {
   3040  1.1  mrg 	return pw_aff_locus(pwaff, &aff_zero_basic_set, 1, NULL);
   3041  1.1  mrg }
   3042  1.1  mrg 
   3043  1.1  mrg /* Bind the affine function "aff" to the parameter "id",
   3044  1.1  mrg  * returning the elements in the domain where the affine expression
   3045  1.1  mrg  * is equal to the parameter.
   3046  1.1  mrg  */
   3047  1.1  mrg __isl_give isl_basic_set *isl_aff_bind_id(__isl_take isl_aff *aff,
   3048  1.1  mrg 	__isl_take isl_id *id)
   3049  1.1  mrg {
   3050  1.1  mrg 	isl_space *space;
   3051  1.1  mrg 	isl_aff *aff_id;
   3052  1.1  mrg 
   3053  1.1  mrg 	space = isl_aff_get_domain_space(aff);
   3054  1.1  mrg 	space = isl_space_add_param_id(space, isl_id_copy(id));
   3055  1.1  mrg 
   3056  1.1  mrg 	aff = isl_aff_align_params(aff, isl_space_copy(space));
   3057  1.1  mrg 	aff_id = isl_aff_param_on_domain_space_id(space, id);
   3058  1.1  mrg 
   3059  1.1  mrg 	return isl_aff_eq_basic_set(aff, aff_id);
   3060  1.1  mrg }
   3061  1.1  mrg 
   3062  1.1  mrg /* Wrapper around isl_aff_bind_id for use as pw_aff_locus callback.
   3063  1.1  mrg  * "rational" should not be set.
   3064  1.1  mrg  */
   3065  1.1  mrg static __isl_give isl_basic_set *aff_bind_id(__isl_take isl_aff *aff,
   3066  1.1  mrg 	int rational, void *user)
   3067  1.1  mrg {
   3068  1.1  mrg 	isl_id *id = user;
   3069  1.1  mrg 
   3070  1.1  mrg 	if (!aff)
   3071  1.1  mrg 		return NULL;
   3072  1.1  mrg 	if (rational)
   3073  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_unsupported,
   3074  1.1  mrg 			"rational binding not supported", goto error);
   3075  1.1  mrg 	return isl_aff_bind_id(aff, isl_id_copy(id));
   3076  1.1  mrg error:
   3077  1.1  mrg 	isl_aff_free(aff);
   3078  1.1  mrg 	return NULL;
   3079  1.1  mrg }
   3080  1.1  mrg 
   3081  1.1  mrg /* Bind the piecewise affine function "pa" to the parameter "id",
   3082  1.1  mrg  * returning the elements in the domain where the expression
   3083  1.1  mrg  * is equal to the parameter.
   3084  1.1  mrg  */
   3085  1.1  mrg __isl_give isl_set *isl_pw_aff_bind_id(__isl_take isl_pw_aff *pa,
   3086  1.1  mrg 	__isl_take isl_id *id)
   3087  1.1  mrg {
   3088  1.1  mrg 	isl_set *bound;
   3089  1.1  mrg 
   3090  1.1  mrg 	bound = pw_aff_locus(pa, &aff_bind_id, 0, id);
   3091  1.1  mrg 	isl_id_free(id);
   3092  1.1  mrg 
   3093  1.1  mrg 	return bound;
   3094  1.1  mrg }
   3095  1.1  mrg 
   3096  1.1  mrg /* Return a set containing those elements in the shared domain
   3097  1.1  mrg  * of pwaff1 and pwaff2 where pwaff1 is greater than (or equal) to pwaff2.
   3098  1.1  mrg  *
   3099  1.1  mrg  * We compute the difference on the shared domain and then construct
   3100  1.1  mrg  * the set of values where this difference is non-negative.
   3101  1.1  mrg  * If strict is set, we first subtract 1 from the difference.
   3102  1.1  mrg  * If equal is set, we only return the elements where pwaff1 and pwaff2
   3103  1.1  mrg  * are equal.
   3104  1.1  mrg  */
   3105  1.1  mrg static __isl_give isl_set *pw_aff_gte_set(__isl_take isl_pw_aff *pwaff1,
   3106  1.1  mrg 	__isl_take isl_pw_aff *pwaff2, int strict, int equal)
   3107  1.1  mrg {
   3108  1.1  mrg 	isl_set *set1, *set2;
   3109  1.1  mrg 
   3110  1.1  mrg 	set1 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff1));
   3111  1.1  mrg 	set2 = isl_pw_aff_domain(isl_pw_aff_copy(pwaff2));
   3112  1.1  mrg 	set1 = isl_set_intersect(set1, set2);
   3113  1.1  mrg 	pwaff1 = isl_pw_aff_intersect_domain(pwaff1, isl_set_copy(set1));
   3114  1.1  mrg 	pwaff2 = isl_pw_aff_intersect_domain(pwaff2, isl_set_copy(set1));
   3115  1.1  mrg 	pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_neg(pwaff2));
   3116  1.1  mrg 
   3117  1.1  mrg 	if (strict) {
   3118  1.1  mrg 		isl_space *space = isl_set_get_space(set1);
   3119  1.1  mrg 		isl_aff *aff;
   3120  1.1  mrg 		aff = isl_aff_zero_on_domain(isl_local_space_from_space(space));
   3121  1.1  mrg 		aff = isl_aff_add_constant_si(aff, -1);
   3122  1.1  mrg 		pwaff1 = isl_pw_aff_add(pwaff1, isl_pw_aff_alloc(set1, aff));
   3123  1.1  mrg 	} else
   3124  1.1  mrg 		isl_set_free(set1);
   3125  1.1  mrg 
   3126  1.1  mrg 	if (equal)
   3127  1.1  mrg 		return isl_pw_aff_zero_set(pwaff1);
   3128  1.1  mrg 	return isl_pw_aff_nonneg_set(pwaff1);
   3129  1.1  mrg }
   3130  1.1  mrg 
   3131  1.1  mrg /* Return a set containing those elements in the shared domain
   3132  1.1  mrg  * of pwaff1 and pwaff2 where pwaff1 is equal to pwaff2.
   3133  1.1  mrg  */
   3134  1.1  mrg __isl_give isl_set *isl_pw_aff_eq_set(__isl_take isl_pw_aff *pwaff1,
   3135  1.1  mrg 	__isl_take isl_pw_aff *pwaff2)
   3136  1.1  mrg {
   3137  1.1  mrg 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   3138  1.1  mrg 	return pw_aff_gte_set(pwaff1, pwaff2, 0, 1);
   3139  1.1  mrg }
   3140  1.1  mrg 
   3141  1.1  mrg /* Return a set containing those elements in the shared domain
   3142  1.1  mrg  * of pwaff1 and pwaff2 where pwaff1 is greater than or equal to pwaff2.
   3143  1.1  mrg  */
   3144  1.1  mrg __isl_give isl_set *isl_pw_aff_ge_set(__isl_take isl_pw_aff *pwaff1,
   3145  1.1  mrg 	__isl_take isl_pw_aff *pwaff2)
   3146  1.1  mrg {
   3147  1.1  mrg 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   3148  1.1  mrg 	return pw_aff_gte_set(pwaff1, pwaff2, 0, 0);
   3149  1.1  mrg }
   3150  1.1  mrg 
   3151  1.1  mrg /* Return a set containing those elements in the shared domain
   3152  1.1  mrg  * of pwaff1 and pwaff2 where pwaff1 is strictly greater than pwaff2.
   3153  1.1  mrg  */
   3154  1.1  mrg __isl_give isl_set *isl_pw_aff_gt_set(__isl_take isl_pw_aff *pwaff1,
   3155  1.1  mrg 	__isl_take isl_pw_aff *pwaff2)
   3156  1.1  mrg {
   3157  1.1  mrg 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   3158  1.1  mrg 	return pw_aff_gte_set(pwaff1, pwaff2, 1, 0);
   3159  1.1  mrg }
   3160  1.1  mrg 
   3161  1.1  mrg __isl_give isl_set *isl_pw_aff_le_set(__isl_take isl_pw_aff *pwaff1,
   3162  1.1  mrg 	__isl_take isl_pw_aff *pwaff2)
   3163  1.1  mrg {
   3164  1.1  mrg 	return isl_pw_aff_ge_set(pwaff2, pwaff1);
   3165  1.1  mrg }
   3166  1.1  mrg 
   3167  1.1  mrg __isl_give isl_set *isl_pw_aff_lt_set(__isl_take isl_pw_aff *pwaff1,
   3168  1.1  mrg 	__isl_take isl_pw_aff *pwaff2)
   3169  1.1  mrg {
   3170  1.1  mrg 	return isl_pw_aff_gt_set(pwaff2, pwaff1);
   3171  1.1  mrg }
   3172  1.1  mrg 
   3173  1.1  mrg /* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
   3174  1.1  mrg  * where the function values are ordered in the same way as "order",
   3175  1.1  mrg  * which returns a set in the shared domain of its two arguments.
   3176  1.1  mrg  *
   3177  1.1  mrg  * Let "pa1" and "pa2" be defined on domains A and B respectively.
   3178  1.1  mrg  * We first pull back the two functions such that they are defined on
   3179  1.1  mrg  * the domain [A -> B].  Then we apply "order", resulting in a set
   3180  1.1  mrg  * in the space [A -> B].  Finally, we unwrap this set to obtain
   3181  1.1  mrg  * a map in the space A -> B.
   3182  1.1  mrg  */
   3183  1.1  mrg static __isl_give isl_map *isl_pw_aff_order_map(
   3184  1.1  mrg 	__isl_take isl_pw_aff *pa1, __isl_take isl_pw_aff *pa2,
   3185  1.1  mrg 	__isl_give isl_set *(*order)(__isl_take isl_pw_aff *pa1,
   3186  1.1  mrg 		__isl_take isl_pw_aff *pa2))
   3187  1.1  mrg {
   3188  1.1  mrg 	isl_space *space1, *space2;
   3189  1.1  mrg 	isl_multi_aff *ma;
   3190  1.1  mrg 	isl_set *set;
   3191  1.1  mrg 
   3192  1.1  mrg 	isl_pw_aff_align_params_bin(&pa1, &pa2);
   3193  1.1  mrg 	space1 = isl_space_domain(isl_pw_aff_get_space(pa1));
   3194  1.1  mrg 	space2 = isl_space_domain(isl_pw_aff_get_space(pa2));
   3195  1.1  mrg 	space1 = isl_space_map_from_domain_and_range(space1, space2);
   3196  1.1  mrg 	ma = isl_multi_aff_domain_map(isl_space_copy(space1));
   3197  1.1  mrg 	pa1 = isl_pw_aff_pullback_multi_aff(pa1, ma);
   3198  1.1  mrg 	ma = isl_multi_aff_range_map(space1);
   3199  1.1  mrg 	pa2 = isl_pw_aff_pullback_multi_aff(pa2, ma);
   3200  1.1  mrg 	set = order(pa1, pa2);
   3201  1.1  mrg 
   3202  1.1  mrg 	return isl_set_unwrap(set);
   3203  1.1  mrg }
   3204  1.1  mrg 
   3205  1.1  mrg /* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
   3206  1.1  mrg  * where the function values are equal.
   3207  1.1  mrg  */
   3208  1.1  mrg __isl_give isl_map *isl_pw_aff_eq_map(__isl_take isl_pw_aff *pa1,
   3209  1.1  mrg 	__isl_take isl_pw_aff *pa2)
   3210  1.1  mrg {
   3211  1.1  mrg 	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_eq_set);
   3212  1.1  mrg }
   3213  1.1  mrg 
   3214  1.1  mrg /* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
   3215  1.1  mrg  * where the function value of "pa1" is less than or equal to
   3216  1.1  mrg  * the function value of "pa2".
   3217  1.1  mrg  */
   3218  1.1  mrg __isl_give isl_map *isl_pw_aff_le_map(__isl_take isl_pw_aff *pa1,
   3219  1.1  mrg 	__isl_take isl_pw_aff *pa2)
   3220  1.1  mrg {
   3221  1.1  mrg 	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_le_set);
   3222  1.1  mrg }
   3223  1.1  mrg 
   3224  1.1  mrg /* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
   3225  1.1  mrg  * where the function value of "pa1" is less than the function value of "pa2".
   3226  1.1  mrg  */
   3227  1.1  mrg __isl_give isl_map *isl_pw_aff_lt_map(__isl_take isl_pw_aff *pa1,
   3228  1.1  mrg 	__isl_take isl_pw_aff *pa2)
   3229  1.1  mrg {
   3230  1.1  mrg 	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_lt_set);
   3231  1.1  mrg }
   3232  1.1  mrg 
   3233  1.1  mrg /* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
   3234  1.1  mrg  * where the function value of "pa1" is greater than or equal to
   3235  1.1  mrg  * the function value of "pa2".
   3236  1.1  mrg  */
   3237  1.1  mrg __isl_give isl_map *isl_pw_aff_ge_map(__isl_take isl_pw_aff *pa1,
   3238  1.1  mrg 	__isl_take isl_pw_aff *pa2)
   3239  1.1  mrg {
   3240  1.1  mrg 	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_ge_set);
   3241  1.1  mrg }
   3242  1.1  mrg 
   3243  1.1  mrg /* Return a map containing pairs of elements in the domains of "pa1" and "pa2"
   3244  1.1  mrg  * where the function value of "pa1" is greater than the function value
   3245  1.1  mrg  * of "pa2".
   3246  1.1  mrg  */
   3247  1.1  mrg __isl_give isl_map *isl_pw_aff_gt_map(__isl_take isl_pw_aff *pa1,
   3248  1.1  mrg 	__isl_take isl_pw_aff *pa2)
   3249  1.1  mrg {
   3250  1.1  mrg 	return isl_pw_aff_order_map(pa1, pa2, &isl_pw_aff_gt_set);
   3251  1.1  mrg }
   3252  1.1  mrg 
   3253  1.1  mrg /* Return a set containing those elements in the shared domain
   3254  1.1  mrg  * of the elements of list1 and list2 where each element in list1
   3255  1.1  mrg  * has the relation specified by "fn" with each element in list2.
   3256  1.1  mrg  */
   3257  1.1  mrg static __isl_give isl_set *pw_aff_list_set(__isl_take isl_pw_aff_list *list1,
   3258  1.1  mrg 	__isl_take isl_pw_aff_list *list2,
   3259  1.1  mrg 	__isl_give isl_set *(*fn)(__isl_take isl_pw_aff *pwaff1,
   3260  1.1  mrg 				    __isl_take isl_pw_aff *pwaff2))
   3261  1.1  mrg {
   3262  1.1  mrg 	int i, j;
   3263  1.1  mrg 	isl_ctx *ctx;
   3264  1.1  mrg 	isl_set *set;
   3265  1.1  mrg 
   3266  1.1  mrg 	if (!list1 || !list2)
   3267  1.1  mrg 		goto error;
   3268  1.1  mrg 
   3269  1.1  mrg 	ctx = isl_pw_aff_list_get_ctx(list1);
   3270  1.1  mrg 	if (list1->n < 1 || list2->n < 1)
   3271  1.1  mrg 		isl_die(ctx, isl_error_invalid,
   3272  1.1  mrg 			"list should contain at least one element", goto error);
   3273  1.1  mrg 
   3274  1.1  mrg 	set = isl_set_universe(isl_pw_aff_get_domain_space(list1->p[0]));
   3275  1.1  mrg 	for (i = 0; i < list1->n; ++i)
   3276  1.1  mrg 		for (j = 0; j < list2->n; ++j) {
   3277  1.1  mrg 			isl_set *set_ij;
   3278  1.1  mrg 
   3279  1.1  mrg 			set_ij = fn(isl_pw_aff_copy(list1->p[i]),
   3280  1.1  mrg 				    isl_pw_aff_copy(list2->p[j]));
   3281  1.1  mrg 			set = isl_set_intersect(set, set_ij);
   3282  1.1  mrg 		}
   3283  1.1  mrg 
   3284  1.1  mrg 	isl_pw_aff_list_free(list1);
   3285  1.1  mrg 	isl_pw_aff_list_free(list2);
   3286  1.1  mrg 	return set;
   3287  1.1  mrg error:
   3288  1.1  mrg 	isl_pw_aff_list_free(list1);
   3289  1.1  mrg 	isl_pw_aff_list_free(list2);
   3290  1.1  mrg 	return NULL;
   3291  1.1  mrg }
   3292  1.1  mrg 
   3293  1.1  mrg /* Return a set containing those elements in the shared domain
   3294  1.1  mrg  * of the elements of list1 and list2 where each element in list1
   3295  1.1  mrg  * is equal to each element in list2.
   3296  1.1  mrg  */
   3297  1.1  mrg __isl_give isl_set *isl_pw_aff_list_eq_set(__isl_take isl_pw_aff_list *list1,
   3298  1.1  mrg 	__isl_take isl_pw_aff_list *list2)
   3299  1.1  mrg {
   3300  1.1  mrg 	return pw_aff_list_set(list1, list2, &isl_pw_aff_eq_set);
   3301  1.1  mrg }
   3302  1.1  mrg 
   3303  1.1  mrg __isl_give isl_set *isl_pw_aff_list_ne_set(__isl_take isl_pw_aff_list *list1,
   3304  1.1  mrg 	__isl_take isl_pw_aff_list *list2)
   3305  1.1  mrg {
   3306  1.1  mrg 	return pw_aff_list_set(list1, list2, &isl_pw_aff_ne_set);
   3307  1.1  mrg }
   3308  1.1  mrg 
   3309  1.1  mrg /* Return a set containing those elements in the shared domain
   3310  1.1  mrg  * of the elements of list1 and list2 where each element in list1
   3311  1.1  mrg  * is less than or equal to each element in list2.
   3312  1.1  mrg  */
   3313  1.1  mrg __isl_give isl_set *isl_pw_aff_list_le_set(__isl_take isl_pw_aff_list *list1,
   3314  1.1  mrg 	__isl_take isl_pw_aff_list *list2)
   3315  1.1  mrg {
   3316  1.1  mrg 	return pw_aff_list_set(list1, list2, &isl_pw_aff_le_set);
   3317  1.1  mrg }
   3318  1.1  mrg 
   3319  1.1  mrg __isl_give isl_set *isl_pw_aff_list_lt_set(__isl_take isl_pw_aff_list *list1,
   3320  1.1  mrg 	__isl_take isl_pw_aff_list *list2)
   3321  1.1  mrg {
   3322  1.1  mrg 	return pw_aff_list_set(list1, list2, &isl_pw_aff_lt_set);
   3323  1.1  mrg }
   3324  1.1  mrg 
   3325  1.1  mrg __isl_give isl_set *isl_pw_aff_list_ge_set(__isl_take isl_pw_aff_list *list1,
   3326  1.1  mrg 	__isl_take isl_pw_aff_list *list2)
   3327  1.1  mrg {
   3328  1.1  mrg 	return pw_aff_list_set(list1, list2, &isl_pw_aff_ge_set);
   3329  1.1  mrg }
   3330  1.1  mrg 
   3331  1.1  mrg __isl_give isl_set *isl_pw_aff_list_gt_set(__isl_take isl_pw_aff_list *list1,
   3332  1.1  mrg 	__isl_take isl_pw_aff_list *list2)
   3333  1.1  mrg {
   3334  1.1  mrg 	return pw_aff_list_set(list1, list2, &isl_pw_aff_gt_set);
   3335  1.1  mrg }
   3336  1.1  mrg 
   3337  1.1  mrg 
   3338  1.1  mrg /* Return a set containing those elements in the shared domain
   3339  1.1  mrg  * of pwaff1 and pwaff2 where pwaff1 is not equal to pwaff2.
   3340  1.1  mrg  */
   3341  1.1  mrg __isl_give isl_set *isl_pw_aff_ne_set(__isl_take isl_pw_aff *pwaff1,
   3342  1.1  mrg 	__isl_take isl_pw_aff *pwaff2)
   3343  1.1  mrg {
   3344  1.1  mrg 	isl_set *set_lt, *set_gt;
   3345  1.1  mrg 
   3346  1.1  mrg 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   3347  1.1  mrg 	set_lt = isl_pw_aff_lt_set(isl_pw_aff_copy(pwaff1),
   3348  1.1  mrg 				   isl_pw_aff_copy(pwaff2));
   3349  1.1  mrg 	set_gt = isl_pw_aff_gt_set(pwaff1, pwaff2);
   3350  1.1  mrg 	return isl_set_union_disjoint(set_lt, set_gt);
   3351  1.1  mrg }
   3352  1.1  mrg 
   3353  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_scale_down(__isl_take isl_pw_aff *pwaff,
   3354  1.1  mrg 	isl_int v)
   3355  1.1  mrg {
   3356  1.1  mrg 	int i;
   3357  1.1  mrg 
   3358  1.1  mrg 	if (isl_int_is_one(v))
   3359  1.1  mrg 		return pwaff;
   3360  1.1  mrg 	if (!isl_int_is_pos(v))
   3361  1.1  mrg 		isl_die(isl_pw_aff_get_ctx(pwaff), isl_error_invalid,
   3362  1.1  mrg 			"factor needs to be positive",
   3363  1.1  mrg 			return isl_pw_aff_free(pwaff));
   3364  1.1  mrg 	pwaff = isl_pw_aff_cow(pwaff);
   3365  1.1  mrg 	if (!pwaff)
   3366  1.1  mrg 		return NULL;
   3367  1.1  mrg 	if (pwaff->n == 0)
   3368  1.1  mrg 		return pwaff;
   3369  1.1  mrg 
   3370  1.1  mrg 	for (i = 0; i < pwaff->n; ++i) {
   3371  1.1  mrg 		pwaff->p[i].aff = isl_aff_scale_down(pwaff->p[i].aff, v);
   3372  1.1  mrg 		if (!pwaff->p[i].aff)
   3373  1.1  mrg 			return isl_pw_aff_free(pwaff);
   3374  1.1  mrg 	}
   3375  1.1  mrg 
   3376  1.1  mrg 	return pwaff;
   3377  1.1  mrg }
   3378  1.1  mrg 
   3379  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_floor(__isl_take isl_pw_aff *pwaff)
   3380  1.1  mrg {
   3381  1.1  mrg 	struct isl_pw_aff_un_op_control control = { .fn_base = &isl_aff_floor };
   3382  1.1  mrg 	return isl_pw_aff_un_op(pwaff, &control);
   3383  1.1  mrg }
   3384  1.1  mrg 
   3385  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_ceil(__isl_take isl_pw_aff *pwaff)
   3386  1.1  mrg {
   3387  1.1  mrg 	struct isl_pw_aff_un_op_control control = { .fn_base = &isl_aff_ceil };
   3388  1.1  mrg 	return isl_pw_aff_un_op(pwaff, &control);
   3389  1.1  mrg }
   3390  1.1  mrg 
   3391  1.1  mrg /* Assuming that "cond1" and "cond2" are disjoint,
   3392  1.1  mrg  * return an affine expression that is equal to pwaff1 on cond1
   3393  1.1  mrg  * and to pwaff2 on cond2.
   3394  1.1  mrg  */
   3395  1.1  mrg static __isl_give isl_pw_aff *isl_pw_aff_select(
   3396  1.1  mrg 	__isl_take isl_set *cond1, __isl_take isl_pw_aff *pwaff1,
   3397  1.1  mrg 	__isl_take isl_set *cond2, __isl_take isl_pw_aff *pwaff2)
   3398  1.1  mrg {
   3399  1.1  mrg 	pwaff1 = isl_pw_aff_intersect_domain(pwaff1, cond1);
   3400  1.1  mrg 	pwaff2 = isl_pw_aff_intersect_domain(pwaff2, cond2);
   3401  1.1  mrg 
   3402  1.1  mrg 	return isl_pw_aff_add_disjoint(pwaff1, pwaff2);
   3403  1.1  mrg }
   3404  1.1  mrg 
   3405  1.1  mrg /* Return an affine expression that is equal to pwaff_true for elements
   3406  1.1  mrg  * where "cond" is non-zero and to pwaff_false for elements where "cond"
   3407  1.1  mrg  * is zero.
   3408  1.1  mrg  * That is, return cond ? pwaff_true : pwaff_false;
   3409  1.1  mrg  *
   3410  1.1  mrg  * If "cond" involves and NaN, then we conservatively return a NaN
   3411  1.1  mrg  * on its entire domain.  In principle, we could consider the pieces
   3412  1.1  mrg  * where it is NaN separately from those where it is not.
   3413  1.1  mrg  *
   3414  1.1  mrg  * If "pwaff_true" and "pwaff_false" are obviously equal to each other,
   3415  1.1  mrg  * then only use the domain of "cond" to restrict the domain.
   3416  1.1  mrg  */
   3417  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_cond(__isl_take isl_pw_aff *cond,
   3418  1.1  mrg 	__isl_take isl_pw_aff *pwaff_true, __isl_take isl_pw_aff *pwaff_false)
   3419  1.1  mrg {
   3420  1.1  mrg 	isl_set *cond_true, *cond_false;
   3421  1.1  mrg 	isl_bool equal;
   3422  1.1  mrg 
   3423  1.1  mrg 	if (!cond)
   3424  1.1  mrg 		goto error;
   3425  1.1  mrg 	if (isl_pw_aff_involves_nan(cond)) {
   3426  1.1  mrg 		isl_space *space = isl_pw_aff_get_domain_space(cond);
   3427  1.1  mrg 		isl_local_space *ls = isl_local_space_from_space(space);
   3428  1.1  mrg 		isl_pw_aff_free(cond);
   3429  1.1  mrg 		isl_pw_aff_free(pwaff_true);
   3430  1.1  mrg 		isl_pw_aff_free(pwaff_false);
   3431  1.1  mrg 		return isl_pw_aff_nan_on_domain(ls);
   3432  1.1  mrg 	}
   3433  1.1  mrg 
   3434  1.1  mrg 	pwaff_true = isl_pw_aff_align_params(pwaff_true,
   3435  1.1  mrg 					    isl_pw_aff_get_space(pwaff_false));
   3436  1.1  mrg 	pwaff_false = isl_pw_aff_align_params(pwaff_false,
   3437  1.1  mrg 					    isl_pw_aff_get_space(pwaff_true));
   3438  1.1  mrg 	equal = isl_pw_aff_plain_is_equal(pwaff_true, pwaff_false);
   3439  1.1  mrg 	if (equal < 0)
   3440  1.1  mrg 		goto error;
   3441  1.1  mrg 	if (equal) {
   3442  1.1  mrg 		isl_set *dom;
   3443  1.1  mrg 
   3444  1.1  mrg 		dom = isl_set_coalesce(isl_pw_aff_domain(cond));
   3445  1.1  mrg 		isl_pw_aff_free(pwaff_false);
   3446  1.1  mrg 		return isl_pw_aff_intersect_domain(pwaff_true, dom);
   3447  1.1  mrg 	}
   3448  1.1  mrg 
   3449  1.1  mrg 	cond_true = isl_pw_aff_non_zero_set(isl_pw_aff_copy(cond));
   3450  1.1  mrg 	cond_false = isl_pw_aff_zero_set(cond);
   3451  1.1  mrg 	return isl_pw_aff_select(cond_true, pwaff_true,
   3452  1.1  mrg 				 cond_false, pwaff_false);
   3453  1.1  mrg error:
   3454  1.1  mrg 	isl_pw_aff_free(cond);
   3455  1.1  mrg 	isl_pw_aff_free(pwaff_true);
   3456  1.1  mrg 	isl_pw_aff_free(pwaff_false);
   3457  1.1  mrg 	return NULL;
   3458  1.1  mrg }
   3459  1.1  mrg 
   3460  1.1  mrg isl_bool isl_aff_is_cst(__isl_keep isl_aff *aff)
   3461  1.1  mrg {
   3462  1.1  mrg 	int pos;
   3463  1.1  mrg 
   3464  1.1  mrg 	if (!aff)
   3465  1.1  mrg 		return isl_bool_error;
   3466  1.1  mrg 
   3467  1.1  mrg 	pos = isl_seq_first_non_zero(aff->v->el + 2, aff->v->size - 2);
   3468  1.1  mrg 	return isl_bool_ok(pos == -1);
   3469  1.1  mrg }
   3470  1.1  mrg 
   3471  1.1  mrg /* Check whether pwaff is a piecewise constant.
   3472  1.1  mrg  */
   3473  1.1  mrg isl_bool isl_pw_aff_is_cst(__isl_keep isl_pw_aff *pwaff)
   3474  1.1  mrg {
   3475  1.1  mrg 	int i;
   3476  1.1  mrg 
   3477  1.1  mrg 	if (!pwaff)
   3478  1.1  mrg 		return isl_bool_error;
   3479  1.1  mrg 
   3480  1.1  mrg 	for (i = 0; i < pwaff->n; ++i) {
   3481  1.1  mrg 		isl_bool is_cst = isl_aff_is_cst(pwaff->p[i].aff);
   3482  1.1  mrg 		if (is_cst < 0 || !is_cst)
   3483  1.1  mrg 			return is_cst;
   3484  1.1  mrg 	}
   3485  1.1  mrg 
   3486  1.1  mrg 	return isl_bool_true;
   3487  1.1  mrg }
   3488  1.1  mrg 
   3489  1.1  mrg /* Return the product of "aff1" and "aff2".
   3490  1.1  mrg  *
   3491  1.1  mrg  * If either of the two is NaN, then the result is NaN.
   3492  1.1  mrg  *
   3493  1.1  mrg  * Otherwise, at least one of "aff1" or "aff2" needs to be a constant.
   3494  1.1  mrg  */
   3495  1.1  mrg __isl_give isl_aff *isl_aff_mul(__isl_take isl_aff *aff1,
   3496  1.1  mrg 	__isl_take isl_aff *aff2)
   3497  1.1  mrg {
   3498  1.1  mrg 	if (!aff1 || !aff2)
   3499  1.1  mrg 		goto error;
   3500  1.1  mrg 
   3501  1.1  mrg 	if (isl_aff_is_nan(aff1)) {
   3502  1.1  mrg 		isl_aff_free(aff2);
   3503  1.1  mrg 		return aff1;
   3504  1.1  mrg 	}
   3505  1.1  mrg 	if (isl_aff_is_nan(aff2)) {
   3506  1.1  mrg 		isl_aff_free(aff1);
   3507  1.1  mrg 		return aff2;
   3508  1.1  mrg 	}
   3509  1.1  mrg 
   3510  1.1  mrg 	if (!isl_aff_is_cst(aff2) && isl_aff_is_cst(aff1))
   3511  1.1  mrg 		return isl_aff_mul(aff2, aff1);
   3512  1.1  mrg 
   3513  1.1  mrg 	if (!isl_aff_is_cst(aff2))
   3514  1.1  mrg 		isl_die(isl_aff_get_ctx(aff1), isl_error_invalid,
   3515  1.1  mrg 			"at least one affine expression should be constant",
   3516  1.1  mrg 			goto error);
   3517  1.1  mrg 
   3518  1.1  mrg 	aff1 = isl_aff_cow(aff1);
   3519  1.1  mrg 	if (!aff1 || !aff2)
   3520  1.1  mrg 		goto error;
   3521  1.1  mrg 
   3522  1.1  mrg 	aff1 = isl_aff_scale(aff1, aff2->v->el[1]);
   3523  1.1  mrg 	aff1 = isl_aff_scale_down(aff1, aff2->v->el[0]);
   3524  1.1  mrg 
   3525  1.1  mrg 	isl_aff_free(aff2);
   3526  1.1  mrg 	return aff1;
   3527  1.1  mrg error:
   3528  1.1  mrg 	isl_aff_free(aff1);
   3529  1.1  mrg 	isl_aff_free(aff2);
   3530  1.1  mrg 	return NULL;
   3531  1.1  mrg }
   3532  1.1  mrg 
   3533  1.1  mrg /* Divide "aff1" by "aff2", assuming "aff2" is a constant.
   3534  1.1  mrg  *
   3535  1.1  mrg  * If either of the two is NaN, then the result is NaN.
   3536  1.1  mrg  * A division by zero also results in NaN.
   3537  1.1  mrg  */
   3538  1.1  mrg __isl_give isl_aff *isl_aff_div(__isl_take isl_aff *aff1,
   3539  1.1  mrg 	__isl_take isl_aff *aff2)
   3540  1.1  mrg {
   3541  1.1  mrg 	isl_bool is_cst, is_zero;
   3542  1.1  mrg 	int neg;
   3543  1.1  mrg 
   3544  1.1  mrg 	if (!aff1 || !aff2)
   3545  1.1  mrg 		goto error;
   3546  1.1  mrg 
   3547  1.1  mrg 	if (isl_aff_is_nan(aff1)) {
   3548  1.1  mrg 		isl_aff_free(aff2);
   3549  1.1  mrg 		return aff1;
   3550  1.1  mrg 	}
   3551  1.1  mrg 	if (isl_aff_is_nan(aff2)) {
   3552  1.1  mrg 		isl_aff_free(aff1);
   3553  1.1  mrg 		return aff2;
   3554  1.1  mrg 	}
   3555  1.1  mrg 
   3556  1.1  mrg 	is_cst = isl_aff_is_cst(aff2);
   3557  1.1  mrg 	if (is_cst < 0)
   3558  1.1  mrg 		goto error;
   3559  1.1  mrg 	if (!is_cst)
   3560  1.1  mrg 		isl_die(isl_aff_get_ctx(aff2), isl_error_invalid,
   3561  1.1  mrg 			"second argument should be a constant", goto error);
   3562  1.1  mrg 	is_zero = isl_aff_plain_is_zero(aff2);
   3563  1.1  mrg 	if (is_zero < 0)
   3564  1.1  mrg 		goto error;
   3565  1.1  mrg 	if (is_zero)
   3566  1.1  mrg 		return set_nan_free(aff1, aff2);
   3567  1.1  mrg 
   3568  1.1  mrg 	neg = isl_int_is_neg(aff2->v->el[1]);
   3569  1.1  mrg 	if (neg) {
   3570  1.1  mrg 		isl_int_neg(aff2->v->el[0], aff2->v->el[0]);
   3571  1.1  mrg 		isl_int_neg(aff2->v->el[1], aff2->v->el[1]);
   3572  1.1  mrg 	}
   3573  1.1  mrg 
   3574  1.1  mrg 	aff1 = isl_aff_scale(aff1, aff2->v->el[0]);
   3575  1.1  mrg 	aff1 = isl_aff_scale_down(aff1, aff2->v->el[1]);
   3576  1.1  mrg 
   3577  1.1  mrg 	if (neg) {
   3578  1.1  mrg 		isl_int_neg(aff2->v->el[0], aff2->v->el[0]);
   3579  1.1  mrg 		isl_int_neg(aff2->v->el[1], aff2->v->el[1]);
   3580  1.1  mrg 	}
   3581  1.1  mrg 
   3582  1.1  mrg 	isl_aff_free(aff2);
   3583  1.1  mrg 	return aff1;
   3584  1.1  mrg error:
   3585  1.1  mrg 	isl_aff_free(aff1);
   3586  1.1  mrg 	isl_aff_free(aff2);
   3587  1.1  mrg 	return NULL;
   3588  1.1  mrg }
   3589  1.1  mrg 
   3590  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_add(__isl_take isl_pw_aff *pwaff1,
   3591  1.1  mrg 	__isl_take isl_pw_aff *pwaff2)
   3592  1.1  mrg {
   3593  1.1  mrg 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   3594  1.1  mrg 	return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_add);
   3595  1.1  mrg }
   3596  1.1  mrg 
   3597  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_mul(__isl_take isl_pw_aff *pwaff1,
   3598  1.1  mrg 	__isl_take isl_pw_aff *pwaff2)
   3599  1.1  mrg {
   3600  1.1  mrg 	isl_pw_aff_align_params_bin(&pwaff1, &pwaff2);
   3601  1.1  mrg 	return isl_pw_aff_on_shared_domain(pwaff1, pwaff2, &isl_aff_mul);
   3602  1.1  mrg }
   3603  1.1  mrg 
   3604  1.1  mrg /* Divide "pa1" by "pa2", assuming "pa2" is a piecewise constant.
   3605  1.1  mrg  */
   3606  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_div(__isl_take isl_pw_aff *pa1,
   3607  1.1  mrg 	__isl_take isl_pw_aff *pa2)
   3608  1.1  mrg {
   3609  1.1  mrg 	int is_cst;
   3610  1.1  mrg 
   3611  1.1  mrg 	is_cst = isl_pw_aff_is_cst(pa2);
   3612  1.1  mrg 	if (is_cst < 0)
   3613  1.1  mrg 		goto error;
   3614  1.1  mrg 	if (!is_cst)
   3615  1.1  mrg 		isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
   3616  1.1  mrg 			"second argument should be a piecewise constant",
   3617  1.1  mrg 			goto error);
   3618  1.1  mrg 	isl_pw_aff_align_params_bin(&pa1, &pa2);
   3619  1.1  mrg 	return isl_pw_aff_on_shared_domain(pa1, pa2, &isl_aff_div);
   3620  1.1  mrg error:
   3621  1.1  mrg 	isl_pw_aff_free(pa1);
   3622  1.1  mrg 	isl_pw_aff_free(pa2);
   3623  1.1  mrg 	return NULL;
   3624  1.1  mrg }
   3625  1.1  mrg 
   3626  1.1  mrg /* Compute the quotient of the integer division of "pa1" by "pa2"
   3627  1.1  mrg  * with rounding towards zero.
   3628  1.1  mrg  * "pa2" is assumed to be a piecewise constant.
   3629  1.1  mrg  *
   3630  1.1  mrg  * In particular, return
   3631  1.1  mrg  *
   3632  1.1  mrg  *	pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2)
   3633  1.1  mrg  *
   3634  1.1  mrg  */
   3635  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_tdiv_q(__isl_take isl_pw_aff *pa1,
   3636  1.1  mrg 	__isl_take isl_pw_aff *pa2)
   3637  1.1  mrg {
   3638  1.1  mrg 	int is_cst;
   3639  1.1  mrg 	isl_set *cond;
   3640  1.1  mrg 	isl_pw_aff *f, *c;
   3641  1.1  mrg 
   3642  1.1  mrg 	is_cst = isl_pw_aff_is_cst(pa2);
   3643  1.1  mrg 	if (is_cst < 0)
   3644  1.1  mrg 		goto error;
   3645  1.1  mrg 	if (!is_cst)
   3646  1.1  mrg 		isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
   3647  1.1  mrg 			"second argument should be a piecewise constant",
   3648  1.1  mrg 			goto error);
   3649  1.1  mrg 
   3650  1.1  mrg 	pa1 = isl_pw_aff_div(pa1, pa2);
   3651  1.1  mrg 
   3652  1.1  mrg 	cond = isl_pw_aff_nonneg_set(isl_pw_aff_copy(pa1));
   3653  1.1  mrg 	f = isl_pw_aff_floor(isl_pw_aff_copy(pa1));
   3654  1.1  mrg 	c = isl_pw_aff_ceil(pa1);
   3655  1.1  mrg 	return isl_pw_aff_cond(isl_set_indicator_function(cond), f, c);
   3656  1.1  mrg error:
   3657  1.1  mrg 	isl_pw_aff_free(pa1);
   3658  1.1  mrg 	isl_pw_aff_free(pa2);
   3659  1.1  mrg 	return NULL;
   3660  1.1  mrg }
   3661  1.1  mrg 
   3662  1.1  mrg /* Compute the remainder of the integer division of "pa1" by "pa2"
   3663  1.1  mrg  * with rounding towards zero.
   3664  1.1  mrg  * "pa2" is assumed to be a piecewise constant.
   3665  1.1  mrg  *
   3666  1.1  mrg  * In particular, return
   3667  1.1  mrg  *
   3668  1.1  mrg  *	pa1 - pa2 * (pa1 >= 0 ? floor(pa1/pa2) : ceil(pa1/pa2))
   3669  1.1  mrg  *
   3670  1.1  mrg  */
   3671  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_tdiv_r(__isl_take isl_pw_aff *pa1,
   3672  1.1  mrg 	__isl_take isl_pw_aff *pa2)
   3673  1.1  mrg {
   3674  1.1  mrg 	int is_cst;
   3675  1.1  mrg 	isl_pw_aff *res;
   3676  1.1  mrg 
   3677  1.1  mrg 	is_cst = isl_pw_aff_is_cst(pa2);
   3678  1.1  mrg 	if (is_cst < 0)
   3679  1.1  mrg 		goto error;
   3680  1.1  mrg 	if (!is_cst)
   3681  1.1  mrg 		isl_die(isl_pw_aff_get_ctx(pa2), isl_error_invalid,
   3682  1.1  mrg 			"second argument should be a piecewise constant",
   3683  1.1  mrg 			goto error);
   3684  1.1  mrg 	res = isl_pw_aff_tdiv_q(isl_pw_aff_copy(pa1), isl_pw_aff_copy(pa2));
   3685  1.1  mrg 	res = isl_pw_aff_mul(pa2, res);
   3686  1.1  mrg 	res = isl_pw_aff_sub(pa1, res);
   3687  1.1  mrg 	return res;
   3688  1.1  mrg error:
   3689  1.1  mrg 	isl_pw_aff_free(pa1);
   3690  1.1  mrg 	isl_pw_aff_free(pa2);
   3691  1.1  mrg 	return NULL;
   3692  1.1  mrg }
   3693  1.1  mrg 
   3694  1.1  mrg /* Does either of "pa1" or "pa2" involve any NaN?
   3695  1.1  mrg  */
   3696  1.1  mrg static isl_bool either_involves_nan(__isl_keep isl_pw_aff *pa1,
   3697  1.1  mrg 	__isl_keep isl_pw_aff *pa2)
   3698  1.1  mrg {
   3699  1.1  mrg 	isl_bool has_nan;
   3700  1.1  mrg 
   3701  1.1  mrg 	has_nan = isl_pw_aff_involves_nan(pa1);
   3702  1.1  mrg 	if (has_nan < 0 || has_nan)
   3703  1.1  mrg 		return has_nan;
   3704  1.1  mrg 	return isl_pw_aff_involves_nan(pa2);
   3705  1.1  mrg }
   3706  1.1  mrg 
   3707  1.1  mrg /* Return a piecewise affine expression defined on the specified domain
   3708  1.1  mrg  * that represents NaN.
   3709  1.1  mrg  */
   3710  1.1  mrg static __isl_give isl_pw_aff *nan_on_domain_set(__isl_take isl_set *dom)
   3711  1.1  mrg {
   3712  1.1  mrg 	isl_local_space *ls;
   3713  1.1  mrg 	isl_pw_aff *pa;
   3714  1.1  mrg 
   3715  1.1  mrg 	ls = isl_local_space_from_space(isl_set_get_space(dom));
   3716  1.1  mrg 	pa = isl_pw_aff_nan_on_domain(ls);
   3717  1.1  mrg 	pa = isl_pw_aff_intersect_domain(pa, dom);
   3718  1.1  mrg 
   3719  1.1  mrg 	return pa;
   3720  1.1  mrg }
   3721  1.1  mrg 
   3722  1.1  mrg /* Replace "pa1" and "pa2" (at least one of which involves a NaN)
   3723  1.1  mrg  * by a NaN on their shared domain.
   3724  1.1  mrg  *
   3725  1.1  mrg  * In principle, the result could be refined to only being NaN
   3726  1.1  mrg  * on the parts of this domain where at least one of "pa1" or "pa2" is NaN.
   3727  1.1  mrg  */
   3728  1.1  mrg static __isl_give isl_pw_aff *replace_by_nan(__isl_take isl_pw_aff *pa1,
   3729  1.1  mrg 	__isl_take isl_pw_aff *pa2)
   3730  1.1  mrg {
   3731  1.1  mrg 	isl_set *dom;
   3732  1.1  mrg 
   3733  1.1  mrg 	dom = isl_set_intersect(isl_pw_aff_domain(pa1), isl_pw_aff_domain(pa2));
   3734  1.1  mrg 	return nan_on_domain_set(dom);
   3735  1.1  mrg }
   3736  1.1  mrg 
   3737  1.1  mrg static __isl_give isl_pw_aff *pw_aff_min(__isl_take isl_pw_aff *pwaff1,
   3738  1.1  mrg 	__isl_take isl_pw_aff *pwaff2)
   3739  1.1  mrg {
   3740  1.1  mrg 	isl_set *le;
   3741  1.1  mrg 	isl_set *dom;
   3742  1.1  mrg 
   3743  1.1  mrg 	dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)),
   3744  1.1  mrg 				isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)));
   3745  1.1  mrg 	le = isl_pw_aff_le_set(isl_pw_aff_copy(pwaff1),
   3746  1.1  mrg 				isl_pw_aff_copy(pwaff2));
   3747  1.1  mrg 	dom = isl_set_subtract(dom, isl_set_copy(le));
   3748  1.1  mrg 	return isl_pw_aff_select(le, pwaff1, dom, pwaff2);
   3749  1.1  mrg }
   3750  1.1  mrg 
   3751  1.1  mrg static __isl_give isl_pw_aff *pw_aff_max(__isl_take isl_pw_aff *pwaff1,
   3752  1.1  mrg 	__isl_take isl_pw_aff *pwaff2)
   3753  1.1  mrg {
   3754  1.1  mrg 	isl_set *ge;
   3755  1.1  mrg 	isl_set *dom;
   3756  1.1  mrg 
   3757  1.1  mrg 	dom = isl_set_intersect(isl_pw_aff_domain(isl_pw_aff_copy(pwaff1)),
   3758  1.1  mrg 				isl_pw_aff_domain(isl_pw_aff_copy(pwaff2)));
   3759  1.1  mrg 	ge = isl_pw_aff_ge_set(isl_pw_aff_copy(pwaff1),
   3760  1.1  mrg 				isl_pw_aff_copy(pwaff2));
   3761  1.1  mrg 	dom = isl_set_subtract(dom, isl_set_copy(ge));
   3762  1.1  mrg 	return isl_pw_aff_select(ge, pwaff1, dom, pwaff2);
   3763  1.1  mrg }
   3764  1.1  mrg 
   3765  1.1  mrg /* Return an expression for the minimum (if "max" is not set) or
   3766  1.1  mrg  * the maximum (if "max" is set) of "pa1" and "pa2".
   3767  1.1  mrg  * If either expression involves any NaN, then return a NaN
   3768  1.1  mrg  * on the shared domain as result.
   3769  1.1  mrg  */
   3770  1.1  mrg static __isl_give isl_pw_aff *pw_aff_min_max(__isl_take isl_pw_aff *pa1,
   3771  1.1  mrg 	__isl_take isl_pw_aff *pa2, int max)
   3772  1.1  mrg {
   3773  1.1  mrg 	isl_bool has_nan;
   3774  1.1  mrg 
   3775  1.1  mrg 	has_nan = either_involves_nan(pa1, pa2);
   3776  1.1  mrg 	if (has_nan < 0)
   3777  1.1  mrg 		pa1 = isl_pw_aff_free(pa1);
   3778  1.1  mrg 	else if (has_nan)
   3779  1.1  mrg 		return replace_by_nan(pa1, pa2);
   3780  1.1  mrg 
   3781  1.1  mrg 	isl_pw_aff_align_params_bin(&pa1, &pa2);
   3782  1.1  mrg 	if (max)
   3783  1.1  mrg 		return pw_aff_max(pa1, pa2);
   3784  1.1  mrg 	else
   3785  1.1  mrg 		return pw_aff_min(pa1, pa2);
   3786  1.1  mrg }
   3787  1.1  mrg 
   3788  1.1  mrg /* Return an expression for the minimum of "pwaff1" and "pwaff2".
   3789  1.1  mrg  */
   3790  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_min(__isl_take isl_pw_aff *pwaff1,
   3791  1.1  mrg 	__isl_take isl_pw_aff *pwaff2)
   3792  1.1  mrg {
   3793  1.1  mrg 	return pw_aff_min_max(pwaff1, pwaff2, 0);
   3794  1.1  mrg }
   3795  1.1  mrg 
   3796  1.1  mrg /* Return an expression for the maximum of "pwaff1" and "pwaff2".
   3797  1.1  mrg  */
   3798  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_max(__isl_take isl_pw_aff *pwaff1,
   3799  1.1  mrg 	__isl_take isl_pw_aff *pwaff2)
   3800  1.1  mrg {
   3801  1.1  mrg 	return pw_aff_min_max(pwaff1, pwaff2, 1);
   3802  1.1  mrg }
   3803  1.1  mrg 
   3804  1.1  mrg /* Does "pa" not involve any NaN?
   3805  1.1  mrg  */
   3806  1.1  mrg static isl_bool pw_aff_no_nan(__isl_keep isl_pw_aff *pa, void *user)
   3807  1.1  mrg {
   3808  1.1  mrg 	return isl_bool_not(isl_pw_aff_involves_nan(pa));
   3809  1.1  mrg }
   3810  1.1  mrg 
   3811  1.1  mrg /* Does any element of "list" involve any NaN?
   3812  1.1  mrg  *
   3813  1.1  mrg  * That is, is it not the case that every element does not involve any NaN?
   3814  1.1  mrg  */
   3815  1.1  mrg static isl_bool isl_pw_aff_list_involves_nan(__isl_keep isl_pw_aff_list *list)
   3816  1.1  mrg {
   3817  1.1  mrg 	return isl_bool_not(isl_pw_aff_list_every(list, &pw_aff_no_nan, NULL));
   3818  1.1  mrg }
   3819  1.1  mrg 
   3820  1.1  mrg /* Replace "list" (consisting of "n" elements, of which
   3821  1.1  mrg  * at least one element involves a NaN)
   3822  1.1  mrg  * by a NaN on the shared domain of the elements.
   3823  1.1  mrg  *
   3824  1.1  mrg  * In principle, the result could be refined to only being NaN
   3825  1.1  mrg  * on the parts of this domain where at least one of the elements is NaN.
   3826  1.1  mrg  */
   3827  1.1  mrg static __isl_give isl_pw_aff *replace_list_by_nan(
   3828  1.1  mrg 	__isl_take isl_pw_aff_list *list, int n)
   3829  1.1  mrg {
   3830  1.1  mrg 	int i;
   3831  1.1  mrg 	isl_set *dom;
   3832  1.1  mrg 
   3833  1.1  mrg 	dom = isl_pw_aff_domain(isl_pw_aff_list_get_at(list, 0));
   3834  1.1  mrg 	for (i = 1; i < n; ++i) {
   3835  1.1  mrg 		isl_set *dom_i;
   3836  1.1  mrg 
   3837  1.1  mrg 		dom_i = isl_pw_aff_domain(isl_pw_aff_list_get_at(list, i));
   3838  1.1  mrg 		dom = isl_set_intersect(dom, dom_i);
   3839  1.1  mrg 	}
   3840  1.1  mrg 
   3841  1.1  mrg 	isl_pw_aff_list_free(list);
   3842  1.1  mrg 	return nan_on_domain_set(dom);
   3843  1.1  mrg }
   3844  1.1  mrg 
   3845  1.1  mrg /* Return the set where the element at "pos1" of "list" is less than or
   3846  1.1  mrg  * equal to the element at "pos2".
   3847  1.1  mrg  * Equality is only allowed if "pos1" is smaller than "pos2".
   3848  1.1  mrg  */
   3849  1.1  mrg static __isl_give isl_set *less(__isl_keep isl_pw_aff_list *list,
   3850  1.1  mrg 	int pos1, int pos2)
   3851  1.1  mrg {
   3852  1.1  mrg 	isl_pw_aff *pa1, *pa2;
   3853  1.1  mrg 
   3854  1.1  mrg 	pa1 = isl_pw_aff_list_get_at(list, pos1);
   3855  1.1  mrg 	pa2 = isl_pw_aff_list_get_at(list, pos2);
   3856  1.1  mrg 
   3857  1.1  mrg 	if (pos1 < pos2)
   3858  1.1  mrg 		return isl_pw_aff_le_set(pa1, pa2);
   3859  1.1  mrg 	else
   3860  1.1  mrg 		return isl_pw_aff_lt_set(pa1, pa2);
   3861  1.1  mrg }
   3862  1.1  mrg 
   3863  1.1  mrg /* Return an isl_pw_aff that maps each element in the intersection of the
   3864  1.1  mrg  * domains of the piecewise affine expressions in "list"
   3865  1.1  mrg  * to the maximal (if "max" is set) or minimal (if "max" is not set)
   3866  1.1  mrg  * expression in "list" at that element.
   3867  1.1  mrg  * If any expression involves any NaN, then return a NaN
   3868  1.1  mrg  * on the shared domain as result.
   3869  1.1  mrg  *
   3870  1.1  mrg  * If "list" has n elements, then the result consists of n pieces,
   3871  1.1  mrg  * where, in the case of a minimum, each piece has as value expression
   3872  1.1  mrg  * the value expression of one of the elements and as domain
   3873  1.1  mrg  * the set of elements where that value expression
   3874  1.1  mrg  * is less than (or equal) to the other value expressions.
   3875  1.1  mrg  * In the case of a maximum, the condition is
   3876  1.1  mrg  * that all the other value expressions are less than (or equal)
   3877  1.1  mrg  * to the given value expression.
   3878  1.1  mrg  *
   3879  1.1  mrg  * In order to produce disjoint pieces, a pair of elements
   3880  1.1  mrg  * in the original domain is only allowed to be equal to each other
   3881  1.1  mrg  * on exactly one of the two pieces corresponding to the two elements.
   3882  1.1  mrg  * The position in the list is used to break ties.
   3883  1.1  mrg  * In particular, in the case of a minimum,
   3884  1.1  mrg  * in the piece corresponding to a given element,
   3885  1.1  mrg  * this element is allowed to be equal to any later element in the list,
   3886  1.1  mrg  * but not to any earlier element in the list.
   3887  1.1  mrg  */
   3888  1.1  mrg static __isl_give isl_pw_aff *isl_pw_aff_list_opt(
   3889  1.1  mrg 	__isl_take isl_pw_aff_list *list, int max)
   3890  1.1  mrg {
   3891  1.1  mrg 	int i, j;
   3892  1.1  mrg 	isl_bool has_nan;
   3893  1.1  mrg 	isl_size n;
   3894  1.1  mrg 	isl_space *space;
   3895  1.1  mrg 	isl_pw_aff *pa, *res;
   3896  1.1  mrg 
   3897  1.1  mrg 	n = isl_pw_aff_list_size(list);
   3898  1.1  mrg 	if (n < 0)
   3899  1.1  mrg 		goto error;
   3900  1.1  mrg 	if (n < 1)
   3901  1.1  mrg 		isl_die(isl_pw_aff_list_get_ctx(list), isl_error_invalid,
   3902  1.1  mrg 			"list should contain at least one element", goto error);
   3903  1.1  mrg 
   3904  1.1  mrg 	has_nan = isl_pw_aff_list_involves_nan(list);
   3905  1.1  mrg 	if (has_nan < 0)
   3906  1.1  mrg 		goto error;
   3907  1.1  mrg 	if (has_nan)
   3908  1.1  mrg 		return replace_list_by_nan(list, n);
   3909  1.1  mrg 
   3910  1.1  mrg 	pa = isl_pw_aff_list_get_at(list, 0);
   3911  1.1  mrg 	space = isl_pw_aff_get_space(pa);
   3912  1.1  mrg 	isl_pw_aff_free(pa);
   3913  1.1  mrg 	res = isl_pw_aff_empty(space);
   3914  1.1  mrg 
   3915  1.1  mrg 	for (i = 0; i < n; ++i) {
   3916  1.1  mrg 		pa = isl_pw_aff_list_get_at(list, i);
   3917  1.1  mrg 		for (j = 0; j < n; ++j) {
   3918  1.1  mrg 			isl_set *dom;
   3919  1.1  mrg 
   3920  1.1  mrg 			if (j == i)
   3921  1.1  mrg 				continue;
   3922  1.1  mrg 			if (max)
   3923  1.1  mrg 				dom = less(list, j, i);
   3924  1.1  mrg 			else
   3925  1.1  mrg 				dom = less(list, i, j);
   3926  1.1  mrg 
   3927  1.1  mrg 			pa = isl_pw_aff_intersect_domain(pa, dom);
   3928  1.1  mrg 		}
   3929  1.1  mrg 		res =  isl_pw_aff_add_disjoint(res, pa);
   3930  1.1  mrg 	}
   3931  1.1  mrg 
   3932  1.1  mrg 	isl_pw_aff_list_free(list);
   3933  1.1  mrg 	return res;
   3934  1.1  mrg error:
   3935  1.1  mrg 	isl_pw_aff_list_free(list);
   3936  1.1  mrg 	return NULL;
   3937  1.1  mrg }
   3938  1.1  mrg 
   3939  1.1  mrg /* Return an isl_pw_aff that maps each element in the intersection of the
   3940  1.1  mrg  * domains of the elements of list to the minimal corresponding affine
   3941  1.1  mrg  * expression.
   3942  1.1  mrg  */
   3943  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_list_min(__isl_take isl_pw_aff_list *list)
   3944  1.1  mrg {
   3945  1.1  mrg 	return isl_pw_aff_list_opt(list, 0);
   3946  1.1  mrg }
   3947  1.1  mrg 
   3948  1.1  mrg /* Return an isl_pw_aff that maps each element in the intersection of the
   3949  1.1  mrg  * domains of the elements of list to the maximal corresponding affine
   3950  1.1  mrg  * expression.
   3951  1.1  mrg  */
   3952  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_list_max(__isl_take isl_pw_aff_list *list)
   3953  1.1  mrg {
   3954  1.1  mrg 	return isl_pw_aff_list_opt(list, 1);
   3955  1.1  mrg }
   3956  1.1  mrg 
   3957  1.1  mrg /* Mark the domains of "pwaff" as rational.
   3958  1.1  mrg  */
   3959  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_set_rational(__isl_take isl_pw_aff *pwaff)
   3960  1.1  mrg {
   3961  1.1  mrg 	int i;
   3962  1.1  mrg 
   3963  1.1  mrg 	pwaff = isl_pw_aff_cow(pwaff);
   3964  1.1  mrg 	if (!pwaff)
   3965  1.1  mrg 		return NULL;
   3966  1.1  mrg 	if (pwaff->n == 0)
   3967  1.1  mrg 		return pwaff;
   3968  1.1  mrg 
   3969  1.1  mrg 	for (i = 0; i < pwaff->n; ++i) {
   3970  1.1  mrg 		pwaff->p[i].set = isl_set_set_rational(pwaff->p[i].set);
   3971  1.1  mrg 		if (!pwaff->p[i].set)
   3972  1.1  mrg 			return isl_pw_aff_free(pwaff);
   3973  1.1  mrg 	}
   3974  1.1  mrg 
   3975  1.1  mrg 	return pwaff;
   3976  1.1  mrg }
   3977  1.1  mrg 
   3978  1.1  mrg /* Mark the domains of the elements of "list" as rational.
   3979  1.1  mrg  */
   3980  1.1  mrg __isl_give isl_pw_aff_list *isl_pw_aff_list_set_rational(
   3981  1.1  mrg 	__isl_take isl_pw_aff_list *list)
   3982  1.1  mrg {
   3983  1.1  mrg 	int i, n;
   3984  1.1  mrg 
   3985  1.1  mrg 	if (!list)
   3986  1.1  mrg 		return NULL;
   3987  1.1  mrg 	if (list->n == 0)
   3988  1.1  mrg 		return list;
   3989  1.1  mrg 
   3990  1.1  mrg 	n = list->n;
   3991  1.1  mrg 	for (i = 0; i < n; ++i) {
   3992  1.1  mrg 		isl_pw_aff *pa;
   3993  1.1  mrg 
   3994  1.1  mrg 		pa = isl_pw_aff_list_get_pw_aff(list, i);
   3995  1.1  mrg 		pa = isl_pw_aff_set_rational(pa);
   3996  1.1  mrg 		list = isl_pw_aff_list_set_pw_aff(list, i, pa);
   3997  1.1  mrg 	}
   3998  1.1  mrg 
   3999  1.1  mrg 	return list;
   4000  1.1  mrg }
   4001  1.1  mrg 
   4002  1.1  mrg /* Do the parameters of "aff" match those of "space"?
   4003  1.1  mrg  */
   4004  1.1  mrg isl_bool isl_aff_matching_params(__isl_keep isl_aff *aff,
   4005  1.1  mrg 	__isl_keep isl_space *space)
   4006  1.1  mrg {
   4007  1.1  mrg 	isl_space *aff_space;
   4008  1.1  mrg 	isl_bool match;
   4009  1.1  mrg 
   4010  1.1  mrg 	if (!aff || !space)
   4011  1.1  mrg 		return isl_bool_error;
   4012  1.1  mrg 
   4013  1.1  mrg 	aff_space = isl_aff_get_domain_space(aff);
   4014  1.1  mrg 
   4015  1.1  mrg 	match = isl_space_has_equal_params(space, aff_space);
   4016  1.1  mrg 
   4017  1.1  mrg 	isl_space_free(aff_space);
   4018  1.1  mrg 	return match;
   4019  1.1  mrg }
   4020  1.1  mrg 
   4021  1.1  mrg /* Check that the domain space of "aff" matches "space".
   4022  1.1  mrg  */
   4023  1.1  mrg isl_stat isl_aff_check_match_domain_space(__isl_keep isl_aff *aff,
   4024  1.1  mrg 	__isl_keep isl_space *space)
   4025  1.1  mrg {
   4026  1.1  mrg 	isl_space *aff_space;
   4027  1.1  mrg 	isl_bool match;
   4028  1.1  mrg 
   4029  1.1  mrg 	if (!aff || !space)
   4030  1.1  mrg 		return isl_stat_error;
   4031  1.1  mrg 
   4032  1.1  mrg 	aff_space = isl_aff_get_domain_space(aff);
   4033  1.1  mrg 
   4034  1.1  mrg 	match = isl_space_has_equal_params(space, aff_space);
   4035  1.1  mrg 	if (match < 0)
   4036  1.1  mrg 		goto error;
   4037  1.1  mrg 	if (!match)
   4038  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   4039  1.1  mrg 			"parameters don't match", goto error);
   4040  1.1  mrg 	match = isl_space_tuple_is_equal(space, isl_dim_in,
   4041  1.1  mrg 					aff_space, isl_dim_set);
   4042  1.1  mrg 	if (match < 0)
   4043  1.1  mrg 		goto error;
   4044  1.1  mrg 	if (!match)
   4045  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   4046  1.1  mrg 			"domains don't match", goto error);
   4047  1.1  mrg 	isl_space_free(aff_space);
   4048  1.1  mrg 	return isl_stat_ok;
   4049  1.1  mrg error:
   4050  1.1  mrg 	isl_space_free(aff_space);
   4051  1.1  mrg 	return isl_stat_error;
   4052  1.1  mrg }
   4053  1.1  mrg 
   4054  1.1  mrg /* Return the shared (universe) domain of the elements of "ma".
   4055  1.1  mrg  *
   4056  1.1  mrg  * Since an isl_multi_aff (and an isl_aff) is always total,
   4057  1.1  mrg  * the domain is always the universe set in its domain space.
   4058  1.1  mrg  * This is a helper function for use in the generic isl_multi_*_bind.
   4059  1.1  mrg  */
   4060  1.1  mrg static __isl_give isl_basic_set *isl_multi_aff_domain(
   4061  1.1  mrg 	__isl_take isl_multi_aff *ma)
   4062  1.1  mrg {
   4063  1.1  mrg 	isl_space *space;
   4064  1.1  mrg 
   4065  1.1  mrg 	space = isl_multi_aff_get_space(ma);
   4066  1.1  mrg 	isl_multi_aff_free(ma);
   4067  1.1  mrg 
   4068  1.1  mrg 	return isl_basic_set_universe(isl_space_domain(space));
   4069  1.1  mrg }
   4070  1.1  mrg 
   4071  1.1  mrg #undef BASE
   4072  1.1  mrg #define BASE aff
   4073  1.1  mrg 
   4074  1.1  mrg #include <isl_multi_no_explicit_domain.c>
   4075  1.1  mrg #include <isl_multi_templ.c>
   4076  1.1  mrg #include <isl_multi_un_op_templ.c>
   4077  1.1  mrg #include <isl_multi_bin_val_templ.c>
   4078  1.1  mrg #include <isl_multi_add_constant_templ.c>
   4079  1.1  mrg #include <isl_multi_align_set.c>
   4080  1.1  mrg #include <isl_multi_arith_templ.c>
   4081  1.1  mrg #include <isl_multi_bind_domain_templ.c>
   4082  1.1  mrg #include <isl_multi_cmp.c>
   4083  1.1  mrg #include <isl_multi_dim_id_templ.c>
   4084  1.1  mrg #include <isl_multi_dims.c>
   4085  1.1  mrg #include <isl_multi_domain_reverse_templ.c>
   4086  1.1  mrg #include <isl_multi_floor.c>
   4087  1.1  mrg #include <isl_multi_from_base_templ.c>
   4088  1.1  mrg #include <isl_multi_identity_templ.c>
   4089  1.1  mrg #include <isl_multi_insert_domain_templ.c>
   4090  1.1  mrg #include <isl_multi_locals_templ.c>
   4091  1.1  mrg #include <isl_multi_move_dims_templ.c>
   4092  1.1  mrg #include <isl_multi_nan_templ.c>
   4093  1.1  mrg #include <isl_multi_product_templ.c>
   4094  1.1  mrg #include <isl_multi_splice_templ.c>
   4095  1.1  mrg #include <isl_multi_tuple_id_templ.c>
   4096  1.1  mrg #include <isl_multi_unbind_params_templ.c>
   4097  1.1  mrg #include <isl_multi_zero_templ.c>
   4098  1.1  mrg 
   4099  1.1  mrg #undef DOMBASE
   4100  1.1  mrg #define DOMBASE set
   4101  1.1  mrg #include <isl_multi_check_domain_templ.c>
   4102  1.1  mrg #include <isl_multi_apply_set_no_explicit_domain_templ.c>
   4103  1.1  mrg #include <isl_multi_gist.c>
   4104  1.1  mrg 
   4105  1.1  mrg #undef DOMBASE
   4106  1.1  mrg #define DOMBASE basic_set
   4107  1.1  mrg #include <isl_multi_bind_templ.c>
   4108  1.1  mrg 
   4109  1.1  mrg /* Construct an isl_multi_aff living in "space" that corresponds
   4110  1.1  mrg  * to the affine transformation matrix "mat".
   4111  1.1  mrg  */
   4112  1.1  mrg __isl_give isl_multi_aff *isl_multi_aff_from_aff_mat(
   4113  1.1  mrg 	__isl_take isl_space *space, __isl_take isl_mat *mat)
   4114  1.1  mrg {
   4115  1.1  mrg 	isl_ctx *ctx;
   4116  1.1  mrg 	isl_local_space *ls = NULL;
   4117  1.1  mrg 	isl_multi_aff *ma = NULL;
   4118  1.1  mrg 	isl_size n_row, n_col, n_out, total;
   4119  1.1  mrg 	int i;
   4120  1.1  mrg 
   4121  1.1  mrg 	if (!space || !mat)
   4122  1.1  mrg 		goto error;
   4123  1.1  mrg 
   4124  1.1  mrg 	ctx = isl_mat_get_ctx(mat);
   4125  1.1  mrg 
   4126  1.1  mrg 	n_row = isl_mat_rows(mat);
   4127  1.1  mrg 	n_col = isl_mat_cols(mat);
   4128  1.1  mrg 	n_out = isl_space_dim(space, isl_dim_out);
   4129  1.1  mrg 	total = isl_space_dim(space, isl_dim_all);
   4130  1.1  mrg 	if (n_row < 0 || n_col < 0 || n_out < 0 || total < 0)
   4131  1.1  mrg 		goto error;
   4132  1.1  mrg 	if (n_row < 1)
   4133  1.1  mrg 		isl_die(ctx, isl_error_invalid,
   4134  1.1  mrg 			"insufficient number of rows", goto error);
   4135  1.1  mrg 	if (n_col < 1)
   4136  1.1  mrg 		isl_die(ctx, isl_error_invalid,
   4137  1.1  mrg 			"insufficient number of columns", goto error);
   4138  1.1  mrg 	if (1 + n_out != n_row || 2 + total != n_row + n_col)
   4139  1.1  mrg 		isl_die(ctx, isl_error_invalid,
   4140  1.1  mrg 			"dimension mismatch", goto error);
   4141  1.1  mrg 
   4142  1.1  mrg 	ma = isl_multi_aff_zero(isl_space_copy(space));
   4143  1.1  mrg 	space = isl_space_domain(space);
   4144  1.1  mrg 	ls = isl_local_space_from_space(isl_space_copy(space));
   4145  1.1  mrg 
   4146  1.1  mrg 	for (i = 0; i < n_row - 1; ++i) {
   4147  1.1  mrg 		isl_vec *v;
   4148  1.1  mrg 		isl_aff *aff;
   4149  1.1  mrg 
   4150  1.1  mrg 		v = isl_vec_alloc(ctx, 1 + n_col);
   4151  1.1  mrg 		if (!v)
   4152  1.1  mrg 			goto error;
   4153  1.1  mrg 		isl_int_set(v->el[0], mat->row[0][0]);
   4154  1.1  mrg 		isl_seq_cpy(v->el + 1, mat->row[1 + i], n_col);
   4155  1.1  mrg 		v = isl_vec_normalize(v);
   4156  1.1  mrg 		aff = isl_aff_alloc_vec_validated(isl_local_space_copy(ls), v);
   4157  1.1  mrg 		ma = isl_multi_aff_set_aff(ma, i, aff);
   4158  1.1  mrg 	}
   4159  1.1  mrg 
   4160  1.1  mrg 	isl_space_free(space);
   4161  1.1  mrg 	isl_local_space_free(ls);
   4162  1.1  mrg 	isl_mat_free(mat);
   4163  1.1  mrg 	return ma;
   4164  1.1  mrg error:
   4165  1.1  mrg 	isl_space_free(space);
   4166  1.1  mrg 	isl_local_space_free(ls);
   4167  1.1  mrg 	isl_mat_free(mat);
   4168  1.1  mrg 	isl_multi_aff_free(ma);
   4169  1.1  mrg 	return NULL;
   4170  1.1  mrg }
   4171  1.1  mrg 
   4172  1.1  mrg /* Return the constant terms of the affine expressions of "ma".
   4173  1.1  mrg  */
   4174  1.1  mrg __isl_give isl_multi_val *isl_multi_aff_get_constant_multi_val(
   4175  1.1  mrg 	__isl_keep isl_multi_aff *ma)
   4176  1.1  mrg {
   4177  1.1  mrg 	int i;
   4178  1.1  mrg 	isl_size n;
   4179  1.1  mrg 	isl_space *space;
   4180  1.1  mrg 	isl_multi_val *mv;
   4181  1.1  mrg 
   4182  1.1  mrg 	n = isl_multi_aff_size(ma);
   4183  1.1  mrg 	if (n < 0)
   4184  1.1  mrg 		return NULL;
   4185  1.1  mrg 	space = isl_space_range(isl_multi_aff_get_space(ma));
   4186  1.1  mrg 	space = isl_space_drop_all_params(space);
   4187  1.1  mrg 	mv = isl_multi_val_zero(space);
   4188  1.1  mrg 
   4189  1.1  mrg 	for (i = 0; i < n; ++i) {
   4190  1.1  mrg 		isl_aff *aff;
   4191  1.1  mrg 		isl_val *val;
   4192  1.1  mrg 
   4193  1.1  mrg 		aff = isl_multi_aff_get_at(ma, i);
   4194  1.1  mrg 		val = isl_aff_get_constant_val(aff);
   4195  1.1  mrg 		isl_aff_free(aff);
   4196  1.1  mrg 		mv = isl_multi_val_set_at(mv, i, val);
   4197  1.1  mrg 	}
   4198  1.1  mrg 
   4199  1.1  mrg 	return mv;
   4200  1.1  mrg }
   4201  1.1  mrg 
   4202  1.1  mrg /* Remove any internal structure of the domain of "ma".
   4203  1.1  mrg  * If there is any such internal structure in the input,
   4204  1.1  mrg  * then the name of the corresponding space is also removed.
   4205  1.1  mrg  */
   4206  1.1  mrg __isl_give isl_multi_aff *isl_multi_aff_flatten_domain(
   4207  1.1  mrg 	__isl_take isl_multi_aff *ma)
   4208  1.1  mrg {
   4209  1.1  mrg 	isl_space *space;
   4210  1.1  mrg 
   4211  1.1  mrg 	if (!ma)
   4212  1.1  mrg 		return NULL;
   4213  1.1  mrg 
   4214  1.1  mrg 	if (!ma->space->nested[0])
   4215  1.1  mrg 		return ma;
   4216  1.1  mrg 
   4217  1.1  mrg 	space = isl_multi_aff_get_space(ma);
   4218  1.1  mrg 	space = isl_space_flatten_domain(space);
   4219  1.1  mrg 	ma = isl_multi_aff_reset_space(ma, space);
   4220  1.1  mrg 
   4221  1.1  mrg 	return ma;
   4222  1.1  mrg }
   4223  1.1  mrg 
   4224  1.1  mrg /* Given a map space, return an isl_multi_aff that maps a wrapped copy
   4225  1.1  mrg  * of the space to its domain.
   4226  1.1  mrg  */
   4227  1.1  mrg __isl_give isl_multi_aff *isl_multi_aff_domain_map(__isl_take isl_space *space)
   4228  1.1  mrg {
   4229  1.1  mrg 	int i;
   4230  1.1  mrg 	isl_size n_in;
   4231  1.1  mrg 	isl_local_space *ls;
   4232  1.1  mrg 	isl_multi_aff *ma;
   4233  1.1  mrg 
   4234  1.1  mrg 	if (!space)
   4235  1.1  mrg 		return NULL;
   4236  1.1  mrg 	if (!isl_space_is_map(space))
   4237  1.1  mrg 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   4238  1.1  mrg 			"not a map space", goto error);
   4239  1.1  mrg 
   4240  1.1  mrg 	n_in = isl_space_dim(space, isl_dim_in);
   4241  1.1  mrg 	if (n_in < 0)
   4242  1.1  mrg 		goto error;
   4243  1.1  mrg 	space = isl_space_domain_map(space);
   4244  1.1  mrg 
   4245  1.1  mrg 	ma = isl_multi_aff_alloc(isl_space_copy(space));
   4246  1.1  mrg 	if (n_in == 0) {
   4247  1.1  mrg 		isl_space_free(space);
   4248  1.1  mrg 		return ma;
   4249  1.1  mrg 	}
   4250  1.1  mrg 
   4251  1.1  mrg 	space = isl_space_domain(space);
   4252  1.1  mrg 	ls = isl_local_space_from_space(space);
   4253  1.1  mrg 	for (i = 0; i < n_in; ++i) {
   4254  1.1  mrg 		isl_aff *aff;
   4255  1.1  mrg 
   4256  1.1  mrg 		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
   4257  1.1  mrg 						isl_dim_set, i);
   4258  1.1  mrg 		ma = isl_multi_aff_set_aff(ma, i, aff);
   4259  1.1  mrg 	}
   4260  1.1  mrg 	isl_local_space_free(ls);
   4261  1.1  mrg 	return ma;
   4262  1.1  mrg error:
   4263  1.1  mrg 	isl_space_free(space);
   4264  1.1  mrg 	return NULL;
   4265  1.1  mrg }
   4266  1.1  mrg 
   4267  1.1  mrg /* This function performs the same operation as isl_multi_aff_domain_map,
   4268  1.1  mrg  * but is considered as a function on an isl_space when exported.
   4269  1.1  mrg  */
   4270  1.1  mrg __isl_give isl_multi_aff *isl_space_domain_map_multi_aff(
   4271  1.1  mrg 	__isl_take isl_space *space)
   4272  1.1  mrg {
   4273  1.1  mrg 	return isl_multi_aff_domain_map(space);
   4274  1.1  mrg }
   4275  1.1  mrg 
   4276  1.1  mrg /* Given a map space, return an isl_multi_aff that maps a wrapped copy
   4277  1.1  mrg  * of the space to its range.
   4278  1.1  mrg  */
   4279  1.1  mrg __isl_give isl_multi_aff *isl_multi_aff_range_map(__isl_take isl_space *space)
   4280  1.1  mrg {
   4281  1.1  mrg 	int i;
   4282  1.1  mrg 	isl_size n_in, n_out;
   4283  1.1  mrg 	isl_local_space *ls;
   4284  1.1  mrg 	isl_multi_aff *ma;
   4285  1.1  mrg 
   4286  1.1  mrg 	if (!space)
   4287  1.1  mrg 		return NULL;
   4288  1.1  mrg 	if (!isl_space_is_map(space))
   4289  1.1  mrg 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   4290  1.1  mrg 			"not a map space", goto error);
   4291  1.1  mrg 
   4292  1.1  mrg 	n_in = isl_space_dim(space, isl_dim_in);
   4293  1.1  mrg 	n_out = isl_space_dim(space, isl_dim_out);
   4294  1.1  mrg 	if (n_in < 0 || n_out < 0)
   4295  1.1  mrg 		goto error;
   4296  1.1  mrg 	space = isl_space_range_map(space);
   4297  1.1  mrg 
   4298  1.1  mrg 	ma = isl_multi_aff_alloc(isl_space_copy(space));
   4299  1.1  mrg 	if (n_out == 0) {
   4300  1.1  mrg 		isl_space_free(space);
   4301  1.1  mrg 		return ma;
   4302  1.1  mrg 	}
   4303  1.1  mrg 
   4304  1.1  mrg 	space = isl_space_domain(space);
   4305  1.1  mrg 	ls = isl_local_space_from_space(space);
   4306  1.1  mrg 	for (i = 0; i < n_out; ++i) {
   4307  1.1  mrg 		isl_aff *aff;
   4308  1.1  mrg 
   4309  1.1  mrg 		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
   4310  1.1  mrg 						isl_dim_set, n_in + i);
   4311  1.1  mrg 		ma = isl_multi_aff_set_aff(ma, i, aff);
   4312  1.1  mrg 	}
   4313  1.1  mrg 	isl_local_space_free(ls);
   4314  1.1  mrg 	return ma;
   4315  1.1  mrg error:
   4316  1.1  mrg 	isl_space_free(space);
   4317  1.1  mrg 	return NULL;
   4318  1.1  mrg }
   4319  1.1  mrg 
   4320  1.1  mrg /* This function performs the same operation as isl_multi_aff_range_map,
   4321  1.1  mrg  * but is considered as a function on an isl_space when exported.
   4322  1.1  mrg  */
   4323  1.1  mrg __isl_give isl_multi_aff *isl_space_range_map_multi_aff(
   4324  1.1  mrg 	__isl_take isl_space *space)
   4325  1.1  mrg {
   4326  1.1  mrg 	return isl_multi_aff_range_map(space);
   4327  1.1  mrg }
   4328  1.1  mrg 
   4329  1.1  mrg /* Given a map space, return an isl_pw_multi_aff that maps a wrapped copy
   4330  1.1  mrg  * of the space to its domain.
   4331  1.1  mrg  */
   4332  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_domain_map(
   4333  1.1  mrg 	__isl_take isl_space *space)
   4334  1.1  mrg {
   4335  1.1  mrg 	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_domain_map(space));
   4336  1.1  mrg }
   4337  1.1  mrg 
   4338  1.1  mrg /* This function performs the same operation as isl_pw_multi_aff_domain_map,
   4339  1.1  mrg  * but is considered as a function on an isl_space when exported.
   4340  1.1  mrg  */
   4341  1.1  mrg __isl_give isl_pw_multi_aff *isl_space_domain_map_pw_multi_aff(
   4342  1.1  mrg 	__isl_take isl_space *space)
   4343  1.1  mrg {
   4344  1.1  mrg 	return isl_pw_multi_aff_domain_map(space);
   4345  1.1  mrg }
   4346  1.1  mrg 
   4347  1.1  mrg /* Given a map space, return an isl_pw_multi_aff that maps a wrapped copy
   4348  1.1  mrg  * of the space to its range.
   4349  1.1  mrg  */
   4350  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_map(
   4351  1.1  mrg 	__isl_take isl_space *space)
   4352  1.1  mrg {
   4353  1.1  mrg 	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_range_map(space));
   4354  1.1  mrg }
   4355  1.1  mrg 
   4356  1.1  mrg /* This function performs the same operation as isl_pw_multi_aff_range_map,
   4357  1.1  mrg  * but is considered as a function on an isl_space when exported.
   4358  1.1  mrg  */
   4359  1.1  mrg __isl_give isl_pw_multi_aff *isl_space_range_map_pw_multi_aff(
   4360  1.1  mrg 	__isl_take isl_space *space)
   4361  1.1  mrg {
   4362  1.1  mrg 	return isl_pw_multi_aff_range_map(space);
   4363  1.1  mrg }
   4364  1.1  mrg 
   4365  1.1  mrg /* Given the space of a set and a range of set dimensions,
   4366  1.1  mrg  * construct an isl_multi_aff that projects out those dimensions.
   4367  1.1  mrg  */
   4368  1.1  mrg __isl_give isl_multi_aff *isl_multi_aff_project_out_map(
   4369  1.1  mrg 	__isl_take isl_space *space, enum isl_dim_type type,
   4370  1.1  mrg 	unsigned first, unsigned n)
   4371  1.1  mrg {
   4372  1.1  mrg 	int i;
   4373  1.1  mrg 	isl_size dim;
   4374  1.1  mrg 	isl_local_space *ls;
   4375  1.1  mrg 	isl_multi_aff *ma;
   4376  1.1  mrg 
   4377  1.1  mrg 	if (!space)
   4378  1.1  mrg 		return NULL;
   4379  1.1  mrg 	if (!isl_space_is_set(space))
   4380  1.1  mrg 		isl_die(isl_space_get_ctx(space), isl_error_unsupported,
   4381  1.1  mrg 			"expecting set space", goto error);
   4382  1.1  mrg 	if (type != isl_dim_set)
   4383  1.1  mrg 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   4384  1.1  mrg 			"only set dimensions can be projected out", goto error);
   4385  1.1  mrg 	if (isl_space_check_range(space, type, first, n) < 0)
   4386  1.1  mrg 		goto error;
   4387  1.1  mrg 
   4388  1.1  mrg 	dim = isl_space_dim(space, isl_dim_set);
   4389  1.1  mrg 	if (dim < 0)
   4390  1.1  mrg 		goto error;
   4391  1.1  mrg 
   4392  1.1  mrg 	space = isl_space_from_domain(space);
   4393  1.1  mrg 	space = isl_space_add_dims(space, isl_dim_out, dim - n);
   4394  1.1  mrg 
   4395  1.1  mrg 	if (dim == n)
   4396  1.1  mrg 		return isl_multi_aff_alloc(space);
   4397  1.1  mrg 
   4398  1.1  mrg 	ma = isl_multi_aff_alloc(isl_space_copy(space));
   4399  1.1  mrg 	space = isl_space_domain(space);
   4400  1.1  mrg 	ls = isl_local_space_from_space(space);
   4401  1.1  mrg 
   4402  1.1  mrg 	for (i = 0; i < first; ++i) {
   4403  1.1  mrg 		isl_aff *aff;
   4404  1.1  mrg 
   4405  1.1  mrg 		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
   4406  1.1  mrg 						isl_dim_set, i);
   4407  1.1  mrg 		ma = isl_multi_aff_set_aff(ma, i, aff);
   4408  1.1  mrg 	}
   4409  1.1  mrg 
   4410  1.1  mrg 	for (i = 0; i < dim - (first + n); ++i) {
   4411  1.1  mrg 		isl_aff *aff;
   4412  1.1  mrg 
   4413  1.1  mrg 		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
   4414  1.1  mrg 						isl_dim_set, first + n + i);
   4415  1.1  mrg 		ma = isl_multi_aff_set_aff(ma, first + i, aff);
   4416  1.1  mrg 	}
   4417  1.1  mrg 
   4418  1.1  mrg 	isl_local_space_free(ls);
   4419  1.1  mrg 	return ma;
   4420  1.1  mrg error:
   4421  1.1  mrg 	isl_space_free(space);
   4422  1.1  mrg 	return NULL;
   4423  1.1  mrg }
   4424  1.1  mrg 
   4425  1.1  mrg /* Given the space of a set and a range of set dimensions,
   4426  1.1  mrg  * construct an isl_pw_multi_aff that projects out those dimensions.
   4427  1.1  mrg  */
   4428  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_project_out_map(
   4429  1.1  mrg 	__isl_take isl_space *space, enum isl_dim_type type,
   4430  1.1  mrg 	unsigned first, unsigned n)
   4431  1.1  mrg {
   4432  1.1  mrg 	isl_multi_aff *ma;
   4433  1.1  mrg 
   4434  1.1  mrg 	ma = isl_multi_aff_project_out_map(space, type, first, n);
   4435  1.1  mrg 	return isl_pw_multi_aff_from_multi_aff(ma);
   4436  1.1  mrg }
   4437  1.1  mrg 
   4438  1.1  mrg /* This function performs the same operation as isl_pw_multi_aff_from_multi_aff,
   4439  1.1  mrg  * but is considered as a function on an isl_multi_aff when exported.
   4440  1.1  mrg  */
   4441  1.1  mrg __isl_give isl_pw_multi_aff *isl_multi_aff_to_pw_multi_aff(
   4442  1.1  mrg 	__isl_take isl_multi_aff *ma)
   4443  1.1  mrg {
   4444  1.1  mrg 	return isl_pw_multi_aff_from_multi_aff(ma);
   4445  1.1  mrg }
   4446  1.1  mrg 
   4447  1.1  mrg /* Create a piecewise multi-affine expression in the given space that maps each
   4448  1.1  mrg  * input dimension to the corresponding output dimension.
   4449  1.1  mrg  */
   4450  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity(
   4451  1.1  mrg 	__isl_take isl_space *space)
   4452  1.1  mrg {
   4453  1.1  mrg 	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_identity(space));
   4454  1.1  mrg }
   4455  1.1  mrg 
   4456  1.1  mrg /* Create a piecewise multi expression that maps elements in the given space
   4457  1.1  mrg  * to themselves.
   4458  1.1  mrg  */
   4459  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_identity_on_domain_space(
   4460  1.1  mrg 	__isl_take isl_space *space)
   4461  1.1  mrg {
   4462  1.1  mrg 	isl_multi_aff *ma;
   4463  1.1  mrg 
   4464  1.1  mrg 	ma = isl_multi_aff_identity_on_domain_space(space);
   4465  1.1  mrg 	return isl_pw_multi_aff_from_multi_aff(ma);
   4466  1.1  mrg }
   4467  1.1  mrg 
   4468  1.1  mrg /* This function performs the same operation as
   4469  1.1  mrg  * isl_pw_multi_aff_identity_on_domain_space,
   4470  1.1  mrg  * but is considered as a function on an isl_space when exported.
   4471  1.1  mrg  */
   4472  1.1  mrg __isl_give isl_pw_multi_aff *isl_space_identity_pw_multi_aff_on_domain(
   4473  1.1  mrg 	__isl_take isl_space *space)
   4474  1.1  mrg {
   4475  1.1  mrg 	return isl_pw_multi_aff_identity_on_domain_space(space);
   4476  1.1  mrg }
   4477  1.1  mrg 
   4478  1.1  mrg /* Exploit the equalities in "eq" to simplify the affine expressions.
   4479  1.1  mrg  */
   4480  1.1  mrg static __isl_give isl_multi_aff *isl_multi_aff_substitute_equalities(
   4481  1.1  mrg 	__isl_take isl_multi_aff *maff, __isl_take isl_basic_set *eq)
   4482  1.1  mrg {
   4483  1.1  mrg 	isl_size n;
   4484  1.1  mrg 	int i;
   4485  1.1  mrg 
   4486  1.1  mrg 	n = isl_multi_aff_size(maff);
   4487  1.1  mrg 	if (n < 0 || !eq)
   4488  1.1  mrg 		goto error;
   4489  1.1  mrg 
   4490  1.1  mrg 	for (i = 0; i < n; ++i) {
   4491  1.1  mrg 		isl_aff *aff;
   4492  1.1  mrg 
   4493  1.1  mrg 		aff = isl_multi_aff_take_at(maff, i);
   4494  1.1  mrg 		aff = isl_aff_substitute_equalities(aff,
   4495  1.1  mrg 						    isl_basic_set_copy(eq));
   4496  1.1  mrg 		maff = isl_multi_aff_restore_at(maff, i, aff);
   4497  1.1  mrg 	}
   4498  1.1  mrg 
   4499  1.1  mrg 	isl_basic_set_free(eq);
   4500  1.1  mrg 	return maff;
   4501  1.1  mrg error:
   4502  1.1  mrg 	isl_basic_set_free(eq);
   4503  1.1  mrg 	isl_multi_aff_free(maff);
   4504  1.1  mrg 	return NULL;
   4505  1.1  mrg }
   4506  1.1  mrg 
   4507  1.1  mrg __isl_give isl_multi_aff *isl_multi_aff_scale(__isl_take isl_multi_aff *maff,
   4508  1.1  mrg 	isl_int f)
   4509  1.1  mrg {
   4510  1.1  mrg 	isl_size n;
   4511  1.1  mrg 	int i;
   4512  1.1  mrg 
   4513  1.1  mrg 	n = isl_multi_aff_size(maff);
   4514  1.1  mrg 	if (n < 0)
   4515  1.1  mrg 		return isl_multi_aff_free(maff);
   4516  1.1  mrg 
   4517  1.1  mrg 	for (i = 0; i < n; ++i) {
   4518  1.1  mrg 		isl_aff *aff;
   4519  1.1  mrg 
   4520  1.1  mrg 		aff = isl_multi_aff_take_at(maff, i);
   4521  1.1  mrg 		aff = isl_aff_scale(aff, f);
   4522  1.1  mrg 		maff = isl_multi_aff_restore_at(maff, i, aff);
   4523  1.1  mrg 	}
   4524  1.1  mrg 
   4525  1.1  mrg 	return maff;
   4526  1.1  mrg }
   4527  1.1  mrg 
   4528  1.1  mrg __isl_give isl_multi_aff *isl_multi_aff_add_on_domain(__isl_keep isl_set *dom,
   4529  1.1  mrg 	__isl_take isl_multi_aff *maff1, __isl_take isl_multi_aff *maff2)
   4530  1.1  mrg {
   4531  1.1  mrg 	maff1 = isl_multi_aff_add(maff1, maff2);
   4532  1.1  mrg 	maff1 = isl_multi_aff_gist(maff1, isl_set_copy(dom));
   4533  1.1  mrg 	return maff1;
   4534  1.1  mrg }
   4535  1.1  mrg 
   4536  1.1  mrg isl_bool isl_multi_aff_is_empty(__isl_keep isl_multi_aff *maff)
   4537  1.1  mrg {
   4538  1.1  mrg 	if (!maff)
   4539  1.1  mrg 		return isl_bool_error;
   4540  1.1  mrg 
   4541  1.1  mrg 	return isl_bool_false;
   4542  1.1  mrg }
   4543  1.1  mrg 
   4544  1.1  mrg /* Return the set of domain elements where "ma1" is lexicographically
   4545  1.1  mrg  * smaller than or equal to "ma2".
   4546  1.1  mrg  */
   4547  1.1  mrg __isl_give isl_set *isl_multi_aff_lex_le_set(__isl_take isl_multi_aff *ma1,
   4548  1.1  mrg 	__isl_take isl_multi_aff *ma2)
   4549  1.1  mrg {
   4550  1.1  mrg 	return isl_multi_aff_lex_ge_set(ma2, ma1);
   4551  1.1  mrg }
   4552  1.1  mrg 
   4553  1.1  mrg /* Return the set of domain elements where "ma1" is lexicographically
   4554  1.1  mrg  * smaller than "ma2".
   4555  1.1  mrg  */
   4556  1.1  mrg __isl_give isl_set *isl_multi_aff_lex_lt_set(__isl_take isl_multi_aff *ma1,
   4557  1.1  mrg 	__isl_take isl_multi_aff *ma2)
   4558  1.1  mrg {
   4559  1.1  mrg 	return isl_multi_aff_lex_gt_set(ma2, ma1);
   4560  1.1  mrg }
   4561  1.1  mrg 
   4562  1.1  mrg /* Return the set of domain elements where "ma1" is lexicographically
   4563  1.1  mrg  * greater than to "ma2".  If "equal" is set, then include the domain
   4564  1.1  mrg  * elements where they are equal.
   4565  1.1  mrg  * Do this for the case where there are no entries.
   4566  1.1  mrg  * In this case, "ma1" cannot be greater than "ma2",
   4567  1.1  mrg  * but it is (greater than or) equal to "ma2".
   4568  1.1  mrg  */
   4569  1.1  mrg static __isl_give isl_set *isl_multi_aff_lex_gte_set_0d(
   4570  1.1  mrg 	__isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2, int equal)
   4571  1.1  mrg {
   4572  1.1  mrg 	isl_space *space;
   4573  1.1  mrg 
   4574  1.1  mrg 	space = isl_multi_aff_get_domain_space(ma1);
   4575  1.1  mrg 
   4576  1.1  mrg 	isl_multi_aff_free(ma1);
   4577  1.1  mrg 	isl_multi_aff_free(ma2);
   4578  1.1  mrg 
   4579  1.1  mrg 	if (equal)
   4580  1.1  mrg 		return isl_set_universe(space);
   4581  1.1  mrg 	else
   4582  1.1  mrg 		return isl_set_empty(space);
   4583  1.1  mrg }
   4584  1.1  mrg 
   4585  1.1  mrg /* Return the set where entry "i" of "ma1" and "ma2"
   4586  1.1  mrg  * satisfy the relation prescribed by "cmp".
   4587  1.1  mrg  */
   4588  1.1  mrg static __isl_give isl_set *isl_multi_aff_order_at(__isl_keep isl_multi_aff *ma1,
   4589  1.1  mrg 	__isl_keep isl_multi_aff *ma2, int i,
   4590  1.1  mrg 	__isl_give isl_set *(*cmp)(__isl_take isl_aff *aff1,
   4591  1.1  mrg 		__isl_take isl_aff *aff2))
   4592  1.1  mrg {
   4593  1.1  mrg 	isl_aff *aff1, *aff2;
   4594  1.1  mrg 
   4595  1.1  mrg 	aff1 = isl_multi_aff_get_at(ma1, i);
   4596  1.1  mrg 	aff2 = isl_multi_aff_get_at(ma2, i);
   4597  1.1  mrg 	return cmp(aff1, aff2);
   4598  1.1  mrg }
   4599  1.1  mrg 
   4600  1.1  mrg /* Return the set of domain elements where "ma1" is lexicographically
   4601  1.1  mrg  * greater than to "ma2".  If "equal" is set, then include the domain
   4602  1.1  mrg  * elements where they are equal.
   4603  1.1  mrg  *
   4604  1.1  mrg  * In particular, for all but the final entry,
   4605  1.1  mrg  * include the set of elements where this entry is strictly greater in "ma1"
   4606  1.1  mrg  * and all previous entries are equal.
   4607  1.1  mrg  * The final entry is also allowed to be equal in the two functions
   4608  1.1  mrg  * if "equal" is set.
   4609  1.1  mrg  *
   4610  1.1  mrg  * The case where there are no entries is handled separately.
   4611  1.1  mrg  */
   4612  1.1  mrg static __isl_give isl_set *isl_multi_aff_lex_gte_set(
   4613  1.1  mrg 	__isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2, int equal)
   4614  1.1  mrg {
   4615  1.1  mrg 	int i;
   4616  1.1  mrg 	isl_size n;
   4617  1.1  mrg 	isl_space *space;
   4618  1.1  mrg 	isl_set *res;
   4619  1.1  mrg 	isl_set *equal_set;
   4620  1.1  mrg 	isl_set *gte;
   4621  1.1  mrg 
   4622  1.1  mrg 	if (isl_multi_aff_check_equal_space(ma1, ma2) < 0)
   4623  1.1  mrg 		goto error;
   4624  1.1  mrg 	n = isl_multi_aff_size(ma1);
   4625  1.1  mrg 	if (n < 0)
   4626  1.1  mrg 		goto error;
   4627  1.1  mrg 	if (n == 0)
   4628  1.1  mrg 		return isl_multi_aff_lex_gte_set_0d(ma1, ma2, equal);
   4629  1.1  mrg 
   4630  1.1  mrg 	space = isl_multi_aff_get_domain_space(ma1);
   4631  1.1  mrg 	res = isl_set_empty(isl_space_copy(space));
   4632  1.1  mrg 	equal_set = isl_set_universe(space);
   4633  1.1  mrg 
   4634  1.1  mrg 	for (i = 0; i + 1 < n; ++i) {
   4635  1.1  mrg 		isl_bool empty;
   4636  1.1  mrg 		isl_set *gt, *eq;
   4637  1.1  mrg 
   4638  1.1  mrg 		gt = isl_multi_aff_order_at(ma1, ma2, i, &isl_aff_gt_set);
   4639  1.1  mrg 		gt = isl_set_intersect(gt, isl_set_copy(equal_set));
   4640  1.1  mrg 		res = isl_set_union(res, gt);
   4641  1.1  mrg 		eq = isl_multi_aff_order_at(ma1, ma2, i, &isl_aff_eq_set);
   4642  1.1  mrg 		equal_set = isl_set_intersect(equal_set, eq);
   4643  1.1  mrg 
   4644  1.1  mrg 		empty = isl_set_is_empty(equal_set);
   4645  1.1  mrg 		if (empty >= 0 && empty)
   4646  1.1  mrg 			break;
   4647  1.1  mrg 	}
   4648  1.1  mrg 
   4649  1.1  mrg 	if (equal)
   4650  1.1  mrg 		gte = isl_multi_aff_order_at(ma1, ma2, n - 1, &isl_aff_ge_set);
   4651  1.1  mrg 	else
   4652  1.1  mrg 		gte = isl_multi_aff_order_at(ma1, ma2, n - 1, &isl_aff_gt_set);
   4653  1.1  mrg 	isl_multi_aff_free(ma1);
   4654  1.1  mrg 	isl_multi_aff_free(ma2);
   4655  1.1  mrg 
   4656  1.1  mrg 	gte = isl_set_intersect(gte, equal_set);
   4657  1.1  mrg 	return isl_set_union(res, gte);
   4658  1.1  mrg error:
   4659  1.1  mrg 	isl_multi_aff_free(ma1);
   4660  1.1  mrg 	isl_multi_aff_free(ma2);
   4661  1.1  mrg 	return NULL;
   4662  1.1  mrg }
   4663  1.1  mrg 
   4664  1.1  mrg /* Return the set of domain elements where "ma1" is lexicographically
   4665  1.1  mrg  * greater than or equal to "ma2".
   4666  1.1  mrg  */
   4667  1.1  mrg __isl_give isl_set *isl_multi_aff_lex_ge_set(__isl_take isl_multi_aff *ma1,
   4668  1.1  mrg 	__isl_take isl_multi_aff *ma2)
   4669  1.1  mrg {
   4670  1.1  mrg 	return isl_multi_aff_lex_gte_set(ma1, ma2, 1);
   4671  1.1  mrg }
   4672  1.1  mrg 
   4673  1.1  mrg /* Return the set of domain elements where "ma1" is lexicographically
   4674  1.1  mrg  * greater than "ma2".
   4675  1.1  mrg  */
   4676  1.1  mrg __isl_give isl_set *isl_multi_aff_lex_gt_set(__isl_take isl_multi_aff *ma1,
   4677  1.1  mrg 	__isl_take isl_multi_aff *ma2)
   4678  1.1  mrg {
   4679  1.1  mrg 	return isl_multi_aff_lex_gte_set(ma1, ma2, 0);
   4680  1.1  mrg }
   4681  1.1  mrg 
   4682  1.1  mrg #define isl_multi_aff_zero_in_space	isl_multi_aff_zero
   4683  1.1  mrg 
   4684  1.1  mrg #undef PW
   4685  1.1  mrg #define PW isl_pw_multi_aff
   4686  1.1  mrg #undef BASE
   4687  1.1  mrg #define BASE multi_aff
   4688  1.1  mrg #undef EL_IS_ZERO
   4689  1.1  mrg #define EL_IS_ZERO is_empty
   4690  1.1  mrg #undef ZERO
   4691  1.1  mrg #define ZERO empty
   4692  1.1  mrg #undef IS_ZERO
   4693  1.1  mrg #define IS_ZERO is_empty
   4694  1.1  mrg #undef FIELD
   4695  1.1  mrg #define FIELD maff
   4696  1.1  mrg #undef DEFAULT_IS_ZERO
   4697  1.1  mrg #define DEFAULT_IS_ZERO 0
   4698  1.1  mrg 
   4699  1.1  mrg #include <isl_pw_templ.c>
   4700  1.1  mrg #include <isl_pw_un_op_templ.c>
   4701  1.1  mrg #include <isl_pw_add_constant_multi_val_templ.c>
   4702  1.1  mrg #include <isl_pw_add_constant_val_templ.c>
   4703  1.1  mrg #include <isl_pw_add_disjoint_templ.c>
   4704  1.1  mrg #include <isl_pw_bind_domain_templ.c>
   4705  1.1  mrg #include <isl_pw_domain_reverse_templ.c>
   4706  1.1  mrg #include <isl_pw_fix_templ.c>
   4707  1.1  mrg #include <isl_pw_from_range_templ.c>
   4708  1.1  mrg #include <isl_pw_insert_dims_templ.c>
   4709  1.1  mrg #include <isl_pw_insert_domain_templ.c>
   4710  1.1  mrg #include <isl_pw_locals_templ.c>
   4711  1.1  mrg #include <isl_pw_move_dims_templ.c>
   4712  1.1  mrg #include <isl_pw_neg_templ.c>
   4713  1.1  mrg #include <isl_pw_pullback_templ.c>
   4714  1.1  mrg #include <isl_pw_range_tuple_id_templ.c>
   4715  1.1  mrg #include <isl_pw_union_opt.c>
   4716  1.1  mrg 
   4717  1.1  mrg #undef BASE
   4718  1.1  mrg #define BASE pw_multi_aff
   4719  1.1  mrg 
   4720  1.1  mrg #include <isl_union_multi.c>
   4721  1.1  mrg #include "isl_union_locals_templ.c"
   4722  1.1  mrg #include <isl_union_neg.c>
   4723  1.1  mrg #include <isl_union_sub_templ.c>
   4724  1.1  mrg 
   4725  1.1  mrg #undef BASE
   4726  1.1  mrg #define BASE multi_aff
   4727  1.1  mrg 
   4728  1.1  mrg #include <isl_union_pw_templ.c>
   4729  1.1  mrg 
   4730  1.1  mrg /* Generic function for extracting a factor from a product "pma".
   4731  1.1  mrg  * "check_space" checks that the space is that of the right kind of product.
   4732  1.1  mrg  * "space_factor" extracts the factor from the space.
   4733  1.1  mrg  * "multi_aff_factor" extracts the factor from the constituent functions.
   4734  1.1  mrg  */
   4735  1.1  mrg static __isl_give isl_pw_multi_aff *pw_multi_aff_factor(
   4736  1.1  mrg 	__isl_take isl_pw_multi_aff *pma,
   4737  1.1  mrg 	isl_stat (*check_space)(__isl_keep isl_pw_multi_aff *pma),
   4738  1.1  mrg 	__isl_give isl_space *(*space_factor)(__isl_take isl_space *space),
   4739  1.1  mrg 	__isl_give isl_multi_aff *(*multi_aff_factor)(
   4740  1.1  mrg 		__isl_take isl_multi_aff *ma))
   4741  1.1  mrg {
   4742  1.1  mrg 	int i;
   4743  1.1  mrg 	isl_space *space;
   4744  1.1  mrg 
   4745  1.1  mrg 	if (check_space(pma) < 0)
   4746  1.1  mrg 		return isl_pw_multi_aff_free(pma);
   4747  1.1  mrg 
   4748  1.1  mrg 	space = isl_pw_multi_aff_take_space(pma);
   4749  1.1  mrg 	space = space_factor(space);
   4750  1.1  mrg 
   4751  1.1  mrg 	for (i = 0; pma && i < pma->n; ++i) {
   4752  1.1  mrg 		isl_multi_aff *ma;
   4753  1.1  mrg 
   4754  1.1  mrg 		ma = isl_pw_multi_aff_take_base_at(pma, i);
   4755  1.1  mrg 		ma = multi_aff_factor(ma);
   4756  1.1  mrg 		pma = isl_pw_multi_aff_restore_base_at(pma, i, ma);
   4757  1.1  mrg 	}
   4758  1.1  mrg 
   4759  1.1  mrg 	pma = isl_pw_multi_aff_restore_space(pma, space);
   4760  1.1  mrg 
   4761  1.1  mrg 	return pma;
   4762  1.1  mrg }
   4763  1.1  mrg 
   4764  1.1  mrg /* Is the range of "pma" a wrapped relation?
   4765  1.1  mrg  */
   4766  1.1  mrg static isl_bool isl_pw_multi_aff_range_is_wrapping(
   4767  1.1  mrg 	__isl_keep isl_pw_multi_aff *pma)
   4768  1.1  mrg {
   4769  1.1  mrg 	return isl_space_range_is_wrapping(isl_pw_multi_aff_peek_space(pma));
   4770  1.1  mrg }
   4771  1.1  mrg 
   4772  1.1  mrg /* Check that the range of "pma" is a product.
   4773  1.1  mrg  */
   4774  1.1  mrg static isl_stat pw_multi_aff_check_range_product(
   4775  1.1  mrg 	__isl_keep isl_pw_multi_aff *pma)
   4776  1.1  mrg {
   4777  1.1  mrg 	isl_bool wraps;
   4778  1.1  mrg 
   4779  1.1  mrg 	wraps = isl_pw_multi_aff_range_is_wrapping(pma);
   4780  1.1  mrg 	if (wraps < 0)
   4781  1.1  mrg 		return isl_stat_error;
   4782  1.1  mrg 	if (!wraps)
   4783  1.1  mrg 		isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
   4784  1.1  mrg 			"range is not a product", return isl_stat_error);
   4785  1.1  mrg 	return isl_stat_ok;
   4786  1.1  mrg }
   4787  1.1  mrg 
   4788  1.1  mrg /* Given a function A -> [B -> C], extract the function A -> B.
   4789  1.1  mrg  */
   4790  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_factor_domain(
   4791  1.1  mrg 	__isl_take isl_pw_multi_aff *pma)
   4792  1.1  mrg {
   4793  1.1  mrg 	return pw_multi_aff_factor(pma, &pw_multi_aff_check_range_product,
   4794  1.1  mrg 				&isl_space_range_factor_domain,
   4795  1.1  mrg 				&isl_multi_aff_range_factor_domain);
   4796  1.1  mrg }
   4797  1.1  mrg 
   4798  1.1  mrg /* Given a function A -> [B -> C], extract the function A -> C.
   4799  1.1  mrg  */
   4800  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_factor_range(
   4801  1.1  mrg 	__isl_take isl_pw_multi_aff *pma)
   4802  1.1  mrg {
   4803  1.1  mrg 	return pw_multi_aff_factor(pma, &pw_multi_aff_check_range_product,
   4804  1.1  mrg 				&isl_space_range_factor_range,
   4805  1.1  mrg 				&isl_multi_aff_range_factor_range);
   4806  1.1  mrg }
   4807  1.1  mrg 
   4808  1.1  mrg /* Given two piecewise multi affine expressions, return a piecewise
   4809  1.1  mrg  * multi-affine expression defined on the union of the definition domains
   4810  1.1  mrg  * of the inputs that is equal to the lexicographic maximum of the two
   4811  1.1  mrg  * inputs on each cell.  If only one of the two inputs is defined on
   4812  1.1  mrg  * a given cell, then it is considered to be the maximum.
   4813  1.1  mrg  */
   4814  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmax(
   4815  1.1  mrg 	__isl_take isl_pw_multi_aff *pma1,
   4816  1.1  mrg 	__isl_take isl_pw_multi_aff *pma2)
   4817  1.1  mrg {
   4818  1.1  mrg 	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
   4819  1.1  mrg 	return isl_pw_multi_aff_union_opt_cmp(pma1, pma2,
   4820  1.1  mrg 					    &isl_multi_aff_lex_ge_set);
   4821  1.1  mrg }
   4822  1.1  mrg 
   4823  1.1  mrg /* Given two piecewise multi affine expressions, return a piecewise
   4824  1.1  mrg  * multi-affine expression defined on the union of the definition domains
   4825  1.1  mrg  * of the inputs that is equal to the lexicographic minimum of the two
   4826  1.1  mrg  * inputs on each cell.  If only one of the two inputs is defined on
   4827  1.1  mrg  * a given cell, then it is considered to be the minimum.
   4828  1.1  mrg  */
   4829  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_union_lexmin(
   4830  1.1  mrg 	__isl_take isl_pw_multi_aff *pma1,
   4831  1.1  mrg 	__isl_take isl_pw_multi_aff *pma2)
   4832  1.1  mrg {
   4833  1.1  mrg 	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
   4834  1.1  mrg 	return isl_pw_multi_aff_union_opt_cmp(pma1, pma2,
   4835  1.1  mrg 					    &isl_multi_aff_lex_le_set);
   4836  1.1  mrg }
   4837  1.1  mrg 
   4838  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_add(
   4839  1.1  mrg 	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
   4840  1.1  mrg {
   4841  1.1  mrg 	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
   4842  1.1  mrg 	return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
   4843  1.1  mrg 						&isl_multi_aff_add);
   4844  1.1  mrg }
   4845  1.1  mrg 
   4846  1.1  mrg /* Subtract "pma2" from "pma1" and return the result.
   4847  1.1  mrg  */
   4848  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_sub(
   4849  1.1  mrg 	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
   4850  1.1  mrg {
   4851  1.1  mrg 	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
   4852  1.1  mrg 	return isl_pw_multi_aff_on_shared_domain(pma1, pma2,
   4853  1.1  mrg 						&isl_multi_aff_sub);
   4854  1.1  mrg }
   4855  1.1  mrg 
   4856  1.1  mrg /* Given two piecewise multi-affine expressions A -> B and C -> D,
   4857  1.1  mrg  * construct a piecewise multi-affine expression [A -> C] -> [B -> D].
   4858  1.1  mrg  */
   4859  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_product(
   4860  1.1  mrg 	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
   4861  1.1  mrg {
   4862  1.1  mrg 	int i, j, n;
   4863  1.1  mrg 	isl_space *space;
   4864  1.1  mrg 	isl_pw_multi_aff *res;
   4865  1.1  mrg 
   4866  1.1  mrg 	if (isl_pw_multi_aff_align_params_bin(&pma1, &pma2) < 0)
   4867  1.1  mrg 		goto error;
   4868  1.1  mrg 
   4869  1.1  mrg 	n = pma1->n * pma2->n;
   4870  1.1  mrg 	space = isl_space_product(isl_space_copy(pma1->dim),
   4871  1.1  mrg 				  isl_space_copy(pma2->dim));
   4872  1.1  mrg 	res = isl_pw_multi_aff_alloc_size(space, n);
   4873  1.1  mrg 
   4874  1.1  mrg 	for (i = 0; i < pma1->n; ++i) {
   4875  1.1  mrg 		for (j = 0; j < pma2->n; ++j) {
   4876  1.1  mrg 			isl_set *domain;
   4877  1.1  mrg 			isl_multi_aff *ma;
   4878  1.1  mrg 
   4879  1.1  mrg 			domain = isl_set_product(isl_set_copy(pma1->p[i].set),
   4880  1.1  mrg 						 isl_set_copy(pma2->p[j].set));
   4881  1.1  mrg 			ma = isl_multi_aff_product(
   4882  1.1  mrg 					isl_multi_aff_copy(pma1->p[i].maff),
   4883  1.1  mrg 					isl_multi_aff_copy(pma2->p[j].maff));
   4884  1.1  mrg 			res = isl_pw_multi_aff_add_piece(res, domain, ma);
   4885  1.1  mrg 		}
   4886  1.1  mrg 	}
   4887  1.1  mrg 
   4888  1.1  mrg 	isl_pw_multi_aff_free(pma1);
   4889  1.1  mrg 	isl_pw_multi_aff_free(pma2);
   4890  1.1  mrg 	return res;
   4891  1.1  mrg error:
   4892  1.1  mrg 	isl_pw_multi_aff_free(pma1);
   4893  1.1  mrg 	isl_pw_multi_aff_free(pma2);
   4894  1.1  mrg 	return NULL;
   4895  1.1  mrg }
   4896  1.1  mrg 
   4897  1.1  mrg /* Subtract the initial "n" elements in "ma" with coefficients in "c" and
   4898  1.1  mrg  * denominator "denom".
   4899  1.1  mrg  * "denom" is allowed to be negative, in which case the actual denominator
   4900  1.1  mrg  * is -denom and the expressions are added instead.
   4901  1.1  mrg  */
   4902  1.1  mrg static __isl_give isl_aff *subtract_initial(__isl_take isl_aff *aff,
   4903  1.1  mrg 	__isl_keep isl_multi_aff *ma, int n, isl_int *c, isl_int denom)
   4904  1.1  mrg {
   4905  1.1  mrg 	int i, first;
   4906  1.1  mrg 	int sign;
   4907  1.1  mrg 	isl_int d;
   4908  1.1  mrg 
   4909  1.1  mrg 	first = isl_seq_first_non_zero(c, n);
   4910  1.1  mrg 	if (first == -1)
   4911  1.1  mrg 		return aff;
   4912  1.1  mrg 
   4913  1.1  mrg 	sign = isl_int_sgn(denom);
   4914  1.1  mrg 	isl_int_init(d);
   4915  1.1  mrg 	isl_int_abs(d, denom);
   4916  1.1  mrg 	for (i = first; i < n; ++i) {
   4917  1.1  mrg 		isl_aff *aff_i;
   4918  1.1  mrg 
   4919  1.1  mrg 		if (isl_int_is_zero(c[i]))
   4920  1.1  mrg 			continue;
   4921  1.1  mrg 		aff_i = isl_multi_aff_get_aff(ma, i);
   4922  1.1  mrg 		aff_i = isl_aff_scale(aff_i, c[i]);
   4923  1.1  mrg 		aff_i = isl_aff_scale_down(aff_i, d);
   4924  1.1  mrg 		if (sign >= 0)
   4925  1.1  mrg 			aff = isl_aff_sub(aff, aff_i);
   4926  1.1  mrg 		else
   4927  1.1  mrg 			aff = isl_aff_add(aff, aff_i);
   4928  1.1  mrg 	}
   4929  1.1  mrg 	isl_int_clear(d);
   4930  1.1  mrg 
   4931  1.1  mrg 	return aff;
   4932  1.1  mrg }
   4933  1.1  mrg 
   4934  1.1  mrg /* Extract an affine expression that expresses the output dimension "pos"
   4935  1.1  mrg  * of "bmap" in terms of the parameters and input dimensions from
   4936  1.1  mrg  * equality "eq".
   4937  1.1  mrg  * Note that this expression may involve integer divisions defined
   4938  1.1  mrg  * in terms of parameters and input dimensions.
   4939  1.1  mrg  * The equality may also involve references to earlier (but not later)
   4940  1.1  mrg  * output dimensions.  These are replaced by the corresponding elements
   4941  1.1  mrg  * in "ma".
   4942  1.1  mrg  *
   4943  1.1  mrg  * If the equality is of the form
   4944  1.1  mrg  *
   4945  1.1  mrg  *	f(i) + h(j) + a x + g(i) = 0,
   4946  1.1  mrg  *
   4947  1.1  mrg  * with f(i) a linear combinations of the parameters and input dimensions,
   4948  1.1  mrg  * g(i) a linear combination of integer divisions defined in terms of the same
   4949  1.1  mrg  * and h(j) a linear combinations of earlier output dimensions,
   4950  1.1  mrg  * then the affine expression is
   4951  1.1  mrg  *
   4952  1.1  mrg  *	(-f(i) - g(i))/a - h(j)/a
   4953  1.1  mrg  *
   4954  1.1  mrg  * If the equality is of the form
   4955  1.1  mrg  *
   4956  1.1  mrg  *	f(i) + h(j) - a x + g(i) = 0,
   4957  1.1  mrg  *
   4958  1.1  mrg  * then the affine expression is
   4959  1.1  mrg  *
   4960  1.1  mrg  *	(f(i) + g(i))/a - h(j)/(-a)
   4961  1.1  mrg  *
   4962  1.1  mrg  *
   4963  1.1  mrg  * If "div" refers to an integer division (i.e., it is smaller than
   4964  1.1  mrg  * the number of integer divisions), then the equality constraint
   4965  1.1  mrg  * does involve an integer division (the one at position "div") that
   4966  1.1  mrg  * is defined in terms of output dimensions.  However, this integer
   4967  1.1  mrg  * division can be eliminated by exploiting a pair of constraints
   4968  1.1  mrg  * x >= l and x <= l + n, with n smaller than the coefficient of "div"
   4969  1.1  mrg  * in the equality constraint.  "ineq" refers to inequality x >= l, i.e.,
   4970  1.1  mrg  * -l + x >= 0.
   4971  1.1  mrg  * In particular, let
   4972  1.1  mrg  *
   4973  1.1  mrg  *	x = e(i) + m floor(...)
   4974  1.1  mrg  *
   4975  1.1  mrg  * with e(i) the expression derived above and floor(...) the integer
   4976  1.1  mrg  * division involving output dimensions.
   4977  1.1  mrg  * From
   4978  1.1  mrg  *
   4979  1.1  mrg  *	l <= x <= l + n,
   4980  1.1  mrg  *
   4981  1.1  mrg  * we have
   4982  1.1  mrg  *
   4983  1.1  mrg  *	0 <= x - l <= n
   4984  1.1  mrg  *
   4985  1.1  mrg  * This means
   4986  1.1  mrg  *
   4987  1.1  mrg  *	e(i) + m floor(...) - l = (e(i) + m floor(...) - l) mod m
   4988  1.1  mrg  *	                        = (e(i) - l) mod m
   4989  1.1  mrg  *
   4990  1.1  mrg  * Therefore,
   4991  1.1  mrg  *
   4992  1.1  mrg  *	x - l = (e(i) - l) mod m
   4993  1.1  mrg  *
   4994  1.1  mrg  * or
   4995  1.1  mrg  *
   4996  1.1  mrg  *	x = ((e(i) - l) mod m) + l
   4997  1.1  mrg  *
   4998  1.1  mrg  * The variable "shift" below contains the expression -l, which may
   4999  1.1  mrg  * also involve a linear combination of earlier output dimensions.
   5000  1.1  mrg  */
   5001  1.1  mrg static __isl_give isl_aff *extract_aff_from_equality(
   5002  1.1  mrg 	__isl_keep isl_basic_map *bmap, int pos, int eq, int div, int ineq,
   5003  1.1  mrg 	__isl_keep isl_multi_aff *ma)
   5004  1.1  mrg {
   5005  1.1  mrg 	unsigned o_out;
   5006  1.1  mrg 	isl_size n_div, n_out;
   5007  1.1  mrg 	isl_ctx *ctx;
   5008  1.1  mrg 	isl_local_space *ls;
   5009  1.1  mrg 	isl_aff *aff, *shift;
   5010  1.1  mrg 	isl_val *mod;
   5011  1.1  mrg 
   5012  1.1  mrg 	ctx = isl_basic_map_get_ctx(bmap);
   5013  1.1  mrg 	ls = isl_basic_map_get_local_space(bmap);
   5014  1.1  mrg 	ls = isl_local_space_domain(ls);
   5015  1.1  mrg 	aff = isl_aff_alloc(isl_local_space_copy(ls));
   5016  1.1  mrg 	if (!aff)
   5017  1.1  mrg 		goto error;
   5018  1.1  mrg 	o_out = isl_basic_map_offset(bmap, isl_dim_out);
   5019  1.1  mrg 	n_out = isl_basic_map_dim(bmap, isl_dim_out);
   5020  1.1  mrg 	n_div = isl_basic_map_dim(bmap, isl_dim_div);
   5021  1.1  mrg 	if (n_out < 0 || n_div < 0)
   5022  1.1  mrg 		goto error;
   5023  1.1  mrg 	if (isl_int_is_neg(bmap->eq[eq][o_out + pos])) {
   5024  1.1  mrg 		isl_seq_cpy(aff->v->el + 1, bmap->eq[eq], o_out);
   5025  1.1  mrg 		isl_seq_cpy(aff->v->el + 1 + o_out,
   5026  1.1  mrg 			    bmap->eq[eq] + o_out + n_out, n_div);
   5027  1.1  mrg 	} else {
   5028  1.1  mrg 		isl_seq_neg(aff->v->el + 1, bmap->eq[eq], o_out);
   5029  1.1  mrg 		isl_seq_neg(aff->v->el + 1 + o_out,
   5030  1.1  mrg 			    bmap->eq[eq] + o_out + n_out, n_div);
   5031  1.1  mrg 	}
   5032  1.1  mrg 	if (div < n_div)
   5033  1.1  mrg 		isl_int_set_si(aff->v->el[1 + o_out + div], 0);
   5034  1.1  mrg 	isl_int_abs(aff->v->el[0], bmap->eq[eq][o_out + pos]);
   5035  1.1  mrg 	aff = subtract_initial(aff, ma, pos, bmap->eq[eq] + o_out,
   5036  1.1  mrg 			    bmap->eq[eq][o_out + pos]);
   5037  1.1  mrg 	if (div < n_div) {
   5038  1.1  mrg 		shift = isl_aff_alloc(isl_local_space_copy(ls));
   5039  1.1  mrg 		if (!shift)
   5040  1.1  mrg 			goto error;
   5041  1.1  mrg 		isl_seq_cpy(shift->v->el + 1, bmap->ineq[ineq], o_out);
   5042  1.1  mrg 		isl_seq_cpy(shift->v->el + 1 + o_out,
   5043  1.1  mrg 			    bmap->ineq[ineq] + o_out + n_out, n_div);
   5044  1.1  mrg 		isl_int_set_si(shift->v->el[0], 1);
   5045  1.1  mrg 		shift = subtract_initial(shift, ma, pos,
   5046  1.1  mrg 					bmap->ineq[ineq] + o_out, ctx->negone);
   5047  1.1  mrg 		aff = isl_aff_add(aff, isl_aff_copy(shift));
   5048  1.1  mrg 		mod = isl_val_int_from_isl_int(ctx,
   5049  1.1  mrg 					    bmap->eq[eq][o_out + n_out + div]);
   5050  1.1  mrg 		mod = isl_val_abs(mod);
   5051  1.1  mrg 		aff = isl_aff_mod_val(aff, mod);
   5052  1.1  mrg 		aff = isl_aff_sub(aff, shift);
   5053  1.1  mrg 	}
   5054  1.1  mrg 
   5055  1.1  mrg 	isl_local_space_free(ls);
   5056  1.1  mrg 	return aff;
   5057  1.1  mrg error:
   5058  1.1  mrg 	isl_local_space_free(ls);
   5059  1.1  mrg 	isl_aff_free(aff);
   5060  1.1  mrg 	return NULL;
   5061  1.1  mrg }
   5062  1.1  mrg 
   5063  1.1  mrg /* Given a basic map with output dimensions defined
   5064  1.1  mrg  * in terms of the parameters input dimensions and earlier
   5065  1.1  mrg  * output dimensions using an equality (and possibly a pair on inequalities),
   5066  1.1  mrg  * extract an isl_aff that expresses output dimension "pos" in terms
   5067  1.1  mrg  * of the parameters and input dimensions.
   5068  1.1  mrg  * Note that this expression may involve integer divisions defined
   5069  1.1  mrg  * in terms of parameters and input dimensions.
   5070  1.1  mrg  * "ma" contains the expressions corresponding to earlier output dimensions.
   5071  1.1  mrg  *
   5072  1.1  mrg  * This function shares some similarities with
   5073  1.1  mrg  * isl_basic_map_has_defining_equality and isl_constraint_get_bound.
   5074  1.1  mrg  */
   5075  1.1  mrg static __isl_give isl_aff *extract_isl_aff_from_basic_map(
   5076  1.1  mrg 	__isl_keep isl_basic_map *bmap, int pos, __isl_keep isl_multi_aff *ma)
   5077  1.1  mrg {
   5078  1.1  mrg 	int eq, div, ineq;
   5079  1.1  mrg 	isl_aff *aff;
   5080  1.1  mrg 
   5081  1.1  mrg 	if (!bmap)
   5082  1.1  mrg 		return NULL;
   5083  1.1  mrg 	eq = isl_basic_map_output_defining_equality(bmap, pos, &div, &ineq);
   5084  1.1  mrg 	if (eq >= bmap->n_eq)
   5085  1.1  mrg 		isl_die(isl_basic_map_get_ctx(bmap), isl_error_invalid,
   5086  1.1  mrg 			"unable to find suitable equality", return NULL);
   5087  1.1  mrg 	aff = extract_aff_from_equality(bmap, pos, eq, div, ineq, ma);
   5088  1.1  mrg 
   5089  1.1  mrg 	aff = isl_aff_remove_unused_divs(aff);
   5090  1.1  mrg 	return aff;
   5091  1.1  mrg }
   5092  1.1  mrg 
   5093  1.1  mrg /* Given a basic map where each output dimension is defined
   5094  1.1  mrg  * in terms of the parameters and input dimensions using an equality,
   5095  1.1  mrg  * extract an isl_multi_aff that expresses the output dimensions in terms
   5096  1.1  mrg  * of the parameters and input dimensions.
   5097  1.1  mrg  */
   5098  1.1  mrg static __isl_give isl_multi_aff *extract_isl_multi_aff_from_basic_map(
   5099  1.1  mrg 	__isl_take isl_basic_map *bmap)
   5100  1.1  mrg {
   5101  1.1  mrg 	int i;
   5102  1.1  mrg 	isl_size n_out;
   5103  1.1  mrg 	isl_multi_aff *ma;
   5104  1.1  mrg 
   5105  1.1  mrg 	if (!bmap)
   5106  1.1  mrg 		return NULL;
   5107  1.1  mrg 
   5108  1.1  mrg 	ma = isl_multi_aff_alloc(isl_basic_map_get_space(bmap));
   5109  1.1  mrg 	n_out = isl_basic_map_dim(bmap, isl_dim_out);
   5110  1.1  mrg 	if (n_out < 0)
   5111  1.1  mrg 		ma = isl_multi_aff_free(ma);
   5112  1.1  mrg 
   5113  1.1  mrg 	for (i = 0; i < n_out; ++i) {
   5114  1.1  mrg 		isl_aff *aff;
   5115  1.1  mrg 
   5116  1.1  mrg 		aff = extract_isl_aff_from_basic_map(bmap, i, ma);
   5117  1.1  mrg 		ma = isl_multi_aff_set_aff(ma, i, aff);
   5118  1.1  mrg 	}
   5119  1.1  mrg 
   5120  1.1  mrg 	isl_basic_map_free(bmap);
   5121  1.1  mrg 
   5122  1.1  mrg 	return ma;
   5123  1.1  mrg }
   5124  1.1  mrg 
   5125  1.1  mrg /* Given a basic set where each set dimension is defined
   5126  1.1  mrg  * in terms of the parameters using an equality,
   5127  1.1  mrg  * extract an isl_multi_aff that expresses the set dimensions in terms
   5128  1.1  mrg  * of the parameters.
   5129  1.1  mrg  */
   5130  1.1  mrg __isl_give isl_multi_aff *isl_multi_aff_from_basic_set_equalities(
   5131  1.1  mrg 	__isl_take isl_basic_set *bset)
   5132  1.1  mrg {
   5133  1.1  mrg 	return extract_isl_multi_aff_from_basic_map(bset);
   5134  1.1  mrg }
   5135  1.1  mrg 
   5136  1.1  mrg /* Create an isl_pw_multi_aff that is equivalent to
   5137  1.1  mrg  * isl_map_intersect_domain(isl_map_from_basic_map(bmap), domain).
   5138  1.1  mrg  * The given basic map is such that each output dimension is defined
   5139  1.1  mrg  * in terms of the parameters and input dimensions using an equality.
   5140  1.1  mrg  *
   5141  1.1  mrg  * Since some applications expect the result of isl_pw_multi_aff_from_map
   5142  1.1  mrg  * to only contain integer affine expressions, we compute the floor
   5143  1.1  mrg  * of the expression before returning.
   5144  1.1  mrg  *
   5145  1.1  mrg  * Remove all constraints involving local variables without
   5146  1.1  mrg  * an explicit representation (resulting in the removal of those
   5147  1.1  mrg  * local variables) prior to the actual extraction to ensure
   5148  1.1  mrg  * that the local spaces in which the resulting affine expressions
   5149  1.1  mrg  * are created do not contain any unknown local variables.
   5150  1.1  mrg  * Removing such constraints is safe because constraints involving
   5151  1.1  mrg  * unknown local variables are not used to determine whether
   5152  1.1  mrg  * a basic map is obviously single-valued.
   5153  1.1  mrg  */
   5154  1.1  mrg static __isl_give isl_pw_multi_aff *plain_pw_multi_aff_from_map(
   5155  1.1  mrg 	__isl_take isl_set *domain, __isl_take isl_basic_map *bmap)
   5156  1.1  mrg {
   5157  1.1  mrg 	isl_multi_aff *ma;
   5158  1.1  mrg 
   5159  1.1  mrg 	bmap = isl_basic_map_drop_constraints_involving_unknown_divs(bmap);
   5160  1.1  mrg 	ma = extract_isl_multi_aff_from_basic_map(bmap);
   5161  1.1  mrg 	ma = isl_multi_aff_floor(ma);
   5162  1.1  mrg 	return isl_pw_multi_aff_alloc(domain, ma);
   5163  1.1  mrg }
   5164  1.1  mrg 
   5165  1.1  mrg /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
   5166  1.1  mrg  * This obviously only works if the input "map" is single-valued.
   5167  1.1  mrg  * If so, we compute the lexicographic minimum of the image in the form
   5168  1.1  mrg  * of an isl_pw_multi_aff.  Since the image is unique, it is equal
   5169  1.1  mrg  * to its lexicographic minimum.
   5170  1.1  mrg  * If the input is not single-valued, we produce an error.
   5171  1.1  mrg  */
   5172  1.1  mrg static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_base(
   5173  1.1  mrg 	__isl_take isl_map *map)
   5174  1.1  mrg {
   5175  1.1  mrg 	int i;
   5176  1.1  mrg 	int sv;
   5177  1.1  mrg 	isl_pw_multi_aff *pma;
   5178  1.1  mrg 
   5179  1.1  mrg 	sv = isl_map_is_single_valued(map);
   5180  1.1  mrg 	if (sv < 0)
   5181  1.1  mrg 		goto error;
   5182  1.1  mrg 	if (!sv)
   5183  1.1  mrg 		isl_die(isl_map_get_ctx(map), isl_error_invalid,
   5184  1.1  mrg 			"map is not single-valued", goto error);
   5185  1.1  mrg 	map = isl_map_make_disjoint(map);
   5186  1.1  mrg 	if (!map)
   5187  1.1  mrg 		return NULL;
   5188  1.1  mrg 
   5189  1.1  mrg 	pma = isl_pw_multi_aff_empty(isl_map_get_space(map));
   5190  1.1  mrg 
   5191  1.1  mrg 	for (i = 0; i < map->n; ++i) {
   5192  1.1  mrg 		isl_pw_multi_aff *pma_i;
   5193  1.1  mrg 		isl_basic_map *bmap;
   5194  1.1  mrg 		bmap = isl_basic_map_copy(map->p[i]);
   5195  1.1  mrg 		pma_i = isl_basic_map_lexmin_pw_multi_aff(bmap);
   5196  1.1  mrg 		pma = isl_pw_multi_aff_add_disjoint(pma, pma_i);
   5197  1.1  mrg 	}
   5198  1.1  mrg 
   5199  1.1  mrg 	isl_map_free(map);
   5200  1.1  mrg 	return pma;
   5201  1.1  mrg error:
   5202  1.1  mrg 	isl_map_free(map);
   5203  1.1  mrg 	return NULL;
   5204  1.1  mrg }
   5205  1.1  mrg 
   5206  1.1  mrg /* Construct an isl_aff from the given domain local space "ls" and
   5207  1.1  mrg  * coefficients "v", where the local space may involve
   5208  1.1  mrg  * local variables without a known expression, as long as these
   5209  1.1  mrg  * do not have a non-zero coefficient in "v".
   5210  1.1  mrg  * These need to be pruned away first since an isl_aff cannot
   5211  1.1  mrg  * reference any local variables without a known expression.
   5212  1.1  mrg  * For simplicity, remove all local variables that have a zero coefficient and
   5213  1.1  mrg  * that are not used in other local variables with a non-zero coefficient.
   5214  1.1  mrg  */
   5215  1.1  mrg static __isl_give isl_aff *isl_aff_alloc_vec_prune(
   5216  1.1  mrg 	__isl_take isl_local_space *ls, __isl_take isl_vec *v)
   5217  1.1  mrg {
   5218  1.1  mrg 	int i;
   5219  1.1  mrg 	isl_size n_div, v_div;
   5220  1.1  mrg 
   5221  1.1  mrg 	n_div = isl_local_space_dim(ls, isl_dim_div);
   5222  1.1  mrg 	v_div = isl_local_space_var_offset(ls, isl_dim_div);
   5223  1.1  mrg 	if (n_div < 0 || v_div < 0 || !v)
   5224  1.1  mrg 		goto error;
   5225  1.1  mrg 	for (i = n_div - 1; i >= 0; --i) {
   5226  1.1  mrg 		isl_bool involves;
   5227  1.1  mrg 
   5228  1.1  mrg 		if (!isl_int_is_zero(v->el[1 + 1 + v_div + i]))
   5229  1.1  mrg 			continue;
   5230  1.1  mrg 		involves = isl_local_space_involves_dims(ls, isl_dim_div, i, 1);
   5231  1.1  mrg 		if (involves < 0)
   5232  1.1  mrg 			goto error;
   5233  1.1  mrg 		if (involves)
   5234  1.1  mrg 			continue;
   5235  1.1  mrg 		ls = isl_local_space_drop_dims(ls, isl_dim_div, i, 1);
   5236  1.1  mrg 		v = isl_vec_drop_els(v, 1 + 1 + v_div + i, 1);
   5237  1.1  mrg 		if (!v)
   5238  1.1  mrg 			goto error;
   5239  1.1  mrg 	}
   5240  1.1  mrg 
   5241  1.1  mrg 	return isl_aff_alloc_vec(ls, v);
   5242  1.1  mrg error:
   5243  1.1  mrg 	isl_local_space_free(ls);
   5244  1.1  mrg 	isl_vec_free(v);
   5245  1.1  mrg 	return NULL;
   5246  1.1  mrg }
   5247  1.1  mrg 
   5248  1.1  mrg /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map,
   5249  1.1  mrg  * taking into account that the output dimension at position "d"
   5250  1.1  mrg  * can be represented as
   5251  1.1  mrg  *
   5252  1.1  mrg  *	x = floor((e(...) + c1) / m)
   5253  1.1  mrg  *
   5254  1.1  mrg  * given that constraint "i" is of the form
   5255  1.1  mrg  *
   5256  1.1  mrg  *	e(...) + c1 - m x >= 0
   5257  1.1  mrg  *
   5258  1.1  mrg  * with e(...) an expression that does not involve any other output dimensions.
   5259  1.1  mrg  *
   5260  1.1  mrg  *
   5261  1.1  mrg  * Let "map" be of the form
   5262  1.1  mrg  *
   5263  1.1  mrg  *	A -> B
   5264  1.1  mrg  *
   5265  1.1  mrg  * We construct a mapping
   5266  1.1  mrg  *
   5267  1.1  mrg  *	A -> [A -> x = floor(...)]
   5268  1.1  mrg  *
   5269  1.1  mrg  * apply that to the map, obtaining
   5270  1.1  mrg  *
   5271  1.1  mrg  *	[A -> x = floor(...)] -> B
   5272  1.1  mrg  *
   5273  1.1  mrg  * and equate dimension "d" to x.
   5274  1.1  mrg  * We then compute a isl_pw_multi_aff representation of the resulting map
   5275  1.1  mrg  * and plug in the mapping above.
   5276  1.1  mrg  *
   5277  1.1  mrg  * The constraint "i" is guaranteed by the caller not to involve
   5278  1.1  mrg  * any local variables without a known expression, but such local variables
   5279  1.1  mrg  * may appear in other constraints.  They therefore need to be removed
   5280  1.1  mrg  * during the construction of the affine expression.
   5281  1.1  mrg  */
   5282  1.1  mrg static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_div(
   5283  1.1  mrg 	__isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i)
   5284  1.1  mrg {
   5285  1.1  mrg 	isl_space *space = NULL;
   5286  1.1  mrg 	isl_local_space *ls;
   5287  1.1  mrg 	isl_multi_aff *ma;
   5288  1.1  mrg 	isl_aff *aff;
   5289  1.1  mrg 	isl_vec *v;
   5290  1.1  mrg 	isl_map *insert;
   5291  1.1  mrg 	isl_size n_in;
   5292  1.1  mrg 	isl_pw_multi_aff *pma;
   5293  1.1  mrg 	isl_bool is_set;
   5294  1.1  mrg 
   5295  1.1  mrg 	is_set = isl_map_is_set(map);
   5296  1.1  mrg 	if (is_set < 0)
   5297  1.1  mrg 		goto error;
   5298  1.1  mrg 
   5299  1.1  mrg 	space = isl_space_domain(isl_map_get_space(map));
   5300  1.1  mrg 	n_in = isl_space_dim(space, isl_dim_set);
   5301  1.1  mrg 	if (n_in < 0)
   5302  1.1  mrg 		goto error;
   5303  1.1  mrg 
   5304  1.1  mrg 	ls = isl_basic_map_get_local_space(hull);
   5305  1.1  mrg 	if (!is_set)
   5306  1.1  mrg 		ls = isl_local_space_wrap(ls);
   5307  1.1  mrg 	v = isl_basic_map_inequality_extract_output_upper_bound(hull, i, d);
   5308  1.1  mrg 	isl_basic_map_free(hull);
   5309  1.1  mrg 
   5310  1.1  mrg 	aff = isl_aff_alloc_vec_prune(ls, v);
   5311  1.1  mrg 	aff = isl_aff_floor(aff);
   5312  1.1  mrg 	if (is_set) {
   5313  1.1  mrg 		aff = isl_aff_project_domain_on_params(aff);
   5314  1.1  mrg 		isl_space_free(space);
   5315  1.1  mrg 		ma = isl_multi_aff_from_aff(aff);
   5316  1.1  mrg 	} else {
   5317  1.1  mrg 		aff = isl_aff_domain_factor_domain(aff);
   5318  1.1  mrg 		ma = isl_multi_aff_identity(isl_space_map_from_set(space));
   5319  1.1  mrg 		ma = isl_multi_aff_range_product(ma,
   5320  1.1  mrg 						isl_multi_aff_from_aff(aff));
   5321  1.1  mrg 	}
   5322  1.1  mrg 
   5323  1.1  mrg 	insert = isl_map_from_multi_aff_internal(isl_multi_aff_copy(ma));
   5324  1.1  mrg 	map = isl_map_apply_domain(map, insert);
   5325  1.1  mrg 	map = isl_map_equate(map, isl_dim_in, n_in, isl_dim_out, d);
   5326  1.1  mrg 	pma = isl_pw_multi_aff_from_map(map);
   5327  1.1  mrg 	pma = isl_pw_multi_aff_pullback_multi_aff(pma, ma);
   5328  1.1  mrg 
   5329  1.1  mrg 	return pma;
   5330  1.1  mrg error:
   5331  1.1  mrg 	isl_space_free(space);
   5332  1.1  mrg 	isl_map_free(map);
   5333  1.1  mrg 	isl_basic_map_free(hull);
   5334  1.1  mrg 	return NULL;
   5335  1.1  mrg }
   5336  1.1  mrg 
   5337  1.1  mrg /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
   5338  1.1  mrg  *
   5339  1.1  mrg  * As a special case, we first check if there is any pair of constraints,
   5340  1.1  mrg  * shared by all the basic maps in "map" that force a given dimension
   5341  1.1  mrg  * to be equal to the floor of some affine combination of the input dimensions.
   5342  1.1  mrg  *
   5343  1.1  mrg  * In particular, if we can find two constraints
   5344  1.1  mrg  *
   5345  1.1  mrg  *	e(...) + c1 - m x >= 0		i.e.,		m x <= e(...) + c1
   5346  1.1  mrg  *
   5347  1.1  mrg  * and
   5348  1.1  mrg  *
   5349  1.1  mrg  *	-e(...) + c2 + m x >= 0		i.e.,		m x >= e(...) - c2
   5350  1.1  mrg  *
   5351  1.1  mrg  * where m > 1 and e only depends on parameters and input dimensions,
   5352  1.1  mrg  * and such that
   5353  1.1  mrg  *
   5354  1.1  mrg  *	c1 + c2 < m			i.e.,		-c2 >= c1 - (m - 1)
   5355  1.1  mrg  *
   5356  1.1  mrg  * then we know that we can take
   5357  1.1  mrg  *
   5358  1.1  mrg  *	x = floor((e(...) + c1) / m)
   5359  1.1  mrg  *
   5360  1.1  mrg  * without having to perform any computation.
   5361  1.1  mrg  *
   5362  1.1  mrg  * Note that we know that
   5363  1.1  mrg  *
   5364  1.1  mrg  *	c1 + c2 >= 1
   5365  1.1  mrg  *
   5366  1.1  mrg  * If c1 + c2 were 0, then we would have detected an equality during
   5367  1.1  mrg  * simplification.  If c1 + c2 were negative, then we would have detected
   5368  1.1  mrg  * a contradiction.
   5369  1.1  mrg  */
   5370  1.1  mrg static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_div(
   5371  1.1  mrg 	__isl_take isl_map *map)
   5372  1.1  mrg {
   5373  1.1  mrg 	int d;
   5374  1.1  mrg 	isl_size dim;
   5375  1.1  mrg 	isl_size i;
   5376  1.1  mrg 	isl_size n_ineq;
   5377  1.1  mrg 	isl_basic_map *hull;
   5378  1.1  mrg 
   5379  1.1  mrg 	hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
   5380  1.1  mrg 	dim = isl_map_dim(map, isl_dim_out);
   5381  1.1  mrg 	n_ineq = isl_basic_map_n_inequality(hull);
   5382  1.1  mrg 	if (dim < 0 || n_ineq < 0)
   5383  1.1  mrg 		goto error;
   5384  1.1  mrg 
   5385  1.1  mrg 	dim = isl_map_dim(map, isl_dim_out);
   5386  1.1  mrg 	for (d = 0; d < dim; ++d) {
   5387  1.1  mrg 		i = isl_basic_map_find_output_upper_div_constraint(hull, d);
   5388  1.1  mrg 		if (i < 0)
   5389  1.1  mrg 			goto error;
   5390  1.1  mrg 		if (i >= n_ineq)
   5391  1.1  mrg 			continue;
   5392  1.1  mrg 		return pw_multi_aff_from_map_div(map, hull, d, i);
   5393  1.1  mrg 	}
   5394  1.1  mrg 	isl_basic_map_free(hull);
   5395  1.1  mrg 	return pw_multi_aff_from_map_base(map);
   5396  1.1  mrg error:
   5397  1.1  mrg 	isl_map_free(map);
   5398  1.1  mrg 	isl_basic_map_free(hull);
   5399  1.1  mrg 	return NULL;
   5400  1.1  mrg }
   5401  1.1  mrg 
   5402  1.1  mrg /* Given an affine expression
   5403  1.1  mrg  *
   5404  1.1  mrg  *	[A -> B] -> f(A,B)
   5405  1.1  mrg  *
   5406  1.1  mrg  * construct an isl_multi_aff
   5407  1.1  mrg  *
   5408  1.1  mrg  *	[A -> B] -> B'
   5409  1.1  mrg  *
   5410  1.1  mrg  * such that dimension "d" in B' is set to "aff" and the remaining
   5411  1.1  mrg  * dimensions are set equal to the corresponding dimensions in B.
   5412  1.1  mrg  * "n_in" is the dimension of the space A.
   5413  1.1  mrg  * "n_out" is the dimension of the space B.
   5414  1.1  mrg  *
   5415  1.1  mrg  * If "is_set" is set, then the affine expression is of the form
   5416  1.1  mrg  *
   5417  1.1  mrg  *	[B] -> f(B)
   5418  1.1  mrg  *
   5419  1.1  mrg  * and we construct an isl_multi_aff
   5420  1.1  mrg  *
   5421  1.1  mrg  *	B -> B'
   5422  1.1  mrg  */
   5423  1.1  mrg static __isl_give isl_multi_aff *range_map(__isl_take isl_aff *aff, int d,
   5424  1.1  mrg 	unsigned n_in, unsigned n_out, int is_set)
   5425  1.1  mrg {
   5426  1.1  mrg 	int i;
   5427  1.1  mrg 	isl_multi_aff *ma;
   5428  1.1  mrg 	isl_space *space, *space2;
   5429  1.1  mrg 	isl_local_space *ls;
   5430  1.1  mrg 
   5431  1.1  mrg 	space = isl_aff_get_domain_space(aff);
   5432  1.1  mrg 	ls = isl_local_space_from_space(isl_space_copy(space));
   5433  1.1  mrg 	space2 = isl_space_copy(space);
   5434  1.1  mrg 	if (!is_set)
   5435  1.1  mrg 		space2 = isl_space_range(isl_space_unwrap(space2));
   5436  1.1  mrg 	space = isl_space_map_from_domain_and_range(space, space2);
   5437  1.1  mrg 	ma = isl_multi_aff_alloc(space);
   5438  1.1  mrg 	ma = isl_multi_aff_set_aff(ma, d, aff);
   5439  1.1  mrg 
   5440  1.1  mrg 	for (i = 0; i < n_out; ++i) {
   5441  1.1  mrg 		if (i == d)
   5442  1.1  mrg 			continue;
   5443  1.1  mrg 		aff = isl_aff_var_on_domain(isl_local_space_copy(ls),
   5444  1.1  mrg 						isl_dim_set, n_in + i);
   5445  1.1  mrg 		ma = isl_multi_aff_set_aff(ma, i, aff);
   5446  1.1  mrg 	}
   5447  1.1  mrg 
   5448  1.1  mrg 	isl_local_space_free(ls);
   5449  1.1  mrg 
   5450  1.1  mrg 	return ma;
   5451  1.1  mrg }
   5452  1.1  mrg 
   5453  1.1  mrg /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map,
   5454  1.1  mrg  * taking into account that the dimension at position "d" can be written as
   5455  1.1  mrg  *
   5456  1.1  mrg  *	x = m a + f(..)						(1)
   5457  1.1  mrg  *
   5458  1.1  mrg  * where m is equal to "gcd".
   5459  1.1  mrg  * "i" is the index of the equality in "hull" that defines f(..).
   5460  1.1  mrg  * In particular, the equality is of the form
   5461  1.1  mrg  *
   5462  1.1  mrg  *	f(..) - x + m g(existentials) = 0
   5463  1.1  mrg  *
   5464  1.1  mrg  * or
   5465  1.1  mrg  *
   5466  1.1  mrg  *	-f(..) + x + m g(existentials) = 0
   5467  1.1  mrg  *
   5468  1.1  mrg  * We basically plug (1) into "map", resulting in a map with "a"
   5469  1.1  mrg  * in the range instead of "x".  The corresponding isl_pw_multi_aff
   5470  1.1  mrg  * defining "a" is then plugged back into (1) to obtain a definition for "x".
   5471  1.1  mrg  *
   5472  1.1  mrg  * Specifically, given the input map
   5473  1.1  mrg  *
   5474  1.1  mrg  *	A -> B
   5475  1.1  mrg  *
   5476  1.1  mrg  * We first wrap it into a set
   5477  1.1  mrg  *
   5478  1.1  mrg  *	[A -> B]
   5479  1.1  mrg  *
   5480  1.1  mrg  * and define (1) on top of the corresponding space, resulting in "aff".
   5481  1.1  mrg  * We use this to create an isl_multi_aff that maps the output position "d"
   5482  1.1  mrg  * from "a" to "x", leaving all other (intput and output) dimensions unchanged.
   5483  1.1  mrg  * We plug this into the wrapped map, unwrap the result and compute the
   5484  1.1  mrg  * corresponding isl_pw_multi_aff.
   5485  1.1  mrg  * The result is an expression
   5486  1.1  mrg  *
   5487  1.1  mrg  *	A -> T(A)
   5488  1.1  mrg  *
   5489  1.1  mrg  * We adjust that to
   5490  1.1  mrg  *
   5491  1.1  mrg  *	A -> [A -> T(A)]
   5492  1.1  mrg  *
   5493  1.1  mrg  * so that we can plug that into "aff", after extending the latter to
   5494  1.1  mrg  * a mapping
   5495  1.1  mrg  *
   5496  1.1  mrg  *	[A -> B] -> B'
   5497  1.1  mrg  *
   5498  1.1  mrg  *
   5499  1.1  mrg  * If "map" is actually a set, then there is no "A" space, meaning
   5500  1.1  mrg  * that we do not need to perform any wrapping, and that the result
   5501  1.1  mrg  * of the recursive call is of the form
   5502  1.1  mrg  *
   5503  1.1  mrg  *	[T]
   5504  1.1  mrg  *
   5505  1.1  mrg  * which is plugged into a mapping of the form
   5506  1.1  mrg  *
   5507  1.1  mrg  *	B -> B'
   5508  1.1  mrg  */
   5509  1.1  mrg static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_stride(
   5510  1.1  mrg 	__isl_take isl_map *map, __isl_take isl_basic_map *hull, int d, int i,
   5511  1.1  mrg 	isl_int gcd)
   5512  1.1  mrg {
   5513  1.1  mrg 	isl_set *set;
   5514  1.1  mrg 	isl_space *space;
   5515  1.1  mrg 	isl_local_space *ls;
   5516  1.1  mrg 	isl_aff *aff;
   5517  1.1  mrg 	isl_multi_aff *ma;
   5518  1.1  mrg 	isl_pw_multi_aff *pma, *id;
   5519  1.1  mrg 	isl_size n_in;
   5520  1.1  mrg 	unsigned o_out;
   5521  1.1  mrg 	isl_size n_out;
   5522  1.1  mrg 	isl_bool is_set;
   5523  1.1  mrg 
   5524  1.1  mrg 	is_set = isl_map_is_set(map);
   5525  1.1  mrg 	if (is_set < 0)
   5526  1.1  mrg 		goto error;
   5527  1.1  mrg 
   5528  1.1  mrg 	n_in = isl_basic_map_dim(hull, isl_dim_in);
   5529  1.1  mrg 	n_out = isl_basic_map_dim(hull, isl_dim_out);
   5530  1.1  mrg 	if (n_in < 0 || n_out < 0)
   5531  1.1  mrg 		goto error;
   5532  1.1  mrg 	o_out = isl_basic_map_offset(hull, isl_dim_out);
   5533  1.1  mrg 
   5534  1.1  mrg 	if (is_set)
   5535  1.1  mrg 		set = map;
   5536  1.1  mrg 	else
   5537  1.1  mrg 		set = isl_map_wrap(map);
   5538  1.1  mrg 	space = isl_space_map_from_set(isl_set_get_space(set));
   5539  1.1  mrg 	ma = isl_multi_aff_identity(space);
   5540  1.1  mrg 	ls = isl_local_space_from_space(isl_set_get_space(set));
   5541  1.1  mrg 	aff = isl_aff_alloc(ls);
   5542  1.1  mrg 	if (aff) {
   5543  1.1  mrg 		isl_int_set_si(aff->v->el[0], 1);
   5544  1.1  mrg 		if (isl_int_is_one(hull->eq[i][o_out + d]))
   5545  1.1  mrg 			isl_seq_neg(aff->v->el + 1, hull->eq[i],
   5546  1.1  mrg 				    aff->v->size - 1);
   5547  1.1  mrg 		else
   5548  1.1  mrg 			isl_seq_cpy(aff->v->el + 1, hull->eq[i],
   5549  1.1  mrg 				    aff->v->size - 1);
   5550  1.1  mrg 		isl_int_set(aff->v->el[1 + o_out + d], gcd);
   5551  1.1  mrg 	}
   5552  1.1  mrg 	ma = isl_multi_aff_set_aff(ma, n_in + d, isl_aff_copy(aff));
   5553  1.1  mrg 	set = isl_set_preimage_multi_aff(set, ma);
   5554  1.1  mrg 
   5555  1.1  mrg 	ma = range_map(aff, d, n_in, n_out, is_set);
   5556  1.1  mrg 
   5557  1.1  mrg 	if (is_set)
   5558  1.1  mrg 		map = set;
   5559  1.1  mrg 	else
   5560  1.1  mrg 		map = isl_set_unwrap(set);
   5561  1.1  mrg 	pma = isl_pw_multi_aff_from_map(map);
   5562  1.1  mrg 
   5563  1.1  mrg 	if (!is_set) {
   5564  1.1  mrg 		space = isl_pw_multi_aff_get_domain_space(pma);
   5565  1.1  mrg 		space = isl_space_map_from_set(space);
   5566  1.1  mrg 		id = isl_pw_multi_aff_identity(space);
   5567  1.1  mrg 		pma = isl_pw_multi_aff_range_product(id, pma);
   5568  1.1  mrg 	}
   5569  1.1  mrg 	id = isl_pw_multi_aff_from_multi_aff(ma);
   5570  1.1  mrg 	pma = isl_pw_multi_aff_pullback_pw_multi_aff(id, pma);
   5571  1.1  mrg 
   5572  1.1  mrg 	isl_basic_map_free(hull);
   5573  1.1  mrg 	return pma;
   5574  1.1  mrg error:
   5575  1.1  mrg 	isl_map_free(map);
   5576  1.1  mrg 	isl_basic_map_free(hull);
   5577  1.1  mrg 	return NULL;
   5578  1.1  mrg }
   5579  1.1  mrg 
   5580  1.1  mrg /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
   5581  1.1  mrg  * "hull" contains the equalities valid for "map".
   5582  1.1  mrg  *
   5583  1.1  mrg  * Check if any of the output dimensions is "strided".
   5584  1.1  mrg  * That is, we check if it can be written as
   5585  1.1  mrg  *
   5586  1.1  mrg  *	x = m a + f(..)
   5587  1.1  mrg  *
   5588  1.1  mrg  * with m greater than 1, a some combination of existentially quantified
   5589  1.1  mrg  * variables and f an expression in the parameters and input dimensions.
   5590  1.1  mrg  * If so, we remove the stride in pw_multi_aff_from_map_stride.
   5591  1.1  mrg  *
   5592  1.1  mrg  * Otherwise, we continue with pw_multi_aff_from_map_check_div for a further
   5593  1.1  mrg  * special case.
   5594  1.1  mrg  */
   5595  1.1  mrg static __isl_give isl_pw_multi_aff *pw_multi_aff_from_map_check_strides(
   5596  1.1  mrg 	__isl_take isl_map *map, __isl_take isl_basic_map *hull)
   5597  1.1  mrg {
   5598  1.1  mrg 	int i, j;
   5599  1.1  mrg 	isl_size n_out;
   5600  1.1  mrg 	unsigned o_out;
   5601  1.1  mrg 	isl_size n_div;
   5602  1.1  mrg 	unsigned o_div;
   5603  1.1  mrg 	isl_int gcd;
   5604  1.1  mrg 
   5605  1.1  mrg 	n_div = isl_basic_map_dim(hull, isl_dim_div);
   5606  1.1  mrg 	n_out = isl_basic_map_dim(hull, isl_dim_out);
   5607  1.1  mrg 	if (n_div < 0 || n_out < 0)
   5608  1.1  mrg 		goto error;
   5609  1.1  mrg 
   5610  1.1  mrg 	if (n_div == 0) {
   5611  1.1  mrg 		isl_basic_map_free(hull);
   5612  1.1  mrg 		return pw_multi_aff_from_map_check_div(map);
   5613  1.1  mrg 	}
   5614  1.1  mrg 
   5615  1.1  mrg 	isl_int_init(gcd);
   5616  1.1  mrg 
   5617  1.1  mrg 	o_div = isl_basic_map_offset(hull, isl_dim_div);
   5618  1.1  mrg 	o_out = isl_basic_map_offset(hull, isl_dim_out);
   5619  1.1  mrg 
   5620  1.1  mrg 	for (i = 0; i < n_out; ++i) {
   5621  1.1  mrg 		for (j = 0; j < hull->n_eq; ++j) {
   5622  1.1  mrg 			isl_int *eq = hull->eq[j];
   5623  1.1  mrg 			isl_pw_multi_aff *res;
   5624  1.1  mrg 
   5625  1.1  mrg 			if (!isl_int_is_one(eq[o_out + i]) &&
   5626  1.1  mrg 			    !isl_int_is_negone(eq[o_out + i]))
   5627  1.1  mrg 				continue;
   5628  1.1  mrg 			if (isl_seq_first_non_zero(eq + o_out, i) != -1)
   5629  1.1  mrg 				continue;
   5630  1.1  mrg 			if (isl_seq_first_non_zero(eq + o_out + i + 1,
   5631  1.1  mrg 						    n_out - (i + 1)) != -1)
   5632  1.1  mrg 				continue;
   5633  1.1  mrg 			isl_seq_gcd(eq + o_div, n_div, &gcd);
   5634  1.1  mrg 			if (isl_int_is_zero(gcd))
   5635  1.1  mrg 				continue;
   5636  1.1  mrg 			if (isl_int_is_one(gcd))
   5637  1.1  mrg 				continue;
   5638  1.1  mrg 
   5639  1.1  mrg 			res = pw_multi_aff_from_map_stride(map, hull,
   5640  1.1  mrg 								i, j, gcd);
   5641  1.1  mrg 			isl_int_clear(gcd);
   5642  1.1  mrg 			return res;
   5643  1.1  mrg 		}
   5644  1.1  mrg 	}
   5645  1.1  mrg 
   5646  1.1  mrg 	isl_int_clear(gcd);
   5647  1.1  mrg 	isl_basic_map_free(hull);
   5648  1.1  mrg 	return pw_multi_aff_from_map_check_div(map);
   5649  1.1  mrg error:
   5650  1.1  mrg 	isl_map_free(map);
   5651  1.1  mrg 	isl_basic_map_free(hull);
   5652  1.1  mrg 	return NULL;
   5653  1.1  mrg }
   5654  1.1  mrg 
   5655  1.1  mrg /* Try and create an isl_pw_multi_aff that is equivalent to the given isl_map.
   5656  1.1  mrg  *
   5657  1.1  mrg  * As a special case, we first check if all output dimensions are uniquely
   5658  1.1  mrg  * defined in terms of the parameters and input dimensions over the entire
   5659  1.1  mrg  * domain.  If so, we extract the desired isl_pw_multi_aff directly
   5660  1.1  mrg  * from the affine hull of "map" and its domain.
   5661  1.1  mrg  *
   5662  1.1  mrg  * Otherwise, continue with pw_multi_aff_from_map_check_strides for more
   5663  1.1  mrg  * special cases.
   5664  1.1  mrg  */
   5665  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_map(__isl_take isl_map *map)
   5666  1.1  mrg {
   5667  1.1  mrg 	isl_bool sv;
   5668  1.1  mrg 	isl_size n;
   5669  1.1  mrg 	isl_basic_map *hull;
   5670  1.1  mrg 
   5671  1.1  mrg 	n = isl_map_n_basic_map(map);
   5672  1.1  mrg 	if (n < 0)
   5673  1.1  mrg 		goto error;
   5674  1.1  mrg 
   5675  1.1  mrg 	if (n == 1) {
   5676  1.1  mrg 		hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
   5677  1.1  mrg 		hull = isl_basic_map_plain_affine_hull(hull);
   5678  1.1  mrg 		sv = isl_basic_map_plain_is_single_valued(hull);
   5679  1.1  mrg 		if (sv >= 0 && sv)
   5680  1.1  mrg 			return plain_pw_multi_aff_from_map(isl_map_domain(map),
   5681  1.1  mrg 							    hull);
   5682  1.1  mrg 		isl_basic_map_free(hull);
   5683  1.1  mrg 	}
   5684  1.1  mrg 	map = isl_map_detect_equalities(map);
   5685  1.1  mrg 	hull = isl_map_unshifted_simple_hull(isl_map_copy(map));
   5686  1.1  mrg 	sv = isl_basic_map_plain_is_single_valued(hull);
   5687  1.1  mrg 	if (sv >= 0 && sv)
   5688  1.1  mrg 		return plain_pw_multi_aff_from_map(isl_map_domain(map), hull);
   5689  1.1  mrg 	if (sv >= 0)
   5690  1.1  mrg 		return pw_multi_aff_from_map_check_strides(map, hull);
   5691  1.1  mrg 	isl_basic_map_free(hull);
   5692  1.1  mrg error:
   5693  1.1  mrg 	isl_map_free(map);
   5694  1.1  mrg 	return NULL;
   5695  1.1  mrg }
   5696  1.1  mrg 
   5697  1.1  mrg /* This function performs the same operation as isl_pw_multi_aff_from_map,
   5698  1.1  mrg  * but is considered as a function on an isl_map when exported.
   5699  1.1  mrg  */
   5700  1.1  mrg __isl_give isl_pw_multi_aff *isl_map_as_pw_multi_aff(__isl_take isl_map *map)
   5701  1.1  mrg {
   5702  1.1  mrg 	return isl_pw_multi_aff_from_map(map);
   5703  1.1  mrg }
   5704  1.1  mrg 
   5705  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_set(__isl_take isl_set *set)
   5706  1.1  mrg {
   5707  1.1  mrg 	return isl_pw_multi_aff_from_map(set);
   5708  1.1  mrg }
   5709  1.1  mrg 
   5710  1.1  mrg /* This function performs the same operation as isl_pw_multi_aff_from_set,
   5711  1.1  mrg  * but is considered as a function on an isl_set when exported.
   5712  1.1  mrg  */
   5713  1.1  mrg __isl_give isl_pw_multi_aff *isl_set_as_pw_multi_aff(__isl_take isl_set *set)
   5714  1.1  mrg {
   5715  1.1  mrg 	return isl_pw_multi_aff_from_set(set);
   5716  1.1  mrg }
   5717  1.1  mrg 
   5718  1.1  mrg /* Convert "map" into an isl_pw_multi_aff (if possible) and
   5719  1.1  mrg  * add it to *user.
   5720  1.1  mrg  */
   5721  1.1  mrg static isl_stat pw_multi_aff_from_map(__isl_take isl_map *map, void *user)
   5722  1.1  mrg {
   5723  1.1  mrg 	isl_union_pw_multi_aff **upma = user;
   5724  1.1  mrg 	isl_pw_multi_aff *pma;
   5725  1.1  mrg 
   5726  1.1  mrg 	pma = isl_pw_multi_aff_from_map(map);
   5727  1.1  mrg 	*upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
   5728  1.1  mrg 
   5729  1.1  mrg 	return *upma ? isl_stat_ok : isl_stat_error;
   5730  1.1  mrg }
   5731  1.1  mrg 
   5732  1.1  mrg /* Create an isl_union_pw_multi_aff with the given isl_aff on a universe
   5733  1.1  mrg  * domain.
   5734  1.1  mrg  */
   5735  1.1  mrg __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_aff(
   5736  1.1  mrg 	__isl_take isl_aff *aff)
   5737  1.1  mrg {
   5738  1.1  mrg 	isl_multi_aff *ma;
   5739  1.1  mrg 	isl_pw_multi_aff *pma;
   5740  1.1  mrg 
   5741  1.1  mrg 	ma = isl_multi_aff_from_aff(aff);
   5742  1.1  mrg 	pma = isl_pw_multi_aff_from_multi_aff(ma);
   5743  1.1  mrg 	return isl_union_pw_multi_aff_from_pw_multi_aff(pma);
   5744  1.1  mrg }
   5745  1.1  mrg 
   5746  1.1  mrg /* Try and create an isl_union_pw_multi_aff that is equivalent
   5747  1.1  mrg  * to the given isl_union_map.
   5748  1.1  mrg  * The isl_union_map is required to be single-valued in each space.
   5749  1.1  mrg  * Otherwise, an error is produced.
   5750  1.1  mrg  */
   5751  1.1  mrg __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_map(
   5752  1.1  mrg 	__isl_take isl_union_map *umap)
   5753  1.1  mrg {
   5754  1.1  mrg 	isl_space *space;
   5755  1.1  mrg 	isl_union_pw_multi_aff *upma;
   5756  1.1  mrg 
   5757  1.1  mrg 	space = isl_union_map_get_space(umap);
   5758  1.1  mrg 	upma = isl_union_pw_multi_aff_empty(space);
   5759  1.1  mrg 	if (isl_union_map_foreach_map(umap, &pw_multi_aff_from_map, &upma) < 0)
   5760  1.1  mrg 		upma = isl_union_pw_multi_aff_free(upma);
   5761  1.1  mrg 	isl_union_map_free(umap);
   5762  1.1  mrg 
   5763  1.1  mrg 	return upma;
   5764  1.1  mrg }
   5765  1.1  mrg 
   5766  1.1  mrg /* This function performs the same operation as
   5767  1.1  mrg  * isl_union_pw_multi_aff_from_union_map,
   5768  1.1  mrg  * but is considered as a function on an isl_union_map when exported.
   5769  1.1  mrg  */
   5770  1.1  mrg __isl_give isl_union_pw_multi_aff *isl_union_map_as_union_pw_multi_aff(
   5771  1.1  mrg 	__isl_take isl_union_map *umap)
   5772  1.1  mrg {
   5773  1.1  mrg 	return isl_union_pw_multi_aff_from_union_map(umap);
   5774  1.1  mrg }
   5775  1.1  mrg 
   5776  1.1  mrg /* Try and create an isl_union_pw_multi_aff that is equivalent
   5777  1.1  mrg  * to the given isl_union_set.
   5778  1.1  mrg  * The isl_union_set is required to be a singleton in each space.
   5779  1.1  mrg  * Otherwise, an error is produced.
   5780  1.1  mrg  */
   5781  1.1  mrg __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_set(
   5782  1.1  mrg 	__isl_take isl_union_set *uset)
   5783  1.1  mrg {
   5784  1.1  mrg 	return isl_union_pw_multi_aff_from_union_map(uset);
   5785  1.1  mrg }
   5786  1.1  mrg 
   5787  1.1  mrg /* Return the piecewise affine expression "set ? 1 : 0".
   5788  1.1  mrg  */
   5789  1.1  mrg __isl_give isl_pw_aff *isl_set_indicator_function(__isl_take isl_set *set)
   5790  1.1  mrg {
   5791  1.1  mrg 	isl_pw_aff *pa;
   5792  1.1  mrg 	isl_space *space = isl_set_get_space(set);
   5793  1.1  mrg 	isl_local_space *ls = isl_local_space_from_space(space);
   5794  1.1  mrg 	isl_aff *zero = isl_aff_zero_on_domain(isl_local_space_copy(ls));
   5795  1.1  mrg 	isl_aff *one = isl_aff_zero_on_domain(ls);
   5796  1.1  mrg 
   5797  1.1  mrg 	one = isl_aff_add_constant_si(one, 1);
   5798  1.1  mrg 	pa = isl_pw_aff_alloc(isl_set_copy(set), one);
   5799  1.1  mrg 	set = isl_set_complement(set);
   5800  1.1  mrg 	pa = isl_pw_aff_add_disjoint(pa, isl_pw_aff_alloc(set, zero));
   5801  1.1  mrg 
   5802  1.1  mrg 	return pa;
   5803  1.1  mrg }
   5804  1.1  mrg 
   5805  1.1  mrg /* Plug in "subs" for dimension "type", "pos" of "aff".
   5806  1.1  mrg  *
   5807  1.1  mrg  * Let i be the dimension to replace and let "subs" be of the form
   5808  1.1  mrg  *
   5809  1.1  mrg  *	f/d
   5810  1.1  mrg  *
   5811  1.1  mrg  * and "aff" of the form
   5812  1.1  mrg  *
   5813  1.1  mrg  *	(a i + g)/m
   5814  1.1  mrg  *
   5815  1.1  mrg  * The result is
   5816  1.1  mrg  *
   5817  1.1  mrg  *	(a f + d g')/(m d)
   5818  1.1  mrg  *
   5819  1.1  mrg  * where g' is the result of plugging in "subs" in each of the integer
   5820  1.1  mrg  * divisions in g.
   5821  1.1  mrg  */
   5822  1.1  mrg __isl_give isl_aff *isl_aff_substitute(__isl_take isl_aff *aff,
   5823  1.1  mrg 	enum isl_dim_type type, unsigned pos, __isl_keep isl_aff *subs)
   5824  1.1  mrg {
   5825  1.1  mrg 	isl_ctx *ctx;
   5826  1.1  mrg 	isl_int v;
   5827  1.1  mrg 	isl_size n_div;
   5828  1.1  mrg 
   5829  1.1  mrg 	aff = isl_aff_cow(aff);
   5830  1.1  mrg 	if (!aff || !subs)
   5831  1.1  mrg 		return isl_aff_free(aff);
   5832  1.1  mrg 
   5833  1.1  mrg 	ctx = isl_aff_get_ctx(aff);
   5834  1.1  mrg 	if (!isl_space_is_equal(aff->ls->dim, subs->ls->dim))
   5835  1.1  mrg 		isl_die(ctx, isl_error_invalid,
   5836  1.1  mrg 			"spaces don't match", return isl_aff_free(aff));
   5837  1.1  mrg 	n_div = isl_aff_domain_dim(subs, isl_dim_div);
   5838  1.1  mrg 	if (n_div < 0)
   5839  1.1  mrg 		return isl_aff_free(aff);
   5840  1.1  mrg 	if (n_div != 0)
   5841  1.1  mrg 		isl_die(ctx, isl_error_unsupported,
   5842  1.1  mrg 			"cannot handle divs yet", return isl_aff_free(aff));
   5843  1.1  mrg 
   5844  1.1  mrg 	aff->ls = isl_local_space_substitute(aff->ls, type, pos, subs);
   5845  1.1  mrg 	if (!aff->ls)
   5846  1.1  mrg 		return isl_aff_free(aff);
   5847  1.1  mrg 
   5848  1.1  mrg 	aff->v = isl_vec_cow(aff->v);
   5849  1.1  mrg 	if (!aff->v)
   5850  1.1  mrg 		return isl_aff_free(aff);
   5851  1.1  mrg 
   5852  1.1  mrg 	pos += isl_local_space_offset(aff->ls, type);
   5853  1.1  mrg 
   5854  1.1  mrg 	isl_int_init(v);
   5855  1.1  mrg 	isl_seq_substitute(aff->v->el, pos, subs->v->el,
   5856  1.1  mrg 			    aff->v->size, subs->v->size, v);
   5857  1.1  mrg 	isl_int_clear(v);
   5858  1.1  mrg 
   5859  1.1  mrg 	return aff;
   5860  1.1  mrg }
   5861  1.1  mrg 
   5862  1.1  mrg /* Plug in "subs" for dimension "type", "pos" in each of the affine
   5863  1.1  mrg  * expressions in "maff".
   5864  1.1  mrg  */
   5865  1.1  mrg __isl_give isl_multi_aff *isl_multi_aff_substitute(
   5866  1.1  mrg 	__isl_take isl_multi_aff *maff, enum isl_dim_type type, unsigned pos,
   5867  1.1  mrg 	__isl_keep isl_aff *subs)
   5868  1.1  mrg {
   5869  1.1  mrg 	isl_size n;
   5870  1.1  mrg 	int i;
   5871  1.1  mrg 
   5872  1.1  mrg 	n = isl_multi_aff_size(maff);
   5873  1.1  mrg 	if (n < 0 || !subs)
   5874  1.1  mrg 		return isl_multi_aff_free(maff);
   5875  1.1  mrg 
   5876  1.1  mrg 	if (type == isl_dim_in)
   5877  1.1  mrg 		type = isl_dim_set;
   5878  1.1  mrg 
   5879  1.1  mrg 	for (i = 0; i < n; ++i) {
   5880  1.1  mrg 		isl_aff *aff;
   5881  1.1  mrg 
   5882  1.1  mrg 		aff = isl_multi_aff_take_at(maff, i);
   5883  1.1  mrg 		aff = isl_aff_substitute(aff, type, pos, subs);
   5884  1.1  mrg 		maff = isl_multi_aff_restore_at(maff, i, aff);
   5885  1.1  mrg 	}
   5886  1.1  mrg 
   5887  1.1  mrg 	return maff;
   5888  1.1  mrg }
   5889  1.1  mrg 
   5890  1.1  mrg /* Plug in "subs" for input dimension "pos" of "pma".
   5891  1.1  mrg  *
   5892  1.1  mrg  * pma is of the form
   5893  1.1  mrg  *
   5894  1.1  mrg  *	A_i(v) -> M_i(v)
   5895  1.1  mrg  *
   5896  1.1  mrg  * while subs is of the form
   5897  1.1  mrg  *
   5898  1.1  mrg  *	v' = B_j(v) -> S_j
   5899  1.1  mrg  *
   5900  1.1  mrg  * Each pair i,j such that C_ij = A_i \cap B_i is non-empty
   5901  1.1  mrg  * has a contribution in the result, in particular
   5902  1.1  mrg  *
   5903  1.1  mrg  *	C_ij(S_j) -> M_i(S_j)
   5904  1.1  mrg  *
   5905  1.1  mrg  * Note that plugging in S_j in C_ij may also result in an empty set
   5906  1.1  mrg  * and this contribution should simply be discarded.
   5907  1.1  mrg  */
   5908  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_substitute(
   5909  1.1  mrg 	__isl_take isl_pw_multi_aff *pma, unsigned pos,
   5910  1.1  mrg 	__isl_keep isl_pw_aff *subs)
   5911  1.1  mrg {
   5912  1.1  mrg 	int i, j, n;
   5913  1.1  mrg 	isl_pw_multi_aff *res;
   5914  1.1  mrg 
   5915  1.1  mrg 	if (!pma || !subs)
   5916  1.1  mrg 		return isl_pw_multi_aff_free(pma);
   5917  1.1  mrg 
   5918  1.1  mrg 	n = pma->n * subs->n;
   5919  1.1  mrg 	res = isl_pw_multi_aff_alloc_size(isl_space_copy(pma->dim), n);
   5920  1.1  mrg 
   5921  1.1  mrg 	for (i = 0; i < pma->n; ++i) {
   5922  1.1  mrg 		for (j = 0; j < subs->n; ++j) {
   5923  1.1  mrg 			isl_set *common;
   5924  1.1  mrg 			isl_multi_aff *res_ij;
   5925  1.1  mrg 			int empty;
   5926  1.1  mrg 
   5927  1.1  mrg 			common = isl_set_intersect(
   5928  1.1  mrg 					isl_set_copy(pma->p[i].set),
   5929  1.1  mrg 					isl_set_copy(subs->p[j].set));
   5930  1.1  mrg 			common = isl_set_substitute(common,
   5931  1.1  mrg 					pos, subs->p[j].aff);
   5932  1.1  mrg 			empty = isl_set_plain_is_empty(common);
   5933  1.1  mrg 			if (empty < 0 || empty) {
   5934  1.1  mrg 				isl_set_free(common);
   5935  1.1  mrg 				if (empty < 0)
   5936  1.1  mrg 					goto error;
   5937  1.1  mrg 				continue;
   5938  1.1  mrg 			}
   5939  1.1  mrg 
   5940  1.1  mrg 			res_ij = isl_multi_aff_substitute(
   5941  1.1  mrg 					isl_multi_aff_copy(pma->p[i].maff),
   5942  1.1  mrg 					isl_dim_in, pos, subs->p[j].aff);
   5943  1.1  mrg 
   5944  1.1  mrg 			res = isl_pw_multi_aff_add_piece(res, common, res_ij);
   5945  1.1  mrg 		}
   5946  1.1  mrg 	}
   5947  1.1  mrg 
   5948  1.1  mrg 	isl_pw_multi_aff_free(pma);
   5949  1.1  mrg 	return res;
   5950  1.1  mrg error:
   5951  1.1  mrg 	isl_pw_multi_aff_free(pma);
   5952  1.1  mrg 	isl_pw_multi_aff_free(res);
   5953  1.1  mrg 	return NULL;
   5954  1.1  mrg }
   5955  1.1  mrg 
   5956  1.1  mrg /* Compute the preimage of a range of dimensions in the affine expression "src"
   5957  1.1  mrg  * under "ma" and put the result in "dst".  The number of dimensions in "src"
   5958  1.1  mrg  * that precede the range is given by "n_before".  The number of dimensions
   5959  1.1  mrg  * in the range is given by the number of output dimensions of "ma".
   5960  1.1  mrg  * The number of dimensions that follow the range is given by "n_after".
   5961  1.1  mrg  * If "has_denom" is set (to one),
   5962  1.1  mrg  * then "src" and "dst" have an extra initial denominator.
   5963  1.1  mrg  * "n_div_ma" is the number of existentials in "ma"
   5964  1.1  mrg  * "n_div_bset" is the number of existentials in "src"
   5965  1.1  mrg  * The resulting "dst" (which is assumed to have been allocated by
   5966  1.1  mrg  * the caller) contains coefficients for both sets of existentials,
   5967  1.1  mrg  * first those in "ma" and then those in "src".
   5968  1.1  mrg  * f, c1, c2 and g are temporary objects that have been initialized
   5969  1.1  mrg  * by the caller.
   5970  1.1  mrg  *
   5971  1.1  mrg  * Let src represent the expression
   5972  1.1  mrg  *
   5973  1.1  mrg  *	(a(p) + f_u u + b v + f_w w + c(divs))/d
   5974  1.1  mrg  *
   5975  1.1  mrg  * and let ma represent the expressions
   5976  1.1  mrg  *
   5977  1.1  mrg  *	v_i = (r_i(p) + s_i(y) + t_i(divs'))/m_i
   5978  1.1  mrg  *
   5979  1.1  mrg  * We start out with the following expression for dst:
   5980  1.1  mrg  *
   5981  1.1  mrg  *	(a(p) + f_u u + 0 y + f_w w + 0 divs' + c(divs) + f \sum_i b_i v_i)/d
   5982  1.1  mrg  *
   5983  1.1  mrg  * with the multiplication factor f initially equal to 1
   5984  1.1  mrg  * and f \sum_i b_i v_i kept separately.
   5985  1.1  mrg  * For each x_i that we substitute, we multiply the numerator
   5986  1.1  mrg  * (and denominator) of dst by c_1 = m_i and add the numerator
   5987  1.1  mrg  * of the x_i expression multiplied by c_2 = f b_i,
   5988  1.1  mrg  * after removing the common factors of c_1 and c_2.
   5989  1.1  mrg  * The multiplication factor f also needs to be multiplied by c_1
   5990  1.1  mrg  * for the next x_j, j > i.
   5991  1.1  mrg  */
   5992  1.1  mrg isl_stat isl_seq_preimage(isl_int *dst, isl_int *src,
   5993  1.1  mrg 	__isl_keep isl_multi_aff *ma, int n_before, int n_after,
   5994  1.1  mrg 	int n_div_ma, int n_div_bmap,
   5995  1.1  mrg 	isl_int f, isl_int c1, isl_int c2, isl_int g, int has_denom)
   5996  1.1  mrg {
   5997  1.1  mrg 	int i;
   5998  1.1  mrg 	isl_size n_param, n_in, n_out;
   5999  1.1  mrg 	int o_dst, o_src;
   6000  1.1  mrg 
   6001  1.1  mrg 	n_param = isl_multi_aff_dim(ma, isl_dim_param);
   6002  1.1  mrg 	n_in = isl_multi_aff_dim(ma, isl_dim_in);
   6003  1.1  mrg 	n_out = isl_multi_aff_dim(ma, isl_dim_out);
   6004  1.1  mrg 	if (n_param < 0 || n_in < 0 || n_out < 0)
   6005  1.1  mrg 		return isl_stat_error;
   6006  1.1  mrg 
   6007  1.1  mrg 	isl_seq_cpy(dst, src, has_denom + 1 + n_param + n_before);
   6008  1.1  mrg 	o_dst = o_src = has_denom + 1 + n_param + n_before;
   6009  1.1  mrg 	isl_seq_clr(dst + o_dst, n_in);
   6010  1.1  mrg 	o_dst += n_in;
   6011  1.1  mrg 	o_src += n_out;
   6012  1.1  mrg 	isl_seq_cpy(dst + o_dst, src + o_src, n_after);
   6013  1.1  mrg 	o_dst += n_after;
   6014  1.1  mrg 	o_src += n_after;
   6015  1.1  mrg 	isl_seq_clr(dst + o_dst, n_div_ma);
   6016  1.1  mrg 	o_dst += n_div_ma;
   6017  1.1  mrg 	isl_seq_cpy(dst + o_dst, src + o_src, n_div_bmap);
   6018  1.1  mrg 
   6019  1.1  mrg 	isl_int_set_si(f, 1);
   6020  1.1  mrg 
   6021  1.1  mrg 	for (i = 0; i < n_out; ++i) {
   6022  1.1  mrg 		int offset = has_denom + 1 + n_param + n_before + i;
   6023  1.1  mrg 
   6024  1.1  mrg 		if (isl_int_is_zero(src[offset]))
   6025  1.1  mrg 			continue;
   6026  1.1  mrg 		isl_int_set(c1, ma->u.p[i]->v->el[0]);
   6027  1.1  mrg 		isl_int_mul(c2, f, src[offset]);
   6028  1.1  mrg 		isl_int_gcd(g, c1, c2);
   6029  1.1  mrg 		isl_int_divexact(c1, c1, g);
   6030  1.1  mrg 		isl_int_divexact(c2, c2, g);
   6031  1.1  mrg 
   6032  1.1  mrg 		isl_int_mul(f, f, c1);
   6033  1.1  mrg 		o_dst = has_denom;
   6034  1.1  mrg 		o_src = 1;
   6035  1.1  mrg 		isl_seq_combine(dst + o_dst, c1, dst + o_dst,
   6036  1.1  mrg 				c2, ma->u.p[i]->v->el + o_src, 1 + n_param);
   6037  1.1  mrg 		o_dst += 1 + n_param;
   6038  1.1  mrg 		o_src += 1 + n_param;
   6039  1.1  mrg 		isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_before);
   6040  1.1  mrg 		o_dst += n_before;
   6041  1.1  mrg 		isl_seq_combine(dst + o_dst, c1, dst + o_dst,
   6042  1.1  mrg 				c2, ma->u.p[i]->v->el + o_src, n_in);
   6043  1.1  mrg 		o_dst += n_in;
   6044  1.1  mrg 		o_src += n_in;
   6045  1.1  mrg 		isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_after);
   6046  1.1  mrg 		o_dst += n_after;
   6047  1.1  mrg 		isl_seq_combine(dst + o_dst, c1, dst + o_dst,
   6048  1.1  mrg 				c2, ma->u.p[i]->v->el + o_src, n_div_ma);
   6049  1.1  mrg 		o_dst += n_div_ma;
   6050  1.1  mrg 		o_src += n_div_ma;
   6051  1.1  mrg 		isl_seq_scale(dst + o_dst, dst + o_dst, c1, n_div_bmap);
   6052  1.1  mrg 		if (has_denom)
   6053  1.1  mrg 			isl_int_mul(dst[0], dst[0], c1);
   6054  1.1  mrg 	}
   6055  1.1  mrg 
   6056  1.1  mrg 	return isl_stat_ok;
   6057  1.1  mrg }
   6058  1.1  mrg 
   6059  1.1  mrg /* Compute the pullback of "aff" by the function represented by "ma".
   6060  1.1  mrg  * In other words, plug in "ma" in "aff".  The result is an affine expression
   6061  1.1  mrg  * defined over the domain space of "ma".
   6062  1.1  mrg  *
   6063  1.1  mrg  * If "aff" is represented by
   6064  1.1  mrg  *
   6065  1.1  mrg  *	(a(p) + b x + c(divs))/d
   6066  1.1  mrg  *
   6067  1.1  mrg  * and ma is represented by
   6068  1.1  mrg  *
   6069  1.1  mrg  *	x = D(p) + F(y) + G(divs')
   6070  1.1  mrg  *
   6071  1.1  mrg  * then the result is
   6072  1.1  mrg  *
   6073  1.1  mrg  *	(a(p) + b D(p) + b F(y) + b G(divs') + c(divs))/d
   6074  1.1  mrg  *
   6075  1.1  mrg  * The divs in the local space of the input are similarly adjusted
   6076  1.1  mrg  * through a call to isl_local_space_preimage_multi_aff.
   6077  1.1  mrg  */
   6078  1.1  mrg __isl_give isl_aff *isl_aff_pullback_multi_aff(__isl_take isl_aff *aff,
   6079  1.1  mrg 	__isl_take isl_multi_aff *ma)
   6080  1.1  mrg {
   6081  1.1  mrg 	isl_aff *res = NULL;
   6082  1.1  mrg 	isl_local_space *ls;
   6083  1.1  mrg 	isl_size n_div_aff, n_div_ma;
   6084  1.1  mrg 	isl_int f, c1, c2, g;
   6085  1.1  mrg 
   6086  1.1  mrg 	ma = isl_multi_aff_align_divs(ma);
   6087  1.1  mrg 	if (!aff || !ma)
   6088  1.1  mrg 		goto error;
   6089  1.1  mrg 
   6090  1.1  mrg 	n_div_aff = isl_aff_dim(aff, isl_dim_div);
   6091  1.1  mrg 	n_div_ma = ma->n ? isl_aff_dim(ma->u.p[0], isl_dim_div) : 0;
   6092  1.1  mrg 	if (n_div_aff < 0 || n_div_ma < 0)
   6093  1.1  mrg 		goto error;
   6094  1.1  mrg 
   6095  1.1  mrg 	ls = isl_aff_get_domain_local_space(aff);
   6096  1.1  mrg 	ls = isl_local_space_preimage_multi_aff(ls, isl_multi_aff_copy(ma));
   6097  1.1  mrg 	res = isl_aff_alloc(ls);
   6098  1.1  mrg 	if (!res)
   6099  1.1  mrg 		goto error;
   6100  1.1  mrg 
   6101  1.1  mrg 	isl_int_init(f);
   6102  1.1  mrg 	isl_int_init(c1);
   6103  1.1  mrg 	isl_int_init(c2);
   6104  1.1  mrg 	isl_int_init(g);
   6105  1.1  mrg 
   6106  1.1  mrg 	if (isl_seq_preimage(res->v->el, aff->v->el, ma, 0, 0,
   6107  1.1  mrg 			    n_div_ma, n_div_aff, f, c1, c2, g, 1) < 0)
   6108  1.1  mrg 		res = isl_aff_free(res);
   6109  1.1  mrg 
   6110  1.1  mrg 	isl_int_clear(f);
   6111  1.1  mrg 	isl_int_clear(c1);
   6112  1.1  mrg 	isl_int_clear(c2);
   6113  1.1  mrg 	isl_int_clear(g);
   6114  1.1  mrg 
   6115  1.1  mrg 	isl_aff_free(aff);
   6116  1.1  mrg 	isl_multi_aff_free(ma);
   6117  1.1  mrg 	res = isl_aff_normalize(res);
   6118  1.1  mrg 	return res;
   6119  1.1  mrg error:
   6120  1.1  mrg 	isl_aff_free(aff);
   6121  1.1  mrg 	isl_multi_aff_free(ma);
   6122  1.1  mrg 	isl_aff_free(res);
   6123  1.1  mrg 	return NULL;
   6124  1.1  mrg }
   6125  1.1  mrg 
   6126  1.1  mrg /* Compute the pullback of "aff1" by the function represented by "aff2".
   6127  1.1  mrg  * In other words, plug in "aff2" in "aff1".  The result is an affine expression
   6128  1.1  mrg  * defined over the domain space of "aff1".
   6129  1.1  mrg  *
   6130  1.1  mrg  * The domain of "aff1" should match the range of "aff2", which means
   6131  1.1  mrg  * that it should be single-dimensional.
   6132  1.1  mrg  */
   6133  1.1  mrg __isl_give isl_aff *isl_aff_pullback_aff(__isl_take isl_aff *aff1,
   6134  1.1  mrg 	__isl_take isl_aff *aff2)
   6135  1.1  mrg {
   6136  1.1  mrg 	isl_multi_aff *ma;
   6137  1.1  mrg 
   6138  1.1  mrg 	ma = isl_multi_aff_from_aff(aff2);
   6139  1.1  mrg 	return isl_aff_pullback_multi_aff(aff1, ma);
   6140  1.1  mrg }
   6141  1.1  mrg 
   6142  1.1  mrg /* Compute the pullback of "ma1" by the function represented by "ma2".
   6143  1.1  mrg  * In other words, plug in "ma2" in "ma1".
   6144  1.1  mrg  */
   6145  1.1  mrg __isl_give isl_multi_aff *isl_multi_aff_pullback_multi_aff(
   6146  1.1  mrg 	__isl_take isl_multi_aff *ma1, __isl_take isl_multi_aff *ma2)
   6147  1.1  mrg {
   6148  1.1  mrg 	int i;
   6149  1.1  mrg 	isl_size n;
   6150  1.1  mrg 	isl_space *space = NULL;
   6151  1.1  mrg 
   6152  1.1  mrg 	isl_multi_aff_align_params_bin(&ma1, &ma2);
   6153  1.1  mrg 	ma2 = isl_multi_aff_align_divs(ma2);
   6154  1.1  mrg 	n = isl_multi_aff_size(ma1);
   6155  1.1  mrg 	if (n < 0 || !ma2)
   6156  1.1  mrg 		goto error;
   6157  1.1  mrg 
   6158  1.1  mrg 	space = isl_space_join(isl_multi_aff_get_space(ma2),
   6159  1.1  mrg 				isl_multi_aff_get_space(ma1));
   6160  1.1  mrg 
   6161  1.1  mrg 	for (i = 0; i < n; ++i) {
   6162  1.1  mrg 		isl_aff *aff;
   6163  1.1  mrg 
   6164  1.1  mrg 		aff = isl_multi_aff_take_at(ma1, i);
   6165  1.1  mrg 		aff = isl_aff_pullback_multi_aff(aff, isl_multi_aff_copy(ma2));
   6166  1.1  mrg 		ma1 = isl_multi_aff_restore_at(ma1, i, aff);
   6167  1.1  mrg 	}
   6168  1.1  mrg 
   6169  1.1  mrg 	ma1 = isl_multi_aff_reset_space(ma1, space);
   6170  1.1  mrg 	isl_multi_aff_free(ma2);
   6171  1.1  mrg 	return ma1;
   6172  1.1  mrg error:
   6173  1.1  mrg 	isl_space_free(space);
   6174  1.1  mrg 	isl_multi_aff_free(ma2);
   6175  1.1  mrg 	isl_multi_aff_free(ma1);
   6176  1.1  mrg 	return NULL;
   6177  1.1  mrg }
   6178  1.1  mrg 
   6179  1.1  mrg /* Extend the local space of "dst" to include the divs
   6180  1.1  mrg  * in the local space of "src".
   6181  1.1  mrg  *
   6182  1.1  mrg  * If "src" does not have any divs or if the local spaces of "dst" and
   6183  1.1  mrg  * "src" are the same, then no extension is required.
   6184  1.1  mrg  */
   6185  1.1  mrg __isl_give isl_aff *isl_aff_align_divs(__isl_take isl_aff *dst,
   6186  1.1  mrg 	__isl_keep isl_aff *src)
   6187  1.1  mrg {
   6188  1.1  mrg 	isl_ctx *ctx;
   6189  1.1  mrg 	isl_size src_n_div, dst_n_div;
   6190  1.1  mrg 	int *exp1 = NULL;
   6191  1.1  mrg 	int *exp2 = NULL;
   6192  1.1  mrg 	isl_bool equal;
   6193  1.1  mrg 	isl_mat *div;
   6194  1.1  mrg 
   6195  1.1  mrg 	if (!src || !dst)
   6196  1.1  mrg 		return isl_aff_free(dst);
   6197  1.1  mrg 
   6198  1.1  mrg 	ctx = isl_aff_get_ctx(src);
   6199  1.1  mrg 	equal = isl_local_space_has_equal_space(src->ls, dst->ls);
   6200  1.1  mrg 	if (equal < 0)
   6201  1.1  mrg 		return isl_aff_free(dst);
   6202  1.1  mrg 	if (!equal)
   6203  1.1  mrg 		isl_die(ctx, isl_error_invalid,
   6204  1.1  mrg 			"spaces don't match", goto error);
   6205  1.1  mrg 
   6206  1.1  mrg 	src_n_div = isl_aff_domain_dim(src, isl_dim_div);
   6207  1.1  mrg 	dst_n_div = isl_aff_domain_dim(dst, isl_dim_div);
   6208  1.1  mrg 	if (src_n_div == 0)
   6209  1.1  mrg 		return dst;
   6210  1.1  mrg 	equal = isl_local_space_is_equal(src->ls, dst->ls);
   6211  1.1  mrg 	if (equal < 0 || src_n_div < 0 || dst_n_div < 0)
   6212  1.1  mrg 		return isl_aff_free(dst);
   6213  1.1  mrg 	if (equal)
   6214  1.1  mrg 		return dst;
   6215  1.1  mrg 
   6216  1.1  mrg 	exp1 = isl_alloc_array(ctx, int, src_n_div);
   6217  1.1  mrg 	exp2 = isl_alloc_array(ctx, int, dst_n_div);
   6218  1.1  mrg 	if (!exp1 || (dst_n_div && !exp2))
   6219  1.1  mrg 		goto error;
   6220  1.1  mrg 
   6221  1.1  mrg 	div = isl_merge_divs(src->ls->div, dst->ls->div, exp1, exp2);
   6222  1.1  mrg 	dst = isl_aff_expand_divs(dst, div, exp2);
   6223  1.1  mrg 	free(exp1);
   6224  1.1  mrg 	free(exp2);
   6225  1.1  mrg 
   6226  1.1  mrg 	return dst;
   6227  1.1  mrg error:
   6228  1.1  mrg 	free(exp1);
   6229  1.1  mrg 	free(exp2);
   6230  1.1  mrg 	return isl_aff_free(dst);
   6231  1.1  mrg }
   6232  1.1  mrg 
   6233  1.1  mrg /* Adjust the local spaces of the affine expressions in "maff"
   6234  1.1  mrg  * such that they all have the save divs.
   6235  1.1  mrg  */
   6236  1.1  mrg __isl_give isl_multi_aff *isl_multi_aff_align_divs(
   6237  1.1  mrg 	__isl_take isl_multi_aff *maff)
   6238  1.1  mrg {
   6239  1.1  mrg 	isl_aff *aff_0;
   6240  1.1  mrg 	isl_size n;
   6241  1.1  mrg 	int i;
   6242  1.1  mrg 
   6243  1.1  mrg 	n = isl_multi_aff_size(maff);
   6244  1.1  mrg 	if (n < 0)
   6245  1.1  mrg 		return isl_multi_aff_free(maff);
   6246  1.1  mrg 	if (n <= 1)
   6247  1.1  mrg 		return maff;
   6248  1.1  mrg 
   6249  1.1  mrg 	aff_0 = isl_multi_aff_take_at(maff, 0);
   6250  1.1  mrg 	for (i = 1; i < n; ++i) {
   6251  1.1  mrg 		isl_aff *aff_i;
   6252  1.1  mrg 
   6253  1.1  mrg 		aff_i = isl_multi_aff_peek_at(maff, i);
   6254  1.1  mrg 		aff_0 = isl_aff_align_divs(aff_0, aff_i);
   6255  1.1  mrg 	}
   6256  1.1  mrg 	maff = isl_multi_aff_restore_at(maff, 0, aff_0);
   6257  1.1  mrg 
   6258  1.1  mrg 	aff_0 = isl_multi_aff_peek_at(maff, 0);
   6259  1.1  mrg 	for (i = 1; i < n; ++i) {
   6260  1.1  mrg 		isl_aff *aff_i;
   6261  1.1  mrg 
   6262  1.1  mrg 		aff_i = isl_multi_aff_take_at(maff, i);
   6263  1.1  mrg 		aff_i = isl_aff_align_divs(aff_i, aff_0);
   6264  1.1  mrg 		maff = isl_multi_aff_restore_at(maff, i, aff_i);
   6265  1.1  mrg 	}
   6266  1.1  mrg 
   6267  1.1  mrg 	return maff;
   6268  1.1  mrg }
   6269  1.1  mrg 
   6270  1.1  mrg __isl_give isl_aff *isl_aff_lift(__isl_take isl_aff *aff)
   6271  1.1  mrg {
   6272  1.1  mrg 	aff = isl_aff_cow(aff);
   6273  1.1  mrg 	if (!aff)
   6274  1.1  mrg 		return NULL;
   6275  1.1  mrg 
   6276  1.1  mrg 	aff->ls = isl_local_space_lift(aff->ls);
   6277  1.1  mrg 	if (!aff->ls)
   6278  1.1  mrg 		return isl_aff_free(aff);
   6279  1.1  mrg 
   6280  1.1  mrg 	return aff;
   6281  1.1  mrg }
   6282  1.1  mrg 
   6283  1.1  mrg /* Lift "maff" to a space with extra dimensions such that the result
   6284  1.1  mrg  * has no more existentially quantified variables.
   6285  1.1  mrg  * If "ls" is not NULL, then *ls is assigned the local space that lies
   6286  1.1  mrg  * at the basis of the lifting applied to "maff".
   6287  1.1  mrg  */
   6288  1.1  mrg __isl_give isl_multi_aff *isl_multi_aff_lift(__isl_take isl_multi_aff *maff,
   6289  1.1  mrg 	__isl_give isl_local_space **ls)
   6290  1.1  mrg {
   6291  1.1  mrg 	int i;
   6292  1.1  mrg 	isl_space *space;
   6293  1.1  mrg 	isl_aff *aff;
   6294  1.1  mrg 	isl_size n, n_div;
   6295  1.1  mrg 
   6296  1.1  mrg 	if (ls)
   6297  1.1  mrg 		*ls = NULL;
   6298  1.1  mrg 
   6299  1.1  mrg 	n = isl_multi_aff_size(maff);
   6300  1.1  mrg 	if (n < 0)
   6301  1.1  mrg 		return isl_multi_aff_free(maff);
   6302  1.1  mrg 
   6303  1.1  mrg 	if (n == 0) {
   6304  1.1  mrg 		if (ls) {
   6305  1.1  mrg 			isl_space *space = isl_multi_aff_get_domain_space(maff);
   6306  1.1  mrg 			*ls = isl_local_space_from_space(space);
   6307  1.1  mrg 			if (!*ls)
   6308  1.1  mrg 				return isl_multi_aff_free(maff);
   6309  1.1  mrg 		}
   6310  1.1  mrg 		return maff;
   6311  1.1  mrg 	}
   6312  1.1  mrg 
   6313  1.1  mrg 	maff = isl_multi_aff_align_divs(maff);
   6314  1.1  mrg 
   6315  1.1  mrg 	aff = isl_multi_aff_peek_at(maff, 0);
   6316  1.1  mrg 	n_div = isl_aff_dim(aff, isl_dim_div);
   6317  1.1  mrg 	if (n_div < 0)
   6318  1.1  mrg 		return isl_multi_aff_free(maff);
   6319  1.1  mrg 	space = isl_multi_aff_get_space(maff);
   6320  1.1  mrg 	space = isl_space_lift(isl_space_domain(space), n_div);
   6321  1.1  mrg 	space = isl_space_extend_domain_with_range(space,
   6322  1.1  mrg 						isl_multi_aff_get_space(maff));
   6323  1.1  mrg 	maff = isl_multi_aff_restore_space(maff, space);
   6324  1.1  mrg 
   6325  1.1  mrg 	if (ls) {
   6326  1.1  mrg 		aff = isl_multi_aff_peek_at(maff, 0);
   6327  1.1  mrg 		*ls = isl_aff_get_domain_local_space(aff);
   6328  1.1  mrg 		if (!*ls)
   6329  1.1  mrg 			return isl_multi_aff_free(maff);
   6330  1.1  mrg 	}
   6331  1.1  mrg 
   6332  1.1  mrg 	for (i = 0; i < n; ++i) {
   6333  1.1  mrg 		aff = isl_multi_aff_take_at(maff, i);
   6334  1.1  mrg 		aff = isl_aff_lift(aff);
   6335  1.1  mrg 		maff = isl_multi_aff_restore_at(maff, i, aff);
   6336  1.1  mrg 	}
   6337  1.1  mrg 
   6338  1.1  mrg 	return maff;
   6339  1.1  mrg }
   6340  1.1  mrg 
   6341  1.1  mrg #undef TYPE
   6342  1.1  mrg #define TYPE	isl_pw_multi_aff
   6343  1.1  mrg static
   6344  1.1  mrg #include "check_type_range_templ.c"
   6345  1.1  mrg 
   6346  1.1  mrg /* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma".
   6347  1.1  mrg  */
   6348  1.1  mrg __isl_give isl_pw_aff *isl_pw_multi_aff_get_at(
   6349  1.1  mrg 	__isl_keep isl_pw_multi_aff *pma, int pos)
   6350  1.1  mrg {
   6351  1.1  mrg 	int i;
   6352  1.1  mrg 	isl_size n_out;
   6353  1.1  mrg 	isl_space *space;
   6354  1.1  mrg 	isl_pw_aff *pa;
   6355  1.1  mrg 
   6356  1.1  mrg 	if (isl_pw_multi_aff_check_range(pma, isl_dim_out, pos, 1) < 0)
   6357  1.1  mrg 		return NULL;
   6358  1.1  mrg 
   6359  1.1  mrg 	n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
   6360  1.1  mrg 	if (n_out < 0)
   6361  1.1  mrg 		return NULL;
   6362  1.1  mrg 
   6363  1.1  mrg 	space = isl_pw_multi_aff_get_space(pma);
   6364  1.1  mrg 	space = isl_space_drop_dims(space, isl_dim_out,
   6365  1.1  mrg 				    pos + 1, n_out - pos - 1);
   6366  1.1  mrg 	space = isl_space_drop_dims(space, isl_dim_out, 0, pos);
   6367  1.1  mrg 
   6368  1.1  mrg 	pa = isl_pw_aff_alloc_size(space, pma->n);
   6369  1.1  mrg 	for (i = 0; i < pma->n; ++i) {
   6370  1.1  mrg 		isl_aff *aff;
   6371  1.1  mrg 		aff = isl_multi_aff_get_aff(pma->p[i].maff, pos);
   6372  1.1  mrg 		pa = isl_pw_aff_add_piece(pa, isl_set_copy(pma->p[i].set), aff);
   6373  1.1  mrg 	}
   6374  1.1  mrg 
   6375  1.1  mrg 	return pa;
   6376  1.1  mrg }
   6377  1.1  mrg 
   6378  1.1  mrg /* This is an alternative name for the function above.
   6379  1.1  mrg  */
   6380  1.1  mrg __isl_give isl_pw_aff *isl_pw_multi_aff_get_pw_aff(
   6381  1.1  mrg 	__isl_keep isl_pw_multi_aff *pma, int pos)
   6382  1.1  mrg {
   6383  1.1  mrg 	return isl_pw_multi_aff_get_at(pma, pos);
   6384  1.1  mrg }
   6385  1.1  mrg 
   6386  1.1  mrg /* Return an isl_pw_multi_aff with the given "set" as domain and
   6387  1.1  mrg  * an unnamed zero-dimensional range.
   6388  1.1  mrg  */
   6389  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_domain(
   6390  1.1  mrg 	__isl_take isl_set *set)
   6391  1.1  mrg {
   6392  1.1  mrg 	isl_multi_aff *ma;
   6393  1.1  mrg 	isl_space *space;
   6394  1.1  mrg 
   6395  1.1  mrg 	space = isl_set_get_space(set);
   6396  1.1  mrg 	space = isl_space_from_domain(space);
   6397  1.1  mrg 	ma = isl_multi_aff_zero(space);
   6398  1.1  mrg 	return isl_pw_multi_aff_alloc(set, ma);
   6399  1.1  mrg }
   6400  1.1  mrg 
   6401  1.1  mrg /* Add an isl_pw_multi_aff with the given "set" as domain and
   6402  1.1  mrg  * an unnamed zero-dimensional range to *user.
   6403  1.1  mrg  */
   6404  1.1  mrg static isl_stat add_pw_multi_aff_from_domain(__isl_take isl_set *set,
   6405  1.1  mrg 	void *user)
   6406  1.1  mrg {
   6407  1.1  mrg 	isl_union_pw_multi_aff **upma = user;
   6408  1.1  mrg 	isl_pw_multi_aff *pma;
   6409  1.1  mrg 
   6410  1.1  mrg 	pma = isl_pw_multi_aff_from_domain(set);
   6411  1.1  mrg 	*upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
   6412  1.1  mrg 
   6413  1.1  mrg 	return isl_stat_ok;
   6414  1.1  mrg }
   6415  1.1  mrg 
   6416  1.1  mrg /* Return an isl_union_pw_multi_aff with the given "uset" as domain and
   6417  1.1  mrg  * an unnamed zero-dimensional range.
   6418  1.1  mrg  */
   6419  1.1  mrg __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_domain(
   6420  1.1  mrg 	__isl_take isl_union_set *uset)
   6421  1.1  mrg {
   6422  1.1  mrg 	isl_space *space;
   6423  1.1  mrg 	isl_union_pw_multi_aff *upma;
   6424  1.1  mrg 
   6425  1.1  mrg 	if (!uset)
   6426  1.1  mrg 		return NULL;
   6427  1.1  mrg 
   6428  1.1  mrg 	space = isl_union_set_get_space(uset);
   6429  1.1  mrg 	upma = isl_union_pw_multi_aff_empty(space);
   6430  1.1  mrg 
   6431  1.1  mrg 	if (isl_union_set_foreach_set(uset,
   6432  1.1  mrg 				    &add_pw_multi_aff_from_domain, &upma) < 0)
   6433  1.1  mrg 		goto error;
   6434  1.1  mrg 
   6435  1.1  mrg 	isl_union_set_free(uset);
   6436  1.1  mrg 	return upma;
   6437  1.1  mrg error:
   6438  1.1  mrg 	isl_union_set_free(uset);
   6439  1.1  mrg 	isl_union_pw_multi_aff_free(upma);
   6440  1.1  mrg 	return NULL;
   6441  1.1  mrg }
   6442  1.1  mrg 
   6443  1.1  mrg /* Local data for bin_entry and the callback "fn".
   6444  1.1  mrg  */
   6445  1.1  mrg struct isl_union_pw_multi_aff_bin_data {
   6446  1.1  mrg 	isl_union_pw_multi_aff *upma2;
   6447  1.1  mrg 	isl_union_pw_multi_aff *res;
   6448  1.1  mrg 	isl_pw_multi_aff *pma;
   6449  1.1  mrg 	isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, void *user);
   6450  1.1  mrg };
   6451  1.1  mrg 
   6452  1.1  mrg /* Given an isl_pw_multi_aff from upma1, store it in data->pma
   6453  1.1  mrg  * and call data->fn for each isl_pw_multi_aff in data->upma2.
   6454  1.1  mrg  */
   6455  1.1  mrg static isl_stat bin_entry(__isl_take isl_pw_multi_aff *pma, void *user)
   6456  1.1  mrg {
   6457  1.1  mrg 	struct isl_union_pw_multi_aff_bin_data *data = user;
   6458  1.1  mrg 	isl_stat r;
   6459  1.1  mrg 
   6460  1.1  mrg 	data->pma = pma;
   6461  1.1  mrg 	r = isl_union_pw_multi_aff_foreach_pw_multi_aff(data->upma2,
   6462  1.1  mrg 				   data->fn, data);
   6463  1.1  mrg 	isl_pw_multi_aff_free(pma);
   6464  1.1  mrg 
   6465  1.1  mrg 	return r;
   6466  1.1  mrg }
   6467  1.1  mrg 
   6468  1.1  mrg /* Call "fn" on each pair of isl_pw_multi_affs in "upma1" and "upma2".
   6469  1.1  mrg  * The isl_pw_multi_aff from upma1 is stored in data->pma (where data is
   6470  1.1  mrg  * passed as user field) and the isl_pw_multi_aff from upma2 is available
   6471  1.1  mrg  * as *entry.  The callback should adjust data->res if desired.
   6472  1.1  mrg  */
   6473  1.1  mrg static __isl_give isl_union_pw_multi_aff *bin_op(
   6474  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma1,
   6475  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma2,
   6476  1.1  mrg 	isl_stat (*fn)(__isl_take isl_pw_multi_aff *pma, void *user))
   6477  1.1  mrg {
   6478  1.1  mrg 	isl_space *space;
   6479  1.1  mrg 	struct isl_union_pw_multi_aff_bin_data data = { NULL, NULL, NULL, fn };
   6480  1.1  mrg 
   6481  1.1  mrg 	space = isl_union_pw_multi_aff_get_space(upma2);
   6482  1.1  mrg 	upma1 = isl_union_pw_multi_aff_align_params(upma1, space);
   6483  1.1  mrg 	space = isl_union_pw_multi_aff_get_space(upma1);
   6484  1.1  mrg 	upma2 = isl_union_pw_multi_aff_align_params(upma2, space);
   6485  1.1  mrg 
   6486  1.1  mrg 	if (!upma1 || !upma2)
   6487  1.1  mrg 		goto error;
   6488  1.1  mrg 
   6489  1.1  mrg 	data.upma2 = upma2;
   6490  1.1  mrg 	data.res = isl_union_pw_multi_aff_alloc_same_size(upma1);
   6491  1.1  mrg 	if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma1,
   6492  1.1  mrg 				   &bin_entry, &data) < 0)
   6493  1.1  mrg 		goto error;
   6494  1.1  mrg 
   6495  1.1  mrg 	isl_union_pw_multi_aff_free(upma1);
   6496  1.1  mrg 	isl_union_pw_multi_aff_free(upma2);
   6497  1.1  mrg 	return data.res;
   6498  1.1  mrg error:
   6499  1.1  mrg 	isl_union_pw_multi_aff_free(upma1);
   6500  1.1  mrg 	isl_union_pw_multi_aff_free(upma2);
   6501  1.1  mrg 	isl_union_pw_multi_aff_free(data.res);
   6502  1.1  mrg 	return NULL;
   6503  1.1  mrg }
   6504  1.1  mrg 
   6505  1.1  mrg /* Given two isl_pw_multi_affs A -> B and C -> D,
   6506  1.1  mrg  * construct an isl_pw_multi_aff (A * C) -> [B -> D].
   6507  1.1  mrg  */
   6508  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_range_product(
   6509  1.1  mrg 	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
   6510  1.1  mrg {
   6511  1.1  mrg 	isl_space *space;
   6512  1.1  mrg 
   6513  1.1  mrg 	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
   6514  1.1  mrg 	space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
   6515  1.1  mrg 					isl_pw_multi_aff_get_space(pma2));
   6516  1.1  mrg 	return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
   6517  1.1  mrg 					    &isl_multi_aff_range_product);
   6518  1.1  mrg }
   6519  1.1  mrg 
   6520  1.1  mrg /* Given two isl_pw_multi_affs A -> B and C -> D,
   6521  1.1  mrg  * construct an isl_pw_multi_aff (A * C) -> (B, D).
   6522  1.1  mrg  */
   6523  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_flat_range_product(
   6524  1.1  mrg 	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
   6525  1.1  mrg {
   6526  1.1  mrg 	isl_space *space;
   6527  1.1  mrg 
   6528  1.1  mrg 	isl_pw_multi_aff_align_params_bin(&pma1, &pma2);
   6529  1.1  mrg 	space = isl_space_range_product(isl_pw_multi_aff_get_space(pma1),
   6530  1.1  mrg 					isl_pw_multi_aff_get_space(pma2));
   6531  1.1  mrg 	space = isl_space_flatten_range(space);
   6532  1.1  mrg 	return isl_pw_multi_aff_on_shared_domain_in(pma1, pma2, space,
   6533  1.1  mrg 					    &isl_multi_aff_flat_range_product);
   6534  1.1  mrg }
   6535  1.1  mrg 
   6536  1.1  mrg /* If data->pma and "pma2" have the same domain space, then use "range_product"
   6537  1.1  mrg  * to compute some form of range product and add the result to data->res.
   6538  1.1  mrg  */
   6539  1.1  mrg static isl_stat gen_range_product_entry(__isl_take isl_pw_multi_aff *pma2,
   6540  1.1  mrg 	__isl_give isl_pw_multi_aff *(*range_product)(
   6541  1.1  mrg 		__isl_take isl_pw_multi_aff *pma1,
   6542  1.1  mrg 		__isl_take isl_pw_multi_aff *pma2),
   6543  1.1  mrg 	void *user)
   6544  1.1  mrg {
   6545  1.1  mrg 	struct isl_union_pw_multi_aff_bin_data *data = user;
   6546  1.1  mrg 	isl_bool match;
   6547  1.1  mrg 	isl_space *space1, *space2;
   6548  1.1  mrg 
   6549  1.1  mrg 	space1 = isl_pw_multi_aff_peek_space(data->pma);
   6550  1.1  mrg 	space2 = isl_pw_multi_aff_peek_space(pma2);
   6551  1.1  mrg 	match = isl_space_tuple_is_equal(space1, isl_dim_in,
   6552  1.1  mrg 					space2, isl_dim_in);
   6553  1.1  mrg 	if (match < 0 || !match) {
   6554  1.1  mrg 		isl_pw_multi_aff_free(pma2);
   6555  1.1  mrg 		return match < 0 ? isl_stat_error : isl_stat_ok;
   6556  1.1  mrg 	}
   6557  1.1  mrg 
   6558  1.1  mrg 	pma2 = range_product(isl_pw_multi_aff_copy(data->pma), pma2);
   6559  1.1  mrg 
   6560  1.1  mrg 	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
   6561  1.1  mrg 
   6562  1.1  mrg 	return isl_stat_ok;
   6563  1.1  mrg }
   6564  1.1  mrg 
   6565  1.1  mrg /* If data->pma and "pma2" have the same domain space, then compute
   6566  1.1  mrg  * their flat range product and add the result to data->res.
   6567  1.1  mrg  */
   6568  1.1  mrg static isl_stat flat_range_product_entry(__isl_take isl_pw_multi_aff *pma2,
   6569  1.1  mrg 	void *user)
   6570  1.1  mrg {
   6571  1.1  mrg 	return gen_range_product_entry(pma2,
   6572  1.1  mrg 				&isl_pw_multi_aff_flat_range_product, user);
   6573  1.1  mrg }
   6574  1.1  mrg 
   6575  1.1  mrg /* Given two isl_union_pw_multi_affs A -> B and C -> D,
   6576  1.1  mrg  * construct an isl_union_pw_multi_aff (A * C) -> (B, D).
   6577  1.1  mrg  */
   6578  1.1  mrg __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_flat_range_product(
   6579  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma1,
   6580  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma2)
   6581  1.1  mrg {
   6582  1.1  mrg 	return bin_op(upma1, upma2, &flat_range_product_entry);
   6583  1.1  mrg }
   6584  1.1  mrg 
   6585  1.1  mrg /* If data->pma and "pma2" have the same domain space, then compute
   6586  1.1  mrg  * their range product and add the result to data->res.
   6587  1.1  mrg  */
   6588  1.1  mrg static isl_stat range_product_entry(__isl_take isl_pw_multi_aff *pma2,
   6589  1.1  mrg 	void *user)
   6590  1.1  mrg {
   6591  1.1  mrg 	return gen_range_product_entry(pma2,
   6592  1.1  mrg 				&isl_pw_multi_aff_range_product, user);
   6593  1.1  mrg }
   6594  1.1  mrg 
   6595  1.1  mrg /* Given two isl_union_pw_multi_affs A -> B and C -> D,
   6596  1.1  mrg  * construct an isl_union_pw_multi_aff (A * C) -> [B -> D].
   6597  1.1  mrg  */
   6598  1.1  mrg __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_product(
   6599  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma1,
   6600  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma2)
   6601  1.1  mrg {
   6602  1.1  mrg 	return bin_op(upma1, upma2, &range_product_entry);
   6603  1.1  mrg }
   6604  1.1  mrg 
   6605  1.1  mrg /* Replace the affine expressions at position "pos" in "pma" by "pa".
   6606  1.1  mrg  * The parameters are assumed to have been aligned.
   6607  1.1  mrg  *
   6608  1.1  mrg  * The implementation essentially performs an isl_pw_*_on_shared_domain,
   6609  1.1  mrg  * except that it works on two different isl_pw_* types.
   6610  1.1  mrg  */
   6611  1.1  mrg static __isl_give isl_pw_multi_aff *pw_multi_aff_set_pw_aff(
   6612  1.1  mrg 	__isl_take isl_pw_multi_aff *pma, unsigned pos,
   6613  1.1  mrg 	__isl_take isl_pw_aff *pa)
   6614  1.1  mrg {
   6615  1.1  mrg 	int i, j, n;
   6616  1.1  mrg 	isl_pw_multi_aff *res = NULL;
   6617  1.1  mrg 
   6618  1.1  mrg 	if (!pma || !pa)
   6619  1.1  mrg 		goto error;
   6620  1.1  mrg 
   6621  1.1  mrg 	if (!isl_space_tuple_is_equal(pma->dim, isl_dim_in,
   6622  1.1  mrg 					pa->dim, isl_dim_in))
   6623  1.1  mrg 		isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
   6624  1.1  mrg 			"domains don't match", goto error);
   6625  1.1  mrg 	if (isl_pw_multi_aff_check_range(pma, isl_dim_out, pos, 1) < 0)
   6626  1.1  mrg 		goto error;
   6627  1.1  mrg 
   6628  1.1  mrg 	n = pma->n * pa->n;
   6629  1.1  mrg 	res = isl_pw_multi_aff_alloc_size(isl_pw_multi_aff_get_space(pma), n);
   6630  1.1  mrg 
   6631  1.1  mrg 	for (i = 0; i < pma->n; ++i) {
   6632  1.1  mrg 		for (j = 0; j < pa->n; ++j) {
   6633  1.1  mrg 			isl_set *common;
   6634  1.1  mrg 			isl_multi_aff *res_ij;
   6635  1.1  mrg 			int empty;
   6636  1.1  mrg 
   6637  1.1  mrg 			common = isl_set_intersect(isl_set_copy(pma->p[i].set),
   6638  1.1  mrg 						   isl_set_copy(pa->p[j].set));
   6639  1.1  mrg 			empty = isl_set_plain_is_empty(common);
   6640  1.1  mrg 			if (empty < 0 || empty) {
   6641  1.1  mrg 				isl_set_free(common);
   6642  1.1  mrg 				if (empty < 0)
   6643  1.1  mrg 					goto error;
   6644  1.1  mrg 				continue;
   6645  1.1  mrg 			}
   6646  1.1  mrg 
   6647  1.1  mrg 			res_ij = isl_multi_aff_set_aff(
   6648  1.1  mrg 					isl_multi_aff_copy(pma->p[i].maff), pos,
   6649  1.1  mrg 					isl_aff_copy(pa->p[j].aff));
   6650  1.1  mrg 			res_ij = isl_multi_aff_gist(res_ij,
   6651  1.1  mrg 					isl_set_copy(common));
   6652  1.1  mrg 
   6653  1.1  mrg 			res = isl_pw_multi_aff_add_piece(res, common, res_ij);
   6654  1.1  mrg 		}
   6655  1.1  mrg 	}
   6656  1.1  mrg 
   6657  1.1  mrg 	isl_pw_multi_aff_free(pma);
   6658  1.1  mrg 	isl_pw_aff_free(pa);
   6659  1.1  mrg 	return res;
   6660  1.1  mrg error:
   6661  1.1  mrg 	isl_pw_multi_aff_free(pma);
   6662  1.1  mrg 	isl_pw_aff_free(pa);
   6663  1.1  mrg 	return isl_pw_multi_aff_free(res);
   6664  1.1  mrg }
   6665  1.1  mrg 
   6666  1.1  mrg /* Replace the affine expressions at position "pos" in "pma" by "pa".
   6667  1.1  mrg  */
   6668  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_set_pw_aff(
   6669  1.1  mrg 	__isl_take isl_pw_multi_aff *pma, unsigned pos,
   6670  1.1  mrg 	__isl_take isl_pw_aff *pa)
   6671  1.1  mrg {
   6672  1.1  mrg 	isl_bool equal_params;
   6673  1.1  mrg 
   6674  1.1  mrg 	if (!pma || !pa)
   6675  1.1  mrg 		goto error;
   6676  1.1  mrg 	equal_params = isl_space_has_equal_params(pma->dim, pa->dim);
   6677  1.1  mrg 	if (equal_params < 0)
   6678  1.1  mrg 		goto error;
   6679  1.1  mrg 	if (equal_params)
   6680  1.1  mrg 		return pw_multi_aff_set_pw_aff(pma, pos, pa);
   6681  1.1  mrg 	if (isl_pw_multi_aff_check_named_params(pma) < 0 ||
   6682  1.1  mrg 	    isl_pw_aff_check_named_params(pa) < 0)
   6683  1.1  mrg 		goto error;
   6684  1.1  mrg 	pma = isl_pw_multi_aff_align_params(pma, isl_pw_aff_get_space(pa));
   6685  1.1  mrg 	pa = isl_pw_aff_align_params(pa, isl_pw_multi_aff_get_space(pma));
   6686  1.1  mrg 	return pw_multi_aff_set_pw_aff(pma, pos, pa);
   6687  1.1  mrg error:
   6688  1.1  mrg 	isl_pw_multi_aff_free(pma);
   6689  1.1  mrg 	isl_pw_aff_free(pa);
   6690  1.1  mrg 	return NULL;
   6691  1.1  mrg }
   6692  1.1  mrg 
   6693  1.1  mrg /* Do the parameters of "pa" match those of "space"?
   6694  1.1  mrg  */
   6695  1.1  mrg isl_bool isl_pw_aff_matching_params(__isl_keep isl_pw_aff *pa,
   6696  1.1  mrg 	__isl_keep isl_space *space)
   6697  1.1  mrg {
   6698  1.1  mrg 	isl_space *pa_space;
   6699  1.1  mrg 	isl_bool match;
   6700  1.1  mrg 
   6701  1.1  mrg 	if (!pa || !space)
   6702  1.1  mrg 		return isl_bool_error;
   6703  1.1  mrg 
   6704  1.1  mrg 	pa_space = isl_pw_aff_get_space(pa);
   6705  1.1  mrg 
   6706  1.1  mrg 	match = isl_space_has_equal_params(space, pa_space);
   6707  1.1  mrg 
   6708  1.1  mrg 	isl_space_free(pa_space);
   6709  1.1  mrg 	return match;
   6710  1.1  mrg }
   6711  1.1  mrg 
   6712  1.1  mrg /* Check that the domain space of "pa" matches "space".
   6713  1.1  mrg  */
   6714  1.1  mrg isl_stat isl_pw_aff_check_match_domain_space(__isl_keep isl_pw_aff *pa,
   6715  1.1  mrg 	__isl_keep isl_space *space)
   6716  1.1  mrg {
   6717  1.1  mrg 	isl_space *pa_space;
   6718  1.1  mrg 	isl_bool match;
   6719  1.1  mrg 
   6720  1.1  mrg 	if (!pa || !space)
   6721  1.1  mrg 		return isl_stat_error;
   6722  1.1  mrg 
   6723  1.1  mrg 	pa_space = isl_pw_aff_get_space(pa);
   6724  1.1  mrg 
   6725  1.1  mrg 	match = isl_space_has_equal_params(space, pa_space);
   6726  1.1  mrg 	if (match < 0)
   6727  1.1  mrg 		goto error;
   6728  1.1  mrg 	if (!match)
   6729  1.1  mrg 		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
   6730  1.1  mrg 			"parameters don't match", goto error);
   6731  1.1  mrg 	match = isl_space_tuple_is_equal(space, isl_dim_in,
   6732  1.1  mrg 					pa_space, isl_dim_in);
   6733  1.1  mrg 	if (match < 0)
   6734  1.1  mrg 		goto error;
   6735  1.1  mrg 	if (!match)
   6736  1.1  mrg 		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
   6737  1.1  mrg 			"domains don't match", goto error);
   6738  1.1  mrg 	isl_space_free(pa_space);
   6739  1.1  mrg 	return isl_stat_ok;
   6740  1.1  mrg error:
   6741  1.1  mrg 	isl_space_free(pa_space);
   6742  1.1  mrg 	return isl_stat_error;
   6743  1.1  mrg }
   6744  1.1  mrg 
   6745  1.1  mrg #undef BASE
   6746  1.1  mrg #define BASE pw_aff
   6747  1.1  mrg #undef DOMBASE
   6748  1.1  mrg #define DOMBASE set
   6749  1.1  mrg 
   6750  1.1  mrg #include <isl_multi_explicit_domain.c>
   6751  1.1  mrg #include <isl_multi_pw_aff_explicit_domain.c>
   6752  1.1  mrg #include <isl_multi_templ.c>
   6753  1.1  mrg #include <isl_multi_un_op_templ.c>
   6754  1.1  mrg #include <isl_multi_bin_val_templ.c>
   6755  1.1  mrg #include <isl_multi_add_constant_templ.c>
   6756  1.1  mrg #include <isl_multi_align_set.c>
   6757  1.1  mrg #include <isl_multi_apply_set_explicit_domain_templ.c>
   6758  1.1  mrg #include <isl_multi_arith_templ.c>
   6759  1.1  mrg #include <isl_multi_bind_templ.c>
   6760  1.1  mrg #include <isl_multi_bind_domain_templ.c>
   6761  1.1  mrg #include <isl_multi_coalesce.c>
   6762  1.1  mrg #include <isl_multi_domain_templ.c>
   6763  1.1  mrg #include <isl_multi_domain_reverse_templ.c>
   6764  1.1  mrg #include <isl_multi_dim_id_templ.c>
   6765  1.1  mrg #include <isl_multi_dims.c>
   6766  1.1  mrg #include <isl_multi_from_base_templ.c>
   6767  1.1  mrg #include <isl_multi_check_domain_templ.c>
   6768  1.1  mrg #include <isl_multi_gist.c>
   6769  1.1  mrg #include <isl_multi_hash.c>
   6770  1.1  mrg #include <isl_multi_identity_templ.c>
   6771  1.1  mrg #include <isl_multi_insert_domain_templ.c>
   6772  1.1  mrg #include <isl_multi_intersect.c>
   6773  1.1  mrg #include <isl_multi_min_max_templ.c>
   6774  1.1  mrg #include <isl_multi_move_dims_templ.c>
   6775  1.1  mrg #include <isl_multi_nan_templ.c>
   6776  1.1  mrg #include <isl_multi_param_templ.c>
   6777  1.1  mrg #include <isl_multi_product_templ.c>
   6778  1.1  mrg #include <isl_multi_splice_templ.c>
   6779  1.1  mrg #include <isl_multi_tuple_id_templ.c>
   6780  1.1  mrg #include <isl_multi_union_add_templ.c>
   6781  1.1  mrg #include <isl_multi_zero_templ.c>
   6782  1.1  mrg #include <isl_multi_unbind_params_templ.c>
   6783  1.1  mrg 
   6784  1.1  mrg /* Is every element of "mpa" defined over a single universe domain?
   6785  1.1  mrg  */
   6786  1.1  mrg isl_bool isl_multi_pw_aff_isa_multi_aff(__isl_keep isl_multi_pw_aff *mpa)
   6787  1.1  mrg {
   6788  1.1  mrg 	return isl_multi_pw_aff_every(mpa, &isl_pw_aff_isa_aff);
   6789  1.1  mrg }
   6790  1.1  mrg 
   6791  1.1  mrg /* Given that every element of "mpa" is defined over a single universe domain,
   6792  1.1  mrg  * return the corresponding base expressions.
   6793  1.1  mrg  */
   6794  1.1  mrg __isl_give isl_multi_aff *isl_multi_pw_aff_as_multi_aff(
   6795  1.1  mrg 	__isl_take isl_multi_pw_aff *mpa)
   6796  1.1  mrg {
   6797  1.1  mrg 	int i;
   6798  1.1  mrg 	isl_size n;
   6799  1.1  mrg 	isl_multi_aff *ma;
   6800  1.1  mrg 
   6801  1.1  mrg 	n = isl_multi_pw_aff_size(mpa);
   6802  1.1  mrg 	if (n < 0)
   6803  1.1  mrg 		mpa = isl_multi_pw_aff_free(mpa);
   6804  1.1  mrg 	ma = isl_multi_aff_alloc(isl_multi_pw_aff_get_space(mpa));
   6805  1.1  mrg 	for (i = 0; i < n; ++i) {
   6806  1.1  mrg 		isl_aff *aff;
   6807  1.1  mrg 
   6808  1.1  mrg 		aff = isl_pw_aff_as_aff(isl_multi_pw_aff_get_at(mpa, i));
   6809  1.1  mrg 		ma = isl_multi_aff_set_aff(ma, i, aff);
   6810  1.1  mrg 	}
   6811  1.1  mrg 	isl_multi_pw_aff_free(mpa);
   6812  1.1  mrg 	return ma;
   6813  1.1  mrg }
   6814  1.1  mrg 
   6815  1.1  mrg /* If "mpa" has an explicit domain, then intersect the domain of "map"
   6816  1.1  mrg  * with this explicit domain.
   6817  1.1  mrg  */
   6818  1.1  mrg __isl_give isl_map *isl_map_intersect_multi_pw_aff_explicit_domain(
   6819  1.1  mrg 	__isl_take isl_map *map, __isl_keep isl_multi_pw_aff *mpa)
   6820  1.1  mrg {
   6821  1.1  mrg 	isl_set *dom;
   6822  1.1  mrg 
   6823  1.1  mrg 	if (!isl_multi_pw_aff_has_explicit_domain(mpa))
   6824  1.1  mrg 		return map;
   6825  1.1  mrg 
   6826  1.1  mrg 	dom = isl_multi_pw_aff_domain(isl_multi_pw_aff_copy(mpa));
   6827  1.1  mrg 	map = isl_map_intersect_domain(map, dom);
   6828  1.1  mrg 
   6829  1.1  mrg 	return map;
   6830  1.1  mrg }
   6831  1.1  mrg 
   6832  1.1  mrg /* Are all elements of "mpa" piecewise constants?
   6833  1.1  mrg  */
   6834  1.1  mrg isl_bool isl_multi_pw_aff_is_cst(__isl_keep isl_multi_pw_aff *mpa)
   6835  1.1  mrg {
   6836  1.1  mrg 	return isl_multi_pw_aff_every(mpa, &isl_pw_aff_is_cst);
   6837  1.1  mrg }
   6838  1.1  mrg 
   6839  1.1  mrg /* Does "mpa" have a non-trivial explicit domain?
   6840  1.1  mrg  *
   6841  1.1  mrg  * The explicit domain, if present, is trivial if it represents
   6842  1.1  mrg  * an (obviously) universe set.
   6843  1.1  mrg  */
   6844  1.1  mrg isl_bool isl_multi_pw_aff_has_non_trivial_domain(
   6845  1.1  mrg 	__isl_keep isl_multi_pw_aff *mpa)
   6846  1.1  mrg {
   6847  1.1  mrg 	if (!mpa)
   6848  1.1  mrg 		return isl_bool_error;
   6849  1.1  mrg 	if (!isl_multi_pw_aff_has_explicit_domain(mpa))
   6850  1.1  mrg 		return isl_bool_false;
   6851  1.1  mrg 	return isl_bool_not(isl_set_plain_is_universe(mpa->u.dom));
   6852  1.1  mrg }
   6853  1.1  mrg 
   6854  1.1  mrg #undef BASE
   6855  1.1  mrg #define BASE	set
   6856  1.1  mrg 
   6857  1.1  mrg #include "isl_opt_mpa_templ.c"
   6858  1.1  mrg 
   6859  1.1  mrg /* Compute the minima of the set dimensions as a function of the
   6860  1.1  mrg  * parameters, but independently of the other set dimensions.
   6861  1.1  mrg  */
   6862  1.1  mrg __isl_give isl_multi_pw_aff *isl_set_min_multi_pw_aff(__isl_take isl_set *set)
   6863  1.1  mrg {
   6864  1.1  mrg 	return set_opt_mpa(set, &isl_set_dim_min);
   6865  1.1  mrg }
   6866  1.1  mrg 
   6867  1.1  mrg /* Compute the maxima of the set dimensions as a function of the
   6868  1.1  mrg  * parameters, but independently of the other set dimensions.
   6869  1.1  mrg  */
   6870  1.1  mrg __isl_give isl_multi_pw_aff *isl_set_max_multi_pw_aff(__isl_take isl_set *set)
   6871  1.1  mrg {
   6872  1.1  mrg 	return set_opt_mpa(set, &isl_set_dim_max);
   6873  1.1  mrg }
   6874  1.1  mrg 
   6875  1.1  mrg #undef BASE
   6876  1.1  mrg #define BASE	map
   6877  1.1  mrg 
   6878  1.1  mrg #include "isl_opt_mpa_templ.c"
   6879  1.1  mrg 
   6880  1.1  mrg /* Compute the minima of the output dimensions as a function of the
   6881  1.1  mrg  * parameters and input dimensions, but independently of
   6882  1.1  mrg  * the other output dimensions.
   6883  1.1  mrg  */
   6884  1.1  mrg __isl_give isl_multi_pw_aff *isl_map_min_multi_pw_aff(__isl_take isl_map *map)
   6885  1.1  mrg {
   6886  1.1  mrg 	return map_opt_mpa(map, &isl_map_dim_min);
   6887  1.1  mrg }
   6888  1.1  mrg 
   6889  1.1  mrg /* Compute the maxima of the output dimensions as a function of the
   6890  1.1  mrg  * parameters and input dimensions, but independently of
   6891  1.1  mrg  * the other output dimensions.
   6892  1.1  mrg  */
   6893  1.1  mrg __isl_give isl_multi_pw_aff *isl_map_max_multi_pw_aff(__isl_take isl_map *map)
   6894  1.1  mrg {
   6895  1.1  mrg 	return map_opt_mpa(map, &isl_map_dim_max);
   6896  1.1  mrg }
   6897  1.1  mrg 
   6898  1.1  mrg #undef TYPE
   6899  1.1  mrg #define TYPE	isl_pw_multi_aff
   6900  1.1  mrg #include "isl_type_check_match_range_multi_val.c"
   6901  1.1  mrg 
   6902  1.1  mrg /* Apply "fn" to the base expressions of "pma" and "mv".
   6903  1.1  mrg  */
   6904  1.1  mrg static __isl_give isl_pw_multi_aff *isl_pw_multi_aff_op_multi_val(
   6905  1.1  mrg 	__isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv,
   6906  1.1  mrg 	__isl_give isl_multi_aff *(*fn)(__isl_take isl_multi_aff *ma,
   6907  1.1  mrg 		__isl_take isl_multi_val *mv))
   6908  1.1  mrg {
   6909  1.1  mrg 	int i;
   6910  1.1  mrg 	isl_size n;
   6911  1.1  mrg 
   6912  1.1  mrg 	if (isl_pw_multi_aff_check_match_range_multi_val(pma, mv) < 0)
   6913  1.1  mrg 		goto error;
   6914  1.1  mrg 
   6915  1.1  mrg 	n = isl_pw_multi_aff_n_piece(pma);
   6916  1.1  mrg 	if (n < 0)
   6917  1.1  mrg 		goto error;
   6918  1.1  mrg 
   6919  1.1  mrg 	for (i = 0; i < n; ++i) {
   6920  1.1  mrg 		isl_multi_aff *ma;
   6921  1.1  mrg 
   6922  1.1  mrg 		ma = isl_pw_multi_aff_take_base_at(pma, i);
   6923  1.1  mrg 		ma = fn(ma, isl_multi_val_copy(mv));
   6924  1.1  mrg 		pma = isl_pw_multi_aff_restore_base_at(pma, i, ma);
   6925  1.1  mrg 	}
   6926  1.1  mrg 
   6927  1.1  mrg 	isl_multi_val_free(mv);
   6928  1.1  mrg 	return pma;
   6929  1.1  mrg error:
   6930  1.1  mrg 	isl_multi_val_free(mv);
   6931  1.1  mrg 	isl_pw_multi_aff_free(pma);
   6932  1.1  mrg 	return NULL;
   6933  1.1  mrg }
   6934  1.1  mrg 
   6935  1.1  mrg /* Scale the elements of "pma" by the corresponding elements of "mv".
   6936  1.1  mrg  */
   6937  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_multi_val(
   6938  1.1  mrg 	__isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv)
   6939  1.1  mrg {
   6940  1.1  mrg 	return isl_pw_multi_aff_op_multi_val(pma, mv,
   6941  1.1  mrg 					&isl_multi_aff_scale_multi_val);
   6942  1.1  mrg }
   6943  1.1  mrg 
   6944  1.1  mrg /* Scale the elements of "pma" down by the corresponding elements of "mv".
   6945  1.1  mrg  */
   6946  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_scale_down_multi_val(
   6947  1.1  mrg 	__isl_take isl_pw_multi_aff *pma, __isl_take isl_multi_val *mv)
   6948  1.1  mrg {
   6949  1.1  mrg 	return isl_pw_multi_aff_op_multi_val(pma, mv,
   6950  1.1  mrg 					&isl_multi_aff_scale_down_multi_val);
   6951  1.1  mrg }
   6952  1.1  mrg 
   6953  1.1  mrg /* This function is called for each entry of an isl_union_pw_multi_aff.
   6954  1.1  mrg  * If the space of the entry matches that of data->mv,
   6955  1.1  mrg  * then apply isl_pw_multi_aff_scale_multi_val and return the result.
   6956  1.1  mrg  * Otherwise, return an empty isl_pw_multi_aff.
   6957  1.1  mrg  */
   6958  1.1  mrg static __isl_give isl_pw_multi_aff *union_pw_multi_aff_scale_multi_val_entry(
   6959  1.1  mrg 	__isl_take isl_pw_multi_aff *pma, void *user)
   6960  1.1  mrg {
   6961  1.1  mrg 	isl_bool equal;
   6962  1.1  mrg 	isl_multi_val *mv = user;
   6963  1.1  mrg 
   6964  1.1  mrg 	equal = isl_pw_multi_aff_match_range_multi_val(pma, mv);
   6965  1.1  mrg 	if (equal < 0)
   6966  1.1  mrg 		return isl_pw_multi_aff_free(pma);
   6967  1.1  mrg 	if (!equal) {
   6968  1.1  mrg 		isl_space *space = isl_pw_multi_aff_get_space(pma);
   6969  1.1  mrg 		isl_pw_multi_aff_free(pma);
   6970  1.1  mrg 		return isl_pw_multi_aff_empty(space);
   6971  1.1  mrg 	}
   6972  1.1  mrg 
   6973  1.1  mrg 	return isl_pw_multi_aff_scale_multi_val(pma, isl_multi_val_copy(mv));
   6974  1.1  mrg }
   6975  1.1  mrg 
   6976  1.1  mrg /* Scale the elements of "upma" by the corresponding elements of "mv",
   6977  1.1  mrg  * for those entries that match the space of "mv".
   6978  1.1  mrg  */
   6979  1.1  mrg __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_scale_multi_val(
   6980  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma, __isl_take isl_multi_val *mv)
   6981  1.1  mrg {
   6982  1.1  mrg 	struct isl_union_pw_multi_aff_transform_control control = {
   6983  1.1  mrg 		.fn = &union_pw_multi_aff_scale_multi_val_entry,
   6984  1.1  mrg 		.fn_user = mv,
   6985  1.1  mrg 	};
   6986  1.1  mrg 
   6987  1.1  mrg 	upma = isl_union_pw_multi_aff_align_params(upma,
   6988  1.1  mrg 						isl_multi_val_get_space(mv));
   6989  1.1  mrg 	mv = isl_multi_val_align_params(mv,
   6990  1.1  mrg 					isl_union_pw_multi_aff_get_space(upma));
   6991  1.1  mrg 	if (!upma || !mv)
   6992  1.1  mrg 		goto error;
   6993  1.1  mrg 
   6994  1.1  mrg 	return isl_union_pw_multi_aff_transform(upma, &control);
   6995  1.1  mrg 
   6996  1.1  mrg 	isl_multi_val_free(mv);
   6997  1.1  mrg 	return upma;
   6998  1.1  mrg error:
   6999  1.1  mrg 	isl_multi_val_free(mv);
   7000  1.1  mrg 	isl_union_pw_multi_aff_free(upma);
   7001  1.1  mrg 	return NULL;
   7002  1.1  mrg }
   7003  1.1  mrg 
   7004  1.1  mrg /* Construct and return a piecewise multi affine expression
   7005  1.1  mrg  * in the given space with value zero in each of the output dimensions and
   7006  1.1  mrg  * a universe domain.
   7007  1.1  mrg  */
   7008  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_zero(__isl_take isl_space *space)
   7009  1.1  mrg {
   7010  1.1  mrg 	return isl_pw_multi_aff_from_multi_aff(isl_multi_aff_zero(space));
   7011  1.1  mrg }
   7012  1.1  mrg 
   7013  1.1  mrg /* Construct and return a piecewise multi affine expression
   7014  1.1  mrg  * that is equal to the given piecewise affine expression.
   7015  1.1  mrg  */
   7016  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_pw_aff(
   7017  1.1  mrg 	__isl_take isl_pw_aff *pa)
   7018  1.1  mrg {
   7019  1.1  mrg 	int i;
   7020  1.1  mrg 	isl_space *space;
   7021  1.1  mrg 	isl_pw_multi_aff *pma;
   7022  1.1  mrg 
   7023  1.1  mrg 	if (!pa)
   7024  1.1  mrg 		return NULL;
   7025  1.1  mrg 
   7026  1.1  mrg 	space = isl_pw_aff_get_space(pa);
   7027  1.1  mrg 	pma = isl_pw_multi_aff_alloc_size(space, pa->n);
   7028  1.1  mrg 
   7029  1.1  mrg 	for (i = 0; i < pa->n; ++i) {
   7030  1.1  mrg 		isl_set *set;
   7031  1.1  mrg 		isl_multi_aff *ma;
   7032  1.1  mrg 
   7033  1.1  mrg 		set = isl_set_copy(pa->p[i].set);
   7034  1.1  mrg 		ma = isl_multi_aff_from_aff(isl_aff_copy(pa->p[i].aff));
   7035  1.1  mrg 		pma = isl_pw_multi_aff_add_piece(pma, set, ma);
   7036  1.1  mrg 	}
   7037  1.1  mrg 
   7038  1.1  mrg 	isl_pw_aff_free(pa);
   7039  1.1  mrg 	return pma;
   7040  1.1  mrg }
   7041  1.1  mrg 
   7042  1.1  mrg /* Construct and return a piecewise multi affine expression
   7043  1.1  mrg  * that is equal to the given multi piecewise affine expression
   7044  1.1  mrg  * on the shared domain of the piecewise affine expressions,
   7045  1.1  mrg  * in the special case of a 0D multi piecewise affine expression.
   7046  1.1  mrg  *
   7047  1.1  mrg  * Create a piecewise multi affine expression with the explicit domain of
   7048  1.1  mrg  * the 0D multi piecewise affine expression as domain.
   7049  1.1  mrg  */
   7050  1.1  mrg static __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff_0D(
   7051  1.1  mrg 	__isl_take isl_multi_pw_aff *mpa)
   7052  1.1  mrg {
   7053  1.1  mrg 	isl_space *space;
   7054  1.1  mrg 	isl_set *dom;
   7055  1.1  mrg 	isl_multi_aff *ma;
   7056  1.1  mrg 
   7057  1.1  mrg 	space = isl_multi_pw_aff_get_space(mpa);
   7058  1.1  mrg 	dom = isl_multi_pw_aff_get_explicit_domain(mpa);
   7059  1.1  mrg 	isl_multi_pw_aff_free(mpa);
   7060  1.1  mrg 
   7061  1.1  mrg 	ma = isl_multi_aff_zero(space);
   7062  1.1  mrg 	return isl_pw_multi_aff_alloc(dom, ma);
   7063  1.1  mrg }
   7064  1.1  mrg 
   7065  1.1  mrg /* Construct and return a piecewise multi affine expression
   7066  1.1  mrg  * that is equal to the given multi piecewise affine expression
   7067  1.1  mrg  * on the shared domain of the piecewise affine expressions.
   7068  1.1  mrg  */
   7069  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_from_multi_pw_aff(
   7070  1.1  mrg 	__isl_take isl_multi_pw_aff *mpa)
   7071  1.1  mrg {
   7072  1.1  mrg 	int i;
   7073  1.1  mrg 	isl_space *space;
   7074  1.1  mrg 	isl_pw_aff *pa;
   7075  1.1  mrg 	isl_pw_multi_aff *pma;
   7076  1.1  mrg 
   7077  1.1  mrg 	if (!mpa)
   7078  1.1  mrg 		return NULL;
   7079  1.1  mrg 
   7080  1.1  mrg 	if (mpa->n == 0)
   7081  1.1  mrg 		return isl_pw_multi_aff_from_multi_pw_aff_0D(mpa);
   7082  1.1  mrg 
   7083  1.1  mrg 	space = isl_multi_pw_aff_get_space(mpa);
   7084  1.1  mrg 	pa = isl_multi_pw_aff_get_pw_aff(mpa, 0);
   7085  1.1  mrg 	pma = isl_pw_multi_aff_from_pw_aff(pa);
   7086  1.1  mrg 
   7087  1.1  mrg 	for (i = 1; i < mpa->n; ++i) {
   7088  1.1  mrg 		isl_pw_multi_aff *pma_i;
   7089  1.1  mrg 
   7090  1.1  mrg 		pa = isl_multi_pw_aff_get_pw_aff(mpa, i);
   7091  1.1  mrg 		pma_i = isl_pw_multi_aff_from_pw_aff(pa);
   7092  1.1  mrg 		pma = isl_pw_multi_aff_range_product(pma, pma_i);
   7093  1.1  mrg 	}
   7094  1.1  mrg 
   7095  1.1  mrg 	pma = isl_pw_multi_aff_reset_space(pma, space);
   7096  1.1  mrg 
   7097  1.1  mrg 	isl_multi_pw_aff_free(mpa);
   7098  1.1  mrg 	return pma;
   7099  1.1  mrg }
   7100  1.1  mrg 
   7101  1.1  mrg /* Convenience function that constructs an isl_multi_pw_aff
   7102  1.1  mrg  * directly from an isl_aff.
   7103  1.1  mrg  */
   7104  1.1  mrg __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_aff(__isl_take isl_aff *aff)
   7105  1.1  mrg {
   7106  1.1  mrg 	return isl_multi_pw_aff_from_pw_aff(isl_pw_aff_from_aff(aff));
   7107  1.1  mrg }
   7108  1.1  mrg 
   7109  1.1  mrg /* Construct and return a multi piecewise affine expression
   7110  1.1  mrg  * that is equal to the given multi affine expression.
   7111  1.1  mrg  */
   7112  1.1  mrg __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_multi_aff(
   7113  1.1  mrg 	__isl_take isl_multi_aff *ma)
   7114  1.1  mrg {
   7115  1.1  mrg 	int i;
   7116  1.1  mrg 	isl_size n;
   7117  1.1  mrg 	isl_multi_pw_aff *mpa;
   7118  1.1  mrg 
   7119  1.1  mrg 	n = isl_multi_aff_dim(ma, isl_dim_out);
   7120  1.1  mrg 	if (n < 0)
   7121  1.1  mrg 		ma = isl_multi_aff_free(ma);
   7122  1.1  mrg 	if (!ma)
   7123  1.1  mrg 		return NULL;
   7124  1.1  mrg 
   7125  1.1  mrg 	mpa = isl_multi_pw_aff_alloc(isl_multi_aff_get_space(ma));
   7126  1.1  mrg 
   7127  1.1  mrg 	for (i = 0; i < n; ++i) {
   7128  1.1  mrg 		isl_pw_aff *pa;
   7129  1.1  mrg 
   7130  1.1  mrg 		pa = isl_pw_aff_from_aff(isl_multi_aff_get_aff(ma, i));
   7131  1.1  mrg 		mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
   7132  1.1  mrg 	}
   7133  1.1  mrg 
   7134  1.1  mrg 	isl_multi_aff_free(ma);
   7135  1.1  mrg 	return mpa;
   7136  1.1  mrg }
   7137  1.1  mrg 
   7138  1.1  mrg /* This function performs the same operation as isl_multi_pw_aff_from_multi_aff,
   7139  1.1  mrg  * but is considered as a function on an isl_multi_aff when exported.
   7140  1.1  mrg  */
   7141  1.1  mrg __isl_give isl_multi_pw_aff *isl_multi_aff_to_multi_pw_aff(
   7142  1.1  mrg 	__isl_take isl_multi_aff *ma)
   7143  1.1  mrg {
   7144  1.1  mrg 	return isl_multi_pw_aff_from_multi_aff(ma);
   7145  1.1  mrg }
   7146  1.1  mrg 
   7147  1.1  mrg /* Construct and return a multi piecewise affine expression
   7148  1.1  mrg  * that is equal to the given piecewise multi affine expression.
   7149  1.1  mrg  *
   7150  1.1  mrg  * If the resulting multi piecewise affine expression has
   7151  1.1  mrg  * an explicit domain, then assign it the domain of the input.
   7152  1.1  mrg  * In other cases, the domain is stored in the individual elements.
   7153  1.1  mrg  */
   7154  1.1  mrg __isl_give isl_multi_pw_aff *isl_multi_pw_aff_from_pw_multi_aff(
   7155  1.1  mrg 	__isl_take isl_pw_multi_aff *pma)
   7156  1.1  mrg {
   7157  1.1  mrg 	int i;
   7158  1.1  mrg 	isl_size n;
   7159  1.1  mrg 	isl_space *space;
   7160  1.1  mrg 	isl_multi_pw_aff *mpa;
   7161  1.1  mrg 
   7162  1.1  mrg 	n = isl_pw_multi_aff_dim(pma, isl_dim_out);
   7163  1.1  mrg 	if (n < 0)
   7164  1.1  mrg 		pma = isl_pw_multi_aff_free(pma);
   7165  1.1  mrg 	space = isl_pw_multi_aff_get_space(pma);
   7166  1.1  mrg 	mpa = isl_multi_pw_aff_alloc(space);
   7167  1.1  mrg 
   7168  1.1  mrg 	for (i = 0; i < n; ++i) {
   7169  1.1  mrg 		isl_pw_aff *pa;
   7170  1.1  mrg 
   7171  1.1  mrg 		pa = isl_pw_multi_aff_get_pw_aff(pma, i);
   7172  1.1  mrg 		mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
   7173  1.1  mrg 	}
   7174  1.1  mrg 	if (isl_multi_pw_aff_has_explicit_domain(mpa)) {
   7175  1.1  mrg 		isl_set *dom;
   7176  1.1  mrg 
   7177  1.1  mrg 		dom = isl_pw_multi_aff_domain(isl_pw_multi_aff_copy(pma));
   7178  1.1  mrg 		mpa = isl_multi_pw_aff_intersect_domain(mpa, dom);
   7179  1.1  mrg 	}
   7180  1.1  mrg 
   7181  1.1  mrg 	isl_pw_multi_aff_free(pma);
   7182  1.1  mrg 	return mpa;
   7183  1.1  mrg }
   7184  1.1  mrg 
   7185  1.1  mrg /* This function performs the same operation as
   7186  1.1  mrg  * isl_multi_pw_aff_from_pw_multi_aff,
   7187  1.1  mrg  * but is considered as a function on an isl_pw_multi_aff when exported.
   7188  1.1  mrg  */
   7189  1.1  mrg __isl_give isl_multi_pw_aff *isl_pw_multi_aff_to_multi_pw_aff(
   7190  1.1  mrg 	__isl_take isl_pw_multi_aff *pma)
   7191  1.1  mrg {
   7192  1.1  mrg 	return isl_multi_pw_aff_from_pw_multi_aff(pma);
   7193  1.1  mrg }
   7194  1.1  mrg 
   7195  1.1  mrg /* Do "pa1" and "pa2" represent the same function?
   7196  1.1  mrg  *
   7197  1.1  mrg  * We first check if they are obviously equal.
   7198  1.1  mrg  * If not, we convert them to maps and check if those are equal.
   7199  1.1  mrg  *
   7200  1.1  mrg  * If "pa1" or "pa2" contain any NaNs, then they are considered
   7201  1.1  mrg  * not to be the same.  A NaN is not equal to anything, not even
   7202  1.1  mrg  * to another NaN.
   7203  1.1  mrg  */
   7204  1.1  mrg isl_bool isl_pw_aff_is_equal(__isl_keep isl_pw_aff *pa1,
   7205  1.1  mrg 	__isl_keep isl_pw_aff *pa2)
   7206  1.1  mrg {
   7207  1.1  mrg 	isl_bool equal;
   7208  1.1  mrg 	isl_bool has_nan;
   7209  1.1  mrg 	isl_map *map1, *map2;
   7210  1.1  mrg 
   7211  1.1  mrg 	if (!pa1 || !pa2)
   7212  1.1  mrg 		return isl_bool_error;
   7213  1.1  mrg 
   7214  1.1  mrg 	equal = isl_pw_aff_plain_is_equal(pa1, pa2);
   7215  1.1  mrg 	if (equal < 0 || equal)
   7216  1.1  mrg 		return equal;
   7217  1.1  mrg 	has_nan = either_involves_nan(pa1, pa2);
   7218  1.1  mrg 	if (has_nan < 0)
   7219  1.1  mrg 		return isl_bool_error;
   7220  1.1  mrg 	if (has_nan)
   7221  1.1  mrg 		return isl_bool_false;
   7222  1.1  mrg 
   7223  1.1  mrg 	map1 = isl_map_from_pw_aff_internal(isl_pw_aff_copy(pa1));
   7224  1.1  mrg 	map2 = isl_map_from_pw_aff_internal(isl_pw_aff_copy(pa2));
   7225  1.1  mrg 	equal = isl_map_is_equal(map1, map2);
   7226  1.1  mrg 	isl_map_free(map1);
   7227  1.1  mrg 	isl_map_free(map2);
   7228  1.1  mrg 
   7229  1.1  mrg 	return equal;
   7230  1.1  mrg }
   7231  1.1  mrg 
   7232  1.1  mrg /* Do "mpa1" and "mpa2" represent the same function?
   7233  1.1  mrg  *
   7234  1.1  mrg  * Note that we cannot convert the entire isl_multi_pw_aff
   7235  1.1  mrg  * to a map because the domains of the piecewise affine expressions
   7236  1.1  mrg  * may not be the same.
   7237  1.1  mrg  */
   7238  1.1  mrg isl_bool isl_multi_pw_aff_is_equal(__isl_keep isl_multi_pw_aff *mpa1,
   7239  1.1  mrg 	__isl_keep isl_multi_pw_aff *mpa2)
   7240  1.1  mrg {
   7241  1.1  mrg 	int i;
   7242  1.1  mrg 	isl_bool equal, equal_params;
   7243  1.1  mrg 
   7244  1.1  mrg 	if (!mpa1 || !mpa2)
   7245  1.1  mrg 		return isl_bool_error;
   7246  1.1  mrg 
   7247  1.1  mrg 	equal_params = isl_space_has_equal_params(mpa1->space, mpa2->space);
   7248  1.1  mrg 	if (equal_params < 0)
   7249  1.1  mrg 		return isl_bool_error;
   7250  1.1  mrg 	if (!equal_params) {
   7251  1.1  mrg 		if (!isl_space_has_named_params(mpa1->space))
   7252  1.1  mrg 			return isl_bool_false;
   7253  1.1  mrg 		if (!isl_space_has_named_params(mpa2->space))
   7254  1.1  mrg 			return isl_bool_false;
   7255  1.1  mrg 		mpa1 = isl_multi_pw_aff_copy(mpa1);
   7256  1.1  mrg 		mpa2 = isl_multi_pw_aff_copy(mpa2);
   7257  1.1  mrg 		mpa1 = isl_multi_pw_aff_align_params(mpa1,
   7258  1.1  mrg 					    isl_multi_pw_aff_get_space(mpa2));
   7259  1.1  mrg 		mpa2 = isl_multi_pw_aff_align_params(mpa2,
   7260  1.1  mrg 					    isl_multi_pw_aff_get_space(mpa1));
   7261  1.1  mrg 		equal = isl_multi_pw_aff_is_equal(mpa1, mpa2);
   7262  1.1  mrg 		isl_multi_pw_aff_free(mpa1);
   7263  1.1  mrg 		isl_multi_pw_aff_free(mpa2);
   7264  1.1  mrg 		return equal;
   7265  1.1  mrg 	}
   7266  1.1  mrg 
   7267  1.1  mrg 	equal = isl_space_is_equal(mpa1->space, mpa2->space);
   7268  1.1  mrg 	if (equal < 0 || !equal)
   7269  1.1  mrg 		return equal;
   7270  1.1  mrg 
   7271  1.1  mrg 	for (i = 0; i < mpa1->n; ++i) {
   7272  1.1  mrg 		equal = isl_pw_aff_is_equal(mpa1->u.p[i], mpa2->u.p[i]);
   7273  1.1  mrg 		if (equal < 0 || !equal)
   7274  1.1  mrg 			return equal;
   7275  1.1  mrg 	}
   7276  1.1  mrg 
   7277  1.1  mrg 	return isl_bool_true;
   7278  1.1  mrg }
   7279  1.1  mrg 
   7280  1.1  mrg /* Do "pma1" and "pma2" represent the same function?
   7281  1.1  mrg  *
   7282  1.1  mrg  * First check if they are obviously equal.
   7283  1.1  mrg  * If not, then convert them to maps and check if those are equal.
   7284  1.1  mrg  *
   7285  1.1  mrg  * If "pa1" or "pa2" contain any NaNs, then they are considered
   7286  1.1  mrg  * not to be the same.  A NaN is not equal to anything, not even
   7287  1.1  mrg  * to another NaN.
   7288  1.1  mrg  */
   7289  1.1  mrg isl_bool isl_pw_multi_aff_is_equal(__isl_keep isl_pw_multi_aff *pma1,
   7290  1.1  mrg 	__isl_keep isl_pw_multi_aff *pma2)
   7291  1.1  mrg {
   7292  1.1  mrg 	isl_bool equal;
   7293  1.1  mrg 	isl_bool has_nan;
   7294  1.1  mrg 	isl_map *map1, *map2;
   7295  1.1  mrg 
   7296  1.1  mrg 	if (!pma1 || !pma2)
   7297  1.1  mrg 		return isl_bool_error;
   7298  1.1  mrg 
   7299  1.1  mrg 	equal = isl_pw_multi_aff_plain_is_equal(pma1, pma2);
   7300  1.1  mrg 	if (equal < 0 || equal)
   7301  1.1  mrg 		return equal;
   7302  1.1  mrg 	has_nan = isl_pw_multi_aff_involves_nan(pma1);
   7303  1.1  mrg 	if (has_nan >= 0 && !has_nan)
   7304  1.1  mrg 		has_nan = isl_pw_multi_aff_involves_nan(pma2);
   7305  1.1  mrg 	if (has_nan < 0 || has_nan)
   7306  1.1  mrg 		return isl_bool_not(has_nan);
   7307  1.1  mrg 
   7308  1.1  mrg 	map1 = isl_map_from_pw_multi_aff_internal(isl_pw_multi_aff_copy(pma1));
   7309  1.1  mrg 	map2 = isl_map_from_pw_multi_aff_internal(isl_pw_multi_aff_copy(pma2));
   7310  1.1  mrg 	equal = isl_map_is_equal(map1, map2);
   7311  1.1  mrg 	isl_map_free(map1);
   7312  1.1  mrg 	isl_map_free(map2);
   7313  1.1  mrg 
   7314  1.1  mrg 	return equal;
   7315  1.1  mrg }
   7316  1.1  mrg 
   7317  1.1  mrg #undef BASE
   7318  1.1  mrg #define BASE	multi_aff
   7319  1.1  mrg 
   7320  1.1  mrg #include "isl_multi_pw_aff_pullback_templ.c"
   7321  1.1  mrg 
   7322  1.1  mrg #undef BASE
   7323  1.1  mrg #define BASE	pw_multi_aff
   7324  1.1  mrg 
   7325  1.1  mrg #include "isl_multi_pw_aff_pullback_templ.c"
   7326  1.1  mrg 
   7327  1.1  mrg /* Apply "aff" to "mpa".  The range of "mpa" needs to be compatible
   7328  1.1  mrg  * with the domain of "aff".  The domain of the result is the same
   7329  1.1  mrg  * as that of "mpa".
   7330  1.1  mrg  * "mpa" and "aff" are assumed to have been aligned.
   7331  1.1  mrg  *
   7332  1.1  mrg  * We first extract the parametric constant from "aff", defined
   7333  1.1  mrg  * over the correct domain.
   7334  1.1  mrg  * Then we add the appropriate combinations of the members of "mpa".
   7335  1.1  mrg  * Finally, we add the integer divisions through recursive calls.
   7336  1.1  mrg  */
   7337  1.1  mrg static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff_aligned(
   7338  1.1  mrg 	__isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff)
   7339  1.1  mrg {
   7340  1.1  mrg 	int i;
   7341  1.1  mrg 	isl_size n_in, n_div, n_mpa_in;
   7342  1.1  mrg 	isl_space *space;
   7343  1.1  mrg 	isl_val *v;
   7344  1.1  mrg 	isl_pw_aff *pa;
   7345  1.1  mrg 	isl_aff *tmp;
   7346  1.1  mrg 
   7347  1.1  mrg 	n_in = isl_aff_dim(aff, isl_dim_in);
   7348  1.1  mrg 	n_div = isl_aff_dim(aff, isl_dim_div);
   7349  1.1  mrg 	n_mpa_in = isl_multi_pw_aff_dim(mpa, isl_dim_in);
   7350  1.1  mrg 	if (n_in < 0 || n_div < 0 || n_mpa_in < 0)
   7351  1.1  mrg 		goto error;
   7352  1.1  mrg 
   7353  1.1  mrg 	space = isl_space_domain(isl_multi_pw_aff_get_space(mpa));
   7354  1.1  mrg 	tmp = isl_aff_copy(aff);
   7355  1.1  mrg 	tmp = isl_aff_drop_dims(tmp, isl_dim_div, 0, n_div);
   7356  1.1  mrg 	tmp = isl_aff_drop_dims(tmp, isl_dim_in, 0, n_in);
   7357  1.1  mrg 	tmp = isl_aff_add_dims(tmp, isl_dim_in, n_mpa_in);
   7358  1.1  mrg 	tmp = isl_aff_reset_domain_space(tmp, space);
   7359  1.1  mrg 	pa = isl_pw_aff_from_aff(tmp);
   7360  1.1  mrg 
   7361  1.1  mrg 	for (i = 0; i < n_in; ++i) {
   7362  1.1  mrg 		isl_pw_aff *pa_i;
   7363  1.1  mrg 
   7364  1.1  mrg 		if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1))
   7365  1.1  mrg 			continue;
   7366  1.1  mrg 		v = isl_aff_get_coefficient_val(aff, isl_dim_in, i);
   7367  1.1  mrg 		pa_i = isl_multi_pw_aff_get_pw_aff(mpa, i);
   7368  1.1  mrg 		pa_i = isl_pw_aff_scale_val(pa_i, v);
   7369  1.1  mrg 		pa = isl_pw_aff_add(pa, pa_i);
   7370  1.1  mrg 	}
   7371  1.1  mrg 
   7372  1.1  mrg 	for (i = 0; i < n_div; ++i) {
   7373  1.1  mrg 		isl_aff *div;
   7374  1.1  mrg 		isl_pw_aff *pa_i;
   7375  1.1  mrg 
   7376  1.1  mrg 		if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1))
   7377  1.1  mrg 			continue;
   7378  1.1  mrg 		div = isl_aff_get_div(aff, i);
   7379  1.1  mrg 		pa_i = isl_multi_pw_aff_apply_aff_aligned(
   7380  1.1  mrg 					    isl_multi_pw_aff_copy(mpa), div);
   7381  1.1  mrg 		pa_i = isl_pw_aff_floor(pa_i);
   7382  1.1  mrg 		v = isl_aff_get_coefficient_val(aff, isl_dim_div, i);
   7383  1.1  mrg 		pa_i = isl_pw_aff_scale_val(pa_i, v);
   7384  1.1  mrg 		pa = isl_pw_aff_add(pa, pa_i);
   7385  1.1  mrg 	}
   7386  1.1  mrg 
   7387  1.1  mrg 	isl_multi_pw_aff_free(mpa);
   7388  1.1  mrg 	isl_aff_free(aff);
   7389  1.1  mrg 
   7390  1.1  mrg 	return pa;
   7391  1.1  mrg error:
   7392  1.1  mrg 	isl_multi_pw_aff_free(mpa);
   7393  1.1  mrg 	isl_aff_free(aff);
   7394  1.1  mrg 	return NULL;
   7395  1.1  mrg }
   7396  1.1  mrg 
   7397  1.1  mrg /* Apply "aff" to "mpa".  The range of "mpa" needs to be compatible
   7398  1.1  mrg  * with the domain of "aff".  The domain of the result is the same
   7399  1.1  mrg  * as that of "mpa".
   7400  1.1  mrg  */
   7401  1.1  mrg __isl_give isl_pw_aff *isl_multi_pw_aff_apply_aff(
   7402  1.1  mrg 	__isl_take isl_multi_pw_aff *mpa, __isl_take isl_aff *aff)
   7403  1.1  mrg {
   7404  1.1  mrg 	isl_bool equal_params;
   7405  1.1  mrg 
   7406  1.1  mrg 	if (!aff || !mpa)
   7407  1.1  mrg 		goto error;
   7408  1.1  mrg 	equal_params = isl_space_has_equal_params(aff->ls->dim, mpa->space);
   7409  1.1  mrg 	if (equal_params < 0)
   7410  1.1  mrg 		goto error;
   7411  1.1  mrg 	if (equal_params)
   7412  1.1  mrg 		return isl_multi_pw_aff_apply_aff_aligned(mpa, aff);
   7413  1.1  mrg 
   7414  1.1  mrg 	aff = isl_aff_align_params(aff, isl_multi_pw_aff_get_space(mpa));
   7415  1.1  mrg 	mpa = isl_multi_pw_aff_align_params(mpa, isl_aff_get_space(aff));
   7416  1.1  mrg 
   7417  1.1  mrg 	return isl_multi_pw_aff_apply_aff_aligned(mpa, aff);
   7418  1.1  mrg error:
   7419  1.1  mrg 	isl_aff_free(aff);
   7420  1.1  mrg 	isl_multi_pw_aff_free(mpa);
   7421  1.1  mrg 	return NULL;
   7422  1.1  mrg }
   7423  1.1  mrg 
   7424  1.1  mrg /* Apply "pa" to "mpa".  The range of "mpa" needs to be compatible
   7425  1.1  mrg  * with the domain of "pa".  The domain of the result is the same
   7426  1.1  mrg  * as that of "mpa".
   7427  1.1  mrg  * "mpa" and "pa" are assumed to have been aligned.
   7428  1.1  mrg  *
   7429  1.1  mrg  * We consider each piece in turn.  Note that the domains of the
   7430  1.1  mrg  * pieces are assumed to be disjoint and they remain disjoint
   7431  1.1  mrg  * after taking the preimage (over the same function).
   7432  1.1  mrg  */
   7433  1.1  mrg static __isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff_aligned(
   7434  1.1  mrg 	__isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa)
   7435  1.1  mrg {
   7436  1.1  mrg 	isl_space *space;
   7437  1.1  mrg 	isl_pw_aff *res;
   7438  1.1  mrg 	int i;
   7439  1.1  mrg 
   7440  1.1  mrg 	if (!mpa || !pa)
   7441  1.1  mrg 		goto error;
   7442  1.1  mrg 
   7443  1.1  mrg 	space = isl_space_join(isl_multi_pw_aff_get_space(mpa),
   7444  1.1  mrg 				isl_pw_aff_get_space(pa));
   7445  1.1  mrg 	res = isl_pw_aff_empty(space);
   7446  1.1  mrg 
   7447  1.1  mrg 	for (i = 0; i < pa->n; ++i) {
   7448  1.1  mrg 		isl_pw_aff *pa_i;
   7449  1.1  mrg 		isl_set *domain;
   7450  1.1  mrg 
   7451  1.1  mrg 		pa_i = isl_multi_pw_aff_apply_aff_aligned(
   7452  1.1  mrg 					isl_multi_pw_aff_copy(mpa),
   7453  1.1  mrg 					isl_aff_copy(pa->p[i].aff));
   7454  1.1  mrg 		domain = isl_set_copy(pa->p[i].set);
   7455  1.1  mrg 		domain = isl_set_preimage_multi_pw_aff(domain,
   7456  1.1  mrg 					isl_multi_pw_aff_copy(mpa));
   7457  1.1  mrg 		pa_i = isl_pw_aff_intersect_domain(pa_i, domain);
   7458  1.1  mrg 		res = isl_pw_aff_add_disjoint(res, pa_i);
   7459  1.1  mrg 	}
   7460  1.1  mrg 
   7461  1.1  mrg 	isl_pw_aff_free(pa);
   7462  1.1  mrg 	isl_multi_pw_aff_free(mpa);
   7463  1.1  mrg 	return res;
   7464  1.1  mrg error:
   7465  1.1  mrg 	isl_pw_aff_free(pa);
   7466  1.1  mrg 	isl_multi_pw_aff_free(mpa);
   7467  1.1  mrg 	return NULL;
   7468  1.1  mrg }
   7469  1.1  mrg 
   7470  1.1  mrg /* Apply "pa" to "mpa".  The range of "mpa" needs to be compatible
   7471  1.1  mrg  * with the domain of "pa".  The domain of the result is the same
   7472  1.1  mrg  * as that of "mpa".
   7473  1.1  mrg  */
   7474  1.1  mrg __isl_give isl_pw_aff *isl_multi_pw_aff_apply_pw_aff(
   7475  1.1  mrg 	__isl_take isl_multi_pw_aff *mpa, __isl_take isl_pw_aff *pa)
   7476  1.1  mrg {
   7477  1.1  mrg 	isl_bool equal_params;
   7478  1.1  mrg 
   7479  1.1  mrg 	if (!pa || !mpa)
   7480  1.1  mrg 		goto error;
   7481  1.1  mrg 	equal_params = isl_space_has_equal_params(pa->dim, mpa->space);
   7482  1.1  mrg 	if (equal_params < 0)
   7483  1.1  mrg 		goto error;
   7484  1.1  mrg 	if (equal_params)
   7485  1.1  mrg 		return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
   7486  1.1  mrg 
   7487  1.1  mrg 	pa = isl_pw_aff_align_params(pa, isl_multi_pw_aff_get_space(mpa));
   7488  1.1  mrg 	mpa = isl_multi_pw_aff_align_params(mpa, isl_pw_aff_get_space(pa));
   7489  1.1  mrg 
   7490  1.1  mrg 	return isl_multi_pw_aff_apply_pw_aff_aligned(mpa, pa);
   7491  1.1  mrg error:
   7492  1.1  mrg 	isl_pw_aff_free(pa);
   7493  1.1  mrg 	isl_multi_pw_aff_free(mpa);
   7494  1.1  mrg 	return NULL;
   7495  1.1  mrg }
   7496  1.1  mrg 
   7497  1.1  mrg /* Compute the pullback of "pa" by the function represented by "mpa".
   7498  1.1  mrg  * In other words, plug in "mpa" in "pa".
   7499  1.1  mrg  *
   7500  1.1  mrg  * The pullback is computed by applying "pa" to "mpa".
   7501  1.1  mrg  */
   7502  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_pullback_multi_pw_aff(
   7503  1.1  mrg 	__isl_take isl_pw_aff *pa, __isl_take isl_multi_pw_aff *mpa)
   7504  1.1  mrg {
   7505  1.1  mrg 	return isl_multi_pw_aff_apply_pw_aff(mpa, pa);
   7506  1.1  mrg }
   7507  1.1  mrg 
   7508  1.1  mrg #undef BASE
   7509  1.1  mrg #define BASE	multi_pw_aff
   7510  1.1  mrg 
   7511  1.1  mrg #include "isl_multi_pw_aff_pullback_templ.c"
   7512  1.1  mrg 
   7513  1.1  mrg /* Align the parameters of "mpa1" and "mpa2", check that the ranges
   7514  1.1  mrg  * of "mpa1" and "mpa2" live in the same space, construct map space
   7515  1.1  mrg  * between the domain spaces of "mpa1" and "mpa2" and call "order"
   7516  1.1  mrg  * with this map space as extract argument.
   7517  1.1  mrg  */
   7518  1.1  mrg static __isl_give isl_map *isl_multi_pw_aff_order_map(
   7519  1.1  mrg 	__isl_take isl_multi_pw_aff *mpa1, __isl_take isl_multi_pw_aff *mpa2,
   7520  1.1  mrg 	__isl_give isl_map *(*order)(__isl_keep isl_multi_pw_aff *mpa1,
   7521  1.1  mrg 		__isl_keep isl_multi_pw_aff *mpa2, __isl_take isl_space *space))
   7522  1.1  mrg {
   7523  1.1  mrg 	int match;
   7524  1.1  mrg 	isl_space *space1, *space2;
   7525  1.1  mrg 	isl_map *res;
   7526  1.1  mrg 
   7527  1.1  mrg 	mpa1 = isl_multi_pw_aff_align_params(mpa1,
   7528  1.1  mrg 					    isl_multi_pw_aff_get_space(mpa2));
   7529  1.1  mrg 	mpa2 = isl_multi_pw_aff_align_params(mpa2,
   7530  1.1  mrg 					    isl_multi_pw_aff_get_space(mpa1));
   7531  1.1  mrg 	if (!mpa1 || !mpa2)
   7532  1.1  mrg 		goto error;
   7533  1.1  mrg 	match = isl_space_tuple_is_equal(mpa1->space, isl_dim_out,
   7534  1.1  mrg 					mpa2->space, isl_dim_out);
   7535  1.1  mrg 	if (match < 0)
   7536  1.1  mrg 		goto error;
   7537  1.1  mrg 	if (!match)
   7538  1.1  mrg 		isl_die(isl_multi_pw_aff_get_ctx(mpa1), isl_error_invalid,
   7539  1.1  mrg 			"range spaces don't match", goto error);
   7540  1.1  mrg 	space1 = isl_space_domain(isl_multi_pw_aff_get_space(mpa1));
   7541  1.1  mrg 	space2 = isl_space_domain(isl_multi_pw_aff_get_space(mpa2));
   7542  1.1  mrg 	space1 = isl_space_map_from_domain_and_range(space1, space2);
   7543  1.1  mrg 
   7544  1.1  mrg 	res = order(mpa1, mpa2, space1);
   7545  1.1  mrg 	isl_multi_pw_aff_free(mpa1);
   7546  1.1  mrg 	isl_multi_pw_aff_free(mpa2);
   7547  1.1  mrg 	return res;
   7548  1.1  mrg error:
   7549  1.1  mrg 	isl_multi_pw_aff_free(mpa1);
   7550  1.1  mrg 	isl_multi_pw_aff_free(mpa2);
   7551  1.1  mrg 	return NULL;
   7552  1.1  mrg }
   7553  1.1  mrg 
   7554  1.1  mrg /* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
   7555  1.1  mrg  * where the function values are equal.  "space" is the space of the result.
   7556  1.1  mrg  * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
   7557  1.1  mrg  *
   7558  1.1  mrg  * "mpa1" and "mpa2" are equal when each of the pairs of elements
   7559  1.1  mrg  * in the sequences are equal.
   7560  1.1  mrg  */
   7561  1.1  mrg static __isl_give isl_map *isl_multi_pw_aff_eq_map_on_space(
   7562  1.1  mrg 	__isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2,
   7563  1.1  mrg 	__isl_take isl_space *space)
   7564  1.1  mrg {
   7565  1.1  mrg 	int i;
   7566  1.1  mrg 	isl_size n;
   7567  1.1  mrg 	isl_map *res;
   7568  1.1  mrg 
   7569  1.1  mrg 	n = isl_multi_pw_aff_dim(mpa1, isl_dim_out);
   7570  1.1  mrg 	if (n < 0)
   7571  1.1  mrg 		space = isl_space_free(space);
   7572  1.1  mrg 	res = isl_map_universe(space);
   7573  1.1  mrg 
   7574  1.1  mrg 	for (i = 0; i < n; ++i) {
   7575  1.1  mrg 		isl_pw_aff *pa1, *pa2;
   7576  1.1  mrg 		isl_map *map;
   7577  1.1  mrg 
   7578  1.1  mrg 		pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
   7579  1.1  mrg 		pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
   7580  1.1  mrg 		map = isl_pw_aff_eq_map(pa1, pa2);
   7581  1.1  mrg 		res = isl_map_intersect(res, map);
   7582  1.1  mrg 	}
   7583  1.1  mrg 
   7584  1.1  mrg 	return res;
   7585  1.1  mrg }
   7586  1.1  mrg 
   7587  1.1  mrg /* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
   7588  1.1  mrg  * where the function values are equal.
   7589  1.1  mrg  */
   7590  1.1  mrg __isl_give isl_map *isl_multi_pw_aff_eq_map(__isl_take isl_multi_pw_aff *mpa1,
   7591  1.1  mrg 	__isl_take isl_multi_pw_aff *mpa2)
   7592  1.1  mrg {
   7593  1.1  mrg 	return isl_multi_pw_aff_order_map(mpa1, mpa2,
   7594  1.1  mrg 					    &isl_multi_pw_aff_eq_map_on_space);
   7595  1.1  mrg }
   7596  1.1  mrg 
   7597  1.1  mrg /* Intersect "map" with the result of applying "order"
   7598  1.1  mrg  * on two copies of "mpa".
   7599  1.1  mrg  */
   7600  1.1  mrg static __isl_give isl_map *isl_map_order_at_multi_pw_aff(
   7601  1.1  mrg 	__isl_take isl_map *map, __isl_take isl_multi_pw_aff *mpa,
   7602  1.1  mrg 	__isl_give isl_map *(*order)(__isl_take isl_multi_pw_aff *mpa1,
   7603  1.1  mrg 		__isl_take isl_multi_pw_aff *mpa2))
   7604  1.1  mrg {
   7605  1.1  mrg 	return isl_map_intersect(map, order(mpa, isl_multi_pw_aff_copy(mpa)));
   7606  1.1  mrg }
   7607  1.1  mrg 
   7608  1.1  mrg /* Return the subset of "map" where the domain and the range
   7609  1.1  mrg  * have equal "mpa" values.
   7610  1.1  mrg  */
   7611  1.1  mrg __isl_give isl_map *isl_map_eq_at_multi_pw_aff(__isl_take isl_map *map,
   7612  1.1  mrg 	__isl_take isl_multi_pw_aff *mpa)
   7613  1.1  mrg {
   7614  1.1  mrg 	return isl_map_order_at_multi_pw_aff(map, mpa,
   7615  1.1  mrg 						&isl_multi_pw_aff_eq_map);
   7616  1.1  mrg }
   7617  1.1  mrg 
   7618  1.1  mrg /* Return a map containing pairs of elements in the domains of "mpa1" and "mpa2"
   7619  1.1  mrg  * where the function values of "mpa1" lexicographically satisfies
   7620  1.1  mrg  * "strict_base"/"base" compared to that of "mpa2".
   7621  1.1  mrg  * "space" is the space of the result.
   7622  1.1  mrg  * The parameters of "mpa1" and "mpa2" are assumed to have been aligned.
   7623  1.1  mrg  *
   7624  1.1  mrg  * "mpa1" lexicographically satisfies "strict_base"/"base" compared to "mpa2"
   7625  1.1  mrg  * if, for some i, the i-th element of "mpa1" satisfies "strict_base"/"base"
   7626  1.1  mrg  * when compared to the i-th element of "mpa2" while all previous elements are
   7627  1.1  mrg  * pairwise equal.
   7628  1.1  mrg  * In particular, if i corresponds to the final elements
   7629  1.1  mrg  * then they need to satisfy "base", while "strict_base" needs to be satisfied
   7630  1.1  mrg  * for other values of i.
   7631  1.1  mrg  * If "base" is a strict order, then "base" and "strict_base" are the same.
   7632  1.1  mrg  */
   7633  1.1  mrg static __isl_give isl_map *isl_multi_pw_aff_lex_map_on_space(
   7634  1.1  mrg 	__isl_keep isl_multi_pw_aff *mpa1, __isl_keep isl_multi_pw_aff *mpa2,
   7635  1.1  mrg 	__isl_give isl_map *(*strict_base)(__isl_take isl_pw_aff *pa1,
   7636  1.1  mrg 		__isl_take isl_pw_aff *pa2),
   7637  1.1  mrg 	__isl_give isl_map *(*base)(__isl_take isl_pw_aff *pa1,
   7638  1.1  mrg 		__isl_take isl_pw_aff *pa2),
   7639  1.1  mrg 	__isl_take isl_space *space)
   7640  1.1  mrg {
   7641  1.1  mrg 	int i;
   7642  1.1  mrg 	isl_size n;
   7643  1.1  mrg 	isl_map *res, *rest;
   7644  1.1  mrg 
   7645  1.1  mrg 	n = isl_multi_pw_aff_dim(mpa1, isl_dim_out);
   7646  1.1  mrg 	if (n < 0)
   7647  1.1  mrg 		space = isl_space_free(space);
   7648  1.1  mrg 	res = isl_map_empty(isl_space_copy(space));
   7649  1.1  mrg 	rest = isl_map_universe(space);
   7650  1.1  mrg 
   7651  1.1  mrg 	for (i = 0; i < n; ++i) {
   7652  1.1  mrg 		int last;
   7653  1.1  mrg 		isl_pw_aff *pa1, *pa2;
   7654  1.1  mrg 		isl_map *map;
   7655  1.1  mrg 
   7656  1.1  mrg 		last = i == n - 1;
   7657  1.1  mrg 
   7658  1.1  mrg 		pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
   7659  1.1  mrg 		pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
   7660  1.1  mrg 		map = last ? base(pa1, pa2) : strict_base(pa1, pa2);
   7661  1.1  mrg 		map = isl_map_intersect(map, isl_map_copy(rest));
   7662  1.1  mrg 		res = isl_map_union(res, map);
   7663  1.1  mrg 
   7664  1.1  mrg 		if (last)
   7665  1.1  mrg 			continue;
   7666  1.1  mrg 
   7667  1.1  mrg 		pa1 = isl_multi_pw_aff_get_pw_aff(mpa1, i);
   7668  1.1  mrg 		pa2 = isl_multi_pw_aff_get_pw_aff(mpa2, i);
   7669  1.1  mrg 		map = isl_pw_aff_eq_map(pa1, pa2);
   7670  1.1  mrg 		rest = isl_map_intersect(rest, map);
   7671  1.1  mrg 	}
   7672  1.1  mrg 
   7673  1.1  mrg 	isl_map_free(rest);
   7674  1.1  mrg 	return res;
   7675  1.1  mrg }
   7676  1.1  mrg 
   7677  1.1  mrg #undef ORDER
   7678  1.1  mrg #define ORDER		le
   7679  1.1  mrg #undef STRICT_ORDER
   7680  1.1  mrg #define STRICT_ORDER	lt
   7681  1.1  mrg #include "isl_aff_lex_templ.c"
   7682  1.1  mrg 
   7683  1.1  mrg #undef ORDER
   7684  1.1  mrg #define ORDER		lt
   7685  1.1  mrg #undef STRICT_ORDER
   7686  1.1  mrg #define STRICT_ORDER	lt
   7687  1.1  mrg #include "isl_aff_lex_templ.c"
   7688  1.1  mrg 
   7689  1.1  mrg #undef ORDER
   7690  1.1  mrg #define ORDER		ge
   7691  1.1  mrg #undef STRICT_ORDER
   7692  1.1  mrg #define STRICT_ORDER	gt
   7693  1.1  mrg #include "isl_aff_lex_templ.c"
   7694  1.1  mrg 
   7695  1.1  mrg #undef ORDER
   7696  1.1  mrg #define ORDER		gt
   7697  1.1  mrg #undef STRICT_ORDER
   7698  1.1  mrg #define STRICT_ORDER	gt
   7699  1.1  mrg #include "isl_aff_lex_templ.c"
   7700  1.1  mrg 
   7701  1.1  mrg /* Compare two isl_affs.
   7702  1.1  mrg  *
   7703  1.1  mrg  * Return -1 if "aff1" is "smaller" than "aff2", 1 if "aff1" is "greater"
   7704  1.1  mrg  * than "aff2" and 0 if they are equal.
   7705  1.1  mrg  *
   7706  1.1  mrg  * The order is fairly arbitrary.  We do consider expressions that only involve
   7707  1.1  mrg  * earlier dimensions as "smaller".
   7708  1.1  mrg  */
   7709  1.1  mrg int isl_aff_plain_cmp(__isl_keep isl_aff *aff1, __isl_keep isl_aff *aff2)
   7710  1.1  mrg {
   7711  1.1  mrg 	int cmp;
   7712  1.1  mrg 	int last1, last2;
   7713  1.1  mrg 
   7714  1.1  mrg 	if (aff1 == aff2)
   7715  1.1  mrg 		return 0;
   7716  1.1  mrg 
   7717  1.1  mrg 	if (!aff1)
   7718  1.1  mrg 		return -1;
   7719  1.1  mrg 	if (!aff2)
   7720  1.1  mrg 		return 1;
   7721  1.1  mrg 
   7722  1.1  mrg 	cmp = isl_local_space_cmp(aff1->ls, aff2->ls);
   7723  1.1  mrg 	if (cmp != 0)
   7724  1.1  mrg 		return cmp;
   7725  1.1  mrg 
   7726  1.1  mrg 	last1 = isl_seq_last_non_zero(aff1->v->el + 1, aff1->v->size - 1);
   7727  1.1  mrg 	last2 = isl_seq_last_non_zero(aff2->v->el + 1, aff1->v->size - 1);
   7728  1.1  mrg 	if (last1 != last2)
   7729  1.1  mrg 		return last1 - last2;
   7730  1.1  mrg 
   7731  1.1  mrg 	return isl_seq_cmp(aff1->v->el, aff2->v->el, aff1->v->size);
   7732  1.1  mrg }
   7733  1.1  mrg 
   7734  1.1  mrg /* Compare two isl_pw_affs.
   7735  1.1  mrg  *
   7736  1.1  mrg  * Return -1 if "pa1" is "smaller" than "pa2", 1 if "pa1" is "greater"
   7737  1.1  mrg  * than "pa2" and 0 if they are equal.
   7738  1.1  mrg  *
   7739  1.1  mrg  * The order is fairly arbitrary.  We do consider expressions that only involve
   7740  1.1  mrg  * earlier dimensions as "smaller".
   7741  1.1  mrg  */
   7742  1.1  mrg int isl_pw_aff_plain_cmp(__isl_keep isl_pw_aff *pa1,
   7743  1.1  mrg 	__isl_keep isl_pw_aff *pa2)
   7744  1.1  mrg {
   7745  1.1  mrg 	int i;
   7746  1.1  mrg 	int cmp;
   7747  1.1  mrg 
   7748  1.1  mrg 	if (pa1 == pa2)
   7749  1.1  mrg 		return 0;
   7750  1.1  mrg 
   7751  1.1  mrg 	if (!pa1)
   7752  1.1  mrg 		return -1;
   7753  1.1  mrg 	if (!pa2)
   7754  1.1  mrg 		return 1;
   7755  1.1  mrg 
   7756  1.1  mrg 	cmp = isl_space_cmp(pa1->dim, pa2->dim);
   7757  1.1  mrg 	if (cmp != 0)
   7758  1.1  mrg 		return cmp;
   7759  1.1  mrg 
   7760  1.1  mrg 	if (pa1->n != pa2->n)
   7761  1.1  mrg 		return pa1->n - pa2->n;
   7762  1.1  mrg 
   7763  1.1  mrg 	for (i = 0; i < pa1->n; ++i) {
   7764  1.1  mrg 		cmp = isl_set_plain_cmp(pa1->p[i].set, pa2->p[i].set);
   7765  1.1  mrg 		if (cmp != 0)
   7766  1.1  mrg 			return cmp;
   7767  1.1  mrg 		cmp = isl_aff_plain_cmp(pa1->p[i].aff, pa2->p[i].aff);
   7768  1.1  mrg 		if (cmp != 0)
   7769  1.1  mrg 			return cmp;
   7770  1.1  mrg 	}
   7771  1.1  mrg 
   7772  1.1  mrg 	return 0;
   7773  1.1  mrg }
   7774  1.1  mrg 
   7775  1.1  mrg /* Return a piecewise affine expression that is equal to "v" on "domain".
   7776  1.1  mrg  */
   7777  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_val_on_domain(__isl_take isl_set *domain,
   7778  1.1  mrg 	__isl_take isl_val *v)
   7779  1.1  mrg {
   7780  1.1  mrg 	isl_space *space;
   7781  1.1  mrg 	isl_local_space *ls;
   7782  1.1  mrg 	isl_aff *aff;
   7783  1.1  mrg 
   7784  1.1  mrg 	space = isl_set_get_space(domain);
   7785  1.1  mrg 	ls = isl_local_space_from_space(space);
   7786  1.1  mrg 	aff = isl_aff_val_on_domain(ls, v);
   7787  1.1  mrg 
   7788  1.1  mrg 	return isl_pw_aff_alloc(domain, aff);
   7789  1.1  mrg }
   7790  1.1  mrg 
   7791  1.1  mrg /* This function performs the same operation as isl_pw_aff_val_on_domain,
   7792  1.1  mrg  * but is considered as a function on an isl_set when exported.
   7793  1.1  mrg  */
   7794  1.1  mrg __isl_give isl_pw_aff *isl_set_pw_aff_on_domain_val(__isl_take isl_set *domain,
   7795  1.1  mrg 	__isl_take isl_val *v)
   7796  1.1  mrg {
   7797  1.1  mrg 	return isl_pw_aff_val_on_domain(domain, v);
   7798  1.1  mrg }
   7799  1.1  mrg 
   7800  1.1  mrg /* Return a piecewise affine expression that is equal to the parameter
   7801  1.1  mrg  * with identifier "id" on "domain".
   7802  1.1  mrg  */
   7803  1.1  mrg __isl_give isl_pw_aff *isl_pw_aff_param_on_domain_id(
   7804  1.1  mrg 	__isl_take isl_set *domain, __isl_take isl_id *id)
   7805  1.1  mrg {
   7806  1.1  mrg 	isl_space *space;
   7807  1.1  mrg 	isl_aff *aff;
   7808  1.1  mrg 
   7809  1.1  mrg 	space = isl_set_get_space(domain);
   7810  1.1  mrg 	space = isl_space_add_param_id(space, isl_id_copy(id));
   7811  1.1  mrg 	domain = isl_set_align_params(domain, isl_space_copy(space));
   7812  1.1  mrg 	aff = isl_aff_param_on_domain_space_id(space, id);
   7813  1.1  mrg 
   7814  1.1  mrg 	return isl_pw_aff_alloc(domain, aff);
   7815  1.1  mrg }
   7816  1.1  mrg 
   7817  1.1  mrg /* This function performs the same operation as
   7818  1.1  mrg  * isl_pw_aff_param_on_domain_id,
   7819  1.1  mrg  * but is considered as a function on an isl_set when exported.
   7820  1.1  mrg  */
   7821  1.1  mrg __isl_give isl_pw_aff *isl_set_param_pw_aff_on_domain_id(
   7822  1.1  mrg 	__isl_take isl_set *domain, __isl_take isl_id *id)
   7823  1.1  mrg {
   7824  1.1  mrg 	return isl_pw_aff_param_on_domain_id(domain, id);
   7825  1.1  mrg }
   7826  1.1  mrg 
   7827  1.1  mrg /* Return a multi affine expression that is equal to "mv" on domain
   7828  1.1  mrg  * space "space".
   7829  1.1  mrg  */
   7830  1.1  mrg __isl_give isl_multi_aff *isl_multi_aff_multi_val_on_domain_space(
   7831  1.1  mrg 	__isl_take isl_space *space, __isl_take isl_multi_val *mv)
   7832  1.1  mrg {
   7833  1.1  mrg 	int i;
   7834  1.1  mrg 	isl_size n;
   7835  1.1  mrg 	isl_space *space2;
   7836  1.1  mrg 	isl_local_space *ls;
   7837  1.1  mrg 	isl_multi_aff *ma;
   7838  1.1  mrg 
   7839  1.1  mrg 	n = isl_multi_val_dim(mv, isl_dim_set);
   7840  1.1  mrg 	if (!space || n < 0)
   7841  1.1  mrg 		goto error;
   7842  1.1  mrg 
   7843  1.1  mrg 	space2 = isl_multi_val_get_space(mv);
   7844  1.1  mrg 	space2 = isl_space_align_params(space2, isl_space_copy(space));
   7845  1.1  mrg 	space = isl_space_align_params(space, isl_space_copy(space2));
   7846  1.1  mrg 	space = isl_space_map_from_domain_and_range(space, space2);
   7847  1.1  mrg 	ma = isl_multi_aff_alloc(isl_space_copy(space));
   7848  1.1  mrg 	ls = isl_local_space_from_space(isl_space_domain(space));
   7849  1.1  mrg 	for (i = 0; i < n; ++i) {
   7850  1.1  mrg 		isl_val *v;
   7851  1.1  mrg 		isl_aff *aff;
   7852  1.1  mrg 
   7853  1.1  mrg 		v = isl_multi_val_get_val(mv, i);
   7854  1.1  mrg 		aff = isl_aff_val_on_domain(isl_local_space_copy(ls), v);
   7855  1.1  mrg 		ma = isl_multi_aff_set_aff(ma, i, aff);
   7856  1.1  mrg 	}
   7857  1.1  mrg 	isl_local_space_free(ls);
   7858  1.1  mrg 
   7859  1.1  mrg 	isl_multi_val_free(mv);
   7860  1.1  mrg 	return ma;
   7861  1.1  mrg error:
   7862  1.1  mrg 	isl_space_free(space);
   7863  1.1  mrg 	isl_multi_val_free(mv);
   7864  1.1  mrg 	return NULL;
   7865  1.1  mrg }
   7866  1.1  mrg 
   7867  1.1  mrg /* This is an alternative name for the function above.
   7868  1.1  mrg  */
   7869  1.1  mrg __isl_give isl_multi_aff *isl_multi_aff_multi_val_on_space(
   7870  1.1  mrg 	__isl_take isl_space *space, __isl_take isl_multi_val *mv)
   7871  1.1  mrg {
   7872  1.1  mrg 	return isl_multi_aff_multi_val_on_domain_space(space, mv);
   7873  1.1  mrg }
   7874  1.1  mrg 
   7875  1.1  mrg /* This function performs the same operation as
   7876  1.1  mrg  * isl_multi_aff_multi_val_on_domain_space,
   7877  1.1  mrg  * but is considered as a function on an isl_space when exported.
   7878  1.1  mrg  */
   7879  1.1  mrg __isl_give isl_multi_aff *isl_space_multi_aff_on_domain_multi_val(
   7880  1.1  mrg 	__isl_take isl_space *space, __isl_take isl_multi_val *mv)
   7881  1.1  mrg {
   7882  1.1  mrg 	return isl_multi_aff_multi_val_on_domain_space(space, mv);
   7883  1.1  mrg }
   7884  1.1  mrg 
   7885  1.1  mrg /* Return a piecewise multi-affine expression
   7886  1.1  mrg  * that is equal to "mv" on "domain".
   7887  1.1  mrg  */
   7888  1.1  mrg __isl_give isl_pw_multi_aff *isl_pw_multi_aff_multi_val_on_domain(
   7889  1.1  mrg 	__isl_take isl_set *domain, __isl_take isl_multi_val *mv)
   7890  1.1  mrg {
   7891  1.1  mrg 	isl_space *space;
   7892  1.1  mrg 	isl_multi_aff *ma;
   7893  1.1  mrg 
   7894  1.1  mrg 	space = isl_set_get_space(domain);
   7895  1.1  mrg 	ma = isl_multi_aff_multi_val_on_space(space, mv);
   7896  1.1  mrg 
   7897  1.1  mrg 	return isl_pw_multi_aff_alloc(domain, ma);
   7898  1.1  mrg }
   7899  1.1  mrg 
   7900  1.1  mrg /* This function performs the same operation as
   7901  1.1  mrg  * isl_pw_multi_aff_multi_val_on_domain,
   7902  1.1  mrg  * but is considered as a function on an isl_set when exported.
   7903  1.1  mrg  */
   7904  1.1  mrg __isl_give isl_pw_multi_aff *isl_set_pw_multi_aff_on_domain_multi_val(
   7905  1.1  mrg 	__isl_take isl_set *domain, __isl_take isl_multi_val *mv)
   7906  1.1  mrg {
   7907  1.1  mrg 	return isl_pw_multi_aff_multi_val_on_domain(domain, mv);
   7908  1.1  mrg }
   7909  1.1  mrg 
   7910  1.1  mrg /* Internal data structure for isl_union_pw_multi_aff_multi_val_on_domain.
   7911  1.1  mrg  * mv is the value that should be attained on each domain set
   7912  1.1  mrg  * res collects the results
   7913  1.1  mrg  */
   7914  1.1  mrg struct isl_union_pw_multi_aff_multi_val_on_domain_data {
   7915  1.1  mrg 	isl_multi_val *mv;
   7916  1.1  mrg 	isl_union_pw_multi_aff *res;
   7917  1.1  mrg };
   7918  1.1  mrg 
   7919  1.1  mrg /* Create an isl_pw_multi_aff equal to data->mv on "domain"
   7920  1.1  mrg  * and add it to data->res.
   7921  1.1  mrg  */
   7922  1.1  mrg static isl_stat pw_multi_aff_multi_val_on_domain(__isl_take isl_set *domain,
   7923  1.1  mrg 	void *user)
   7924  1.1  mrg {
   7925  1.1  mrg 	struct isl_union_pw_multi_aff_multi_val_on_domain_data *data = user;
   7926  1.1  mrg 	isl_pw_multi_aff *pma;
   7927  1.1  mrg 	isl_multi_val *mv;
   7928  1.1  mrg 
   7929  1.1  mrg 	mv = isl_multi_val_copy(data->mv);
   7930  1.1  mrg 	pma = isl_pw_multi_aff_multi_val_on_domain(domain, mv);
   7931  1.1  mrg 	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma);
   7932  1.1  mrg 
   7933  1.1  mrg 	return data->res ? isl_stat_ok : isl_stat_error;
   7934  1.1  mrg }
   7935  1.1  mrg 
   7936  1.1  mrg /* Return a union piecewise multi-affine expression
   7937  1.1  mrg  * that is equal to "mv" on "domain".
   7938  1.1  mrg  */
   7939  1.1  mrg __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_multi_val_on_domain(
   7940  1.1  mrg 	__isl_take isl_union_set *domain, __isl_take isl_multi_val *mv)
   7941  1.1  mrg {
   7942  1.1  mrg 	struct isl_union_pw_multi_aff_multi_val_on_domain_data data;
   7943  1.1  mrg 	isl_space *space;
   7944  1.1  mrg 
   7945  1.1  mrg 	space = isl_union_set_get_space(domain);
   7946  1.1  mrg 	data.res = isl_union_pw_multi_aff_empty(space);
   7947  1.1  mrg 	data.mv = mv;
   7948  1.1  mrg 	if (isl_union_set_foreach_set(domain,
   7949  1.1  mrg 			&pw_multi_aff_multi_val_on_domain, &data) < 0)
   7950  1.1  mrg 		data.res = isl_union_pw_multi_aff_free(data.res);
   7951  1.1  mrg 	isl_union_set_free(domain);
   7952  1.1  mrg 	isl_multi_val_free(mv);
   7953  1.1  mrg 	return data.res;
   7954  1.1  mrg }
   7955  1.1  mrg 
   7956  1.1  mrg /* Compute the pullback of data->pma by the function represented by "pma2",
   7957  1.1  mrg  * provided the spaces match, and add the results to data->res.
   7958  1.1  mrg  */
   7959  1.1  mrg static isl_stat pullback_entry(__isl_take isl_pw_multi_aff *pma2, void *user)
   7960  1.1  mrg {
   7961  1.1  mrg 	struct isl_union_pw_multi_aff_bin_data *data = user;
   7962  1.1  mrg 
   7963  1.1  mrg 	if (!isl_space_tuple_is_equal(data->pma->dim, isl_dim_in,
   7964  1.1  mrg 				 pma2->dim, isl_dim_out)) {
   7965  1.1  mrg 		isl_pw_multi_aff_free(pma2);
   7966  1.1  mrg 		return isl_stat_ok;
   7967  1.1  mrg 	}
   7968  1.1  mrg 
   7969  1.1  mrg 	pma2 = isl_pw_multi_aff_pullback_pw_multi_aff(
   7970  1.1  mrg 					isl_pw_multi_aff_copy(data->pma), pma2);
   7971  1.1  mrg 
   7972  1.1  mrg 	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
   7973  1.1  mrg 	if (!data->res)
   7974  1.1  mrg 		return isl_stat_error;
   7975  1.1  mrg 
   7976  1.1  mrg 	return isl_stat_ok;
   7977  1.1  mrg }
   7978  1.1  mrg 
   7979  1.1  mrg /* Compute the pullback of "upma1" by the function represented by "upma2".
   7980  1.1  mrg  */
   7981  1.1  mrg __isl_give isl_union_pw_multi_aff *
   7982  1.1  mrg isl_union_pw_multi_aff_pullback_union_pw_multi_aff(
   7983  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma1,
   7984  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma2)
   7985  1.1  mrg {
   7986  1.1  mrg 	return bin_op(upma1, upma2, &pullback_entry);
   7987  1.1  mrg }
   7988  1.1  mrg 
   7989  1.1  mrg /* Apply "upma2" to "upma1".
   7990  1.1  mrg  *
   7991  1.1  mrg  * That is, compute the pullback of "upma2" by "upma1".
   7992  1.1  mrg  */
   7993  1.1  mrg __isl_give isl_union_pw_multi_aff *
   7994  1.1  mrg isl_union_pw_multi_aff_apply_union_pw_multi_aff(
   7995  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma1,
   7996  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma2)
   7997  1.1  mrg {
   7998  1.1  mrg 	return isl_union_pw_multi_aff_pullback_union_pw_multi_aff(upma2, upma1);
   7999  1.1  mrg }
   8000  1.1  mrg 
   8001  1.1  mrg #undef BASE
   8002  1.1  mrg #define BASE pw_multi_aff
   8003  1.1  mrg static
   8004  1.1  mrg #include "isl_copy_tuple_id_templ.c"
   8005  1.1  mrg 
   8006  1.1  mrg /* Given a function "pma1" of the form A[B -> C] -> D and
   8007  1.1  mrg  * a function "pma2" of the form E -> B,
   8008  1.1  mrg  * replace the domain of the wrapped relation inside the domain of "pma1"
   8009  1.1  mrg  * by the preimage with respect to "pma2".
   8010  1.1  mrg  * In other words, plug in "pma2" in this nested domain.
   8011  1.1  mrg  * The result is of the form A[E -> C] -> D.
   8012  1.1  mrg  *
   8013  1.1  mrg  * In particular, extend E -> B to A[E -> C] -> A[B -> C] and
   8014  1.1  mrg  * plug that into "pma1".
   8015  1.1  mrg  */
   8016  1.1  mrg __isl_give isl_pw_multi_aff *
   8017  1.1  mrg isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(
   8018  1.1  mrg 	__isl_take isl_pw_multi_aff *pma1, __isl_take isl_pw_multi_aff *pma2)
   8019  1.1  mrg {
   8020  1.1  mrg 	isl_space *pma1_space, *pma2_space;
   8021  1.1  mrg 	isl_space *space;
   8022  1.1  mrg 	isl_pw_multi_aff *id;
   8023  1.1  mrg 
   8024  1.1  mrg 	pma1_space = isl_pw_multi_aff_peek_space(pma1);
   8025  1.1  mrg 	pma2_space = isl_pw_multi_aff_peek_space(pma2);
   8026  1.1  mrg 
   8027  1.1  mrg 	if (isl_space_check_domain_is_wrapping(pma1_space) < 0)
   8028  1.1  mrg 		goto error;
   8029  1.1  mrg 	if (isl_space_check_wrapped_tuple_is_equal(pma1_space,
   8030  1.1  mrg 			isl_dim_in, isl_dim_in, pma2_space, isl_dim_out) < 0)
   8031  1.1  mrg 		goto error;
   8032  1.1  mrg 
   8033  1.1  mrg 	space = isl_space_domain(isl_space_copy(pma1_space));
   8034  1.1  mrg 	space = isl_space_range(isl_space_unwrap(space));
   8035  1.1  mrg 	id = isl_pw_multi_aff_identity_on_domain_space(space);
   8036  1.1  mrg 	pma2 = isl_pw_multi_aff_product(pma2, id);
   8037  1.1  mrg 
   8038  1.1  mrg 	pma2 = isl_pw_multi_aff_copy_tuple_id(pma2, isl_dim_in,
   8039  1.1  mrg 						pma1_space, isl_dim_in);
   8040  1.1  mrg 	pma2 = isl_pw_multi_aff_copy_tuple_id(pma2, isl_dim_out,
   8041  1.1  mrg 						pma1_space, isl_dim_in);
   8042  1.1  mrg 
   8043  1.1  mrg 	return isl_pw_multi_aff_pullback_pw_multi_aff(pma1, pma2);
   8044  1.1  mrg error:
   8045  1.1  mrg 	isl_pw_multi_aff_free(pma1);
   8046  1.1  mrg 	isl_pw_multi_aff_free(pma2);
   8047  1.1  mrg 	return NULL;
   8048  1.1  mrg }
   8049  1.1  mrg 
   8050  1.1  mrg /* If data->pma and "pma2" are such that
   8051  1.1  mrg  * data->pma is of the form A[B -> C] -> D and
   8052  1.1  mrg  * "pma2" is of the form E -> B,
   8053  1.1  mrg  * then replace the domain of the wrapped relation
   8054  1.1  mrg  * inside the domain of data->pma by the preimage with respect to "pma2" and
   8055  1.1  mrg  * add the result to data->res.
   8056  1.1  mrg  */
   8057  1.1  mrg static isl_stat preimage_domain_wrapped_domain_entry(
   8058  1.1  mrg 	__isl_take isl_pw_multi_aff *pma2, void *user)
   8059  1.1  mrg {
   8060  1.1  mrg 	struct isl_union_pw_multi_aff_bin_data *data = user;
   8061  1.1  mrg 	isl_space *pma1_space, *pma2_space;
   8062  1.1  mrg 	isl_bool match;
   8063  1.1  mrg 
   8064  1.1  mrg 	pma1_space = isl_pw_multi_aff_peek_space(data->pma);
   8065  1.1  mrg 	pma2_space = isl_pw_multi_aff_peek_space(pma2);
   8066  1.1  mrg 
   8067  1.1  mrg 	match = isl_space_domain_is_wrapping(pma1_space);
   8068  1.1  mrg 	if (match >= 0 && match)
   8069  1.1  mrg 		match = isl_space_wrapped_tuple_is_equal(pma1_space, isl_dim_in,
   8070  1.1  mrg 					isl_dim_in, pma2_space, isl_dim_out);
   8071  1.1  mrg 	if (match < 0 || !match) {
   8072  1.1  mrg 		isl_pw_multi_aff_free(pma2);
   8073  1.1  mrg 		return match < 0 ? isl_stat_error : isl_stat_ok;
   8074  1.1  mrg 	}
   8075  1.1  mrg 
   8076  1.1  mrg 	pma2 = isl_pw_multi_aff_preimage_domain_wrapped_domain_pw_multi_aff(
   8077  1.1  mrg 		isl_pw_multi_aff_copy(data->pma), pma2);
   8078  1.1  mrg 
   8079  1.1  mrg 	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma2);
   8080  1.1  mrg 
   8081  1.1  mrg 	return isl_stat_non_null(data->res);
   8082  1.1  mrg }
   8083  1.1  mrg 
   8084  1.1  mrg /* For each pair of functions A[B -> C] -> D in "upma1" and
   8085  1.1  mrg  * E -> B in "upma2",
   8086  1.1  mrg  * replace the domain of the wrapped relation inside the domain of the first
   8087  1.1  mrg  * by the preimage with respect to the second and collect the results.
   8088  1.1  mrg  * In other words, plug in the second function in this nested domain.
   8089  1.1  mrg  * The results are of the form A[E -> C] -> D.
   8090  1.1  mrg  */
   8091  1.1  mrg __isl_give isl_union_pw_multi_aff *
   8092  1.1  mrg isl_union_pw_multi_aff_preimage_domain_wrapped_domain_union_pw_multi_aff(
   8093  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma1,
   8094  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma2)
   8095  1.1  mrg {
   8096  1.1  mrg 	return bin_op(upma1, upma2, &preimage_domain_wrapped_domain_entry);
   8097  1.1  mrg }
   8098  1.1  mrg 
   8099  1.1  mrg /* Check that the domain space of "upa" matches "space".
   8100  1.1  mrg  *
   8101  1.1  mrg  * This function is called from isl_multi_union_pw_aff_set_union_pw_aff and
   8102  1.1  mrg  * can in principle never fail since the space "space" is that
   8103  1.1  mrg  * of the isl_multi_union_pw_aff and is a set space such that
   8104  1.1  mrg  * there is no domain space to match.
   8105  1.1  mrg  *
   8106  1.1  mrg  * We check the parameters and double-check that "space" is
   8107  1.1  mrg  * indeed that of a set.
   8108  1.1  mrg  */
   8109  1.1  mrg static isl_stat isl_union_pw_aff_check_match_domain_space(
   8110  1.1  mrg 	__isl_keep isl_union_pw_aff *upa, __isl_keep isl_space *space)
   8111  1.1  mrg {
   8112  1.1  mrg 	isl_space *upa_space;
   8113  1.1  mrg 	isl_bool match;
   8114  1.1  mrg 
   8115  1.1  mrg 	if (!upa || !space)
   8116  1.1  mrg 		return isl_stat_error;
   8117  1.1  mrg 
   8118  1.1  mrg 	match = isl_space_is_set(space);
   8119  1.1  mrg 	if (match < 0)
   8120  1.1  mrg 		return isl_stat_error;
   8121  1.1  mrg 	if (!match)
   8122  1.1  mrg 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   8123  1.1  mrg 			"expecting set space", return isl_stat_error);
   8124  1.1  mrg 
   8125  1.1  mrg 	upa_space = isl_union_pw_aff_get_space(upa);
   8126  1.1  mrg 	match = isl_space_has_equal_params(space, upa_space);
   8127  1.1  mrg 	if (match < 0)
   8128  1.1  mrg 		goto error;
   8129  1.1  mrg 	if (!match)
   8130  1.1  mrg 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   8131  1.1  mrg 			"parameters don't match", goto error);
   8132  1.1  mrg 
   8133  1.1  mrg 	isl_space_free(upa_space);
   8134  1.1  mrg 	return isl_stat_ok;
   8135  1.1  mrg error:
   8136  1.1  mrg 	isl_space_free(upa_space);
   8137  1.1  mrg 	return isl_stat_error;
   8138  1.1  mrg }
   8139  1.1  mrg 
   8140  1.1  mrg /* Do the parameters of "upa" match those of "space"?
   8141  1.1  mrg  */
   8142  1.1  mrg static isl_bool isl_union_pw_aff_matching_params(
   8143  1.1  mrg 	__isl_keep isl_union_pw_aff *upa, __isl_keep isl_space *space)
   8144  1.1  mrg {
   8145  1.1  mrg 	isl_space *upa_space;
   8146  1.1  mrg 	isl_bool match;
   8147  1.1  mrg 
   8148  1.1  mrg 	if (!upa || !space)
   8149  1.1  mrg 		return isl_bool_error;
   8150  1.1  mrg 
   8151  1.1  mrg 	upa_space = isl_union_pw_aff_get_space(upa);
   8152  1.1  mrg 
   8153  1.1  mrg 	match = isl_space_has_equal_params(space, upa_space);
   8154  1.1  mrg 
   8155  1.1  mrg 	isl_space_free(upa_space);
   8156  1.1  mrg 	return match;
   8157  1.1  mrg }
   8158  1.1  mrg 
   8159  1.1  mrg /* Internal data structure for isl_union_pw_aff_reset_domain_space.
   8160  1.1  mrg  * space represents the new parameters.
   8161  1.1  mrg  * res collects the results.
   8162  1.1  mrg  */
   8163  1.1  mrg struct isl_union_pw_aff_reset_params_data {
   8164  1.1  mrg 	isl_space *space;
   8165  1.1  mrg 	isl_union_pw_aff *res;
   8166  1.1  mrg };
   8167  1.1  mrg 
   8168  1.1  mrg /* Replace the parameters of "pa" by data->space and
   8169  1.1  mrg  * add the result to data->res.
   8170  1.1  mrg  */
   8171  1.1  mrg static isl_stat reset_params(__isl_take isl_pw_aff *pa, void *user)
   8172  1.1  mrg {
   8173  1.1  mrg 	struct isl_union_pw_aff_reset_params_data *data = user;
   8174  1.1  mrg 	isl_space *space;
   8175  1.1  mrg 
   8176  1.1  mrg 	space = isl_pw_aff_get_space(pa);
   8177  1.1  mrg 	space = isl_space_replace_params(space, data->space);
   8178  1.1  mrg 	pa = isl_pw_aff_reset_space(pa, space);
   8179  1.1  mrg 	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
   8180  1.1  mrg 
   8181  1.1  mrg 	return data->res ? isl_stat_ok : isl_stat_error;
   8182  1.1  mrg }
   8183  1.1  mrg 
   8184  1.1  mrg /* Replace the domain space of "upa" by "space".
   8185  1.1  mrg  * Since a union expression does not have a (single) domain space,
   8186  1.1  mrg  * "space" is necessarily a parameter space.
   8187  1.1  mrg  *
   8188  1.1  mrg  * Since the order and the names of the parameters determine
   8189  1.1  mrg  * the hash value, we need to create a new hash table.
   8190  1.1  mrg  */
   8191  1.1  mrg static __isl_give isl_union_pw_aff *isl_union_pw_aff_reset_domain_space(
   8192  1.1  mrg 	__isl_take isl_union_pw_aff *upa, __isl_take isl_space *space)
   8193  1.1  mrg {
   8194  1.1  mrg 	struct isl_union_pw_aff_reset_params_data data = { space };
   8195  1.1  mrg 	isl_bool match;
   8196  1.1  mrg 
   8197  1.1  mrg 	match = isl_union_pw_aff_matching_params(upa, space);
   8198  1.1  mrg 	if (match < 0)
   8199  1.1  mrg 		upa = isl_union_pw_aff_free(upa);
   8200  1.1  mrg 	else if (match) {
   8201  1.1  mrg 		isl_space_free(space);
   8202  1.1  mrg 		return upa;
   8203  1.1  mrg 	}
   8204  1.1  mrg 
   8205  1.1  mrg 	data.res = isl_union_pw_aff_empty(isl_space_copy(space));
   8206  1.1  mrg 	if (isl_union_pw_aff_foreach_pw_aff(upa, &reset_params, &data) < 0)
   8207  1.1  mrg 		data.res = isl_union_pw_aff_free(data.res);
   8208  1.1  mrg 
   8209  1.1  mrg 	isl_union_pw_aff_free(upa);
   8210  1.1  mrg 	isl_space_free(space);
   8211  1.1  mrg 	return data.res;
   8212  1.1  mrg }
   8213  1.1  mrg 
   8214  1.1  mrg /* Return the floor of "pa".
   8215  1.1  mrg  */
   8216  1.1  mrg static __isl_give isl_pw_aff *floor_entry(__isl_take isl_pw_aff *pa, void *user)
   8217  1.1  mrg {
   8218  1.1  mrg 	return isl_pw_aff_floor(pa);
   8219  1.1  mrg }
   8220  1.1  mrg 
   8221  1.1  mrg /* Given f, return floor(f).
   8222  1.1  mrg  */
   8223  1.1  mrg __isl_give isl_union_pw_aff *isl_union_pw_aff_floor(
   8224  1.1  mrg 	__isl_take isl_union_pw_aff *upa)
   8225  1.1  mrg {
   8226  1.1  mrg 	return isl_union_pw_aff_transform_inplace(upa, &floor_entry, NULL);
   8227  1.1  mrg }
   8228  1.1  mrg 
   8229  1.1  mrg /* Compute
   8230  1.1  mrg  *
   8231  1.1  mrg  *	upa mod m = upa - m * floor(upa/m)
   8232  1.1  mrg  *
   8233  1.1  mrg  * with m an integer value.
   8234  1.1  mrg  */
   8235  1.1  mrg __isl_give isl_union_pw_aff *isl_union_pw_aff_mod_val(
   8236  1.1  mrg 	__isl_take isl_union_pw_aff *upa, __isl_take isl_val *m)
   8237  1.1  mrg {
   8238  1.1  mrg 	isl_union_pw_aff *res;
   8239  1.1  mrg 
   8240  1.1  mrg 	if (!upa || !m)
   8241  1.1  mrg 		goto error;
   8242  1.1  mrg 
   8243  1.1  mrg 	if (!isl_val_is_int(m))
   8244  1.1  mrg 		isl_die(isl_val_get_ctx(m), isl_error_invalid,
   8245  1.1  mrg 			"expecting integer modulo", goto error);
   8246  1.1  mrg 	if (!isl_val_is_pos(m))
   8247  1.1  mrg 		isl_die(isl_val_get_ctx(m), isl_error_invalid,
   8248  1.1  mrg 			"expecting positive modulo", goto error);
   8249  1.1  mrg 
   8250  1.1  mrg 	res = isl_union_pw_aff_copy(upa);
   8251  1.1  mrg 	upa = isl_union_pw_aff_scale_down_val(upa, isl_val_copy(m));
   8252  1.1  mrg 	upa = isl_union_pw_aff_floor(upa);
   8253  1.1  mrg 	upa = isl_union_pw_aff_scale_val(upa, m);
   8254  1.1  mrg 	res = isl_union_pw_aff_sub(res, upa);
   8255  1.1  mrg 
   8256  1.1  mrg 	return res;
   8257  1.1  mrg error:
   8258  1.1  mrg 	isl_val_free(m);
   8259  1.1  mrg 	isl_union_pw_aff_free(upa);
   8260  1.1  mrg 	return NULL;
   8261  1.1  mrg }
   8262  1.1  mrg 
   8263  1.1  mrg /* Internal data structure for isl_union_pw_multi_aff_get_union_pw_aff.
   8264  1.1  mrg  * pos is the output position that needs to be extracted.
   8265  1.1  mrg  * res collects the results.
   8266  1.1  mrg  */
   8267  1.1  mrg struct isl_union_pw_multi_aff_get_union_pw_aff_data {
   8268  1.1  mrg 	int pos;
   8269  1.1  mrg 	isl_union_pw_aff *res;
   8270  1.1  mrg };
   8271  1.1  mrg 
   8272  1.1  mrg /* Extract an isl_pw_aff corresponding to output dimension "pos" of "pma"
   8273  1.1  mrg  * (assuming it has such a dimension) and add it to data->res.
   8274  1.1  mrg  */
   8275  1.1  mrg static isl_stat get_union_pw_aff(__isl_take isl_pw_multi_aff *pma, void *user)
   8276  1.1  mrg {
   8277  1.1  mrg 	struct isl_union_pw_multi_aff_get_union_pw_aff_data *data = user;
   8278  1.1  mrg 	isl_size n_out;
   8279  1.1  mrg 	isl_pw_aff *pa;
   8280  1.1  mrg 
   8281  1.1  mrg 	n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
   8282  1.1  mrg 	if (n_out < 0)
   8283  1.1  mrg 		return isl_stat_error;
   8284  1.1  mrg 	if (data->pos >= n_out) {
   8285  1.1  mrg 		isl_pw_multi_aff_free(pma);
   8286  1.1  mrg 		return isl_stat_ok;
   8287  1.1  mrg 	}
   8288  1.1  mrg 
   8289  1.1  mrg 	pa = isl_pw_multi_aff_get_pw_aff(pma, data->pos);
   8290  1.1  mrg 	isl_pw_multi_aff_free(pma);
   8291  1.1  mrg 
   8292  1.1  mrg 	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
   8293  1.1  mrg 
   8294  1.1  mrg 	return data->res ? isl_stat_ok : isl_stat_error;
   8295  1.1  mrg }
   8296  1.1  mrg 
   8297  1.1  mrg /* Extract an isl_union_pw_aff corresponding to
   8298  1.1  mrg  * output dimension "pos" of "upma".
   8299  1.1  mrg  */
   8300  1.1  mrg __isl_give isl_union_pw_aff *isl_union_pw_multi_aff_get_union_pw_aff(
   8301  1.1  mrg 	__isl_keep isl_union_pw_multi_aff *upma, int pos)
   8302  1.1  mrg {
   8303  1.1  mrg 	struct isl_union_pw_multi_aff_get_union_pw_aff_data data;
   8304  1.1  mrg 	isl_space *space;
   8305  1.1  mrg 
   8306  1.1  mrg 	if (!upma)
   8307  1.1  mrg 		return NULL;
   8308  1.1  mrg 
   8309  1.1  mrg 	if (pos < 0)
   8310  1.1  mrg 		isl_die(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid,
   8311  1.1  mrg 			"cannot extract at negative position", return NULL);
   8312  1.1  mrg 
   8313  1.1  mrg 	space = isl_union_pw_multi_aff_get_space(upma);
   8314  1.1  mrg 	data.res = isl_union_pw_aff_empty(space);
   8315  1.1  mrg 	data.pos = pos;
   8316  1.1  mrg 	if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
   8317  1.1  mrg 						&get_union_pw_aff, &data) < 0)
   8318  1.1  mrg 		data.res = isl_union_pw_aff_free(data.res);
   8319  1.1  mrg 
   8320  1.1  mrg 	return data.res;
   8321  1.1  mrg }
   8322  1.1  mrg 
   8323  1.1  mrg /* Return a union piecewise affine expression
   8324  1.1  mrg  * that is equal to "aff" on "domain".
   8325  1.1  mrg  */
   8326  1.1  mrg __isl_give isl_union_pw_aff *isl_union_pw_aff_aff_on_domain(
   8327  1.1  mrg 	__isl_take isl_union_set *domain, __isl_take isl_aff *aff)
   8328  1.1  mrg {
   8329  1.1  mrg 	isl_pw_aff *pa;
   8330  1.1  mrg 
   8331  1.1  mrg 	pa = isl_pw_aff_from_aff(aff);
   8332  1.1  mrg 	return isl_union_pw_aff_pw_aff_on_domain(domain, pa);
   8333  1.1  mrg }
   8334  1.1  mrg 
   8335  1.1  mrg /* Return a union piecewise affine expression
   8336  1.1  mrg  * that is equal to the parameter identified by "id" on "domain".
   8337  1.1  mrg  *
   8338  1.1  mrg  * Make sure the parameter appears in the space passed to
   8339  1.1  mrg  * isl_aff_param_on_domain_space_id.
   8340  1.1  mrg  */
   8341  1.1  mrg __isl_give isl_union_pw_aff *isl_union_pw_aff_param_on_domain_id(
   8342  1.1  mrg 	__isl_take isl_union_set *domain, __isl_take isl_id *id)
   8343  1.1  mrg {
   8344  1.1  mrg 	isl_space *space;
   8345  1.1  mrg 	isl_aff *aff;
   8346  1.1  mrg 
   8347  1.1  mrg 	space = isl_union_set_get_space(domain);
   8348  1.1  mrg 	space = isl_space_add_param_id(space, isl_id_copy(id));
   8349  1.1  mrg 	aff = isl_aff_param_on_domain_space_id(space, id);
   8350  1.1  mrg 	return isl_union_pw_aff_aff_on_domain(domain, aff);
   8351  1.1  mrg }
   8352  1.1  mrg 
   8353  1.1  mrg /* Internal data structure for isl_union_pw_aff_pw_aff_on_domain.
   8354  1.1  mrg  * "pa" is the piecewise symbolic value that the resulting isl_union_pw_aff
   8355  1.1  mrg  * needs to attain.
   8356  1.1  mrg  * "res" collects the results.
   8357  1.1  mrg  */
   8358  1.1  mrg struct isl_union_pw_aff_pw_aff_on_domain_data {
   8359  1.1  mrg 	isl_pw_aff *pa;
   8360  1.1  mrg 	isl_union_pw_aff *res;
   8361  1.1  mrg };
   8362  1.1  mrg 
   8363  1.1  mrg /* Construct a piecewise affine expression that is equal to data->pa
   8364  1.1  mrg  * on "domain" and add the result to data->res.
   8365  1.1  mrg  */
   8366  1.1  mrg static isl_stat pw_aff_on_domain(__isl_take isl_set *domain, void *user)
   8367  1.1  mrg {
   8368  1.1  mrg 	struct isl_union_pw_aff_pw_aff_on_domain_data *data = user;
   8369  1.1  mrg 	isl_pw_aff *pa;
   8370  1.1  mrg 	isl_size dim;
   8371  1.1  mrg 
   8372  1.1  mrg 	pa = isl_pw_aff_copy(data->pa);
   8373  1.1  mrg 	dim = isl_set_dim(domain, isl_dim_set);
   8374  1.1  mrg 	if (dim < 0)
   8375  1.1  mrg 		pa = isl_pw_aff_free(pa);
   8376  1.1  mrg 	pa = isl_pw_aff_from_range(pa);
   8377  1.1  mrg 	pa = isl_pw_aff_add_dims(pa, isl_dim_in, dim);
   8378  1.1  mrg 	pa = isl_pw_aff_reset_domain_space(pa, isl_set_get_space(domain));
   8379  1.1  mrg 	pa = isl_pw_aff_intersect_domain(pa, domain);
   8380  1.1  mrg 	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
   8381  1.1  mrg 
   8382  1.1  mrg 	return data->res ? isl_stat_ok : isl_stat_error;
   8383  1.1  mrg }
   8384  1.1  mrg 
   8385  1.1  mrg /* Return a union piecewise affine expression
   8386  1.1  mrg  * that is equal to "pa" on "domain", assuming "domain" and "pa"
   8387  1.1  mrg  * have been aligned.
   8388  1.1  mrg  *
   8389  1.1  mrg  * Construct an isl_pw_aff on each of the sets in "domain" and
   8390  1.1  mrg  * collect the results.
   8391  1.1  mrg  */
   8392  1.1  mrg static __isl_give isl_union_pw_aff *isl_union_pw_aff_pw_aff_on_domain_aligned(
   8393  1.1  mrg 	__isl_take isl_union_set *domain, __isl_take isl_pw_aff *pa)
   8394  1.1  mrg {
   8395  1.1  mrg 	struct isl_union_pw_aff_pw_aff_on_domain_data data;
   8396  1.1  mrg 	isl_space *space;
   8397  1.1  mrg 
   8398  1.1  mrg 	space = isl_union_set_get_space(domain);
   8399  1.1  mrg 	data.res = isl_union_pw_aff_empty(space);
   8400  1.1  mrg 	data.pa = pa;
   8401  1.1  mrg 	if (isl_union_set_foreach_set(domain, &pw_aff_on_domain, &data) < 0)
   8402  1.1  mrg 		data.res = isl_union_pw_aff_free(data.res);
   8403  1.1  mrg 	isl_union_set_free(domain);
   8404  1.1  mrg 	isl_pw_aff_free(pa);
   8405  1.1  mrg 	return data.res;
   8406  1.1  mrg }
   8407  1.1  mrg 
   8408  1.1  mrg /* Return a union piecewise affine expression
   8409  1.1  mrg  * that is equal to "pa" on "domain".
   8410  1.1  mrg  *
   8411  1.1  mrg  * Check that "pa" is a parametric expression,
   8412  1.1  mrg  * align the parameters if needed and call
   8413  1.1  mrg  * isl_union_pw_aff_pw_aff_on_domain_aligned.
   8414  1.1  mrg  */
   8415  1.1  mrg __isl_give isl_union_pw_aff *isl_union_pw_aff_pw_aff_on_domain(
   8416  1.1  mrg 	__isl_take isl_union_set *domain, __isl_take isl_pw_aff *pa)
   8417  1.1  mrg {
   8418  1.1  mrg 	isl_bool is_set;
   8419  1.1  mrg 	isl_bool equal_params;
   8420  1.1  mrg 	isl_space *domain_space, *pa_space;
   8421  1.1  mrg 
   8422  1.1  mrg 	pa_space = isl_pw_aff_peek_space(pa);
   8423  1.1  mrg 	is_set = isl_space_is_set(pa_space);
   8424  1.1  mrg 	if (is_set < 0)
   8425  1.1  mrg 		goto error;
   8426  1.1  mrg 	if (!is_set)
   8427  1.1  mrg 		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
   8428  1.1  mrg 			"expecting parametric expression", goto error);
   8429  1.1  mrg 
   8430  1.1  mrg 	domain_space = isl_union_set_get_space(domain);
   8431  1.1  mrg 	pa_space = isl_pw_aff_get_space(pa);
   8432  1.1  mrg 	equal_params = isl_space_has_equal_params(domain_space, pa_space);
   8433  1.1  mrg 	if (equal_params >= 0 && !equal_params) {
   8434  1.1  mrg 		isl_space *space;
   8435  1.1  mrg 
   8436  1.1  mrg 		space = isl_space_align_params(domain_space, pa_space);
   8437  1.1  mrg 		pa = isl_pw_aff_align_params(pa, isl_space_copy(space));
   8438  1.1  mrg 		domain = isl_union_set_align_params(domain, space);
   8439  1.1  mrg 	} else {
   8440  1.1  mrg 		isl_space_free(domain_space);
   8441  1.1  mrg 		isl_space_free(pa_space);
   8442  1.1  mrg 	}
   8443  1.1  mrg 
   8444  1.1  mrg 	if (equal_params < 0)
   8445  1.1  mrg 		goto error;
   8446  1.1  mrg 	return isl_union_pw_aff_pw_aff_on_domain_aligned(domain, pa);
   8447  1.1  mrg error:
   8448  1.1  mrg 	isl_union_set_free(domain);
   8449  1.1  mrg 	isl_pw_aff_free(pa);
   8450  1.1  mrg 	return NULL;
   8451  1.1  mrg }
   8452  1.1  mrg 
   8453  1.1  mrg /* Internal data structure for isl_union_pw_aff_val_on_domain.
   8454  1.1  mrg  * "v" is the value that the resulting isl_union_pw_aff needs to attain.
   8455  1.1  mrg  * "res" collects the results.
   8456  1.1  mrg  */
   8457  1.1  mrg struct isl_union_pw_aff_val_on_domain_data {
   8458  1.1  mrg 	isl_val *v;
   8459  1.1  mrg 	isl_union_pw_aff *res;
   8460  1.1  mrg };
   8461  1.1  mrg 
   8462  1.1  mrg /* Construct a piecewise affine expression that is equal to data->v
   8463  1.1  mrg  * on "domain" and add the result to data->res.
   8464  1.1  mrg  */
   8465  1.1  mrg static isl_stat pw_aff_val_on_domain(__isl_take isl_set *domain, void *user)
   8466  1.1  mrg {
   8467  1.1  mrg 	struct isl_union_pw_aff_val_on_domain_data *data = user;
   8468  1.1  mrg 	isl_pw_aff *pa;
   8469  1.1  mrg 	isl_val *v;
   8470  1.1  mrg 
   8471  1.1  mrg 	v = isl_val_copy(data->v);
   8472  1.1  mrg 	pa = isl_pw_aff_val_on_domain(domain, v);
   8473  1.1  mrg 	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
   8474  1.1  mrg 
   8475  1.1  mrg 	return data->res ? isl_stat_ok : isl_stat_error;
   8476  1.1  mrg }
   8477  1.1  mrg 
   8478  1.1  mrg /* Return a union piecewise affine expression
   8479  1.1  mrg  * that is equal to "v" on "domain".
   8480  1.1  mrg  *
   8481  1.1  mrg  * Construct an isl_pw_aff on each of the sets in "domain" and
   8482  1.1  mrg  * collect the results.
   8483  1.1  mrg  */
   8484  1.1  mrg __isl_give isl_union_pw_aff *isl_union_pw_aff_val_on_domain(
   8485  1.1  mrg 	__isl_take isl_union_set *domain, __isl_take isl_val *v)
   8486  1.1  mrg {
   8487  1.1  mrg 	struct isl_union_pw_aff_val_on_domain_data data;
   8488  1.1  mrg 	isl_space *space;
   8489  1.1  mrg 
   8490  1.1  mrg 	space = isl_union_set_get_space(domain);
   8491  1.1  mrg 	data.res = isl_union_pw_aff_empty(space);
   8492  1.1  mrg 	data.v = v;
   8493  1.1  mrg 	if (isl_union_set_foreach_set(domain, &pw_aff_val_on_domain, &data) < 0)
   8494  1.1  mrg 		data.res = isl_union_pw_aff_free(data.res);
   8495  1.1  mrg 	isl_union_set_free(domain);
   8496  1.1  mrg 	isl_val_free(v);
   8497  1.1  mrg 	return data.res;
   8498  1.1  mrg }
   8499  1.1  mrg 
   8500  1.1  mrg /* Construct a piecewise multi affine expression
   8501  1.1  mrg  * that is equal to "pa" and add it to upma.
   8502  1.1  mrg  */
   8503  1.1  mrg static isl_stat pw_multi_aff_from_pw_aff_entry(__isl_take isl_pw_aff *pa,
   8504  1.1  mrg 	void *user)
   8505  1.1  mrg {
   8506  1.1  mrg 	isl_union_pw_multi_aff **upma = user;
   8507  1.1  mrg 	isl_pw_multi_aff *pma;
   8508  1.1  mrg 
   8509  1.1  mrg 	pma = isl_pw_multi_aff_from_pw_aff(pa);
   8510  1.1  mrg 	*upma = isl_union_pw_multi_aff_add_pw_multi_aff(*upma, pma);
   8511  1.1  mrg 
   8512  1.1  mrg 	return *upma ? isl_stat_ok : isl_stat_error;
   8513  1.1  mrg }
   8514  1.1  mrg 
   8515  1.1  mrg /* Construct and return a union piecewise multi affine expression
   8516  1.1  mrg  * that is equal to the given union piecewise affine expression.
   8517  1.1  mrg  */
   8518  1.1  mrg __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_from_union_pw_aff(
   8519  1.1  mrg 	__isl_take isl_union_pw_aff *upa)
   8520  1.1  mrg {
   8521  1.1  mrg 	isl_space *space;
   8522  1.1  mrg 	isl_union_pw_multi_aff *upma;
   8523  1.1  mrg 
   8524  1.1  mrg 	if (!upa)
   8525  1.1  mrg 		return NULL;
   8526  1.1  mrg 
   8527  1.1  mrg 	space = isl_union_pw_aff_get_space(upa);
   8528  1.1  mrg 	upma = isl_union_pw_multi_aff_empty(space);
   8529  1.1  mrg 
   8530  1.1  mrg 	if (isl_union_pw_aff_foreach_pw_aff(upa,
   8531  1.1  mrg 				&pw_multi_aff_from_pw_aff_entry, &upma) < 0)
   8532  1.1  mrg 		upma = isl_union_pw_multi_aff_free(upma);
   8533  1.1  mrg 
   8534  1.1  mrg 	isl_union_pw_aff_free(upa);
   8535  1.1  mrg 	return upma;
   8536  1.1  mrg }
   8537  1.1  mrg 
   8538  1.1  mrg /* Compute the set of elements in the domain of "pa" where it is zero and
   8539  1.1  mrg  * add this set to "uset".
   8540  1.1  mrg  */
   8541  1.1  mrg static isl_stat zero_union_set(__isl_take isl_pw_aff *pa, void *user)
   8542  1.1  mrg {
   8543  1.1  mrg 	isl_union_set **uset = (isl_union_set **)user;
   8544  1.1  mrg 
   8545  1.1  mrg 	*uset = isl_union_set_add_set(*uset, isl_pw_aff_zero_set(pa));
   8546  1.1  mrg 
   8547  1.1  mrg 	return *uset ? isl_stat_ok : isl_stat_error;
   8548  1.1  mrg }
   8549  1.1  mrg 
   8550  1.1  mrg /* Return a union set containing those elements in the domain
   8551  1.1  mrg  * of "upa" where it is zero.
   8552  1.1  mrg  */
   8553  1.1  mrg __isl_give isl_union_set *isl_union_pw_aff_zero_union_set(
   8554  1.1  mrg 	__isl_take isl_union_pw_aff *upa)
   8555  1.1  mrg {
   8556  1.1  mrg 	isl_union_set *zero;
   8557  1.1  mrg 
   8558  1.1  mrg 	zero = isl_union_set_empty(isl_union_pw_aff_get_space(upa));
   8559  1.1  mrg 	if (isl_union_pw_aff_foreach_pw_aff(upa, &zero_union_set, &zero) < 0)
   8560  1.1  mrg 		zero = isl_union_set_free(zero);
   8561  1.1  mrg 
   8562  1.1  mrg 	isl_union_pw_aff_free(upa);
   8563  1.1  mrg 	return zero;
   8564  1.1  mrg }
   8565  1.1  mrg 
   8566  1.1  mrg /* Internal data structure for isl_union_pw_aff_bind_id,
   8567  1.1  mrg  * storing the parameter that needs to be bound and
   8568  1.1  mrg  * the accumulated results.
   8569  1.1  mrg  */
   8570  1.1  mrg struct isl_bind_id_data {
   8571  1.1  mrg 	isl_id *id;
   8572  1.1  mrg 	isl_union_set *bound;
   8573  1.1  mrg };
   8574  1.1  mrg 
   8575  1.1  mrg /* Bind the piecewise affine function "pa" to the parameter data->id,
   8576  1.1  mrg  * adding the resulting elements in the domain where the expression
   8577  1.1  mrg  * is equal to the parameter to data->bound.
   8578  1.1  mrg  */
   8579  1.1  mrg static isl_stat bind_id(__isl_take isl_pw_aff *pa, void *user)
   8580  1.1  mrg {
   8581  1.1  mrg 	struct isl_bind_id_data *data = user;
   8582  1.1  mrg 	isl_set *bound;
   8583  1.1  mrg 
   8584  1.1  mrg 	bound = isl_pw_aff_bind_id(pa, isl_id_copy(data->id));
   8585  1.1  mrg 	data->bound = isl_union_set_add_set(data->bound, bound);
   8586  1.1  mrg 
   8587  1.1  mrg 	return data->bound ? isl_stat_ok : isl_stat_error;
   8588  1.1  mrg }
   8589  1.1  mrg 
   8590  1.1  mrg /* Bind the union piecewise affine function "upa" to the parameter "id",
   8591  1.1  mrg  * returning the elements in the domain where the expression
   8592  1.1  mrg  * is equal to the parameter.
   8593  1.1  mrg  */
   8594  1.1  mrg __isl_give isl_union_set *isl_union_pw_aff_bind_id(
   8595  1.1  mrg 	__isl_take isl_union_pw_aff *upa, __isl_take isl_id *id)
   8596  1.1  mrg {
   8597  1.1  mrg 	struct isl_bind_id_data data = { id };
   8598  1.1  mrg 
   8599  1.1  mrg 	data.bound = isl_union_set_empty(isl_union_pw_aff_get_space(upa));
   8600  1.1  mrg 	if (isl_union_pw_aff_foreach_pw_aff(upa, &bind_id, &data) < 0)
   8601  1.1  mrg 		data.bound = isl_union_set_free(data.bound);
   8602  1.1  mrg 
   8603  1.1  mrg 	isl_union_pw_aff_free(upa);
   8604  1.1  mrg 	isl_id_free(id);
   8605  1.1  mrg 	return data.bound;
   8606  1.1  mrg }
   8607  1.1  mrg 
   8608  1.1  mrg /* Internal data structure for isl_union_pw_aff_pullback_union_pw_multi_aff.
   8609  1.1  mrg  * upma is the function that is plugged in.
   8610  1.1  mrg  * pa is the current part of the function in which upma is plugged in.
   8611  1.1  mrg  * res collects the results.
   8612  1.1  mrg  */
   8613  1.1  mrg struct isl_union_pw_aff_pullback_upma_data {
   8614  1.1  mrg 	isl_union_pw_multi_aff *upma;
   8615  1.1  mrg 	isl_pw_aff *pa;
   8616  1.1  mrg 	isl_union_pw_aff *res;
   8617  1.1  mrg };
   8618  1.1  mrg 
   8619  1.1  mrg /* Check if "pma" can be plugged into data->pa.
   8620  1.1  mrg  * If so, perform the pullback and add the result to data->res.
   8621  1.1  mrg  */
   8622  1.1  mrg static isl_stat pa_pb_pma(__isl_take isl_pw_multi_aff *pma, void *user)
   8623  1.1  mrg {
   8624  1.1  mrg 	struct isl_union_pw_aff_pullback_upma_data *data = user;
   8625  1.1  mrg 	isl_pw_aff *pa;
   8626  1.1  mrg 
   8627  1.1  mrg 	if (!isl_space_tuple_is_equal(data->pa->dim, isl_dim_in,
   8628  1.1  mrg 				 pma->dim, isl_dim_out)) {
   8629  1.1  mrg 		isl_pw_multi_aff_free(pma);
   8630  1.1  mrg 		return isl_stat_ok;
   8631  1.1  mrg 	}
   8632  1.1  mrg 
   8633  1.1  mrg 	pa = isl_pw_aff_copy(data->pa);
   8634  1.1  mrg 	pa = isl_pw_aff_pullback_pw_multi_aff(pa, pma);
   8635  1.1  mrg 
   8636  1.1  mrg 	data->res = isl_union_pw_aff_add_pw_aff(data->res, pa);
   8637  1.1  mrg 
   8638  1.1  mrg 	return data->res ? isl_stat_ok : isl_stat_error;
   8639  1.1  mrg }
   8640  1.1  mrg 
   8641  1.1  mrg /* Check if any of the elements of data->upma can be plugged into pa,
   8642  1.1  mrg  * add if so add the result to data->res.
   8643  1.1  mrg  */
   8644  1.1  mrg static isl_stat upa_pb_upma(__isl_take isl_pw_aff *pa, void *user)
   8645  1.1  mrg {
   8646  1.1  mrg 	struct isl_union_pw_aff_pullback_upma_data *data = user;
   8647  1.1  mrg 	isl_stat r;
   8648  1.1  mrg 
   8649  1.1  mrg 	data->pa = pa;
   8650  1.1  mrg 	r = isl_union_pw_multi_aff_foreach_pw_multi_aff(data->upma,
   8651  1.1  mrg 				   &pa_pb_pma, data);
   8652  1.1  mrg 	isl_pw_aff_free(pa);
   8653  1.1  mrg 
   8654  1.1  mrg 	return r;
   8655  1.1  mrg }
   8656  1.1  mrg 
   8657  1.1  mrg /* Compute the pullback of "upa" by the function represented by "upma".
   8658  1.1  mrg  * In other words, plug in "upma" in "upa".  The result contains
   8659  1.1  mrg  * expressions defined over the domain space of "upma".
   8660  1.1  mrg  *
   8661  1.1  mrg  * Run over all pairs of elements in "upa" and "upma", perform
   8662  1.1  mrg  * the pullback when appropriate and collect the results.
   8663  1.1  mrg  * If the hash value were based on the domain space rather than
   8664  1.1  mrg  * the function space, then we could run through all elements
   8665  1.1  mrg  * of "upma" and directly pick out the corresponding element of "upa".
   8666  1.1  mrg  */
   8667  1.1  mrg __isl_give isl_union_pw_aff *isl_union_pw_aff_pullback_union_pw_multi_aff(
   8668  1.1  mrg 	__isl_take isl_union_pw_aff *upa,
   8669  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma)
   8670  1.1  mrg {
   8671  1.1  mrg 	struct isl_union_pw_aff_pullback_upma_data data = { NULL, NULL };
   8672  1.1  mrg 	isl_space *space;
   8673  1.1  mrg 
   8674  1.1  mrg 	space = isl_union_pw_multi_aff_get_space(upma);
   8675  1.1  mrg 	upa = isl_union_pw_aff_align_params(upa, space);
   8676  1.1  mrg 	space = isl_union_pw_aff_get_space(upa);
   8677  1.1  mrg 	upma = isl_union_pw_multi_aff_align_params(upma, space);
   8678  1.1  mrg 
   8679  1.1  mrg 	if (!upa || !upma)
   8680  1.1  mrg 		goto error;
   8681  1.1  mrg 
   8682  1.1  mrg 	data.upma = upma;
   8683  1.1  mrg 	data.res = isl_union_pw_aff_alloc_same_size(upa);
   8684  1.1  mrg 	if (isl_union_pw_aff_foreach_pw_aff(upa, &upa_pb_upma, &data) < 0)
   8685  1.1  mrg 		data.res = isl_union_pw_aff_free(data.res);
   8686  1.1  mrg 
   8687  1.1  mrg 	isl_union_pw_aff_free(upa);
   8688  1.1  mrg 	isl_union_pw_multi_aff_free(upma);
   8689  1.1  mrg 	return data.res;
   8690  1.1  mrg error:
   8691  1.1  mrg 	isl_union_pw_aff_free(upa);
   8692  1.1  mrg 	isl_union_pw_multi_aff_free(upma);
   8693  1.1  mrg 	return NULL;
   8694  1.1  mrg }
   8695  1.1  mrg 
   8696  1.1  mrg #undef BASE
   8697  1.1  mrg #define BASE union_pw_aff
   8698  1.1  mrg #undef DOMBASE
   8699  1.1  mrg #define DOMBASE union_set
   8700  1.1  mrg 
   8701  1.1  mrg #include <isl_multi_explicit_domain.c>
   8702  1.1  mrg #include <isl_multi_union_pw_aff_explicit_domain.c>
   8703  1.1  mrg #include <isl_multi_templ.c>
   8704  1.1  mrg #include <isl_multi_un_op_templ.c>
   8705  1.1  mrg #include <isl_multi_bin_val_templ.c>
   8706  1.1  mrg #include <isl_multi_align_set.c>
   8707  1.1  mrg #include <isl_multi_align_union_set.c>
   8708  1.1  mrg #include <isl_multi_apply_set_explicit_domain_templ.c>
   8709  1.1  mrg #include <isl_multi_apply_union_set_explicit_domain_templ.c>
   8710  1.1  mrg #include <isl_multi_arith_templ.c>
   8711  1.1  mrg #include <isl_multi_bind_templ.c>
   8712  1.1  mrg #include <isl_multi_coalesce.c>
   8713  1.1  mrg #include <isl_multi_dim_id_templ.c>
   8714  1.1  mrg #include <isl_multi_floor.c>
   8715  1.1  mrg #include <isl_multi_from_base_templ.c>
   8716  1.1  mrg #include <isl_multi_check_domain_templ.c>
   8717  1.1  mrg #include <isl_multi_gist.c>
   8718  1.1  mrg #include <isl_multi_intersect.c>
   8719  1.1  mrg #include <isl_multi_nan_templ.c>
   8720  1.1  mrg #include <isl_multi_tuple_id_templ.c>
   8721  1.1  mrg #include <isl_multi_union_add_templ.c>
   8722  1.1  mrg #include <isl_multi_zero_space_templ.c>
   8723  1.1  mrg 
   8724  1.1  mrg /* Does "mupa" have a non-trivial explicit domain?
   8725  1.1  mrg  *
   8726  1.1  mrg  * The explicit domain, if present, is trivial if it represents
   8727  1.1  mrg  * an (obviously) universe parameter set.
   8728  1.1  mrg  */
   8729  1.1  mrg isl_bool isl_multi_union_pw_aff_has_non_trivial_domain(
   8730  1.1  mrg 	__isl_keep isl_multi_union_pw_aff *mupa)
   8731  1.1  mrg {
   8732  1.1  mrg 	isl_bool is_params, trivial;
   8733  1.1  mrg 	isl_set *set;
   8734  1.1  mrg 
   8735  1.1  mrg 	if (!mupa)
   8736  1.1  mrg 		return isl_bool_error;
   8737  1.1  mrg 	if (!isl_multi_union_pw_aff_has_explicit_domain(mupa))
   8738  1.1  mrg 		return isl_bool_false;
   8739  1.1  mrg 	is_params = isl_union_set_is_params(mupa->u.dom);
   8740  1.1  mrg 	if (is_params < 0 || !is_params)
   8741  1.1  mrg 		return isl_bool_not(is_params);
   8742  1.1  mrg 	set = isl_set_from_union_set(isl_union_set_copy(mupa->u.dom));
   8743  1.1  mrg 	trivial = isl_set_plain_is_universe(set);
   8744  1.1  mrg 	isl_set_free(set);
   8745  1.1  mrg 	return isl_bool_not(trivial);
   8746  1.1  mrg }
   8747  1.1  mrg 
   8748  1.1  mrg /* Construct a multiple union piecewise affine expression
   8749  1.1  mrg  * in the given space with value zero in each of the output dimensions.
   8750  1.1  mrg  *
   8751  1.1  mrg  * Since there is no canonical zero value for
   8752  1.1  mrg  * a union piecewise affine expression, we can only construct
   8753  1.1  mrg  * a zero-dimensional "zero" value.
   8754  1.1  mrg  */
   8755  1.1  mrg __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_zero(
   8756  1.1  mrg 	__isl_take isl_space *space)
   8757  1.1  mrg {
   8758  1.1  mrg 	isl_bool params;
   8759  1.1  mrg 	isl_size dim;
   8760  1.1  mrg 
   8761  1.1  mrg 	if (!space)
   8762  1.1  mrg 		return NULL;
   8763  1.1  mrg 
   8764  1.1  mrg 	params = isl_space_is_params(space);
   8765  1.1  mrg 	if (params < 0)
   8766  1.1  mrg 		goto error;
   8767  1.1  mrg 	if (params)
   8768  1.1  mrg 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   8769  1.1  mrg 			"expecting proper set space", goto error);
   8770  1.1  mrg 	if (!isl_space_is_set(space))
   8771  1.1  mrg 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   8772  1.1  mrg 			"expecting set space", goto error);
   8773  1.1  mrg 	dim = isl_space_dim(space, isl_dim_out);
   8774  1.1  mrg 	if (dim < 0)
   8775  1.1  mrg 		goto error;
   8776  1.1  mrg 	if (dim != 0)
   8777  1.1  mrg 		isl_die(isl_space_get_ctx(space), isl_error_invalid,
   8778  1.1  mrg 			"expecting 0D space", goto error);
   8779  1.1  mrg 
   8780  1.1  mrg 	return isl_multi_union_pw_aff_alloc(space);
   8781  1.1  mrg error:
   8782  1.1  mrg 	isl_space_free(space);
   8783  1.1  mrg 	return NULL;
   8784  1.1  mrg }
   8785  1.1  mrg 
   8786  1.1  mrg /* Construct and return a multi union piecewise affine expression
   8787  1.1  mrg  * that is equal to the given multi affine expression.
   8788  1.1  mrg  */
   8789  1.1  mrg __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_aff(
   8790  1.1  mrg 	__isl_take isl_multi_aff *ma)
   8791  1.1  mrg {
   8792  1.1  mrg 	isl_multi_pw_aff *mpa;
   8793  1.1  mrg 
   8794  1.1  mrg 	mpa = isl_multi_pw_aff_from_multi_aff(ma);
   8795  1.1  mrg 	return isl_multi_union_pw_aff_from_multi_pw_aff(mpa);
   8796  1.1  mrg }
   8797  1.1  mrg 
   8798  1.1  mrg /* This function performs the same operation as
   8799  1.1  mrg  * isl_multi_union_pw_aff_from_multi_aff, but is considered as a function on an
   8800  1.1  mrg  * isl_multi_aff when exported.
   8801  1.1  mrg  */
   8802  1.1  mrg __isl_give isl_multi_union_pw_aff *isl_multi_aff_to_multi_union_pw_aff(
   8803  1.1  mrg         __isl_take isl_multi_aff *ma)
   8804  1.1  mrg {
   8805  1.1  mrg         return isl_multi_union_pw_aff_from_multi_aff(ma);
   8806  1.1  mrg }
   8807  1.1  mrg 
   8808  1.1  mrg /* Construct and return a multi union piecewise affine expression
   8809  1.1  mrg  * that is equal to the given multi piecewise affine expression.
   8810  1.1  mrg  *
   8811  1.1  mrg  * If the resulting multi union piecewise affine expression has
   8812  1.1  mrg  * an explicit domain, then assign it the domain of the input.
   8813  1.1  mrg  * In other cases, the domain is stored in the individual elements.
   8814  1.1  mrg  */
   8815  1.1  mrg __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_multi_pw_aff(
   8816  1.1  mrg 	__isl_take isl_multi_pw_aff *mpa)
   8817  1.1  mrg {
   8818  1.1  mrg 	int i;
   8819  1.1  mrg 	isl_size n;
   8820  1.1  mrg 	isl_space *space;
   8821  1.1  mrg 	isl_multi_union_pw_aff *mupa;
   8822  1.1  mrg 
   8823  1.1  mrg 	n = isl_multi_pw_aff_dim(mpa, isl_dim_out);
   8824  1.1  mrg 	if (n < 0)
   8825  1.1  mrg 		mpa = isl_multi_pw_aff_free(mpa);
   8826  1.1  mrg 	if (!mpa)
   8827  1.1  mrg 		return NULL;
   8828  1.1  mrg 
   8829  1.1  mrg 	space = isl_multi_pw_aff_get_space(mpa);
   8830  1.1  mrg 	space = isl_space_range(space);
   8831  1.1  mrg 	mupa = isl_multi_union_pw_aff_alloc(space);
   8832  1.1  mrg 
   8833  1.1  mrg 	for (i = 0; i < n; ++i) {
   8834  1.1  mrg 		isl_pw_aff *pa;
   8835  1.1  mrg 		isl_union_pw_aff *upa;
   8836  1.1  mrg 
   8837  1.1  mrg 		pa = isl_multi_pw_aff_get_pw_aff(mpa, i);
   8838  1.1  mrg 		upa = isl_union_pw_aff_from_pw_aff(pa);
   8839  1.1  mrg 		mupa = isl_multi_union_pw_aff_restore_check_space(mupa, i, upa);
   8840  1.1  mrg 	}
   8841  1.1  mrg 	if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) {
   8842  1.1  mrg 		isl_union_set *dom;
   8843  1.1  mrg 		isl_multi_pw_aff *copy;
   8844  1.1  mrg 
   8845  1.1  mrg 		copy = isl_multi_pw_aff_copy(mpa);
   8846  1.1  mrg 		dom = isl_union_set_from_set(isl_multi_pw_aff_domain(copy));
   8847  1.1  mrg 		mupa = isl_multi_union_pw_aff_intersect_domain(mupa, dom);
   8848  1.1  mrg 	}
   8849  1.1  mrg 
   8850  1.1  mrg 	isl_multi_pw_aff_free(mpa);
   8851  1.1  mrg 
   8852  1.1  mrg 	return mupa;
   8853  1.1  mrg }
   8854  1.1  mrg 
   8855  1.1  mrg /* Extract the range space of "pma" and assign it to *space.
   8856  1.1  mrg  * If *space has already been set (through a previous call to this function),
   8857  1.1  mrg  * then check that the range space is the same.
   8858  1.1  mrg  */
   8859  1.1  mrg static isl_stat extract_space(__isl_take isl_pw_multi_aff *pma, void *user)
   8860  1.1  mrg {
   8861  1.1  mrg 	isl_space **space = user;
   8862  1.1  mrg 	isl_space *pma_space;
   8863  1.1  mrg 	isl_bool equal;
   8864  1.1  mrg 
   8865  1.1  mrg 	pma_space = isl_space_range(isl_pw_multi_aff_get_space(pma));
   8866  1.1  mrg 	isl_pw_multi_aff_free(pma);
   8867  1.1  mrg 
   8868  1.1  mrg 	if (!pma_space)
   8869  1.1  mrg 		return isl_stat_error;
   8870  1.1  mrg 	if (!*space) {
   8871  1.1  mrg 		*space = pma_space;
   8872  1.1  mrg 		return isl_stat_ok;
   8873  1.1  mrg 	}
   8874  1.1  mrg 
   8875  1.1  mrg 	equal = isl_space_is_equal(pma_space, *space);
   8876  1.1  mrg 	isl_space_free(pma_space);
   8877  1.1  mrg 
   8878  1.1  mrg 	if (equal < 0)
   8879  1.1  mrg 		return isl_stat_error;
   8880  1.1  mrg 	if (!equal)
   8881  1.1  mrg 		isl_die(isl_space_get_ctx(*space), isl_error_invalid,
   8882  1.1  mrg 			"range spaces not the same", return isl_stat_error);
   8883  1.1  mrg 	return isl_stat_ok;
   8884  1.1  mrg }
   8885  1.1  mrg 
   8886  1.1  mrg /* Construct and return a multi union piecewise affine expression
   8887  1.1  mrg  * that is equal to the given union piecewise multi affine expression.
   8888  1.1  mrg  *
   8889  1.1  mrg  * In order to be able to perform the conversion, the input
   8890  1.1  mrg  * needs to be non-empty and may only involve a single range space.
   8891  1.1  mrg  *
   8892  1.1  mrg  * If the resulting multi union piecewise affine expression has
   8893  1.1  mrg  * an explicit domain, then assign it the domain of the input.
   8894  1.1  mrg  * In other cases, the domain is stored in the individual elements.
   8895  1.1  mrg  */
   8896  1.1  mrg __isl_give isl_multi_union_pw_aff *
   8897  1.1  mrg isl_multi_union_pw_aff_from_union_pw_multi_aff(
   8898  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma)
   8899  1.1  mrg {
   8900  1.1  mrg 	isl_space *space = NULL;
   8901  1.1  mrg 	isl_multi_union_pw_aff *mupa;
   8902  1.1  mrg 	int i;
   8903  1.1  mrg 	isl_size n;
   8904  1.1  mrg 
   8905  1.1  mrg 	n = isl_union_pw_multi_aff_n_pw_multi_aff(upma);
   8906  1.1  mrg 	if (n < 0)
   8907  1.1  mrg 		goto error;
   8908  1.1  mrg 	if (n == 0)
   8909  1.1  mrg 		isl_die(isl_union_pw_multi_aff_get_ctx(upma), isl_error_invalid,
   8910  1.1  mrg 			"cannot extract range space from empty input",
   8911  1.1  mrg 			goto error);
   8912  1.1  mrg 	if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma, &extract_space,
   8913  1.1  mrg 							&space) < 0)
   8914  1.1  mrg 		goto error;
   8915  1.1  mrg 
   8916  1.1  mrg 	if (!space)
   8917  1.1  mrg 		goto error;
   8918  1.1  mrg 
   8919  1.1  mrg 	n = isl_space_dim(space, isl_dim_set);
   8920  1.1  mrg 	if (n < 0)
   8921  1.1  mrg 		space = isl_space_free(space);
   8922  1.1  mrg 	mupa = isl_multi_union_pw_aff_alloc(space);
   8923  1.1  mrg 
   8924  1.1  mrg 	for (i = 0; i < n; ++i) {
   8925  1.1  mrg 		isl_union_pw_aff *upa;
   8926  1.1  mrg 
   8927  1.1  mrg 		upa = isl_union_pw_multi_aff_get_union_pw_aff(upma, i);
   8928  1.1  mrg 		mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
   8929  1.1  mrg 	}
   8930  1.1  mrg 	if (isl_multi_union_pw_aff_has_explicit_domain(mupa)) {
   8931  1.1  mrg 		isl_union_set *dom;
   8932  1.1  mrg 		isl_union_pw_multi_aff *copy;
   8933  1.1  mrg 
   8934  1.1  mrg 		copy = isl_union_pw_multi_aff_copy(upma);
   8935  1.1  mrg 		dom = isl_union_pw_multi_aff_domain(copy);
   8936  1.1  mrg 		mupa = isl_multi_union_pw_aff_intersect_domain(mupa, dom);
   8937  1.1  mrg 	}
   8938  1.1  mrg 
   8939  1.1  mrg 	isl_union_pw_multi_aff_free(upma);
   8940  1.1  mrg 	return mupa;
   8941  1.1  mrg error:
   8942  1.1  mrg 	isl_space_free(space);
   8943  1.1  mrg 	isl_union_pw_multi_aff_free(upma);
   8944  1.1  mrg 	return NULL;
   8945  1.1  mrg }
   8946  1.1  mrg 
   8947  1.1  mrg /* This function performs the same operation as
   8948  1.1  mrg  * isl_multi_union_pw_aff_from_union_pw_multi_aff,
   8949  1.1  mrg  * but is considered as a function on an isl_union_pw_multi_aff when exported.
   8950  1.1  mrg  */
   8951  1.1  mrg __isl_give isl_multi_union_pw_aff *
   8952  1.1  mrg isl_union_pw_multi_aff_as_multi_union_pw_aff(
   8953  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma)
   8954  1.1  mrg {
   8955  1.1  mrg 	return isl_multi_union_pw_aff_from_union_pw_multi_aff(upma);
   8956  1.1  mrg }
   8957  1.1  mrg 
   8958  1.1  mrg /* Try and create an isl_multi_union_pw_aff that is equivalent
   8959  1.1  mrg  * to the given isl_union_map.
   8960  1.1  mrg  * The isl_union_map is required to be single-valued in each space.
   8961  1.1  mrg  * Moreover, it cannot be empty and all range spaces need to be the same.
   8962  1.1  mrg  * Otherwise, an error is produced.
   8963  1.1  mrg  */
   8964  1.1  mrg __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_from_union_map(
   8965  1.1  mrg 	__isl_take isl_union_map *umap)
   8966  1.1  mrg {
   8967  1.1  mrg 	isl_union_pw_multi_aff *upma;
   8968  1.1  mrg 
   8969  1.1  mrg 	upma = isl_union_pw_multi_aff_from_union_map(umap);
   8970  1.1  mrg 	return isl_multi_union_pw_aff_from_union_pw_multi_aff(upma);
   8971  1.1  mrg }
   8972  1.1  mrg 
   8973  1.1  mrg /* This function performs the same operation as
   8974  1.1  mrg  * isl_multi_union_pw_aff_from_union_map,
   8975  1.1  mrg  * but is considered as a function on an isl_union_map when exported.
   8976  1.1  mrg  */
   8977  1.1  mrg __isl_give isl_multi_union_pw_aff *isl_union_map_as_multi_union_pw_aff(
   8978  1.1  mrg 	__isl_take isl_union_map *umap)
   8979  1.1  mrg {
   8980  1.1  mrg 	return isl_multi_union_pw_aff_from_union_map(umap);
   8981  1.1  mrg }
   8982  1.1  mrg 
   8983  1.1  mrg /* Return a multiple union piecewise affine expression
   8984  1.1  mrg  * that is equal to "mv" on "domain", assuming "domain" and "mv"
   8985  1.1  mrg  * have been aligned.
   8986  1.1  mrg  *
   8987  1.1  mrg  * If the resulting multi union piecewise affine expression has
   8988  1.1  mrg  * an explicit domain, then assign it the input domain.
   8989  1.1  mrg  * In other cases, the domain is stored in the individual elements.
   8990  1.1  mrg  */
   8991  1.1  mrg static __isl_give isl_multi_union_pw_aff *
   8992  1.1  mrg isl_multi_union_pw_aff_multi_val_on_domain_aligned(
   8993  1.1  mrg 	__isl_take isl_union_set *domain, __isl_take isl_multi_val *mv)
   8994  1.1  mrg {
   8995  1.1  mrg 	int i;
   8996  1.1  mrg 	isl_size n;
   8997  1.1  mrg 	isl_space *space;
   8998  1.1  mrg 	isl_multi_union_pw_aff *mupa;
   8999  1.1  mrg 
   9000  1.1  mrg 	n = isl_multi_val_dim(mv, isl_dim_set);
   9001  1.1  mrg 	if (!domain || n < 0)
   9002  1.1  mrg 		goto error;
   9003  1.1  mrg 
   9004  1.1  mrg 	space = isl_multi_val_get_space(mv);
   9005  1.1  mrg 	mupa = isl_multi_union_pw_aff_alloc(space);
   9006  1.1  mrg 	for (i = 0; i < n; ++i) {
   9007  1.1  mrg 		isl_val *v;
   9008  1.1  mrg 		isl_union_pw_aff *upa;
   9009  1.1  mrg 
   9010  1.1  mrg 		v = isl_multi_val_get_val(mv, i);
   9011  1.1  mrg 		upa = isl_union_pw_aff_val_on_domain(isl_union_set_copy(domain),
   9012  1.1  mrg 							v);
   9013  1.1  mrg 		mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
   9014  1.1  mrg 	}
   9015  1.1  mrg 	if (isl_multi_union_pw_aff_has_explicit_domain(mupa))
   9016  1.1  mrg 		mupa = isl_multi_union_pw_aff_intersect_domain(mupa,
   9017  1.1  mrg 						    isl_union_set_copy(domain));
   9018  1.1  mrg 
   9019  1.1  mrg 	isl_union_set_free(domain);
   9020  1.1  mrg 	isl_multi_val_free(mv);
   9021  1.1  mrg 	return mupa;
   9022  1.1  mrg error:
   9023  1.1  mrg 	isl_union_set_free(domain);
   9024  1.1  mrg 	isl_multi_val_free(mv);
   9025  1.1  mrg 	return NULL;
   9026  1.1  mrg }
   9027  1.1  mrg 
   9028  1.1  mrg /* Return a multiple union piecewise affine expression
   9029  1.1  mrg  * that is equal to "mv" on "domain".
   9030  1.1  mrg  */
   9031  1.1  mrg __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_val_on_domain(
   9032  1.1  mrg 	__isl_take isl_union_set *domain, __isl_take isl_multi_val *mv)
   9033  1.1  mrg {
   9034  1.1  mrg 	isl_bool equal_params;
   9035  1.1  mrg 
   9036  1.1  mrg 	if (!domain || !mv)
   9037  1.1  mrg 		goto error;
   9038  1.1  mrg 	equal_params = isl_space_has_equal_params(domain->dim, mv->space);
   9039  1.1  mrg 	if (equal_params < 0)
   9040  1.1  mrg 		goto error;
   9041  1.1  mrg 	if (equal_params)
   9042  1.1  mrg 		return isl_multi_union_pw_aff_multi_val_on_domain_aligned(
   9043  1.1  mrg 								    domain, mv);
   9044  1.1  mrg 	domain = isl_union_set_align_params(domain,
   9045  1.1  mrg 						isl_multi_val_get_space(mv));
   9046  1.1  mrg 	mv = isl_multi_val_align_params(mv, isl_union_set_get_space(domain));
   9047  1.1  mrg 	return isl_multi_union_pw_aff_multi_val_on_domain_aligned(domain, mv);
   9048  1.1  mrg error:
   9049  1.1  mrg 	isl_union_set_free(domain);
   9050  1.1  mrg 	isl_multi_val_free(mv);
   9051  1.1  mrg 	return NULL;
   9052  1.1  mrg }
   9053  1.1  mrg 
   9054  1.1  mrg /* Return a multiple union piecewise affine expression
   9055  1.1  mrg  * that is equal to "ma" on "domain".
   9056  1.1  mrg  */
   9057  1.1  mrg __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_multi_aff_on_domain(
   9058  1.1  mrg 	__isl_take isl_union_set *domain, __isl_take isl_multi_aff *ma)
   9059  1.1  mrg {
   9060  1.1  mrg 	isl_pw_multi_aff *pma;
   9061  1.1  mrg 
   9062  1.1  mrg 	pma = isl_pw_multi_aff_from_multi_aff(ma);
   9063  1.1  mrg 	return isl_multi_union_pw_aff_pw_multi_aff_on_domain(domain, pma);
   9064  1.1  mrg }
   9065  1.1  mrg 
   9066  1.1  mrg /* Return a multiple union piecewise affine expression
   9067  1.1  mrg  * that is equal to "pma" on "domain", assuming "domain" and "pma"
   9068  1.1  mrg  * have been aligned.
   9069  1.1  mrg  *
   9070  1.1  mrg  * If the resulting multi union piecewise affine expression has
   9071  1.1  mrg  * an explicit domain, then assign it the input domain.
   9072  1.1  mrg  * In other cases, the domain is stored in the individual elements.
   9073  1.1  mrg  */
   9074  1.1  mrg static __isl_give isl_multi_union_pw_aff *
   9075  1.1  mrg isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned(
   9076  1.1  mrg 	__isl_take isl_union_set *domain, __isl_take isl_pw_multi_aff *pma)
   9077  1.1  mrg {
   9078  1.1  mrg 	int i;
   9079  1.1  mrg 	isl_size n;
   9080  1.1  mrg 	isl_space *space;
   9081  1.1  mrg 	isl_multi_union_pw_aff *mupa;
   9082  1.1  mrg 
   9083  1.1  mrg 	n = isl_pw_multi_aff_dim(pma, isl_dim_set);
   9084  1.1  mrg 	if (!domain || n < 0)
   9085  1.1  mrg 		goto error;
   9086  1.1  mrg 	space = isl_pw_multi_aff_get_space(pma);
   9087  1.1  mrg 	mupa = isl_multi_union_pw_aff_alloc(space);
   9088  1.1  mrg 	for (i = 0; i < n; ++i) {
   9089  1.1  mrg 		isl_pw_aff *pa;
   9090  1.1  mrg 		isl_union_pw_aff *upa;
   9091  1.1  mrg 
   9092  1.1  mrg 		pa = isl_pw_multi_aff_get_pw_aff(pma, i);
   9093  1.1  mrg 		upa = isl_union_pw_aff_pw_aff_on_domain(
   9094  1.1  mrg 					    isl_union_set_copy(domain), pa);
   9095  1.1  mrg 		mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
   9096  1.1  mrg 	}
   9097  1.1  mrg 	if (isl_multi_union_pw_aff_has_explicit_domain(mupa))
   9098  1.1  mrg 		mupa = isl_multi_union_pw_aff_intersect_domain(mupa,
   9099  1.1  mrg 						    isl_union_set_copy(domain));
   9100  1.1  mrg 
   9101  1.1  mrg 	isl_union_set_free(domain);
   9102  1.1  mrg 	isl_pw_multi_aff_free(pma);
   9103  1.1  mrg 	return mupa;
   9104  1.1  mrg error:
   9105  1.1  mrg 	isl_union_set_free(domain);
   9106  1.1  mrg 	isl_pw_multi_aff_free(pma);
   9107  1.1  mrg 	return NULL;
   9108  1.1  mrg }
   9109  1.1  mrg 
   9110  1.1  mrg /* Return a multiple union piecewise affine expression
   9111  1.1  mrg  * that is equal to "pma" on "domain".
   9112  1.1  mrg  */
   9113  1.1  mrg __isl_give isl_multi_union_pw_aff *
   9114  1.1  mrg isl_multi_union_pw_aff_pw_multi_aff_on_domain(__isl_take isl_union_set *domain,
   9115  1.1  mrg 	__isl_take isl_pw_multi_aff *pma)
   9116  1.1  mrg {
   9117  1.1  mrg 	isl_bool equal_params;
   9118  1.1  mrg 	isl_space *space;
   9119  1.1  mrg 
   9120  1.1  mrg 	space = isl_pw_multi_aff_peek_space(pma);
   9121  1.1  mrg 	equal_params = isl_union_set_space_has_equal_params(domain, space);
   9122  1.1  mrg 	if (equal_params < 0)
   9123  1.1  mrg 		goto error;
   9124  1.1  mrg 	if (equal_params)
   9125  1.1  mrg 		return isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned(
   9126  1.1  mrg 								domain, pma);
   9127  1.1  mrg 	domain = isl_union_set_align_params(domain,
   9128  1.1  mrg 					    isl_pw_multi_aff_get_space(pma));
   9129  1.1  mrg 	pma = isl_pw_multi_aff_align_params(pma,
   9130  1.1  mrg 					    isl_union_set_get_space(domain));
   9131  1.1  mrg 	return isl_multi_union_pw_aff_pw_multi_aff_on_domain_aligned(domain,
   9132  1.1  mrg 									pma);
   9133  1.1  mrg error:
   9134  1.1  mrg 	isl_union_set_free(domain);
   9135  1.1  mrg 	isl_pw_multi_aff_free(pma);
   9136  1.1  mrg 	return NULL;
   9137  1.1  mrg }
   9138  1.1  mrg 
   9139  1.1  mrg /* Return a union set containing those elements in the domains
   9140  1.1  mrg  * of the elements of "mupa" where they are all zero.
   9141  1.1  mrg  *
   9142  1.1  mrg  * If there are no elements, then simply return the entire domain.
   9143  1.1  mrg  */
   9144  1.1  mrg __isl_give isl_union_set *isl_multi_union_pw_aff_zero_union_set(
   9145  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa)
   9146  1.1  mrg {
   9147  1.1  mrg 	int i;
   9148  1.1  mrg 	isl_size n;
   9149  1.1  mrg 	isl_union_pw_aff *upa;
   9150  1.1  mrg 	isl_union_set *zero;
   9151  1.1  mrg 
   9152  1.1  mrg 	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
   9153  1.1  mrg 	if (n < 0)
   9154  1.1  mrg 		mupa = isl_multi_union_pw_aff_free(mupa);
   9155  1.1  mrg 	if (!mupa)
   9156  1.1  mrg 		return NULL;
   9157  1.1  mrg 
   9158  1.1  mrg 	if (n == 0)
   9159  1.1  mrg 		return isl_multi_union_pw_aff_domain(mupa);
   9160  1.1  mrg 
   9161  1.1  mrg 	upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
   9162  1.1  mrg 	zero = isl_union_pw_aff_zero_union_set(upa);
   9163  1.1  mrg 
   9164  1.1  mrg 	for (i = 1; i < n; ++i) {
   9165  1.1  mrg 		isl_union_set *zero_i;
   9166  1.1  mrg 
   9167  1.1  mrg 		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
   9168  1.1  mrg 		zero_i = isl_union_pw_aff_zero_union_set(upa);
   9169  1.1  mrg 
   9170  1.1  mrg 		zero = isl_union_set_intersect(zero, zero_i);
   9171  1.1  mrg 	}
   9172  1.1  mrg 
   9173  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9174  1.1  mrg 	return zero;
   9175  1.1  mrg }
   9176  1.1  mrg 
   9177  1.1  mrg /* Construct a union map mapping the shared domain
   9178  1.1  mrg  * of the union piecewise affine expressions to the range of "mupa"
   9179  1.1  mrg  * in the special case of a 0D multi union piecewise affine expression.
   9180  1.1  mrg  *
   9181  1.1  mrg  * Construct a map between the explicit domain of "mupa" and
   9182  1.1  mrg  * the range space.
   9183  1.1  mrg  * Note that this assumes that the domain consists of explicit elements.
   9184  1.1  mrg  */
   9185  1.1  mrg static __isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff_0D(
   9186  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa)
   9187  1.1  mrg {
   9188  1.1  mrg 	isl_bool is_params;
   9189  1.1  mrg 	isl_space *space;
   9190  1.1  mrg 	isl_union_set *dom, *ran;
   9191  1.1  mrg 
   9192  1.1  mrg 	space = isl_multi_union_pw_aff_get_space(mupa);
   9193  1.1  mrg 	dom = isl_multi_union_pw_aff_domain(mupa);
   9194  1.1  mrg 	ran = isl_union_set_from_set(isl_set_universe(space));
   9195  1.1  mrg 
   9196  1.1  mrg 	is_params = isl_union_set_is_params(dom);
   9197  1.1  mrg 	if (is_params < 0)
   9198  1.1  mrg 		dom = isl_union_set_free(dom);
   9199  1.1  mrg 	else if (is_params)
   9200  1.1  mrg 		isl_die(isl_union_set_get_ctx(dom), isl_error_invalid,
   9201  1.1  mrg 			"cannot create union map from expression without "
   9202  1.1  mrg 			"explicit domain elements",
   9203  1.1  mrg 			dom = isl_union_set_free(dom));
   9204  1.1  mrg 
   9205  1.1  mrg 	return isl_union_map_from_domain_and_range(dom, ran);
   9206  1.1  mrg }
   9207  1.1  mrg 
   9208  1.1  mrg /* Construct a union map mapping the shared domain
   9209  1.1  mrg  * of the union piecewise affine expressions to the range of "mupa"
   9210  1.1  mrg  * with each dimension in the range equated to the
   9211  1.1  mrg  * corresponding union piecewise affine expression.
   9212  1.1  mrg  *
   9213  1.1  mrg  * If the input is zero-dimensional, then construct a mapping
   9214  1.1  mrg  * from its explicit domain.
   9215  1.1  mrg  */
   9216  1.1  mrg __isl_give isl_union_map *isl_union_map_from_multi_union_pw_aff(
   9217  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa)
   9218  1.1  mrg {
   9219  1.1  mrg 	int i;
   9220  1.1  mrg 	isl_size n;
   9221  1.1  mrg 	isl_space *space;
   9222  1.1  mrg 	isl_union_map *umap;
   9223  1.1  mrg 	isl_union_pw_aff *upa;
   9224  1.1  mrg 
   9225  1.1  mrg 	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
   9226  1.1  mrg 	if (n < 0)
   9227  1.1  mrg 		mupa = isl_multi_union_pw_aff_free(mupa);
   9228  1.1  mrg 	if (!mupa)
   9229  1.1  mrg 		return NULL;
   9230  1.1  mrg 
   9231  1.1  mrg 	if (n == 0)
   9232  1.1  mrg 		return isl_union_map_from_multi_union_pw_aff_0D(mupa);
   9233  1.1  mrg 
   9234  1.1  mrg 	upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
   9235  1.1  mrg 	umap = isl_union_map_from_union_pw_aff(upa);
   9236  1.1  mrg 
   9237  1.1  mrg 	for (i = 1; i < n; ++i) {
   9238  1.1  mrg 		isl_union_map *umap_i;
   9239  1.1  mrg 
   9240  1.1  mrg 		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
   9241  1.1  mrg 		umap_i = isl_union_map_from_union_pw_aff(upa);
   9242  1.1  mrg 		umap = isl_union_map_flat_range_product(umap, umap_i);
   9243  1.1  mrg 	}
   9244  1.1  mrg 
   9245  1.1  mrg 	space = isl_multi_union_pw_aff_get_space(mupa);
   9246  1.1  mrg 	umap = isl_union_map_reset_range_space(umap, space);
   9247  1.1  mrg 
   9248  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9249  1.1  mrg 	return umap;
   9250  1.1  mrg }
   9251  1.1  mrg 
   9252  1.1  mrg /* Internal data structure for isl_union_pw_multi_aff_reset_range_space.
   9253  1.1  mrg  * "range" is the space from which to set the range space.
   9254  1.1  mrg  * "res" collects the results.
   9255  1.1  mrg  */
   9256  1.1  mrg struct isl_union_pw_multi_aff_reset_range_space_data {
   9257  1.1  mrg 	isl_space *range;
   9258  1.1  mrg 	isl_union_pw_multi_aff *res;
   9259  1.1  mrg };
   9260  1.1  mrg 
   9261  1.1  mrg /* Replace the range space of "pma" by the range space of data->range and
   9262  1.1  mrg  * add the result to data->res.
   9263  1.1  mrg  */
   9264  1.1  mrg static isl_stat reset_range_space(__isl_take isl_pw_multi_aff *pma, void *user)
   9265  1.1  mrg {
   9266  1.1  mrg 	struct isl_union_pw_multi_aff_reset_range_space_data *data = user;
   9267  1.1  mrg 	isl_space *space;
   9268  1.1  mrg 
   9269  1.1  mrg 	space = isl_pw_multi_aff_get_space(pma);
   9270  1.1  mrg 	space = isl_space_domain(space);
   9271  1.1  mrg 	space = isl_space_extend_domain_with_range(space,
   9272  1.1  mrg 						isl_space_copy(data->range));
   9273  1.1  mrg 	pma = isl_pw_multi_aff_reset_space(pma, space);
   9274  1.1  mrg 	data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma);
   9275  1.1  mrg 
   9276  1.1  mrg 	return data->res ? isl_stat_ok : isl_stat_error;
   9277  1.1  mrg }
   9278  1.1  mrg 
   9279  1.1  mrg /* Replace the range space of all the piecewise affine expressions in "upma" by
   9280  1.1  mrg  * the range space of "space".
   9281  1.1  mrg  *
   9282  1.1  mrg  * This assumes that all these expressions have the same output dimension.
   9283  1.1  mrg  *
   9284  1.1  mrg  * Since the spaces of the expressions change, so do their hash values.
   9285  1.1  mrg  * We therefore need to create a new isl_union_pw_multi_aff.
   9286  1.1  mrg  * Note that the hash value is currently computed based on the entire
   9287  1.1  mrg  * space even though there can only be a single expression with a given
   9288  1.1  mrg  * domain space.
   9289  1.1  mrg  */
   9290  1.1  mrg static __isl_give isl_union_pw_multi_aff *
   9291  1.1  mrg isl_union_pw_multi_aff_reset_range_space(
   9292  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma, __isl_take isl_space *space)
   9293  1.1  mrg {
   9294  1.1  mrg 	struct isl_union_pw_multi_aff_reset_range_space_data data = { space };
   9295  1.1  mrg 	isl_space *space_upma;
   9296  1.1  mrg 
   9297  1.1  mrg 	space_upma = isl_union_pw_multi_aff_get_space(upma);
   9298  1.1  mrg 	data.res = isl_union_pw_multi_aff_empty(space_upma);
   9299  1.1  mrg 	if (isl_union_pw_multi_aff_foreach_pw_multi_aff(upma,
   9300  1.1  mrg 					&reset_range_space, &data) < 0)
   9301  1.1  mrg 		data.res = isl_union_pw_multi_aff_free(data.res);
   9302  1.1  mrg 
   9303  1.1  mrg 	isl_space_free(space);
   9304  1.1  mrg 	isl_union_pw_multi_aff_free(upma);
   9305  1.1  mrg 	return data.res;
   9306  1.1  mrg }
   9307  1.1  mrg 
   9308  1.1  mrg /* Construct and return a union piecewise multi affine expression
   9309  1.1  mrg  * that is equal to the given multi union piecewise affine expression,
   9310  1.1  mrg  * in the special case of a 0D multi union piecewise affine expression.
   9311  1.1  mrg  *
   9312  1.1  mrg  * Construct a union piecewise multi affine expression
   9313  1.1  mrg  * on top of the explicit domain of the input.
   9314  1.1  mrg  */
   9315  1.1  mrg __isl_give isl_union_pw_multi_aff *
   9316  1.1  mrg isl_union_pw_multi_aff_from_multi_union_pw_aff_0D(
   9317  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa)
   9318  1.1  mrg {
   9319  1.1  mrg 	isl_space *space;
   9320  1.1  mrg 	isl_multi_val *mv;
   9321  1.1  mrg 	isl_union_set *domain;
   9322  1.1  mrg 
   9323  1.1  mrg 	space = isl_multi_union_pw_aff_get_space(mupa);
   9324  1.1  mrg 	mv = isl_multi_val_zero(space);
   9325  1.1  mrg 	domain = isl_multi_union_pw_aff_domain(mupa);
   9326  1.1  mrg 	return isl_union_pw_multi_aff_multi_val_on_domain(domain, mv);
   9327  1.1  mrg }
   9328  1.1  mrg 
   9329  1.1  mrg /* Construct and return a union piecewise multi affine expression
   9330  1.1  mrg  * that is equal to the given multi union piecewise affine expression.
   9331  1.1  mrg  *
   9332  1.1  mrg  * If the input is zero-dimensional, then
   9333  1.1  mrg  * construct a union piecewise multi affine expression
   9334  1.1  mrg  * on top of the explicit domain of the input.
   9335  1.1  mrg  */
   9336  1.1  mrg __isl_give isl_union_pw_multi_aff *
   9337  1.1  mrg isl_union_pw_multi_aff_from_multi_union_pw_aff(
   9338  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa)
   9339  1.1  mrg {
   9340  1.1  mrg 	int i;
   9341  1.1  mrg 	isl_size n;
   9342  1.1  mrg 	isl_space *space;
   9343  1.1  mrg 	isl_union_pw_multi_aff *upma;
   9344  1.1  mrg 	isl_union_pw_aff *upa;
   9345  1.1  mrg 
   9346  1.1  mrg 	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
   9347  1.1  mrg 	if (n < 0)
   9348  1.1  mrg 		mupa = isl_multi_union_pw_aff_free(mupa);
   9349  1.1  mrg 	if (!mupa)
   9350  1.1  mrg 		return NULL;
   9351  1.1  mrg 
   9352  1.1  mrg 	if (n == 0)
   9353  1.1  mrg 		return isl_union_pw_multi_aff_from_multi_union_pw_aff_0D(mupa);
   9354  1.1  mrg 
   9355  1.1  mrg 	space = isl_multi_union_pw_aff_get_space(mupa);
   9356  1.1  mrg 	upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
   9357  1.1  mrg 	upma = isl_union_pw_multi_aff_from_union_pw_aff(upa);
   9358  1.1  mrg 
   9359  1.1  mrg 	for (i = 1; i < n; ++i) {
   9360  1.1  mrg 		isl_union_pw_multi_aff *upma_i;
   9361  1.1  mrg 
   9362  1.1  mrg 		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
   9363  1.1  mrg 		upma_i = isl_union_pw_multi_aff_from_union_pw_aff(upa);
   9364  1.1  mrg 		upma = isl_union_pw_multi_aff_flat_range_product(upma, upma_i);
   9365  1.1  mrg 	}
   9366  1.1  mrg 
   9367  1.1  mrg 	upma = isl_union_pw_multi_aff_reset_range_space(upma, space);
   9368  1.1  mrg 
   9369  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9370  1.1  mrg 	return upma;
   9371  1.1  mrg }
   9372  1.1  mrg 
   9373  1.1  mrg /* Intersect the range of "mupa" with "range",
   9374  1.1  mrg  * in the special case where "mupa" is 0D.
   9375  1.1  mrg  *
   9376  1.1  mrg  * Intersect the domain of "mupa" with the constraints on the parameters
   9377  1.1  mrg  * of "range".
   9378  1.1  mrg  */
   9379  1.1  mrg static __isl_give isl_multi_union_pw_aff *mupa_intersect_range_0D(
   9380  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *range)
   9381  1.1  mrg {
   9382  1.1  mrg 	range = isl_set_params(range);
   9383  1.1  mrg 	mupa = isl_multi_union_pw_aff_intersect_params(mupa, range);
   9384  1.1  mrg 	return mupa;
   9385  1.1  mrg }
   9386  1.1  mrg 
   9387  1.1  mrg /* Intersect the range of "mupa" with "range".
   9388  1.1  mrg  * That is, keep only those domain elements that have a function value
   9389  1.1  mrg  * in "range".
   9390  1.1  mrg  */
   9391  1.1  mrg __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_intersect_range(
   9392  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_set *range)
   9393  1.1  mrg {
   9394  1.1  mrg 	isl_union_pw_multi_aff *upma;
   9395  1.1  mrg 	isl_union_set *domain;
   9396  1.1  mrg 	isl_space *space;
   9397  1.1  mrg 	isl_size n;
   9398  1.1  mrg 	int match;
   9399  1.1  mrg 
   9400  1.1  mrg 	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
   9401  1.1  mrg 	if (n < 0 || !range)
   9402  1.1  mrg 		goto error;
   9403  1.1  mrg 
   9404  1.1  mrg 	space = isl_set_get_space(range);
   9405  1.1  mrg 	match = isl_space_tuple_is_equal(mupa->space, isl_dim_set,
   9406  1.1  mrg 					space, isl_dim_set);
   9407  1.1  mrg 	isl_space_free(space);
   9408  1.1  mrg 	if (match < 0)
   9409  1.1  mrg 		goto error;
   9410  1.1  mrg 	if (!match)
   9411  1.1  mrg 		isl_die(isl_multi_union_pw_aff_get_ctx(mupa), isl_error_invalid,
   9412  1.1  mrg 			"space don't match", goto error);
   9413  1.1  mrg 	if (n == 0)
   9414  1.1  mrg 		return mupa_intersect_range_0D(mupa, range);
   9415  1.1  mrg 
   9416  1.1  mrg 	upma = isl_union_pw_multi_aff_from_multi_union_pw_aff(
   9417  1.1  mrg 					isl_multi_union_pw_aff_copy(mupa));
   9418  1.1  mrg 	domain = isl_union_set_from_set(range);
   9419  1.1  mrg 	domain = isl_union_set_preimage_union_pw_multi_aff(domain, upma);
   9420  1.1  mrg 	mupa = isl_multi_union_pw_aff_intersect_domain(mupa, domain);
   9421  1.1  mrg 
   9422  1.1  mrg 	return mupa;
   9423  1.1  mrg error:
   9424  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9425  1.1  mrg 	isl_set_free(range);
   9426  1.1  mrg 	return NULL;
   9427  1.1  mrg }
   9428  1.1  mrg 
   9429  1.1  mrg /* Return the shared domain of the elements of "mupa",
   9430  1.1  mrg  * in the special case where "mupa" is zero-dimensional.
   9431  1.1  mrg  *
   9432  1.1  mrg  * Return the explicit domain of "mupa".
   9433  1.1  mrg  * Note that this domain may be a parameter set, either
   9434  1.1  mrg  * because "mupa" is meant to live in a set space or
   9435  1.1  mrg  * because no explicit domain has been set.
   9436  1.1  mrg  */
   9437  1.1  mrg __isl_give isl_union_set *isl_multi_union_pw_aff_domain_0D(
   9438  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa)
   9439  1.1  mrg {
   9440  1.1  mrg 	isl_union_set *dom;
   9441  1.1  mrg 
   9442  1.1  mrg 	dom = isl_multi_union_pw_aff_get_explicit_domain(mupa);
   9443  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9444  1.1  mrg 
   9445  1.1  mrg 	return dom;
   9446  1.1  mrg }
   9447  1.1  mrg 
   9448  1.1  mrg /* Return the shared domain of the elements of "mupa".
   9449  1.1  mrg  *
   9450  1.1  mrg  * If "mupa" is zero-dimensional, then return its explicit domain.
   9451  1.1  mrg  */
   9452  1.1  mrg __isl_give isl_union_set *isl_multi_union_pw_aff_domain(
   9453  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa)
   9454  1.1  mrg {
   9455  1.1  mrg 	int i;
   9456  1.1  mrg 	isl_size n;
   9457  1.1  mrg 	isl_union_pw_aff *upa;
   9458  1.1  mrg 	isl_union_set *dom;
   9459  1.1  mrg 
   9460  1.1  mrg 	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
   9461  1.1  mrg 	if (n < 0)
   9462  1.1  mrg 		mupa = isl_multi_union_pw_aff_free(mupa);
   9463  1.1  mrg 	if (!mupa)
   9464  1.1  mrg 		return NULL;
   9465  1.1  mrg 
   9466  1.1  mrg 	if (n == 0)
   9467  1.1  mrg 		return isl_multi_union_pw_aff_domain_0D(mupa);
   9468  1.1  mrg 
   9469  1.1  mrg 	upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, 0);
   9470  1.1  mrg 	dom = isl_union_pw_aff_domain(upa);
   9471  1.1  mrg 	for (i = 1; i < n; ++i) {
   9472  1.1  mrg 		isl_union_set *dom_i;
   9473  1.1  mrg 
   9474  1.1  mrg 		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
   9475  1.1  mrg 		dom_i = isl_union_pw_aff_domain(upa);
   9476  1.1  mrg 		dom = isl_union_set_intersect(dom, dom_i);
   9477  1.1  mrg 	}
   9478  1.1  mrg 
   9479  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9480  1.1  mrg 	return dom;
   9481  1.1  mrg }
   9482  1.1  mrg 
   9483  1.1  mrg /* Apply "aff" to "mupa".  The space of "mupa" is equal to the domain of "aff".
   9484  1.1  mrg  * In particular, the spaces have been aligned.
   9485  1.1  mrg  * The result is defined over the shared domain of the elements of "mupa"
   9486  1.1  mrg  *
   9487  1.1  mrg  * We first extract the parametric constant part of "aff" and
   9488  1.1  mrg  * define that over the shared domain.
   9489  1.1  mrg  * Then we iterate over all input dimensions of "aff" and add the corresponding
   9490  1.1  mrg  * multiples of the elements of "mupa".
   9491  1.1  mrg  * Finally, we consider the integer divisions, calling the function
   9492  1.1  mrg  * recursively to obtain an isl_union_pw_aff corresponding to the
   9493  1.1  mrg  * integer division argument.
   9494  1.1  mrg  */
   9495  1.1  mrg static __isl_give isl_union_pw_aff *multi_union_pw_aff_apply_aff(
   9496  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff)
   9497  1.1  mrg {
   9498  1.1  mrg 	int i;
   9499  1.1  mrg 	isl_size n_in, n_div;
   9500  1.1  mrg 	isl_union_pw_aff *upa;
   9501  1.1  mrg 	isl_union_set *uset;
   9502  1.1  mrg 	isl_val *v;
   9503  1.1  mrg 	isl_aff *cst;
   9504  1.1  mrg 
   9505  1.1  mrg 	n_in = isl_aff_dim(aff, isl_dim_in);
   9506  1.1  mrg 	n_div = isl_aff_dim(aff, isl_dim_div);
   9507  1.1  mrg 	if (n_in < 0 || n_div < 0)
   9508  1.1  mrg 		goto error;
   9509  1.1  mrg 
   9510  1.1  mrg 	uset = isl_multi_union_pw_aff_domain(isl_multi_union_pw_aff_copy(mupa));
   9511  1.1  mrg 	cst = isl_aff_copy(aff);
   9512  1.1  mrg 	cst = isl_aff_drop_dims(cst, isl_dim_div, 0, n_div);
   9513  1.1  mrg 	cst = isl_aff_drop_dims(cst, isl_dim_in, 0, n_in);
   9514  1.1  mrg 	cst = isl_aff_project_domain_on_params(cst);
   9515  1.1  mrg 	upa = isl_union_pw_aff_aff_on_domain(uset, cst);
   9516  1.1  mrg 
   9517  1.1  mrg 	for (i = 0; i < n_in; ++i) {
   9518  1.1  mrg 		isl_union_pw_aff *upa_i;
   9519  1.1  mrg 
   9520  1.1  mrg 		if (!isl_aff_involves_dims(aff, isl_dim_in, i, 1))
   9521  1.1  mrg 			continue;
   9522  1.1  mrg 		v = isl_aff_get_coefficient_val(aff, isl_dim_in, i);
   9523  1.1  mrg 		upa_i = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
   9524  1.1  mrg 		upa_i = isl_union_pw_aff_scale_val(upa_i, v);
   9525  1.1  mrg 		upa = isl_union_pw_aff_add(upa, upa_i);
   9526  1.1  mrg 	}
   9527  1.1  mrg 
   9528  1.1  mrg 	for (i = 0; i < n_div; ++i) {
   9529  1.1  mrg 		isl_aff *div;
   9530  1.1  mrg 		isl_union_pw_aff *upa_i;
   9531  1.1  mrg 
   9532  1.1  mrg 		if (!isl_aff_involves_dims(aff, isl_dim_div, i, 1))
   9533  1.1  mrg 			continue;
   9534  1.1  mrg 		div = isl_aff_get_div(aff, i);
   9535  1.1  mrg 		upa_i = multi_union_pw_aff_apply_aff(
   9536  1.1  mrg 					isl_multi_union_pw_aff_copy(mupa), div);
   9537  1.1  mrg 		upa_i = isl_union_pw_aff_floor(upa_i);
   9538  1.1  mrg 		v = isl_aff_get_coefficient_val(aff, isl_dim_div, i);
   9539  1.1  mrg 		upa_i = isl_union_pw_aff_scale_val(upa_i, v);
   9540  1.1  mrg 		upa = isl_union_pw_aff_add(upa, upa_i);
   9541  1.1  mrg 	}
   9542  1.1  mrg 
   9543  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9544  1.1  mrg 	isl_aff_free(aff);
   9545  1.1  mrg 
   9546  1.1  mrg 	return upa;
   9547  1.1  mrg error:
   9548  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9549  1.1  mrg 	isl_aff_free(aff);
   9550  1.1  mrg 	return NULL;
   9551  1.1  mrg }
   9552  1.1  mrg 
   9553  1.1  mrg /* Apply "aff" to "mupa".  The space of "mupa" needs to be compatible
   9554  1.1  mrg  * with the domain of "aff".
   9555  1.1  mrg  * Furthermore, the dimension of this space needs to be greater than zero.
   9556  1.1  mrg  * The result is defined over the shared domain of the elements of "mupa"
   9557  1.1  mrg  *
   9558  1.1  mrg  * We perform these checks and then hand over control to
   9559  1.1  mrg  * multi_union_pw_aff_apply_aff.
   9560  1.1  mrg  */
   9561  1.1  mrg __isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_aff(
   9562  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_aff *aff)
   9563  1.1  mrg {
   9564  1.1  mrg 	isl_size dim;
   9565  1.1  mrg 	isl_space *space1, *space2;
   9566  1.1  mrg 	isl_bool equal;
   9567  1.1  mrg 
   9568  1.1  mrg 	mupa = isl_multi_union_pw_aff_align_params(mupa,
   9569  1.1  mrg 						isl_aff_get_space(aff));
   9570  1.1  mrg 	aff = isl_aff_align_params(aff, isl_multi_union_pw_aff_get_space(mupa));
   9571  1.1  mrg 	if (!mupa || !aff)
   9572  1.1  mrg 		goto error;
   9573  1.1  mrg 
   9574  1.1  mrg 	space1 = isl_multi_union_pw_aff_get_space(mupa);
   9575  1.1  mrg 	space2 = isl_aff_get_domain_space(aff);
   9576  1.1  mrg 	equal = isl_space_is_equal(space1, space2);
   9577  1.1  mrg 	isl_space_free(space1);
   9578  1.1  mrg 	isl_space_free(space2);
   9579  1.1  mrg 	if (equal < 0)
   9580  1.1  mrg 		goto error;
   9581  1.1  mrg 	if (!equal)
   9582  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   9583  1.1  mrg 			"spaces don't match", goto error);
   9584  1.1  mrg 	dim = isl_aff_dim(aff, isl_dim_in);
   9585  1.1  mrg 	if (dim < 0)
   9586  1.1  mrg 		goto error;
   9587  1.1  mrg 	if (dim == 0)
   9588  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   9589  1.1  mrg 			"cannot determine domains", goto error);
   9590  1.1  mrg 
   9591  1.1  mrg 	return multi_union_pw_aff_apply_aff(mupa, aff);
   9592  1.1  mrg error:
   9593  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9594  1.1  mrg 	isl_aff_free(aff);
   9595  1.1  mrg 	return NULL;
   9596  1.1  mrg }
   9597  1.1  mrg 
   9598  1.1  mrg /* Apply "ma" to "mupa", in the special case where "mupa" is 0D.
   9599  1.1  mrg  * The space of "mupa" is known to be compatible with the domain of "ma".
   9600  1.1  mrg  *
   9601  1.1  mrg  * Construct an isl_multi_union_pw_aff that is equal to "ma"
   9602  1.1  mrg  * on the domain of "mupa".
   9603  1.1  mrg  */
   9604  1.1  mrg static __isl_give isl_multi_union_pw_aff *mupa_apply_multi_aff_0D(
   9605  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma)
   9606  1.1  mrg {
   9607  1.1  mrg 	isl_union_set *dom;
   9608  1.1  mrg 
   9609  1.1  mrg 	dom = isl_multi_union_pw_aff_domain(mupa);
   9610  1.1  mrg 	ma = isl_multi_aff_project_domain_on_params(ma);
   9611  1.1  mrg 
   9612  1.1  mrg 	return isl_multi_union_pw_aff_multi_aff_on_domain(dom, ma);
   9613  1.1  mrg }
   9614  1.1  mrg 
   9615  1.1  mrg /* Apply "ma" to "mupa".  The space of "mupa" needs to be compatible
   9616  1.1  mrg  * with the domain of "ma".
   9617  1.1  mrg  * The result is defined over the shared domain of the elements of "mupa"
   9618  1.1  mrg  */
   9619  1.1  mrg __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_multi_aff(
   9620  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_multi_aff *ma)
   9621  1.1  mrg {
   9622  1.1  mrg 	isl_space *space1, *space2;
   9623  1.1  mrg 	isl_multi_union_pw_aff *res;
   9624  1.1  mrg 	isl_bool equal;
   9625  1.1  mrg 	int i;
   9626  1.1  mrg 	isl_size n_in, n_out;
   9627  1.1  mrg 
   9628  1.1  mrg 	mupa = isl_multi_union_pw_aff_align_params(mupa,
   9629  1.1  mrg 						isl_multi_aff_get_space(ma));
   9630  1.1  mrg 	ma = isl_multi_aff_align_params(ma,
   9631  1.1  mrg 					isl_multi_union_pw_aff_get_space(mupa));
   9632  1.1  mrg 	n_in = isl_multi_aff_dim(ma, isl_dim_in);
   9633  1.1  mrg 	n_out = isl_multi_aff_dim(ma, isl_dim_out);
   9634  1.1  mrg 	if (!mupa || n_in < 0 || n_out < 0)
   9635  1.1  mrg 		goto error;
   9636  1.1  mrg 
   9637  1.1  mrg 	space1 = isl_multi_union_pw_aff_get_space(mupa);
   9638  1.1  mrg 	space2 = isl_multi_aff_get_domain_space(ma);
   9639  1.1  mrg 	equal = isl_space_is_equal(space1, space2);
   9640  1.1  mrg 	isl_space_free(space1);
   9641  1.1  mrg 	isl_space_free(space2);
   9642  1.1  mrg 	if (equal < 0)
   9643  1.1  mrg 		goto error;
   9644  1.1  mrg 	if (!equal)
   9645  1.1  mrg 		isl_die(isl_multi_aff_get_ctx(ma), isl_error_invalid,
   9646  1.1  mrg 			"spaces don't match", goto error);
   9647  1.1  mrg 	if (n_in == 0)
   9648  1.1  mrg 		return mupa_apply_multi_aff_0D(mupa, ma);
   9649  1.1  mrg 
   9650  1.1  mrg 	space1 = isl_space_range(isl_multi_aff_get_space(ma));
   9651  1.1  mrg 	res = isl_multi_union_pw_aff_alloc(space1);
   9652  1.1  mrg 
   9653  1.1  mrg 	for (i = 0; i < n_out; ++i) {
   9654  1.1  mrg 		isl_aff *aff;
   9655  1.1  mrg 		isl_union_pw_aff *upa;
   9656  1.1  mrg 
   9657  1.1  mrg 		aff = isl_multi_aff_get_aff(ma, i);
   9658  1.1  mrg 		upa = multi_union_pw_aff_apply_aff(
   9659  1.1  mrg 					isl_multi_union_pw_aff_copy(mupa), aff);
   9660  1.1  mrg 		res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa);
   9661  1.1  mrg 	}
   9662  1.1  mrg 
   9663  1.1  mrg 	isl_multi_aff_free(ma);
   9664  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9665  1.1  mrg 	return res;
   9666  1.1  mrg error:
   9667  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9668  1.1  mrg 	isl_multi_aff_free(ma);
   9669  1.1  mrg 	return NULL;
   9670  1.1  mrg }
   9671  1.1  mrg 
   9672  1.1  mrg /* Apply "pa" to "mupa", in the special case where "mupa" is 0D.
   9673  1.1  mrg  * The space of "mupa" is known to be compatible with the domain of "pa".
   9674  1.1  mrg  *
   9675  1.1  mrg  * Construct an isl_multi_union_pw_aff that is equal to "pa"
   9676  1.1  mrg  * on the domain of "mupa".
   9677  1.1  mrg  */
   9678  1.1  mrg static __isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff_0D(
   9679  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa)
   9680  1.1  mrg {
   9681  1.1  mrg 	isl_union_set *dom;
   9682  1.1  mrg 
   9683  1.1  mrg 	dom = isl_multi_union_pw_aff_domain(mupa);
   9684  1.1  mrg 	pa = isl_pw_aff_project_domain_on_params(pa);
   9685  1.1  mrg 
   9686  1.1  mrg 	return isl_union_pw_aff_pw_aff_on_domain(dom, pa);
   9687  1.1  mrg }
   9688  1.1  mrg 
   9689  1.1  mrg /* Apply "pa" to "mupa".  The space of "mupa" needs to be compatible
   9690  1.1  mrg  * with the domain of "pa".
   9691  1.1  mrg  * Furthermore, the dimension of this space needs to be greater than zero.
   9692  1.1  mrg  * The result is defined over the shared domain of the elements of "mupa"
   9693  1.1  mrg  */
   9694  1.1  mrg __isl_give isl_union_pw_aff *isl_multi_union_pw_aff_apply_pw_aff(
   9695  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa, __isl_take isl_pw_aff *pa)
   9696  1.1  mrg {
   9697  1.1  mrg 	int i;
   9698  1.1  mrg 	isl_bool equal;
   9699  1.1  mrg 	isl_size n_in;
   9700  1.1  mrg 	isl_space *space, *space2;
   9701  1.1  mrg 	isl_union_pw_aff *upa;
   9702  1.1  mrg 
   9703  1.1  mrg 	mupa = isl_multi_union_pw_aff_align_params(mupa,
   9704  1.1  mrg 						isl_pw_aff_get_space(pa));
   9705  1.1  mrg 	pa = isl_pw_aff_align_params(pa,
   9706  1.1  mrg 				    isl_multi_union_pw_aff_get_space(mupa));
   9707  1.1  mrg 	if (!mupa || !pa)
   9708  1.1  mrg 		goto error;
   9709  1.1  mrg 
   9710  1.1  mrg 	space = isl_multi_union_pw_aff_get_space(mupa);
   9711  1.1  mrg 	space2 = isl_pw_aff_get_domain_space(pa);
   9712  1.1  mrg 	equal = isl_space_is_equal(space, space2);
   9713  1.1  mrg 	isl_space_free(space);
   9714  1.1  mrg 	isl_space_free(space2);
   9715  1.1  mrg 	if (equal < 0)
   9716  1.1  mrg 		goto error;
   9717  1.1  mrg 	if (!equal)
   9718  1.1  mrg 		isl_die(isl_pw_aff_get_ctx(pa), isl_error_invalid,
   9719  1.1  mrg 			"spaces don't match", goto error);
   9720  1.1  mrg 	n_in = isl_pw_aff_dim(pa, isl_dim_in);
   9721  1.1  mrg 	if (n_in < 0)
   9722  1.1  mrg 		goto error;
   9723  1.1  mrg 	if (n_in == 0)
   9724  1.1  mrg 		return isl_multi_union_pw_aff_apply_pw_aff_0D(mupa, pa);
   9725  1.1  mrg 
   9726  1.1  mrg 	space = isl_space_params(isl_multi_union_pw_aff_get_space(mupa));
   9727  1.1  mrg 	upa = isl_union_pw_aff_empty(space);
   9728  1.1  mrg 
   9729  1.1  mrg 	for (i = 0; i < pa->n; ++i) {
   9730  1.1  mrg 		isl_aff *aff;
   9731  1.1  mrg 		isl_set *domain;
   9732  1.1  mrg 		isl_multi_union_pw_aff *mupa_i;
   9733  1.1  mrg 		isl_union_pw_aff *upa_i;
   9734  1.1  mrg 
   9735  1.1  mrg 		mupa_i = isl_multi_union_pw_aff_copy(mupa);
   9736  1.1  mrg 		domain = isl_set_copy(pa->p[i].set);
   9737  1.1  mrg 		mupa_i = isl_multi_union_pw_aff_intersect_range(mupa_i, domain);
   9738  1.1  mrg 		aff = isl_aff_copy(pa->p[i].aff);
   9739  1.1  mrg 		upa_i = multi_union_pw_aff_apply_aff(mupa_i, aff);
   9740  1.1  mrg 		upa = isl_union_pw_aff_union_add(upa, upa_i);
   9741  1.1  mrg 	}
   9742  1.1  mrg 
   9743  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9744  1.1  mrg 	isl_pw_aff_free(pa);
   9745  1.1  mrg 	return upa;
   9746  1.1  mrg error:
   9747  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9748  1.1  mrg 	isl_pw_aff_free(pa);
   9749  1.1  mrg 	return NULL;
   9750  1.1  mrg }
   9751  1.1  mrg 
   9752  1.1  mrg /* Apply "pma" to "mupa", in the special case where "mupa" is 0D.
   9753  1.1  mrg  * The space of "mupa" is known to be compatible with the domain of "pma".
   9754  1.1  mrg  *
   9755  1.1  mrg  * Construct an isl_multi_union_pw_aff that is equal to "pma"
   9756  1.1  mrg  * on the domain of "mupa".
   9757  1.1  mrg  */
   9758  1.1  mrg static __isl_give isl_multi_union_pw_aff *mupa_apply_pw_multi_aff_0D(
   9759  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa,
   9760  1.1  mrg 	__isl_take isl_pw_multi_aff *pma)
   9761  1.1  mrg {
   9762  1.1  mrg 	isl_union_set *dom;
   9763  1.1  mrg 
   9764  1.1  mrg 	dom = isl_multi_union_pw_aff_domain(mupa);
   9765  1.1  mrg 	pma = isl_pw_multi_aff_project_domain_on_params(pma);
   9766  1.1  mrg 
   9767  1.1  mrg 	return isl_multi_union_pw_aff_pw_multi_aff_on_domain(dom, pma);
   9768  1.1  mrg }
   9769  1.1  mrg 
   9770  1.1  mrg /* Apply "pma" to "mupa".  The space of "mupa" needs to be compatible
   9771  1.1  mrg  * with the domain of "pma".
   9772  1.1  mrg  * The result is defined over the shared domain of the elements of "mupa"
   9773  1.1  mrg  */
   9774  1.1  mrg __isl_give isl_multi_union_pw_aff *isl_multi_union_pw_aff_apply_pw_multi_aff(
   9775  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa,
   9776  1.1  mrg 	__isl_take isl_pw_multi_aff *pma)
   9777  1.1  mrg {
   9778  1.1  mrg 	isl_space *space1, *space2;
   9779  1.1  mrg 	isl_multi_union_pw_aff *res;
   9780  1.1  mrg 	isl_bool equal;
   9781  1.1  mrg 	int i;
   9782  1.1  mrg 	isl_size n_in, n_out;
   9783  1.1  mrg 
   9784  1.1  mrg 	mupa = isl_multi_union_pw_aff_align_params(mupa,
   9785  1.1  mrg 					isl_pw_multi_aff_get_space(pma));
   9786  1.1  mrg 	pma = isl_pw_multi_aff_align_params(pma,
   9787  1.1  mrg 					isl_multi_union_pw_aff_get_space(mupa));
   9788  1.1  mrg 	if (!mupa || !pma)
   9789  1.1  mrg 		goto error;
   9790  1.1  mrg 
   9791  1.1  mrg 	space1 = isl_multi_union_pw_aff_get_space(mupa);
   9792  1.1  mrg 	space2 = isl_pw_multi_aff_get_domain_space(pma);
   9793  1.1  mrg 	equal = isl_space_is_equal(space1, space2);
   9794  1.1  mrg 	isl_space_free(space1);
   9795  1.1  mrg 	isl_space_free(space2);
   9796  1.1  mrg 	if (equal < 0)
   9797  1.1  mrg 		goto error;
   9798  1.1  mrg 	if (!equal)
   9799  1.1  mrg 		isl_die(isl_pw_multi_aff_get_ctx(pma), isl_error_invalid,
   9800  1.1  mrg 			"spaces don't match", goto error);
   9801  1.1  mrg 	n_in = isl_pw_multi_aff_dim(pma, isl_dim_in);
   9802  1.1  mrg 	n_out = isl_pw_multi_aff_dim(pma, isl_dim_out);
   9803  1.1  mrg 	if (n_in < 0 || n_out < 0)
   9804  1.1  mrg 		goto error;
   9805  1.1  mrg 	if (n_in == 0)
   9806  1.1  mrg 		return mupa_apply_pw_multi_aff_0D(mupa, pma);
   9807  1.1  mrg 
   9808  1.1  mrg 	space1 = isl_space_range(isl_pw_multi_aff_get_space(pma));
   9809  1.1  mrg 	res = isl_multi_union_pw_aff_alloc(space1);
   9810  1.1  mrg 
   9811  1.1  mrg 	for (i = 0; i < n_out; ++i) {
   9812  1.1  mrg 		isl_pw_aff *pa;
   9813  1.1  mrg 		isl_union_pw_aff *upa;
   9814  1.1  mrg 
   9815  1.1  mrg 		pa = isl_pw_multi_aff_get_pw_aff(pma, i);
   9816  1.1  mrg 		upa = isl_multi_union_pw_aff_apply_pw_aff(
   9817  1.1  mrg 					isl_multi_union_pw_aff_copy(mupa), pa);
   9818  1.1  mrg 		res = isl_multi_union_pw_aff_set_union_pw_aff(res, i, upa);
   9819  1.1  mrg 	}
   9820  1.1  mrg 
   9821  1.1  mrg 	isl_pw_multi_aff_free(pma);
   9822  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9823  1.1  mrg 	return res;
   9824  1.1  mrg error:
   9825  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9826  1.1  mrg 	isl_pw_multi_aff_free(pma);
   9827  1.1  mrg 	return NULL;
   9828  1.1  mrg }
   9829  1.1  mrg 
   9830  1.1  mrg /* Replace the explicit domain of "mupa" by its preimage under "upma".
   9831  1.1  mrg  * If the explicit domain only keeps track of constraints on the parameters,
   9832  1.1  mrg  * then only update those constraints.
   9833  1.1  mrg  */
   9834  1.1  mrg static __isl_give isl_multi_union_pw_aff *preimage_explicit_domain(
   9835  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa,
   9836  1.1  mrg 	__isl_keep isl_union_pw_multi_aff *upma)
   9837  1.1  mrg {
   9838  1.1  mrg 	isl_bool is_params;
   9839  1.1  mrg 
   9840  1.1  mrg 	if (isl_multi_union_pw_aff_check_has_explicit_domain(mupa) < 0)
   9841  1.1  mrg 		return isl_multi_union_pw_aff_free(mupa);
   9842  1.1  mrg 
   9843  1.1  mrg 	mupa = isl_multi_union_pw_aff_cow(mupa);
   9844  1.1  mrg 	if (!mupa)
   9845  1.1  mrg 		return NULL;
   9846  1.1  mrg 
   9847  1.1  mrg 	is_params = isl_union_set_is_params(mupa->u.dom);
   9848  1.1  mrg 	if (is_params < 0)
   9849  1.1  mrg 		return isl_multi_union_pw_aff_free(mupa);
   9850  1.1  mrg 
   9851  1.1  mrg 	upma = isl_union_pw_multi_aff_copy(upma);
   9852  1.1  mrg 	if (is_params)
   9853  1.1  mrg 		mupa->u.dom = isl_union_set_intersect_params(mupa->u.dom,
   9854  1.1  mrg 		    isl_union_set_params(isl_union_pw_multi_aff_domain(upma)));
   9855  1.1  mrg 	else
   9856  1.1  mrg 		mupa->u.dom = isl_union_set_preimage_union_pw_multi_aff(
   9857  1.1  mrg 							    mupa->u.dom, upma);
   9858  1.1  mrg 	if (!mupa->u.dom)
   9859  1.1  mrg 		return isl_multi_union_pw_aff_free(mupa);
   9860  1.1  mrg 	return mupa;
   9861  1.1  mrg }
   9862  1.1  mrg 
   9863  1.1  mrg /* Compute the pullback of "mupa" by the function represented by "upma".
   9864  1.1  mrg  * In other words, plug in "upma" in "mupa".  The result contains
   9865  1.1  mrg  * expressions defined over the domain space of "upma".
   9866  1.1  mrg  *
   9867  1.1  mrg  * Run over all elements of "mupa" and plug in "upma" in each of them.
   9868  1.1  mrg  *
   9869  1.1  mrg  * If "mupa" has an explicit domain, then it is this domain
   9870  1.1  mrg  * that needs to undergo a pullback instead, i.e., a preimage.
   9871  1.1  mrg  */
   9872  1.1  mrg __isl_give isl_multi_union_pw_aff *
   9873  1.1  mrg isl_multi_union_pw_aff_pullback_union_pw_multi_aff(
   9874  1.1  mrg 	__isl_take isl_multi_union_pw_aff *mupa,
   9875  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma)
   9876  1.1  mrg {
   9877  1.1  mrg 	int i;
   9878  1.1  mrg 	isl_size n;
   9879  1.1  mrg 
   9880  1.1  mrg 	mupa = isl_multi_union_pw_aff_align_params(mupa,
   9881  1.1  mrg 				    isl_union_pw_multi_aff_get_space(upma));
   9882  1.1  mrg 	upma = isl_union_pw_multi_aff_align_params(upma,
   9883  1.1  mrg 				    isl_multi_union_pw_aff_get_space(mupa));
   9884  1.1  mrg 	mupa = isl_multi_union_pw_aff_cow(mupa);
   9885  1.1  mrg 	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
   9886  1.1  mrg 	if (n < 0 || !upma)
   9887  1.1  mrg 		goto error;
   9888  1.1  mrg 
   9889  1.1  mrg 	for (i = 0; i < n; ++i) {
   9890  1.1  mrg 		isl_union_pw_aff *upa;
   9891  1.1  mrg 
   9892  1.1  mrg 		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
   9893  1.1  mrg 		upa = isl_union_pw_aff_pullback_union_pw_multi_aff(upa,
   9894  1.1  mrg 					    isl_union_pw_multi_aff_copy(upma));
   9895  1.1  mrg 		mupa = isl_multi_union_pw_aff_set_union_pw_aff(mupa, i, upa);
   9896  1.1  mrg 	}
   9897  1.1  mrg 
   9898  1.1  mrg 	if (isl_multi_union_pw_aff_has_explicit_domain(mupa))
   9899  1.1  mrg 		mupa = preimage_explicit_domain(mupa, upma);
   9900  1.1  mrg 
   9901  1.1  mrg 	isl_union_pw_multi_aff_free(upma);
   9902  1.1  mrg 	return mupa;
   9903  1.1  mrg error:
   9904  1.1  mrg 	isl_multi_union_pw_aff_free(mupa);
   9905  1.1  mrg 	isl_union_pw_multi_aff_free(upma);
   9906  1.1  mrg 	return NULL;
   9907  1.1  mrg }
   9908  1.1  mrg 
   9909  1.1  mrg /* Extract the sequence of elements in "mupa" with domain space "space"
   9910  1.1  mrg  * (ignoring parameters).
   9911  1.1  mrg  *
   9912  1.1  mrg  * For the elements of "mupa" that are not defined on the specified space,
   9913  1.1  mrg  * the corresponding element in the result is empty.
   9914  1.1  mrg  */
   9915  1.1  mrg __isl_give isl_multi_pw_aff *isl_multi_union_pw_aff_extract_multi_pw_aff(
   9916  1.1  mrg 	__isl_keep isl_multi_union_pw_aff *mupa, __isl_take isl_space *space)
   9917  1.1  mrg {
   9918  1.1  mrg 	int i;
   9919  1.1  mrg 	isl_size n;
   9920  1.1  mrg 	isl_space *space_mpa;
   9921  1.1  mrg 	isl_multi_pw_aff *mpa;
   9922  1.1  mrg 
   9923  1.1  mrg 	n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
   9924  1.1  mrg 	if (n < 0 || !space)
   9925  1.1  mrg 		goto error;
   9926  1.1  mrg 
   9927  1.1  mrg 	space_mpa = isl_multi_union_pw_aff_get_space(mupa);
   9928  1.1  mrg 	space = isl_space_replace_params(space, space_mpa);
   9929  1.1  mrg 	space_mpa = isl_space_map_from_domain_and_range(isl_space_copy(space),
   9930  1.1  mrg 							space_mpa);
   9931  1.1  mrg 	mpa = isl_multi_pw_aff_alloc(space_mpa);
   9932  1.1  mrg 
   9933  1.1  mrg 	space = isl_space_from_domain(space);
   9934  1.1  mrg 	space = isl_space_add_dims(space, isl_dim_out, 1);
   9935  1.1  mrg 	for (i = 0; i < n; ++i) {
   9936  1.1  mrg 		isl_union_pw_aff *upa;
   9937  1.1  mrg 		isl_pw_aff *pa;
   9938  1.1  mrg 
   9939  1.1  mrg 		upa = isl_multi_union_pw_aff_get_union_pw_aff(mupa, i);
   9940  1.1  mrg 		pa = isl_union_pw_aff_extract_pw_aff(upa,
   9941  1.1  mrg 							isl_space_copy(space));
   9942  1.1  mrg 		mpa = isl_multi_pw_aff_set_pw_aff(mpa, i, pa);
   9943  1.1  mrg 		isl_union_pw_aff_free(upa);
   9944  1.1  mrg 	}
   9945  1.1  mrg 
   9946  1.1  mrg 	isl_space_free(space);
   9947  1.1  mrg 	return mpa;
   9948  1.1  mrg error:
   9949  1.1  mrg 	isl_space_free(space);
   9950  1.1  mrg 	return NULL;
   9951  1.1  mrg }
   9952  1.1  mrg 
   9953  1.1  mrg /* Data structure that specifies how isl_union_pw_multi_aff_un_op
   9954  1.1  mrg  * should modify the base expressions in the input.
   9955  1.1  mrg  *
   9956  1.1  mrg  * If "filter" is not NULL, then only the base expressions that satisfy "filter"
   9957  1.1  mrg  * are taken into account.
   9958  1.1  mrg  * "fn" is applied to each entry in the input.
   9959  1.1  mrg  */
   9960  1.1  mrg struct isl_union_pw_multi_aff_un_op_control {
   9961  1.1  mrg 	isl_bool (*filter)(__isl_keep isl_pw_multi_aff *part);
   9962  1.1  mrg 	__isl_give isl_pw_multi_aff *(*fn)(__isl_take isl_pw_multi_aff *pma);
   9963  1.1  mrg };
   9964  1.1  mrg 
   9965  1.1  mrg /* Wrapper for isl_union_pw_multi_aff_un_op filter functions (which do not take
   9966  1.1  mrg  * a second argument) for use as an isl_union_pw_multi_aff_transform
   9967  1.1  mrg  * filter function (which does take a second argument).
   9968  1.1  mrg  * Simply call control->filter without the second argument.
   9969  1.1  mrg  */
   9970  1.1  mrg static isl_bool isl_union_pw_multi_aff_un_op_filter_drop_user(
   9971  1.1  mrg 	__isl_take isl_pw_multi_aff *pma, void *user)
   9972  1.1  mrg {
   9973  1.1  mrg 	struct isl_union_pw_multi_aff_un_op_control *control = user;
   9974  1.1  mrg 
   9975  1.1  mrg 	return control->filter(pma);
   9976  1.1  mrg }
   9977  1.1  mrg 
   9978  1.1  mrg /* Wrapper for isl_union_pw_multi_aff_un_op base functions (which do not take
   9979  1.1  mrg  * a second argument) for use as an isl_union_pw_multi_aff_transform
   9980  1.1  mrg  * base function (which does take a second argument).
   9981  1.1  mrg  * Simply call control->fn without the second argument.
   9982  1.1  mrg  */
   9983  1.1  mrg static __isl_give isl_pw_multi_aff *isl_union_pw_multi_aff_un_op_drop_user(
   9984  1.1  mrg 	__isl_take isl_pw_multi_aff *pma, void *user)
   9985  1.1  mrg {
   9986  1.1  mrg 	struct isl_union_pw_multi_aff_un_op_control *control = user;
   9987  1.1  mrg 
   9988  1.1  mrg 	return control->fn(pma);
   9989  1.1  mrg }
   9990  1.1  mrg 
   9991  1.1  mrg /* Construct an isl_union_pw_multi_aff that is obtained by
   9992  1.1  mrg  * modifying "upma" according to "control".
   9993  1.1  mrg  *
   9994  1.1  mrg  * isl_union_pw_multi_aff_transform performs essentially
   9995  1.1  mrg  * the same operation, but takes a filter and a callback function
   9996  1.1  mrg  * of a different form (with an extra argument).
   9997  1.1  mrg  * Call isl_union_pw_multi_aff_transform with wrappers
   9998  1.1  mrg  * that remove this extra argument.
   9999  1.1  mrg  */
   10000  1.1  mrg static __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_un_op(
   10001  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma,
   10002  1.1  mrg 	struct isl_union_pw_multi_aff_un_op_control *control)
   10003  1.1  mrg {
   10004  1.1  mrg 	struct isl_union_pw_multi_aff_transform_control t_control = {
   10005  1.1  mrg 		.filter = &isl_union_pw_multi_aff_un_op_filter_drop_user,
   10006  1.1  mrg 		.filter_user = control,
   10007  1.1  mrg 		.fn = &isl_union_pw_multi_aff_un_op_drop_user,
   10008  1.1  mrg 		.fn_user = control,
   10009  1.1  mrg 	};
   10010  1.1  mrg 
   10011  1.1  mrg 	return isl_union_pw_multi_aff_transform(upma, &t_control);
   10012  1.1  mrg }
   10013  1.1  mrg 
   10014  1.1  mrg /* For each function in "upma" of the form A -> [B -> C],
   10015  1.1  mrg  * extract the function A -> B and collect the results.
   10016  1.1  mrg  */
   10017  1.1  mrg __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_factor_domain(
   10018  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma)
   10019  1.1  mrg {
   10020  1.1  mrg 	struct isl_union_pw_multi_aff_un_op_control control = {
   10021  1.1  mrg 		.filter = &isl_pw_multi_aff_range_is_wrapping,
   10022  1.1  mrg 		.fn = &isl_pw_multi_aff_range_factor_domain,
   10023  1.1  mrg 	};
   10024  1.1  mrg 	return isl_union_pw_multi_aff_un_op(upma, &control);
   10025  1.1  mrg }
   10026  1.1  mrg 
   10027  1.1  mrg /* For each function in "upma" of the form A -> [B -> C],
   10028  1.1  mrg  * extract the function A -> C and collect the results.
   10029  1.1  mrg  */
   10030  1.1  mrg __isl_give isl_union_pw_multi_aff *isl_union_pw_multi_aff_range_factor_range(
   10031  1.1  mrg 	__isl_take isl_union_pw_multi_aff *upma)
   10032  1.1  mrg {
   10033  1.1  mrg 	struct isl_union_pw_multi_aff_un_op_control control = {
   10034  1.1  mrg 		.filter = &isl_pw_multi_aff_range_is_wrapping,
   10035  1.1  mrg 		.fn = &isl_pw_multi_aff_range_factor_range,
   10036  1.1  mrg 	};
   10037  1.1  mrg 	return isl_union_pw_multi_aff_un_op(upma, &control);
   10038  1.1  mrg }
   10039  1.1  mrg 
   10040  1.1  mrg /* Evaluate the affine function "aff" in the void point "pnt".
   10041  1.1  mrg  * In particular, return the value NaN.
   10042  1.1  mrg  */
   10043  1.1  mrg static __isl_give isl_val *eval_void(__isl_take isl_aff *aff,
   10044  1.1  mrg 	__isl_take isl_point *pnt)
   10045  1.1  mrg {
   10046  1.1  mrg 	isl_ctx *ctx;
   10047  1.1  mrg 
   10048  1.1  mrg 	ctx = isl_point_get_ctx(pnt);
   10049  1.1  mrg 	isl_aff_free(aff);
   10050  1.1  mrg 	isl_point_free(pnt);
   10051  1.1  mrg 	return isl_val_nan(ctx);
   10052  1.1  mrg }
   10053  1.1  mrg 
   10054  1.1  mrg /* Evaluate the affine expression "aff"
   10055  1.1  mrg  * in the coordinates (with denominator) "pnt".
   10056  1.1  mrg  */
   10057  1.1  mrg static __isl_give isl_val *eval(__isl_keep isl_vec *aff,
   10058  1.1  mrg 	__isl_keep isl_vec *pnt)
   10059  1.1  mrg {
   10060  1.1  mrg 	isl_int n, d;
   10061  1.1  mrg 	isl_ctx *ctx;
   10062  1.1  mrg 	isl_val *v;
   10063  1.1  mrg 
   10064  1.1  mrg 	if (!aff || !pnt)
   10065  1.1  mrg 		return NULL;
   10066  1.1  mrg 
   10067  1.1  mrg 	ctx = isl_vec_get_ctx(aff);
   10068  1.1  mrg 	isl_int_init(n);
   10069  1.1  mrg 	isl_int_init(d);
   10070  1.1  mrg 	isl_seq_inner_product(aff->el + 1, pnt->el, pnt->size, &n);
   10071  1.1  mrg 	isl_int_mul(d, aff->el[0], pnt->el[0]);
   10072  1.1  mrg 	v = isl_val_rat_from_isl_int(ctx, n, d);
   10073  1.1  mrg 	v = isl_val_normalize(v);
   10074  1.1  mrg 	isl_int_clear(n);
   10075  1.1  mrg 	isl_int_clear(d);
   10076  1.1  mrg 
   10077  1.1  mrg 	return v;
   10078  1.1  mrg }
   10079  1.1  mrg 
   10080  1.1  mrg /* Check that the domain space of "aff" is equal to "space".
   10081  1.1  mrg  */
   10082  1.1  mrg static isl_stat isl_aff_check_has_domain_space(__isl_keep isl_aff *aff,
   10083  1.1  mrg 	__isl_keep isl_space *space)
   10084  1.1  mrg {
   10085  1.1  mrg 	isl_bool ok;
   10086  1.1  mrg 
   10087  1.1  mrg 	ok = isl_space_is_equal(isl_aff_peek_domain_space(aff), space);
   10088  1.1  mrg 	if (ok < 0)
   10089  1.1  mrg 		return isl_stat_error;
   10090  1.1  mrg 	if (!ok)
   10091  1.1  mrg 		isl_die(isl_aff_get_ctx(aff), isl_error_invalid,
   10092  1.1  mrg 			"incompatible spaces", return isl_stat_error);
   10093  1.1  mrg 	return isl_stat_ok;
   10094  1.1  mrg }
   10095  1.1  mrg 
   10096  1.1  mrg /* Evaluate the affine function "aff" in "pnt".
   10097  1.1  mrg  */
   10098  1.1  mrg __isl_give isl_val *isl_aff_eval(__isl_take isl_aff *aff,
   10099  1.1  mrg 	__isl_take isl_point *pnt)
   10100  1.1  mrg {
   10101  1.1  mrg 	isl_bool is_void;
   10102  1.1  mrg 	isl_val *v;
   10103  1.1  mrg 	isl_local_space *ls;
   10104  1.1  mrg 
   10105  1.1  mrg 	if (isl_aff_check_has_domain_space(aff, isl_point_peek_space(pnt)) < 0)
   10106  1.1  mrg 		goto error;
   10107  1.1  mrg 	is_void = isl_point_is_void(pnt);
   10108  1.1  mrg 	if (is_void < 0)
   10109  1.1  mrg 		goto error;
   10110  1.1  mrg 	if (is_void)
   10111  1.1  mrg 		return eval_void(aff, pnt);
   10112  1.1  mrg 
   10113  1.1  mrg 	ls = isl_aff_get_domain_local_space(aff);
   10114  1.1  mrg 	pnt = isl_local_space_lift_point(ls, pnt);
   10115  1.1  mrg 
   10116  1.1  mrg 	v = eval(aff->v, isl_point_peek_vec(pnt));
   10117  1.1  mrg 
   10118  1.1  mrg 	isl_aff_free(aff);
   10119  1.1  mrg 	isl_point_free(pnt);
   10120  1.1  mrg 
   10121  1.1  mrg 	return v;
   10122  1.1  mrg error:
   10123  1.1  mrg 	isl_aff_free(aff);
   10124  1.1  mrg 	isl_point_free(pnt);
   10125  1.1  mrg 	return NULL;
   10126  1.1  mrg }
   10127