From 8c0888fbe138d5f30842361a3b7af369ebfc3a0b Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Thu, 24 Oct 2019 15:46:38 +0200 Subject: [PATCH] add exported isl_aff_domain_reverse This complements the already exported isl_space_domain_reverse. Signed-off-by: Sven Verdoolaege --- doc/user.pod | 4 ++++ include/isl/aff.h | 2 ++ isl_aff.c | 38 ++++++++++++++++++++++++++++++++++++++ isl_test2.cc | 9 +++++++++ 4 files changed, 53 insertions(+) diff --git a/doc/user.pod b/doc/user.pod index 274a01a3..8684fd3e 100644 --- a/doc/user.pod +++ b/doc/user.pod @@ -5425,6 +5425,10 @@ earlier dimensions before those that involve later dimensions. __isl_give isl_space *isl_space_range_reverse( __isl_take isl_space *space); + #include + __isl_give isl_aff *isl_aff_domain_reverse( + __isl_take isl_aff *aff); + #include __isl_give isl_basic_map *isl_basic_map_reverse( __isl_take isl_basic_map *bmap); diff --git a/include/isl/aff.h b/include/isl/aff.h index f7044b2d..e6a166ea 100644 --- a/include/isl/aff.h +++ b/include/isl/aff.h @@ -134,6 +134,8 @@ __isl_overload __isl_give isl_aff *isl_aff_scale_down_val(__isl_take isl_aff *aff, __isl_take isl_val *v); +__isl_export +__isl_give isl_aff *isl_aff_domain_reverse(__isl_take isl_aff *aff); __isl_give isl_aff *isl_aff_insert_dims(__isl_take isl_aff *aff, enum isl_dim_type type, unsigned first, unsigned n); __isl_give isl_aff *isl_aff_add_dims(__isl_take isl_aff *aff, diff --git a/isl_aff.c b/isl_aff.c index 0c17cf39..937abb66 100644 --- a/isl_aff.c +++ b/isl_aff.c @@ -2819,6 +2819,44 @@ __isl_give isl_aff *isl_aff_move_dims(__isl_take isl_aff *aff, return aff; } +/* Given an affine function on a domain (A -> B), + * interchange A and B in the wrapped domain + * to obtain a function on the domain (B -> A). + * + * Since this may change the position of some variables, + * it may also change the normalized order of the local variables. + * Restore this order. Since sort_divs assumes the input + * has a single reference, an explicit isl_aff_cow is required. + */ +__isl_give isl_aff *isl_aff_domain_reverse(__isl_take isl_aff *aff) +{ + isl_space *space; + isl_local_space *ls; + isl_vec *v; + isl_size n_in, n_out; + unsigned offset; + + space = isl_aff_peek_domain_space(aff); + offset = isl_space_offset(space, isl_dim_set); + n_in = isl_space_wrapped_dim(space, isl_dim_set, isl_dim_in); + n_out = isl_space_wrapped_dim(space, isl_dim_set, isl_dim_out); + if (n_in < 0 || n_out < 0) + return isl_aff_free(aff); + + v = isl_aff_take_rat_aff(aff); + v = isl_vec_move_els(v, 1 + 1 + offset, 1 + 1 + offset + n_in, n_out); + aff = isl_aff_restore_rat_aff(aff, v); + + ls = isl_aff_take_domain_local_space(aff); + ls = isl_local_space_wrapped_reverse(ls); + aff = isl_aff_restore_domain_local_space(aff, ls); + + aff = isl_aff_cow(aff); + aff = sort_divs(aff); + + return aff; +} + /* Return a zero isl_aff in the given space. * * This is a helper function for isl_pw_*_as_* that ensures a uniform diff --git a/isl_test2.cc b/isl_test2.cc index 5a4ad407..2ec134a9 100644 --- a/isl_test2.cc +++ b/isl_test2.cc @@ -458,6 +458,15 @@ static void test_project(isl::ctx ctx) */ static void test_reverse(isl::ctx ctx) { + C(&isl::aff::domain_reverse, { + { "{ T[A[] -> B[*]] -> [0] }", + "{ [B[*] -> A[]] -> [0] }" }, + { "{ T[A[] -> A[]] -> [0] }", + "{ T[A[] -> A[]] -> [0] }" }, + { "{ [A[x] -> B[y]] -> [5*(x // 2) + 7*(y // 3)] }", + "{ [B[y] -> A[x]] -> [5*(x // 2) + 7*(y // 3)] }" }, + }); + C(&isl::union_map::range_reverse, { { "{ A[] -> [B[] -> C[]]; A[] -> B[]; A[0] -> N[B[1] -> B[2]] }", "{ A[] -> [C[] -> B[]]; A[0] -> N[B[2] -> B[1]] }" }, -- 2.11.4.GIT