From 8a9ec5513f29cf8bab6342b9419726d3c010000e Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Sat, 6 Dec 2014 10:32:36 +0100 Subject: [PATCH] gpu.c: extract_access: handle references that do not access anything If a reference does not access anything, then the access relation is empty and we cannot extract a map representation from the union map representation. We therefore reconstruct a map representation from the index expression instead. Signed-off-by: Sven Verdoolaege --- gpu.c | 55 ++++++++++++++++++++++++++++++++-- schedule.h | 2 ++ tests/not_accessed.c | 29 ++++++++++++++++++ tests/not_accessed_opencl_functions.cl | 5 ++++ 4 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 tests/not_accessed.c create mode 100644 tests/not_accessed_opencl_functions.cl diff --git a/gpu.c b/gpu.c index efd988f..3fb8a10 100644 --- a/gpu.c +++ b/gpu.c @@ -5703,6 +5703,55 @@ struct ppcg_extract_access_data { isl_union_map *any_to_outer; }; +/* Given a tagged access relation to a single array "tagged", extract it + * as a map, taking into account that the input may be empty. + * If the access relation is empty, then it does not contain + * any space information, so we try to recover it from the index + * expression. + * The space of the index expression is of the form I -> A, + * with I the statement instances and A the array, or [I -> F] -> A, + * with F the filters corresponding to arguments. + * We first drop F, if present, obtaining I -> A. + * Then we construct I -> R, with R the reference tag, + * combine the two into I -> [R -> A] and uncurry to obtain + * the final result [I -> R] -> A. + * Note that the index expression may have a lower dimension + * than that of the array, but this dimension is not used + * if the access relation is empty. + */ +static __isl_give isl_map *extract_single_tagged_access( + __isl_take isl_union_map *tagged, __isl_keep pet_expr *expr) +{ + int empty; + isl_id *id; + isl_space *space, *space2; + isl_multi_pw_aff *index; + + empty = isl_union_map_is_empty(tagged); + if (empty < 0) + goto error; + if (!empty) + return isl_map_from_union_map(tagged); + isl_union_map_free(tagged); + + index = pet_expr_access_get_index(expr); + space = isl_multi_pw_aff_get_space(index); + isl_multi_pw_aff_free(index); + if (isl_space_domain_is_wrapping(space)) + space = isl_space_domain_factor_domain(space); + space2 = isl_space_copy(space); + space2 = isl_space_from_domain(isl_space_domain(space)); + id = pet_expr_access_get_ref_id(expr); + space2 = isl_space_set_tuple_id(space2, isl_dim_out, id); + space = isl_space_range_product(space2, space); + space = isl_space_uncurry(space); + + return isl_map_empty(space); +error: + isl_union_map_free(tagged); + return NULL; +} + /* Extract a gpu_stmt_access from "expr", append it to the list * that ends in *data->next_access and update the end of the list. * If the access expression performs a write, then it is considered @@ -5745,14 +5794,14 @@ static int extract_access(__isl_keep pet_expr *expr, void *user) isl_union_map_free(must); isl_union_map_free(may); } - access->tagged_access = isl_map_from_union_map(tagged); - access->access = isl_map_copy(access->tagged_access); - access->access = isl_map_domain_factor_domain(access->access); index = pet_expr_access_get_index(expr); access->n_index = isl_multi_pw_aff_dim(index, isl_dim_out); isl_multi_pw_aff_free(index); access->ref_id = pet_expr_access_get_ref_id(expr); access->group = -1; + access->tagged_access = extract_single_tagged_access(tagged, expr); + access->access = isl_map_copy(access->tagged_access); + access->access = isl_map_domain_factor_domain(access->access); *data->next_access = access; data->next_access = &(*data->next_access)->next; diff --git a/schedule.h b/schedule.h index cb8c2b0..6f8ada3 100644 --- a/schedule.h +++ b/schedule.h @@ -4,6 +4,8 @@ /* An access to an outer array element or an iterator. * Accesses to iterators have an access relation that maps to an unnamed space. * An access may be both read and write. + * If the access relation is empty, then the output dimension may + * not be equal to the dimension of the corresponding array. */ struct gpu_stmt_access { /* Access reads elements */ diff --git a/tests/not_accessed.c b/tests/not_accessed.c new file mode 100644 index 0000000..e5fb892 --- /dev/null +++ b/tests/not_accessed.c @@ -0,0 +1,29 @@ +#include + +void copy_summary(int b[1000], int a[1000], int pos, int c[1000]) +{ + b[pos] = 0; + int d = a[pos]; +} + +#ifdef pencil_access +__attribute__((pencil_access(copy_summary))) +#endif +void copy(int b[1000], int a[1000], int pos, int c[1000]); + +int main() +{ + int a[1000], b[1000], c[1000]; + + for (int i = 0; i < 1000; ++i) + a[i] = i; +#pragma scop + for (int i = 0; i < 1000; ++i) + copy(b, a, i, c); +#pragma endscop + for (int i = 0; i < 1000; ++i) + if (b[i] != a[i]) + return EXIT_FAILURE; + + return EXIT_SUCCESS; +} diff --git a/tests/not_accessed_opencl_functions.cl b/tests/not_accessed_opencl_functions.cl new file mode 100644 index 0000000..e1588e0 --- /dev/null +++ b/tests/not_accessed_opencl_functions.cl @@ -0,0 +1,5 @@ +void copy(__global int b[1000], __global int a[1000], int pos, + __global int c[1000]) +{ + b[pos] = a[pos]; +} -- 2.11.4.GIT