From 25ba75c54e4361b57e1e6e0df9274e59ec762a10 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 15 Oct 2013 12:44:42 +0200 Subject: [PATCH] gpu: also create (a single) array reference group for arrays of structs We currently do not map such arrays to shared or private memory, so there is no real need to compute array reference groups. However, the fact that there are no array reference groups is also used as an indication that the array is not accessed at all and we need to take into account that we cannot draw this conclusion for arrays of structs. Create a single combined array reference group for arrays of structs, assuming the array is accessed at all, so that we can remove the special case. Signed-off-by: Sven Verdoolaege --- gpu.c | 5 ++--- gpu.h | 3 --- gpu_group.c | 30 +++++++++++++++++++++++++----- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/gpu.c b/gpu.c index a4ad78c..3722f84 100644 --- a/gpu.c +++ b/gpu.c @@ -1246,8 +1246,7 @@ static __isl_give isl_pw_aff *set_universally_zero(__isl_take isl_pw_aff *pa) * * We only need these localized bounds for arrays that are accessed * by the current kernel. If we have found at least one reference group - * then the array is accessed by the kernel. If the array has compound - * elements then we skipped the construction of array reference groups. + * then the array is accessed by the kernel. * * The resulting sizes may be functions that are nowhere defined * in case the access function cannot possibly access anything inside @@ -1269,7 +1268,7 @@ static void localize_bounds(struct ppcg_kernel *kernel, isl_pw_aff_list *bound; int n_index; - if (local->n_group == 0 && !local->array->has_compound_element) + if (local->n_group == 0) continue; n_index = local->array->n_index; diff --git a/gpu.h b/gpu.h index a613513..3d34d9b 100644 --- a/gpu.h +++ b/gpu.h @@ -58,9 +58,6 @@ struct gpu_array_info { * * "array" points to the corresponding array in the gpu_prog. * The "n_group" "groups" are the reference groups associated to the array. - * If the outer array represented by the gpu_local_array_info - * contains structures, then the references are not - * collected and the reference groups are not computed. * If "force_private" is set, then the array (in practice a scalar) * must be mapped to a register. * For each index i with 0 <= i < n_index, diff --git a/gpu_group.c b/gpu_group.c index 93b9ba7..061ea60 100644 --- a/gpu_group.c +++ b/gpu_group.c @@ -1227,6 +1227,22 @@ static void set_array_groups(struct gpu_local_array_info *array, groups[i]->nr = i; } +/* Combine all groups in "groups" into a single group and return + * the new number of groups (1 or 0 if there were no groups to start with). + */ +static int join_all_groups(int n, struct gpu_array_ref_group **groups) +{ + int i; + + for (i = n - 1; i > 0; --i) { + groups[0] = join_groups_and_free(groups[0], groups[i]); + groups[i] = NULL; + n--; + } + + return n; +} + /* Group array references that should be considered together when * deciding whether to access them from private, shared or global memory. * Return -1 on error. @@ -1242,8 +1258,9 @@ static void set_array_groups(struct gpu_local_array_info *array, * combination of the two also admits a shared memory tile, we merge * the two groups. * - * If the array contains structures, then there is no need to compute - * reference groups since we do not map such arrays to private or shared + * If the array contains structures, then we compute a single + * reference group without trying to find any tiles + * since we do not map such arrays to private or shared * memory. */ static int group_array_references(struct ppcg_kernel *kernel, @@ -1254,9 +1271,6 @@ static int group_array_references(struct ppcg_kernel *kernel, isl_ctx *ctx = isl_union_map_get_ctx(data->shared_sched); struct gpu_array_ref_group **groups; - if (local->array->has_compound_element) - return 0; - groups = isl_calloc_array(ctx, struct gpu_array_ref_group *, local->array->n_ref); if (!groups) @@ -1264,6 +1278,12 @@ static int group_array_references(struct ppcg_kernel *kernel, n = populate_array_references(local, groups, data); + if (local->array->has_compound_element) { + n = join_all_groups(n, groups); + set_array_groups(local, n, groups); + return 0; + } + n = group_overlapping_writes(kernel, n, groups, data); for (i = 0; i < n; ++i) -- 2.11.4.GIT