update barvinok for use of new glp_ API
[ppn.git] / check_channel_sizes.cc
blobf3ff1f60999eb5aa3e8c05040e56dd2cbcef7e63
1 #include <iostream>
2 #include <isl/aff.h>
3 #include <isl/ast_build.h>
5 #include <isa/yaml.h>
6 #include <isa/pdg.h>
8 using namespace std;
9 using namespace pdg;
11 struct pos_dep {
12 int pos;
13 pdg::dependence *dep;
16 static __isl_give isl_printer *print_access_pair(__isl_take isl_printer *p,
17 int pos, pdg::node *from, int from_access, pdg::node *to, int to_access)
19 p = isl_printer_print_int(p, pos);
20 p = isl_printer_print_str(p, "_");
21 p = isl_printer_print_int(p, from->nr);
22 p = isl_printer_print_str(p, "_");
23 p = isl_printer_print_int(p, from_access);
24 p = isl_printer_print_str(p, "_");
25 p = isl_printer_print_int(p, to->nr);
26 p = isl_printer_print_str(p, "_");
27 p = isl_printer_print_int(p, to_access);
28 return p;
31 static __isl_give isl_printer *print_core_domain(__isl_take isl_printer *p,
32 __isl_take isl_ast_print_options *print_options,
33 __isl_keep isl_ast_node *node, void *user)
35 pos_dep *pd;
36 int pos;
37 pdg::dependence *dep;
38 pdg::node *from;
39 pdg::node *to;
40 int from_access;
41 int to_access;
42 isl_id *id;
43 isl_ast_expr *expr, *arg;
44 const char *name;
46 expr = isl_ast_node_user_get_expr(node);
47 arg = isl_ast_expr_get_op_arg(expr, 0);
48 id = isl_ast_expr_get_id(arg);
49 name = isl_id_get_name(id);
50 pd = (pos_dep *) isl_id_get_user(id);
51 dep = pd->dep;
52 pos = pd->pos;
53 isl_id_free(id);
54 isl_ast_expr_free(arg);
55 isl_ast_expr_free(expr);
57 from = dep->from;
58 to = dep->to;
59 from_access = dep->from_access ? dep->from_access->nr
60 : from->statement->accesses.size();
61 to_access = dep->to_access ? dep->to_access->nr
62 : to->statement->accesses.size();
64 if (!strcmp(name, "write")) {
65 p = isl_printer_start_line(p);
66 p = isl_printer_print_str(p, "if (++i_");
67 p = print_access_pair(p, pos, from, from_access, to, to_access);
68 p = isl_printer_print_str(p, " > s_");
69 p = print_access_pair(p, pos, from, from_access, to, to_access);
70 p = isl_printer_print_str(p, ")");
71 p = isl_printer_end_line(p);
72 p = isl_printer_indent(p, 4);
73 p = isl_printer_start_line(p);
74 p = isl_printer_print_str(p, "s_");
75 p = print_access_pair(p, pos, from, from_access, to, to_access);
76 p = isl_printer_print_str(p, " = i_");
77 p = print_access_pair(p, pos, from, from_access, to, to_access);
78 p = isl_printer_print_str(p, ";");
79 p = isl_printer_end_line(p);
80 p = isl_printer_indent(p, -4);
81 } else {
82 p = isl_printer_start_line(p);
83 p = isl_printer_print_str(p, "--i_");
84 p = print_access_pair(p, pos, from, from_access, to, to_access);
85 p = isl_printer_print_str(p, ";");
86 p = isl_printer_end_line(p);
89 isl_ast_print_options_free(print_options);
90 return p;
93 static __isl_give isl_union_map *add_schedule(__isl_take isl_union_map *sched,
94 __isl_take isl_set *domain, int maxdim, const char *type, pos_dep *pd)
96 isl_id *id;
97 isl_map *sched_i;
98 int n;
100 sched_i = isl_set_identity(domain);
101 n = isl_map_dim(sched_i, isl_dim_out);
102 sched_i = isl_map_add_dims(sched_i, isl_dim_out, maxdim - n);
103 for (int i = n; i < maxdim; ++i)
104 sched_i = isl_map_fix_si(sched_i, isl_dim_out, i, 0);
105 id = isl_id_alloc(isl_union_map_get_ctx(sched), type, pd);
106 sched_i = isl_map_set_tuple_id(sched_i, isl_dim_in, id);
107 sched = isl_union_map_add_map(sched, sched_i);
109 return sched;
112 static __isl_give isl_printer *print_user(__isl_take isl_printer *p,
113 __isl_take isl_ast_print_options *print_options,
114 __isl_keep isl_ast_node *node, void *user)
116 PDG *pdg = (PDG *) user;
117 isl_ctx *ctx = pdg->get_isl_ctx();
118 int maxdim = 0;
119 isl_ast_build *build;
120 isl_ast_node *tree;
121 isl_union_map *sched;
122 pos_dep *data;
124 p = isl_printer_start_line(p);
125 p = isl_printer_print_str(p, "{");
126 p = isl_printer_end_line(p);
127 p = isl_printer_indent(p, 2);
129 int nparam = pdg->params.size();
131 for (int i = 0; i < pdg->nodes.size(); ++i) {
132 pdg::node *node = pdg->nodes[i];
133 if (node->prefix.size() > maxdim)
134 maxdim = node->prefix.size();
137 sched = isl_union_map_empty(isl_space_params_alloc(ctx, 0));
139 data = new pos_dep[pdg->dependences.size()];
140 std::map<pdg::dependence *,int> pos;
142 for (int i = 0; i < pdg->dependences.size(); ++i) {
143 pdg::dependence *dep = pdg->dependences[i];
144 if (dep->type == pdg::dependence::uninitialized)
145 continue;
146 if (dep->type == pdg::dependence::pn_part)
147 continue;
148 pdg::node* from = dep->from;
149 pdg::node* to = dep->to;
150 int from_access = dep->from_access ? dep->from_access->nr
151 : from->statement->accesses.size();
152 int to_access = dep->to_access ? dep->to_access->nr
153 : to->statement->accesses.size();
154 if (!dep->size)
155 continue;
156 pos[dep] = i;
158 p = isl_printer_start_line(p);
159 p = isl_printer_print_str(p, "int i_");
160 p = print_access_pair(p, i, from, from_access, to, to_access);
161 p = isl_printer_print_str(p, " = 0;");
162 p = isl_printer_end_line(p);
163 p = isl_printer_start_line(p);
164 p = isl_printer_print_str(p, "int s_");
165 p = print_access_pair(p, i, from, from_access, to, to_access);
166 p = isl_printer_print_str(p, " = 0;");
167 p = isl_printer_end_line(p);
170 for (int i = 0; i < pdg->dependences.size(); ++i) {
171 isl_set *domain;
172 pdg::dependence *dep = pdg->dependences[i];
173 pdg::dependence *container = dep;
174 if (dep->type == pdg::dependence::uninitialized)
175 continue;
176 if (dep->type == pdg::dependence::pn_union)
177 continue;
178 if (dep->type == pdg::dependence::pn_part)
179 container = dep->container;
180 if (!container->size)
181 continue;
182 data[i].pos = pos.find(container)->second;
183 data[i].dep = container;
185 isl_map *map = scatter_dependence(pdg, dep);
186 domain = isl_map_range(isl_map_copy(map));
187 sched = add_schedule(sched, domain, maxdim, "read", &data[i]);
188 domain = isl_map_domain(map);
189 sched = add_schedule(sched, domain, maxdim, "write", &data[i]);
192 build = isl_ast_build_from_context(pdg->get_context_isl_set());
193 tree = isl_ast_build_ast_from_schedule(build, sched);
194 isl_ast_build_free(build);
196 print_options = isl_ast_print_options_set_print_user(print_options,
197 &print_core_domain, NULL);
198 p = isl_ast_node_print(tree, p, print_options);
200 isl_ast_node_free(tree);
202 for (int i = 0; i < pdg->dependences.size(); ++i) {
203 pdg::dependence *dep = pdg->dependences[i];
204 if (dep->type == pdg::dependence::uninitialized)
205 continue;
206 if (dep->type == pdg::dependence::pn_part)
207 continue;
208 pdg::node* from = dep->from;
209 pdg::node* to = dep->to;
210 int from_access = dep->from_access ? dep->from_access->nr
211 : from->statement->accesses.size();
212 int to_access = dep->to_access ? dep->to_access->nr
213 : to->statement->accesses.size();
214 if (!dep->size)
215 continue;
217 p = isl_printer_start_line(p);
218 p = isl_printer_print_str(p, "assert(i_");
219 p = print_access_pair(p, i, from, from_access, to, to_access);
220 p = isl_printer_print_str(p, " == 0);");
221 p = isl_printer_end_line(p);
223 p = isl_printer_start_line(p);
224 p = isl_printer_print_str(p, "printf(\"s_");
225 p = print_access_pair(p, i, from, from_access, to, to_access);
226 p = isl_printer_print_str(p, ": %d; %d\\n\", s_");
227 p = print_access_pair(p, i, from, from_access, to, to_access);
228 p = isl_printer_print_str(p, ", (int)(");
229 p = isl_printer_print_str(p, dep->size->s->c_str());
230 p = isl_printer_print_str(p, "));");
231 p = isl_printer_end_line(p);
233 p = isl_printer_start_line(p);
234 p = isl_printer_print_str(p, "assert(s_");
235 p = print_access_pair(p, i, from, from_access, to, to_access);
236 p = isl_printer_print_str(p, " <= (int)(");
237 p = isl_printer_print_str(p, dep->size->s->c_str());
238 p = isl_printer_print_str(p, "));");
239 p = isl_printer_end_line(p);
242 p = isl_printer_indent(p, -2);
243 p = isl_printer_start_line(p);
244 p = isl_printer_print_str(p, "}");
245 p = isl_printer_end_line(p);
247 delete [] data;
249 return p;
252 static int print_macro(enum isl_ast_op_type type, void *user)
254 isl_printer **p = (isl_printer **) user;
256 if (type == isl_ast_op_fdiv_q)
257 return 0;
259 *p = isl_ast_op_type_print_macro(type, *p);
261 return 0;
264 /* Print the required macros for "node", including one for floord.
265 * We always print a macro for floord as it may also appear in the statements.
267 static __isl_give isl_printer *print_macros(
268 __isl_keep isl_ast_node *node, __isl_take isl_printer *p)
270 p = isl_ast_op_type_print_macro(isl_ast_op_fdiv_q, p);
271 if (isl_ast_node_foreach_ast_op_type(node, &print_macro, &p) < 0) {
272 isl_printer_free(p);
273 return NULL;
275 return p;
278 static void print(__isl_keep isl_ast_node *tree, PDG *pdg)
280 isl_ctx *ctx;
281 FILE *out = stdout;
282 isl_printer *p;
283 isl_ast_print_options *print_options;
285 ctx = isl_ast_node_get_ctx(tree);
287 p = isl_printer_to_file(ctx, out);
288 p = isl_printer_set_output_format(p, ISL_FORMAT_C);
290 p = isl_printer_start_line(p);
291 p = isl_printer_print_str(p, "#include <assert.h>");
292 p = isl_printer_end_line(p);
294 p = isl_printer_start_line(p);
295 p = isl_printer_print_str(p, "#include <stdio.h>");
296 p = isl_printer_end_line(p);
298 p = print_macros(tree, p);
300 p = isl_printer_start_line(p);
301 p = isl_printer_print_str(p, "int main()");
302 p = isl_printer_end_line(p);
303 p = isl_printer_start_line(p);
304 p = isl_printer_print_str(p, "{");
305 p = isl_printer_end_line(p);
307 p = isl_printer_indent(p, 4);
309 print_options = isl_ast_print_options_alloc(ctx);
310 print_options = isl_ast_print_options_set_print_user(print_options,
311 &print_user, pdg);
312 p = isl_ast_node_print(tree, p, print_options);
314 p = isl_printer_start_line(p);
315 p = isl_printer_print_str(p, "return 0;");
316 p = isl_printer_end_line(p);
318 p = isl_printer_indent(p, -4);
320 p = isl_printer_start_line(p);
321 p = isl_printer_print_str(p, "}");
322 p = isl_printer_end_line(p);
324 isl_printer_free(p);
327 void print_program(PDG *pdg)
329 isl_ctx *ctx = pdg->get_isl_ctx();
330 isl_set *context;
331 isl_union_map *sched;
332 isl_ast_build *build;
333 isl_ast_node *tree;
334 isl_id_list *iterators;
335 unsigned nparam;
337 context = pdg->get_context_isl_set();
338 context = isl_set_from_params(context);
339 nparam = isl_set_dim(context, isl_dim_param);
340 context = isl_set_move_dims(context, isl_dim_set, 0,
341 isl_dim_param, 0, nparam);
342 sched = isl_union_map_from_map(isl_set_identity(context));
344 context = isl_set_universe(isl_union_map_get_space(sched));
346 iterators = isl_id_list_alloc(ctx, nparam);
347 for (int i = 0; i < nparam; ++i) {
348 isl_id *id = isl_id_alloc(ctx, pdg->params[i]->name->s.c_str(), NULL);
349 iterators = isl_id_list_add(iterators, id);
352 build = isl_ast_build_from_context(context);
353 build = isl_ast_build_set_iterators(build, iterators);
354 tree = isl_ast_build_ast_from_schedule(build, sched);
355 isl_ast_build_free(build);
357 print(tree, pdg);
359 isl_ast_node_free(tree);
362 int main(int argc, char * argv[])
364 PDG *pdg;
365 isl_ctx *ctx = isl_ctx_alloc();
366 pdg = PDG::Load(stdin, ctx);
368 assert(pdg->context);
370 print_program(pdg);
372 pdg->free();
373 delete pdg;
374 isl_ctx_free(ctx);
376 return 0;