From 8c4af29e639b24582dbfb56f61d0f434c18aa87c Mon Sep 17 00:00:00 2001 From: Sven Verdoolaege Date: Tue, 16 Oct 2012 20:22:01 +0200 Subject: [PATCH] pass ppcg_scop to generate_* generate_cpu would already construct a ppcg_scop. Move the construction out of generate_cpu and pass the same ppcg_scop to generate_cuda. This allows us to perform some optimizations only once and have them take effect for both targets. Signed-off-by: Sven Verdoolaege --- Makefile.am | 1 + cpu.c | 57 ++------------------------------------------------------- cpu.h | 5 +++-- cuda.c | 2 +- cuda.h | 4 ++-- gpu.c | 14 ++++++-------- gpu.h | 6 +++--- ppcg.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- ppcg.h | 33 +++++++++++++++++++++++++++++++++ 9 files changed, 104 insertions(+), 73 deletions(-) create mode 100644 ppcg.h diff --git a/Makefile.am b/Makefile.am index de4cadb..f9cd74b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -43,6 +43,7 @@ ppcg_SOURCES = \ ppcg_options.c \ ppcg_options.h \ ppcg.c \ + ppcg.h \ version.c dist-hook: diff --git a/cpu.c b/cpu.c index d70f7a4..9f01530 100644 --- a/cpu.c +++ b/cpu.c @@ -17,6 +17,7 @@ #include #include +#include "ppcg.h" #include "cpu.h" #include "pet_printer.h" #include "rewrite.h" @@ -50,56 +51,6 @@ static void ppcg_stmt_free(void *user) free(stmt); } -struct ppcg_scop { - isl_set *context; - isl_union_set *domain; - isl_union_map *reads; - isl_union_map *writes; - isl_union_map *schedule; - - int n_stmt; - struct pet_stmt **stmts; -}; - -static struct ppcg_scop *ppcg_scop_from_pet_scop(struct pet_scop *scop) -{ - isl_ctx *ctx; - struct ppcg_scop *ps; - - if (!scop) - return NULL; - - ctx = isl_set_get_ctx(scop->context); - - ps = isl_calloc_type(ctx, struct ppcg_scop); - if (!ps) - return NULL; - - ps->context = isl_set_copy(scop->context); - ps->domain = pet_scop_collect_domains(scop); - ps->reads = pet_scop_collect_reads(scop); - ps->writes = pet_scop_collect_writes(scop); - ps->schedule = pet_scop_collect_schedule(scop); - ps->n_stmt = scop->n_stmt; - ps->stmts = scop->stmts; - - return ps; -} - -static void ppcg_scop_free(struct ppcg_scop *ps) -{ - if (!ps) - return; - - isl_set_free(ps->context); - isl_union_set_free(ps->domain); - isl_union_map_free(ps->reads); - isl_union_map_free(ps->writes); - isl_union_map_free(ps->schedule); - - free(ps); -} - /* Derive the output file name from the input file name. * 'input' is the entire path of the input file. The output * is the file name plus the additional extension. @@ -409,14 +360,12 @@ static void print_scop(isl_ctx *ctx, struct ppcg_scop *scop, FILE *output) fprintf(output, "\n"); } -int generate_cpu(isl_ctx *ctx, struct pet_scop *scop, +int generate_cpu(isl_ctx *ctx, struct ppcg_scop *ps, struct ppcg_options *options, const char *input) { FILE *input_file; FILE *output_file; - struct ppcg_scop *ps; - ps = ppcg_scop_from_pet_scop(scop); if (!ps) return -1; @@ -428,8 +377,6 @@ int generate_cpu(isl_ctx *ctx, struct pet_scop *scop, print_scop(ctx, ps, output_file); copy_after_scop(input_file, output_file); - ppcg_scop_free(ps); - fclose(output_file); fclose(input_file); diff --git a/cpu.h b/cpu.h index 0a45e13..0d7696a 100644 --- a/cpu.h +++ b/cpu.h @@ -3,10 +3,11 @@ #include -struct pet_scop; +#include "ppcg.h" + struct ppcg_options; -int generate_cpu(isl_ctx *ctx, struct pet_scop *scop, +int generate_cpu(isl_ctx *ctx, struct ppcg_scop *ps, struct ppcg_options *options, const char *input); #endif diff --git a/cuda.c b/cuda.c index 63d359d..c1239c9 100644 --- a/cuda.c +++ b/cuda.c @@ -779,7 +779,7 @@ static void free_device_arrays(FILE *out, struct gpu_prog *prog) } } -int generate_cuda(isl_ctx *ctx, struct pet_scop *scop, +int generate_cuda(isl_ctx *ctx, struct ppcg_scop *scop, struct ppcg_options *options, const char *input) { struct cuda_info cuda; diff --git a/cuda.h b/cuda.h index 344634b..4f6a541 100644 --- a/cuda.h +++ b/cuda.h @@ -1,10 +1,10 @@ #ifndef _CUDA_H #define _CUDA_H -#include #include "ppcg_options.h" +#include "ppcg.h" -int generate_cuda(isl_ctx *ctx, struct pet_scop *scop, +int generate_cuda(isl_ctx *ctx, struct ppcg_scop *scop, struct ppcg_options *options, const char *input); #endif diff --git a/gpu.c b/gpu.c index a08c29e..a2f892e 100644 --- a/gpu.c +++ b/gpu.c @@ -277,7 +277,7 @@ static void free_bound_list(struct gpu_array_bound *bound, int n_index) free(bound); } -static struct pet_array *find_array(struct pet_scop *scop, +static struct pet_array *find_array(struct ppcg_scop *scop, __isl_keep isl_set *accessed) { int i; @@ -4698,7 +4698,7 @@ static void pet_stmt_extract_accesses(struct gpu_stmt *stmt) /* Return an array of gpu_stmt representing the statements in "scop". */ -static struct gpu_stmt *extract_stmts(isl_ctx *ctx, struct pet_scop *scop, +static struct gpu_stmt *extract_stmts(isl_ctx *ctx, struct ppcg_scop *scop, __isl_keep isl_set *context) { int i; @@ -4777,7 +4777,7 @@ __isl_give isl_ast_node *generate_gpu(isl_ctx *ctx, struct gpu_prog *prog, gen.sizes = extract_sizes_from_str(ctx, options->sizes); gen.options = options; - sched = pet_scop_collect_schedule(prog->scop); + sched = isl_union_map_copy(prog->scop->schedule); compute_schedule(&gen, sched); @@ -4789,15 +4789,13 @@ __isl_give isl_ast_node *generate_gpu(isl_ctx *ctx, struct gpu_prog *prog, return tree; } -struct gpu_prog *gpu_prog_alloc(isl_ctx *ctx, struct pet_scop *scop) +struct gpu_prog *gpu_prog_alloc(isl_ctx *ctx, struct ppcg_scop *scop) { struct gpu_prog *prog; if (!scop) return NULL; - scop = pet_scop_align_params(scop); - prog = isl_calloc_type(ctx, struct gpu_prog); assert(prog); @@ -4806,8 +4804,8 @@ struct gpu_prog *gpu_prog_alloc(isl_ctx *ctx, struct pet_scop *scop) prog->context = isl_set_copy(scop->context); prog->n_stmts = scop->n_stmt; prog->stmts = extract_stmts(ctx, scop, prog->context); - prog->read = pet_scop_collect_reads(scop); - prog->write = pet_scop_collect_writes(scop); + prog->read = isl_union_map_copy(scop->reads); + prog->write = isl_union_map_copy(scop->writes); collect_array_info(prog); diff --git a/gpu.h b/gpu.h index 7e277be..0731026 100644 --- a/gpu.h +++ b/gpu.h @@ -1,7 +1,7 @@ #ifndef _GPU_H #define _GPU_H -#include +#include "ppcg.h" #include "ppcg_options.h" struct gpu_array_info { @@ -37,7 +37,7 @@ struct gpu_local_array_info { struct gpu_prog { isl_ctx *ctx; - struct pet_scop *scop; + struct ppcg_scop *scop; /* Set of parameter values */ isl_set *context; @@ -196,7 +196,7 @@ struct ppcg_kernel { int gpu_array_is_scalar(struct gpu_array_info *array); int gpu_array_is_read_only_scalar(struct gpu_array_info *array); -struct gpu_prog *gpu_prog_alloc(isl_ctx *ctx, struct pet_scop *scop); +struct gpu_prog *gpu_prog_alloc(isl_ctx *ctx, struct ppcg_scop *scop); void gpu_prog_free(struct gpu_prog *prog); __isl_give isl_set *add_context_from_str(__isl_take isl_set *set, diff --git a/ppcg.c b/ppcg.c index d4ab63b..e72c094 100644 --- a/ppcg.c +++ b/ppcg.c @@ -14,6 +14,7 @@ #include #include #include +#include "ppcg.h" #include "ppcg_options.h" #include "cuda.h" #include "cpu.h" @@ -41,12 +42,59 @@ ISL_ARGS_END ISL_ARG_DEF(options, struct options, options_args) +/* Extract a ppcg_scop from a pet_scop. + * + * The constructed ppcg_scop refers to elements from the pet_scop + * so the pet_scop should not be freed before the ppcg_scop. + */ +static struct ppcg_scop *ppcg_scop_from_pet_scop(struct pet_scop *scop) +{ + isl_ctx *ctx; + struct ppcg_scop *ps; + + if (!scop) + return NULL; + + ctx = isl_set_get_ctx(scop->context); + + ps = isl_calloc_type(ctx, struct ppcg_scop); + if (!ps) + return NULL; + + ps->context = isl_set_copy(scop->context); + ps->domain = pet_scop_collect_domains(scop); + ps->reads = pet_scop_collect_reads(scop); + ps->writes = pet_scop_collect_writes(scop); + ps->schedule = pet_scop_collect_schedule(scop); + ps->n_array = scop->n_array; + ps->arrays = scop->arrays; + ps->n_stmt = scop->n_stmt; + ps->stmts = scop->stmts; + + return ps; +} + +static void ppcg_scop_free(struct ppcg_scop *ps) +{ + if (!ps) + return; + + isl_set_free(ps->context); + isl_union_set_free(ps->domain); + isl_union_map_free(ps->reads); + isl_union_map_free(ps->writes); + isl_union_map_free(ps->schedule); + + free(ps); +} + int main(int argc, char **argv) { int r; isl_ctx *ctx; struct options *options; struct pet_scop *scop; + struct ppcg_scop *ps; options = options_new_with_defaults(); assert(options); @@ -56,12 +104,15 @@ int main(int argc, char **argv) argc = options_parse(options, argc, argv, ISL_ARG_ALL); scop = pet_scop_extract_from_C_source(ctx, options->input, NULL); + scop = pet_scop_align_params(scop); + ps = ppcg_scop_from_pet_scop(scop); if (options->ppcg->target == PPCG_TARGET_CUDA) - r = generate_cuda(ctx, scop, options->ppcg, options->input); + r = generate_cuda(ctx, ps, options->ppcg, options->input); else - r = generate_cpu(ctx, scop, options->ppcg, options->input); + r = generate_cpu(ctx, ps, options->ppcg, options->input); + ppcg_scop_free(ps); pet_scop_free(scop); isl_ctx_free(ctx); diff --git a/ppcg.h b/ppcg.h new file mode 100644 index 0000000..a3d14dc --- /dev/null +++ b/ppcg.h @@ -0,0 +1,33 @@ +#ifndef PPCG_H +#define PPCG_H + +#include +#include +#include +#include + +/* Representation of the scop for use inside PPCG. + * + * "context" represents constraints on the parameters. + * "domain" is the union of all iteration domains. + * "reads" contains all read accesses. + * "writes" contains all write accesses. + * "schedule" represents the (original) schedule. + * + * "arrays" and "stmts" are copies of the corresponding elements + * of the original pet_scop. + */ +struct ppcg_scop { + isl_set *context; + isl_union_set *domain; + isl_union_map *reads; + isl_union_map *writes; + isl_union_map *schedule; + + int n_array; + struct pet_array **arrays; + int n_stmt; + struct pet_stmt **stmts; +}; + +#endif -- 2.11.4.GIT