From a9c418fd320aa44305c26e4a8b2e4c8caca74b79 Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 16 Oct 2012 08:33:37 +0200 Subject: [PATCH] print declarations for variables declared inside the scop For GPU code generation, we only declare those variables that are still visible after the scop. Those that are only visible inside the scop are only used on the GPU. For CPU code generation, we need to declare both type of variables, but make sure that the variables that are not visible after the scop remain that way. Signed-off-by: Sven Verdoolaege --- cpu.c | 27 ++++++++++++++++++++ cuda.c | 1 + print.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ print.h | 5 ++++ 4 files changed, 123 insertions(+) diff --git a/cpu.c b/cpu.c index cd58a79..c498eeb 100644 --- a/cpu.c +++ b/cpu.c @@ -20,6 +20,7 @@ #include "ppcg.h" #include "cpu.h" #include "pet_printer.h" +#include "print.h" #include "rewrite.h" /* Representation of a statement inside a generated AST. @@ -356,12 +357,30 @@ static __isl_give isl_printer *print_scop(isl_ctx *ctx, struct ppcg_scop *scop, return p; } +/* Does "scop" refer to any arrays that are declared, but not + * exposed to the code after the scop? + */ +static int any_hidden_declarations(struct ppcg_scop *scop) +{ + int i; + + if (!scop) + return 0; + + for (i = 0; i < scop->n_array; ++i) + if (scop->arrays[i]->declared && !scop->arrays[i]->exposed) + return 1; + + return 0; +} + int generate_cpu(isl_ctx *ctx, struct ppcg_scop *ps, struct ppcg_options *options, const char *input) { FILE *input_file; FILE *output_file; isl_printer *p; + int hidden; if (!ps) return -1; @@ -373,7 +392,15 @@ int generate_cpu(isl_ctx *ctx, struct ppcg_scop *ps, fprintf(output_file, "/* ppcg generated CPU code */\n\n"); p = isl_printer_to_file(ctx, output_file); p = isl_printer_set_output_format(p, ISL_FORMAT_C); + p = ppcg_print_exposed_declarations(p, ps); + hidden = any_hidden_declarations(ps); + if (hidden) { + p = ppcg_start_block(p); + p = ppcg_print_hidden_declarations(p, ps); + } p = print_scop(ctx, ps, p); + if (hidden) + p = ppcg_end_block(p); isl_printer_free(p); copy_after_scop(input_file, output_file); diff --git a/cuda.c b/cuda.c index 4cfacee..6b8709f 100644 --- a/cuda.c +++ b/cuda.c @@ -836,6 +836,7 @@ int generate_cuda(isl_ctx *ctx, struct ppcg_scop *scop, p = isl_printer_to_file(ctx, cuda.host_c); p = isl_printer_set_output_format(p, ISL_FORMAT_C); + p = ppcg_print_exposed_declarations(p, scop); p = ppcg_start_block(p); p = print_cuda_macros(p); diff --git a/print.c b/print.c index 70090bc..3025b36 100644 --- a/print.c +++ b/print.c @@ -28,3 +28,93 @@ __isl_give isl_printer *ppcg_end_block(__isl_take isl_printer *p) p = isl_printer_end_line(p); return p; } + +/* Print "extent" as a sequence of + * + * [1 + maximal_value] + * + * one for each dimension. + */ +static __isl_give isl_printer *print_extent(__isl_take isl_printer *p, + __isl_keep isl_set *extent) +{ + int i, n; + + n = isl_set_dim(extent, isl_dim_set); + if (n == 0) + return p; + + for (i = 0; i < n; ++i) { + isl_set *dom; + isl_local_space *ls; + isl_aff *one; + isl_pw_aff *bound; + + bound = isl_set_dim_max(isl_set_copy(extent), i); + dom = isl_pw_aff_domain(isl_pw_aff_copy(bound)); + ls = isl_local_space_from_space(isl_set_get_space(dom)); + one = isl_aff_zero_on_domain(ls); + one = isl_aff_add_constant_si(one, 1); + bound = isl_pw_aff_add(bound, isl_pw_aff_alloc(dom, one)); + + p = isl_printer_print_str(p, "["); + p = isl_printer_print_pw_aff(p, bound); + p = isl_printer_print_str(p, "]"); + + isl_pw_aff_free(bound); + } + + return p; +} + +/* Print declarations for the arrays in "scop" that are declared + * and that are exposed (if exposed == 1) or not exposed (if exposed == 0). + */ +static __isl_give isl_printer *print_declarations(__isl_take isl_printer *p, + struct ppcg_scop *scop, int exposed) +{ + int i; + + if (!scop) + return isl_printer_free(p); + + for (i = 0; i < scop->n_array; ++i) { + struct pet_array *array = scop->arrays[i]; + const char *name; + + if (!array->declared) + continue; + if (array->exposed != exposed) + continue; + + name = isl_set_get_tuple_name(array->extent); + + p = isl_printer_start_line(p); + p = isl_printer_print_str(p, array->element_type); + p = isl_printer_print_str(p, " "); + p = isl_printer_print_str(p, name); + p = print_extent(p, array->extent); + p = isl_printer_print_str(p, ";"); + p = isl_printer_end_line(p); + } + + return p; +} + +/* Print declarations for the arrays in "scop" that are declared + * and exposed to the code after the scop. + */ +__isl_give isl_printer *ppcg_print_exposed_declarations( + __isl_take isl_printer *p, struct ppcg_scop *scop) +{ + return print_declarations(p, scop, 1); +} + +/* Print declarations for the arrays in "scop" that are declared, + * but not exposed to the code after the scop. + */ +__isl_give isl_printer *ppcg_print_hidden_declarations( + __isl_take isl_printer *p, struct ppcg_scop *scop) +{ + return print_declarations(p, scop, 0); +} diff --git a/print.h b/print.h index fe6518e..5803799 100644 --- a/print.h +++ b/print.h @@ -6,4 +6,9 @@ __isl_give isl_printer *ppcg_start_block(__isl_take isl_printer *p); __isl_give isl_printer *ppcg_end_block(__isl_take isl_printer *p); +__isl_give isl_printer *ppcg_print_exposed_declarations( + __isl_take isl_printer *p, struct ppcg_scop *scop); +__isl_give isl_printer *ppcg_print_hidden_declarations( + __isl_take isl_printer *p, struct ppcg_scop *scop); + #endif -- 2.11.4.GIT