From d835e13a07ea8f46ff15d15fa24a1940e9bb8a59 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Wed, 26 May 2010 22:30:49 +0200 Subject: [PATCH] isl_access_info_compute_flow: handle multi-valued sink access relations In particular, if any given sink iteration accesses more than one data element, then we compute dependences for each of these data elements. Before, we would only compute a dependence for the data elements that was accessed last before the sink. --- isl_flow.c | 29 ++++++++++++++++++++++++--- isl_test.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 3 deletions(-) diff --git a/isl_flow.c b/isl_flow.c index 2e51b92..40b2e57 100644 --- a/isl_flow.c +++ b/isl_flow.c @@ -447,9 +447,10 @@ static int intermediate_sources(__isl_keep isl_access_info *acc, } /* Given a "sink" access, a list of n "source" accesses, - * compute for each iteration of the sink access, + * compute for each iteration of the sink access + * and for each element accessed by that iteration, * the source access in the list that last accessed the - * same element accessed by the sink access before this sink access. + * element accessed by the sink access before this sink access. * Each access is given as a map from the loop iterators * to the array indices. * The result is a list of n relations between source and sink @@ -474,6 +475,12 @@ static int intermediate_sources(__isl_keep isl_access_info *acc, * of dep * add result to possible last accesses at level l of write w2 * and replace possible last accesses dep by the remainder + * + * + * To deal with multi-valued sink access relations, the sink iteration + * domain is first extended with dimensions that correspond to the data + * space. After the computation is finished, these extra dimensions are + * projected out again. */ __isl_give isl_flow *isl_access_info_compute_flow(__isl_take isl_access_info *acc) { @@ -483,15 +490,28 @@ __isl_give isl_flow *isl_access_info_compute_flow(__isl_take isl_access_info *ac int depth; struct isl_map **temp_rel; struct isl_flow *res; + isl_dim *dim; + isl_map *id; + unsigned n_sink; + unsigned n_data; acc = isl_access_info_sort_sources(acc); + n_sink = isl_map_dim(acc->sink.map, isl_dim_in); + n_data = isl_map_dim(acc->sink.map, isl_dim_out); + dim = isl_dim_range(isl_map_get_dim(acc->sink.map)); + id = isl_map_identity(dim); + id = isl_map_insert(id, isl_dim_in, 0, n_sink); + acc->sink.map = isl_map_insert(acc->sink.map, isl_dim_in, + n_sink, n_data); + acc->sink.map = isl_map_intersect(acc->sink.map, id); + res = isl_flow_alloc(acc); if (!res) goto error; ctx = acc->sink.map->ctx; - depth = 2 * isl_map_dim(acc->sink.map, isl_dim_in) + 1; + depth = 2 * n_sink + 1; todo = isl_map_domain(isl_map_copy(acc->sink.map)); if (isl_set_fast_is_empty(todo)) goto done; @@ -541,6 +561,9 @@ __isl_give isl_flow *isl_access_info_compute_flow(__isl_take isl_access_info *ac free(temp_rel); done: + for (j = 0; j < res->n_source; ++j) + res->dep[j].map = isl_map_project_out(res->dep[j].map, + isl_dim_out, n_sink, n_data); res->no_source = todo; isl_access_info_free(acc); return res; diff --git a/isl_test.c b/isl_test.c index 5e622ba..9eb4cc1 100644 --- a/isl_test.c +++ b/isl_test.c @@ -12,6 +12,7 @@ #include #include #include +#include #include static char *srcdir; @@ -1034,6 +1035,70 @@ void test_lexmin(struct isl_ctx *ctx) isl_map_free(map); } +struct dep { + isl_map *dep; +}; + +static int collect_dep(__isl_take isl_map *dep, void *dep_user, void *user) +{ + struct dep *d = (struct dep *)user; + + d->dep = isl_map_union(d->dep, dep); + + return 0; +} + +static int common_space(void *first, void *second) +{ + int depth = *(int *)first; + return 2 * depth; +} + +int map_is_equal(__isl_keep isl_map *map, const char *str) +{ + isl_map *map2; + int equal; + + map2 = isl_map_read_from_str(map->ctx, str, -1); + equal = isl_map_is_equal(map, map2); + isl_map_free(map2); + + return equal; +} + +void test_dep(struct isl_ctx *ctx) +{ + const char *str; + isl_dim *dim; + isl_map *map; + isl_access_info *ai; + isl_flow *flow; + int depth; + struct dep dep; + + depth = 5; + + str = "{ [1,i,0,0,0] -> [i,j] : 0 <= i <= 10 and 0 <= j <= 10 }"; + map = isl_map_read_from_str(ctx, str, -1); + ai = isl_access_info_alloc(map, &depth, &common_space, 1); + + str = "{ [0,i,0,j,0] -> [i,j] : 0 <= i <= 10 and 0 <= j <= 10 }"; + map = isl_map_read_from_str(ctx, str, -1); + ai = isl_access_info_add_source(ai, map, &depth); + + flow = isl_access_info_compute_flow(ai); + dim = isl_dim_alloc(ctx, 0, 5, 5); + dep.dep = isl_map_empty(dim); + + isl_flow_foreach(flow, collect_dep, &dep); + + str = "{ [0,i,0,j,0] -> [1,i,0,0,0] : 0 <= i,j <= 10 }"; + assert(map_is_equal(dep.dep, str)); + + isl_map_free(dep.dep); + isl_flow_free(flow); +} + int main() { struct isl_ctx *ctx; @@ -1042,6 +1107,7 @@ int main() assert(srcdir); ctx = isl_ctx_alloc(); + test_dep(ctx); test_read(ctx); test_construction(ctx); test_dim(ctx); -- 2.7.4