gpu.c: extract_access: propagate error instead of asserting
[ppcg.git] / schedule.c
blob8d49e4ee889354ded47918c20d3688d2791bcf10
1 /*
2 * Copyright 2010-2011 INRIA Saclay
4 * Use of this software is governed by the MIT license
6 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
7 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
8 * 91893 Orsay, France
9 */
11 #include <assert.h>
12 #include <ctype.h>
13 #include <stdio.h>
14 #include <string.h>
16 #include <isl/set.h>
17 #include <isl/map.h>
18 #include <isl/constraint.h>
20 #include "grouping.h"
21 #include "schedule.h"
23 /* Add parameters with identifiers "ids" to "set".
25 static __isl_give isl_set *add_params(__isl_take isl_set *set,
26 __isl_keep isl_id_list *ids)
28 int i, n;
29 unsigned nparam;
31 n = isl_id_list_n_id(ids);
33 nparam = isl_set_dim(set, isl_dim_param);
34 set = isl_set_add_dims(set, isl_dim_param, n);
36 for (i = 0; i < n; ++i) {
37 isl_id *id;
39 id = isl_id_list_get_id(ids, i);
40 set = isl_set_set_dim_id(set, isl_dim_param, nparam + i, id);
43 return set;
46 /* Equate the dimensions of "set" starting at "first" to
47 * freshly created parameters with identifiers "ids".
48 * The number of equated dimensions is equal to the number of elements in "ids".
50 static __isl_give isl_set *parametrize(__isl_take isl_set *set,
51 int first, __isl_keep isl_id_list *ids)
53 int i, n;
54 unsigned nparam;
56 nparam = isl_set_dim(set, isl_dim_param);
58 set = add_params(set, ids);
60 n = isl_id_list_n_id(ids);
61 for (i = 0; i < n; ++i)
62 set = isl_set_equate(set, isl_dim_param, nparam + i,
63 isl_dim_set, first + i);
65 return set;
68 /* Given a parameter space "space", create a set of dimension "len"
69 * of which the dimensions starting at "first" are equated to
70 * freshly created parameters with identifiers "ids".
72 __isl_give isl_set *parametrization(__isl_take isl_space *space,
73 int len, int first, __isl_keep isl_id_list *ids)
75 isl_set *set;
77 space = isl_space_set_from_params(space);
78 space = isl_space_add_dims(space, isl_dim_set, len);
79 set = isl_set_universe(space);
81 return parametrize(set, first, ids);
84 /* Load and return a schedule from a file called "filename".
86 static __isl_give isl_schedule *load_schedule(isl_ctx *ctx,
87 const char *filename)
89 FILE *file;
90 isl_schedule *schedule;
92 file = fopen(filename, "r");
93 if (!file) {
94 fprintf(stderr, "Unable to open '%s' for reading\n", filename);
95 return NULL;
97 schedule = isl_schedule_read_from_file(ctx, file);
98 fclose(file);
100 return schedule;
103 /* Save the schedule "schedule" to a file called "filename".
104 * The schedule is printed in block style.
106 static void save_schedule(__isl_keep isl_schedule *schedule,
107 const char *filename)
109 FILE *file;
110 isl_ctx *ctx;
111 isl_printer *p;
113 if (!schedule)
114 return;
116 file = fopen(filename, "w");
117 if (!file) {
118 fprintf(stderr, "Unable to open '%s' for writing\n", filename);
119 return;
121 ctx = isl_schedule_get_ctx(schedule);
122 p = isl_printer_to_file(ctx, file);
123 p = isl_printer_set_yaml_style(p, ISL_YAML_STYLE_BLOCK);
124 p = isl_printer_print_schedule(p, schedule);
125 isl_printer_free(p);
126 fclose(file);
129 /* Compute a schedule on the domain of "sc" that respects the schedule
130 * constraints in "sc", without trying to combine groups of statements.
132 __isl_give isl_schedule *ppcg_compute_non_grouping_schedule(
133 __isl_take isl_schedule_constraints *sc, struct ppcg_options *options)
135 if (options->debug->dump_schedule_constraints)
136 isl_schedule_constraints_dump(sc);
137 return isl_schedule_constraints_compute_schedule(sc);
140 /* Compute a schedule on the domain of "sc" that respects the schedule
141 * constraints in "sc".
143 * "schedule" is a known correct schedule that is used to combine
144 * groups of statements if options->group_chains is set.
146 __isl_give isl_schedule *ppcg_compute_schedule(
147 __isl_take isl_schedule_constraints *sc,
148 __isl_keep isl_schedule *schedule, struct ppcg_options *options)
150 if (options->group_chains)
151 return ppcg_compute_grouping_schedule(sc, schedule, options);
152 return ppcg_compute_non_grouping_schedule(sc, options);
155 /* Obtain a schedule, either by reading it form a file
156 * or by computing it using "compute".
157 * Also take care of saving the computed schedule and/or
158 * dumping the obtained schedule if requested by the user.
160 __isl_give isl_schedule *ppcg_get_schedule(isl_ctx *ctx,
161 struct ppcg_options *options,
162 __isl_give isl_schedule *(*compute)(void *user), void *user)
164 isl_schedule *schedule;
166 if (options->load_schedule_file) {
167 schedule = load_schedule(ctx, options->load_schedule_file);
168 } else {
169 schedule = compute(user);
170 if (options->save_schedule_file)
171 save_schedule(schedule, options->save_schedule_file);
173 if (options->debug->dump_schedule)
174 isl_schedule_dump(schedule);
176 return schedule;
179 /* Mark all dimensions in the band node "node" to be of "type".
181 __isl_give isl_schedule_node *ppcg_set_schedule_node_type(
182 __isl_take isl_schedule_node *node, enum isl_ast_loop_type type)
184 int i, n;
186 n = isl_schedule_node_band_n_member(node);
187 for (i = 0; i < n; ++i)
188 node = isl_schedule_node_band_member_set_ast_loop_type(node, i,
189 type);
191 return node;