/* * Copyright 2010-2011 INRIA Saclay * * Use of this software is governed by the MIT license * * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France, * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod, * 91893 Orsay, France */ #include #include #include #include #include #include #include #include "schedule.h" /* Add parameters with identifiers "ids" to "set". */ static __isl_give isl_set *add_params(__isl_take isl_set *set, __isl_keep isl_id_list *ids) { int i, n; unsigned nparam; n = isl_id_list_n_id(ids); nparam = isl_set_dim(set, isl_dim_param); set = isl_set_add_dims(set, isl_dim_param, n); for (i = 0; i < n; ++i) { isl_id *id; id = isl_id_list_get_id(ids, i); set = isl_set_set_dim_id(set, isl_dim_param, nparam + i, id); } return set; } /* Equate the dimensions of "set" starting at "first" to * freshly created parameters with identifiers "ids". * The number of equated dimensions is equal to the number of elements in "ids". */ static __isl_give isl_set *parametrize(__isl_take isl_set *set, int first, __isl_keep isl_id_list *ids) { int i, n; unsigned nparam; nparam = isl_set_dim(set, isl_dim_param); set = add_params(set, ids); n = isl_id_list_n_id(ids); for (i = 0; i < n; ++i) set = isl_set_equate(set, isl_dim_param, nparam + i, isl_dim_set, first + i); return set; } /* Given a parameter space "space", create a set of dimension "len" * of which the dimensions starting at "first" are equated to * freshly created parameters with identifiers "ids". */ __isl_give isl_set *parametrization(__isl_take isl_space *space, int len, int first, __isl_keep isl_id_list *ids) { isl_set *set; space = isl_space_set_from_params(space); space = isl_space_add_dims(space, isl_dim_set, len); set = isl_set_universe(space); return parametrize(set, first, ids); } /* Load and return a schedule from a file called "filename". */ static __isl_give isl_schedule *load_schedule(isl_ctx *ctx, const char *filename) { FILE *file; isl_schedule *schedule; file = fopen(filename, "r"); if (!file) { fprintf(stderr, "Unable to open '%s' for reading\n", filename); return NULL; } schedule = isl_schedule_read_from_file(ctx, file); fclose(file); return schedule; } /* Save the schedule "schedule" to a file called "filename". * The schedule is printed in block style. */ static void save_schedule(__isl_keep isl_schedule *schedule, const char *filename) { FILE *file; isl_ctx *ctx; isl_printer *p; if (!schedule) return; file = fopen(filename, "w"); if (!file) { fprintf(stderr, "Unable to open '%s' for writing\n", filename); return; } ctx = isl_schedule_get_ctx(schedule); p = isl_printer_to_file(ctx, file); p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_BLOCK); p = isl_printer_print_schedule(p, schedule); isl_printer_free(p); fclose(file); } /* Obtain a schedule, either by reading it form a file * or by computing it using "compute". * Also take care of saving the computed schedule and/or * dumping the obtained schedule if requested by the user. */ __isl_give isl_schedule *ppcg_get_schedule(isl_ctx *ctx, struct ppcg_options *options, __isl_give isl_schedule *(*compute)(void *user), void *user) { isl_schedule *schedule; if (options->load_schedule_file) { schedule = load_schedule(ctx, options->load_schedule_file); } else { schedule = compute(user); if (options->save_schedule_file) save_schedule(schedule, options->save_schedule_file); } if (options->debug->dump_schedule) isl_schedule_dump(schedule); return schedule; } /* Mark all dimensions in the band node "node" to be of "type". */ __isl_give isl_schedule_node *ppcg_set_schedule_node_type( __isl_take isl_schedule_node *node, enum isl_ast_loop_type type) { int i, n; n = isl_schedule_node_band_n_member(node); for (i = 0; i < n; ++i) node = isl_schedule_node_band_member_set_ast_loop_type(node, i, type); return node; }