3 #include <isl/ast_build.h>
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
);
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
)
43 isl_ast_expr
*expr
, *arg
;
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
);
54 isl_ast_expr_free(arg
);
55 isl_ast_expr_free(expr
);
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);
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
);
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
)
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
);
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();
119 isl_ast_build
*build
;
121 isl_union_map
*sched
;
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
)
146 if (dep
->type
== pdg::dependence::pn_part
)
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();
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
) {
172 pdg::dependence
*dep
= pdg
->dependences
[i
];
173 pdg::dependence
*container
= dep
;
174 if (dep
->type
== pdg::dependence::uninitialized
)
176 if (dep
->type
== pdg::dependence::pn_union
)
178 if (dep
->type
== pdg::dependence::pn_part
)
179 container
= dep
->container
;
180 if (!container
->size
)
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
)
206 if (dep
->type
== pdg::dependence::pn_part
)
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();
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
);
252 static isl_stat
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
)
259 *p
= isl_ast_op_type_print_macro(type
, *p
);
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) {
278 static void print(__isl_keep isl_ast_node
*tree
, PDG
*pdg
)
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
,
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
);
327 void print_program(PDG
*pdg
)
329 isl_ctx
*ctx
= pdg
->get_isl_ctx();
331 isl_union_map
*sched
;
332 isl_ast_build
*build
;
334 isl_id_list
*iterators
;
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
);
359 isl_ast_node_free(tree
);
362 int main(int argc
, char * argv
[])
365 isl_ctx
*ctx
= isl_ctx_alloc();
366 pdg
= PDG::Load(stdin
, ctx
);
368 assert(pdg
->context
);