From 220f51603c7fef603c7c03969e1418b66b6f85ad Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Sat, 8 Mar 2014 14:15:29 +0100 Subject: [PATCH] add pet_scop_intersect_domain_prefix We will need this function in the next commit. Signed-off-by: Sven Verdoolaege --- scop.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ scop.h | 2 + 2 files changed, 141 insertions(+) diff --git a/scop.c b/scop.c index cc9d8a1..9042310 100644 --- a/scop.c +++ b/scop.c @@ -36,6 +36,7 @@ #include #include +#include "aff.h" #include "expr.h" #include "filter.h" #include "loc.h" @@ -1049,6 +1050,144 @@ static int extent_is_virtual_array(__isl_keep isl_set *extent) return is_virtual; } +/* Intersect the initial dimensions of "array" with "domain", provided + * that "array" represents a virtual array. + * + * If "array" is virtual, then We take the preimage of "domain" + * over the projection of the extent of "array" onto its initial dimensions + * and intersect this extent with the result. + */ +static struct pet_array *virtual_array_intersect_domain_prefix( + struct pet_array *array, __isl_take isl_set *domain) +{ + int n; + isl_space *space; + isl_multi_aff *ma; + + if (!array || !extent_is_virtual_array(array->extent)) { + isl_set_free(domain); + return array; + } + + space = isl_set_get_space(array->extent); + n = isl_set_dim(domain, isl_dim_set); + ma = pet_prefix_projection(space, n); + domain = isl_set_preimage_multi_aff(domain, ma); + + array->extent = isl_set_intersect(array->extent, domain); + if (!array->extent) + return pet_array_free(array); + + return array; +} + +/* Intersect the initial dimensions of the domain of "stmt" + * with "domain". + * + * We take the preimage of "domain" over the projection of the + * domain of "stmt" onto its initial dimensions and intersect + * the domain of "stmt" with the result. + */ +static struct pet_stmt *stmt_intersect_domain_prefix(struct pet_stmt *stmt, + __isl_take isl_set *domain) +{ + int n; + isl_space *space; + isl_multi_aff *ma; + + if (!stmt) + goto error; + + space = isl_set_get_space(stmt->domain); + n = isl_set_dim(domain, isl_dim_set); + ma = pet_prefix_projection(space, n); + domain = isl_set_preimage_multi_aff(domain, ma); + + stmt->domain = isl_set_intersect(stmt->domain, domain); + if (!stmt->domain) + return pet_stmt_free(stmt); + + return stmt; +error: + isl_set_free(domain); + return pet_stmt_free(stmt); +} + +/* Intersect the initial dimensions of the domain of "implication" + * with "domain". + * + * We take the preimage of "domain" over the projection of the + * domain of "implication" onto its initial dimensions and intersect + * the domain of "implication" with the result. + */ +static struct pet_implication *implication_intersect_domain_prefix( + struct pet_implication *implication, __isl_take isl_set *domain) +{ + int n; + isl_space *space; + isl_multi_aff *ma; + + if (!implication) + goto error; + + space = isl_map_get_space(implication->extension); + n = isl_set_dim(domain, isl_dim_set); + ma = pet_prefix_projection(isl_space_domain(space), n); + domain = isl_set_preimage_multi_aff(domain, ma); + + implication->extension = + isl_map_intersect_domain(implication->extension, domain); + if (!implication->extension) + return pet_implication_free(implication); + + return implication; +error: + isl_set_free(domain); + return pet_implication_free(implication); +} + +/* Intersect the initial dimensions of the domains in "scop" with "domain". + * + * The extents of the virtual arrays match the iteration domains, + * so if the iteration domain changes, we need to change those extents too. + */ +struct pet_scop *pet_scop_intersect_domain_prefix(struct pet_scop *scop, + __isl_take isl_set *domain) +{ + int i; + + if (!scop) + goto error; + + for (i = 0; i < scop->n_array; ++i) { + scop->arrays[i] = virtual_array_intersect_domain_prefix( + scop->arrays[i], isl_set_copy(domain)); + if (!scop->arrays[i]) + goto error; + } + + for (i = 0; i < scop->n_stmt; ++i) { + scop->stmts[i] = stmt_intersect_domain_prefix(scop->stmts[i], + isl_set_copy(domain)); + if (!scop->stmts[i]) + goto error; + } + + for (i = 0; i < scop->n_implication; ++i) { + scop->implications[i] = + implication_intersect_domain_prefix(scop->implications[i], + isl_set_copy(domain)); + if (!scop->implications[i]) + return pet_scop_free(scop); + } + + isl_set_free(domain); + return scop; +error: + isl_set_free(domain); + return pet_scop_free(scop); +} + /* Prefix the schedule of "stmt" with an extra dimension with constant * value "pos". */ diff --git a/scop.h b/scop.h index c0eeb5a..a92b11d 100644 --- a/scop.h +++ b/scop.h @@ -43,6 +43,8 @@ struct pet_scop *pet_scop_add_par(isl_ctx *ctx, struct pet_scop *scop1, int pet_scop_is_equal(struct pet_scop *scop1, struct pet_scop *scop2); +struct pet_scop *pet_scop_intersect_domain_prefix(struct pet_scop *scop, + __isl_take isl_set *domain); struct pet_scop *pet_scop_prefix(struct pet_scop *scop, int pos); struct pet_scop *pet_scop_embed(struct pet_scop *scop, __isl_take isl_set *dom, __isl_take isl_aff *sched, __isl_take isl_aff *iv_map, -- 2.11.4.GIT