6 #include <isl/union_map.h>
7 #include <isl/polynomial.h>
9 #include <isl/ast_build.h>
10 #include <isl/printer.h>
11 #include <barvinok/isl.h>
15 #include "mem_options.h"
17 #define ALLOC(type) (type*)malloc(sizeof(type))
22 static void dump_program(PDG
*pdg
, int *output
, struct options
*options
);
24 int main(int argc
, char * argv
[])
28 struct options
*options
= options_new_with_defaults();
30 argc
= options_parse(options
, argc
, argv
, ISL_ARG_ALL
);
32 ctx
= isl_ctx_alloc_with_options(&options_args
, options
);
34 pdg
= PDG::Load(stdin
, ctx
);
35 int output
[pdg
->arrays
.size()];
37 for (int i
= 0; i
< pdg
->arrays
.size(); ++i
) {
38 int n
= pdg
->dependences
.size();
39 find_deps(pdg
, pdg
->arrays
[i
], data_reuse
);
40 output
[i
] = n
== pdg
->dependences
.size();
43 dump_program(pdg
, output
, options
);
51 static __isl_give isl_map
*schedule(__isl_take isl_set
*domain
,
52 pdg::node
*node
, pdg::access
*ac
, int dep
, int maxdim
, int write
)
54 int fulldim
= node
->prefix
.size() + 1;
58 schedule
= isl_map_from_domain(domain
);
59 schedule
= isl_map_add_dims(schedule
, isl_dim_out
, 2);
60 schedule
= isl_map_fix_si(schedule
, isl_dim_out
, 0, ac
->nr
);
61 schedule
= isl_map_fix_si(schedule
, isl_dim_out
, 1, dep
);
62 schedule
= isl_set_identity(isl_map_wrap(schedule
));
63 schedule
= isl_map_flatten_range(schedule
);
65 for (int i
= 0; i
< node
->prefix
.size(); ++i
) {
66 if (node
->prefix
[i
] == -1)
68 schedule
= isl_map_insert_dims(schedule
, isl_dim_out
, i
, 1);
69 schedule
= isl_map_fix_si(schedule
, isl_dim_out
, i
, node
->prefix
[i
]);
72 dim
= isl_map_dim(schedule
, isl_dim_out
);
73 schedule
= isl_map_project_out(schedule
, isl_dim_out
, dim
- 1, 1);
75 schedule
= isl_map_add_dims(schedule
, isl_dim_out
, maxdim
- dim
);
76 for (int i
= dim
; i
< maxdim
; ++i
)
77 schedule
= isl_map_fix_si(schedule
, isl_dim_out
, i
, 0);
80 schedule
= isl_map_set_tuple_name(schedule
, isl_dim_in
, "write");
82 schedule
= isl_map_set_tuple_name(schedule
, isl_dim_in
, "read");
87 /* Compute the number of array elements that are read but not
88 * (previously) written. These are assumed to be the input.
90 static __isl_give isl_pw_qpolynomial
*compute_input_size(PDG
*pdg
,
91 struct options
*options
)
93 unsigned nparam
= pdg
->params
.size();
95 isl_pw_qpolynomial
*inputsize
;
97 space
= isl_space_set_alloc(pdg
->get_isl_ctx(), nparam
, 1);
98 isl_dim_set_parameter_names(space
, pdg
->params
);
99 inputsize
= isl_pw_qpolynomial_zero(space
);
101 if (!options
->with_input
)
104 for (int i
= 0; i
< pdg
->dependences
.size(); ++i
) {
106 isl_pw_qpolynomial
*size
;
107 pdg::dependence
*dep
= pdg
->dependences
[i
];
109 if (dep
->type
!= pdg::dependence::uninitialized
)
112 map
= dep
->relation
->get_isl_map(pdg
->get_isl_ctx());
113 size
= isl_set_card(isl_map_range(map
));
114 inputsize
= isl_pw_qpolynomial_add(inputsize
, size
);
120 static __isl_give isl_printer
*print_user(__isl_take isl_printer
*p
,
121 __isl_take isl_ast_print_options
*print_options
,
122 __isl_keep isl_ast_node
*node
, void *user
)
125 isl_ast_expr
*expr
, *arg
;
128 expr
= isl_ast_node_user_get_expr(node
);
129 arg
= isl_ast_expr_get_op_arg(expr
, 0);
130 id
= isl_ast_expr_get_id(arg
);
131 name
= isl_id_get_name(id
);
132 if (!strcmp(name
, "write")) {
133 p
= isl_printer_start_line(p
);
134 p
= isl_printer_print_str(p
, "if (++count > max)");
135 p
= isl_printer_end_line(p
);
136 p
= isl_printer_indent(p
, 4);
137 p
= isl_printer_start_line(p
);
138 p
= isl_printer_print_str(p
, "max = count;");
139 p
= isl_printer_end_line(p
);
140 p
= isl_printer_indent(p
, -4);
142 p
= isl_printer_start_line(p
);
143 p
= isl_printer_print_str(p
, "--count;");
144 p
= isl_printer_end_line(p
);
147 isl_ast_expr_free(arg
);
148 isl_ast_expr_free(expr
);
149 isl_ast_print_options_free(print_options
);
153 static void print(__isl_keep isl_ast_node
*tree
, const char *inputsize
)
158 isl_ast_print_options
*print_options
;
160 ctx
= isl_ast_node_get_ctx(tree
);
162 p
= isl_printer_to_file(ctx
, out
);
163 p
= isl_printer_set_output_format(p
, ISL_FORMAT_C
);
165 p
= isl_printer_start_line(p
);
166 p
= isl_printer_print_str(p
, "#include <stdio.h>");
167 p
= isl_printer_end_line(p
);
169 p
= isl_ast_node_print_macros(tree
, p
);
171 p
= isl_printer_start_line(p
);
172 p
= isl_printer_print_str(p
, "int main() {");
173 p
= isl_printer_end_line(p
);
175 p
= isl_printer_indent(p
, 4);
177 p
= isl_printer_start_line(p
);
178 p
= isl_printer_print_str(p
, "long count = ");
179 p
= isl_printer_print_str(p
, inputsize
);
180 p
= isl_printer_print_str(p
, ";");
181 p
= isl_printer_end_line(p
);
183 p
= isl_printer_start_line(p
);
184 p
= isl_printer_print_str(p
, "long max = count;");
185 p
= isl_printer_end_line(p
);
187 print_options
= isl_ast_print_options_alloc(ctx
);
188 print_options
= isl_ast_print_options_set_print_user(print_options
,
190 p
= isl_ast_node_print(tree
, p
, print_options
);
192 p
= isl_printer_start_line(p
);
193 p
= isl_printer_print_str(p
, "printf(\"final: %ld\\n\", count);");
194 p
= isl_printer_end_line(p
);
196 p
= isl_printer_start_line(p
);
197 p
= isl_printer_print_str(p
, "printf(\"max: %ld\\n\", max);");
198 p
= isl_printer_end_line(p
);
200 p
= isl_printer_start_line(p
);
201 p
= isl_printer_print_str(p
, "return 0;");
202 p
= isl_printer_end_line(p
);
204 p
= isl_printer_indent(p
, -4);
206 p
= isl_printer_start_line(p
);
207 p
= isl_printer_print_str(p
, "}");
208 p
= isl_printer_end_line(p
);
213 static void dump_program(PDG
*pdg
, int *output
, struct options
*options
)
215 int nparam
= pdg
->params
.size();
216 isl_ctx
*ctx
= pdg
->get_isl_ctx();
217 isl_set
*context
= pdg
->get_context_isl_set();
219 isl_union_map
*sched
;
220 isl_ast_build
*build
;
223 isl_pw_qpolynomial
*inputsize
;
227 inputsize
= compute_input_size(pdg
, options
);
228 inputsize
= isl_pw_qpolynomial_gist(inputsize
, isl_set_copy(context
));
229 p
= isl_printer_to_str(pdg
->get_isl_ctx());
230 p
= isl_printer_set_output_format(p
, ISL_FORMAT_C
);
231 p
= isl_printer_print_pw_qpolynomial(p
, inputsize
);
232 s_inputsize
= isl_printer_get_str(p
);
234 isl_pw_qpolynomial_free(inputsize
);
236 sched
= isl_union_map_empty(isl_set_get_space(context
));
238 for (int i
= 0; i
< pdg
->nodes
.size(); ++i
) {
239 pdg::node
*node
= pdg
->nodes
[i
];
240 if (node
->prefix
.size() + 1 > maxdim
)
241 maxdim
= node
->prefix
.size() + 1;
244 for (int i
= 0; i
< pdg
->nodes
.size(); ++i
) {
245 pdg::node
*node
= pdg
->nodes
[i
];
246 pdg::statement
*s
= pdg
->nodes
[i
]->statement
;
248 for (int j
= 0; j
< pdg
->dependences
.size(); ++j
) {
249 pdg::dependence
*dep
= pdg
->dependences
[j
];
250 if (dep
->to
!= pdg
->nodes
[i
] && dep
->from
!= pdg
->nodes
[i
])
252 if (!options
->with_input
&&
253 dep
->type
== pdg::dependence::uninitialized
)
255 isl_map
*rel
= dep
->relation
->get_isl_map(pdg
->get_isl_ctx());
256 if (dep
->to
== pdg
->nodes
[i
]) {
257 isl_set
*read
= isl_map_range(isl_map_copy(rel
));
258 sched_i
= schedule(read
, dep
->to
, dep
->to_access
, j
,
260 sched
= isl_union_map_add_map(sched
, sched_i
);
262 if (dep
->from
== pdg
->nodes
[i
]) {
263 isl_set
*write
= isl_map_domain(isl_map_copy(rel
));
264 sched_i
= schedule(write
, dep
->from
, dep
->from_access
, j
,
266 sched
= isl_union_map_add_map(sched
, sched_i
);
270 for (int j
= 0; j
< s
->accesses
.size(); ++j
) {
271 pdg::access
*access
= s
->accesses
[j
];
272 if (access
->type
== pdg::access::read
)
275 for (k
= 0; k
< pdg
->arrays
.size(); ++k
)
276 if (pdg
->arrays
[k
] == access
->array
)
280 isl_set
*source
= node
->source
->get_isl_set(pdg
->get_isl_ctx());
281 sched_i
= schedule(source
, node
, access
, -(j
+ 1), maxdim
, 1);
282 sched
= isl_union_map_add_map(sched
, sched_i
);
286 build
= isl_ast_build_from_context(context
);
287 tree
= isl_ast_build_ast_from_schedule(build
, sched
);
288 isl_ast_build_free(build
);
290 print(tree
, s_inputsize
);
292 isl_ast_node_free(tree
);