+#ifndef NO_REALIGN
+__isl_give PW *FN(PW,realign_domain)(__isl_take PW *pw,
+ __isl_take isl_reordering *exp)
+{
+ int i;
+
+ pw = FN(PW,cow)(pw);
+ if (!pw || !exp)
+ goto error;
+
+ for (i = 0; i < pw->n; ++i) {
+ pw->p[i].set = isl_set_realign(pw->p[i].set,
+ isl_reordering_copy(exp));
+ if (!pw->p[i].set)
+ goto error;
+ pw->p[i].FIELD = FN(EL,realign_domain)(pw->p[i].FIELD,
+ isl_reordering_copy(exp));
+ if (!pw->p[i].FIELD)
+ goto error;
+ }
+
+ pw = FN(PW,reset_domain_space)(pw, isl_space_copy(exp->dim));
+
+ isl_reordering_free(exp);
+ return pw;
+error:
+ isl_reordering_free(exp);
+ FN(PW,free)(pw);
+ return NULL;
+}
+
+/* Align the parameters of "pw" to those of "model".
+ */
+__isl_give PW *FN(PW,align_params)(__isl_take PW *pw, __isl_take isl_space *model)
+{
+ isl_ctx *ctx;
+
+ if (!pw || !model)
+ goto error;
+
+ ctx = isl_space_get_ctx(model);
+ if (!isl_space_has_named_params(model))
+ isl_die(ctx, isl_error_invalid,
+ "model has unnamed parameters", goto error);
+ if (!isl_space_has_named_params(pw->dim))
+ isl_die(ctx, isl_error_invalid,
+ "input has unnamed parameters", goto error);
+ if (!isl_space_match(pw->dim, isl_dim_param, model, isl_dim_param)) {
+ isl_reordering *exp;
+
+ model = isl_space_drop_dims(model, isl_dim_in,
+ 0, isl_space_dim(model, isl_dim_in));
+ model = isl_space_drop_dims(model, isl_dim_out,
+ 0, isl_space_dim(model, isl_dim_out));
+ exp = isl_parameter_alignment_reordering(pw->dim, model);
+ exp = isl_reordering_extend_space(exp,
+ FN(PW,get_domain_space)(pw));
+ pw = FN(PW,realign_domain)(pw, exp);
+ }
+
+ isl_space_free(model);
+ return pw;
+error:
+ isl_space_free(model);
+ FN(PW,free)(pw);
+ return NULL;
+}
+
+static __isl_give PW *FN(PW,align_params_pw_pw_and)(__isl_take PW *pw1,
+ __isl_take PW *pw2,
+ __isl_give PW *(*fn)(__isl_take PW *pw1, __isl_take PW *pw2))
+{
+ isl_ctx *ctx;
+
+ if (!pw1 || !pw2)
+ goto error;
+ if (isl_space_match(pw1->dim, isl_dim_param, pw2->dim, isl_dim_param))
+ return fn(pw1, pw2);
+ ctx = FN(PW,get_ctx)(pw1);
+ if (!isl_space_has_named_params(pw1->dim) ||
+ !isl_space_has_named_params(pw2->dim))
+ isl_die(ctx, isl_error_invalid,
+ "unaligned unnamed parameters", goto error);
+ pw1 = FN(PW,align_params)(pw1, FN(PW,get_space)(pw2));
+ pw2 = FN(PW,align_params)(pw2, FN(PW,get_space)(pw1));
+ return fn(pw1, pw2);
+error:
+ FN(PW,free)(pw1);
+ FN(PW,free)(pw2);
+ return NULL;
+}
+
+static __isl_give PW *FN(PW,align_params_pw_set_and)(__isl_take PW *pw,
+ __isl_take isl_set *set,
+ __isl_give PW *(*fn)(__isl_take PW *pw, __isl_take isl_set *set))
+{
+ isl_ctx *ctx;
+
+ if (!pw || !set)
+ goto error;
+ if (isl_space_match(pw->dim, isl_dim_param, set->dim, isl_dim_param))
+ return fn(pw, set);
+ ctx = FN(PW,get_ctx)(pw);
+ if (!isl_space_has_named_params(pw->dim) ||
+ !isl_space_has_named_params(set->dim))
+ isl_die(ctx, isl_error_invalid,
+ "unaligned unnamed parameters", goto error);
+ pw = FN(PW,align_params)(pw, isl_set_get_space(set));
+ set = isl_set_align_params(set, FN(PW,get_space)(pw));
+ return fn(pw, set);
+error:
+ FN(PW,free)(pw);
+ isl_set_free(set);
+ return NULL;
+}
+#endif
+
+static __isl_give PW *FN(PW,union_add_aligned)(__isl_take PW *pw1,
+ __isl_take PW *pw2)