2 * Copyright 2012-2013 Ecole Normale Superieure. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided
14 * with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY ECOLE NORMALE SUPERIEURE ''AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ECOLE NORMALE SUPERIEURE OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * The views and conclusions contained in the software and documentation
29 * are those of the authors and should not be interpreted as
30 * representing official policies, either expressed or implied, of
31 * Ecole Normale Superieure.
36 #include <isl/ast_build.h>
37 #include <isl/options.h>
40 #include <isl/union_set.h>
41 #include <isl/schedule_node.h>
44 struct isl_options
*isl
;
48 unsigned read_options
;
51 ISL_ARGS_START(struct options
, options_args
)
52 ISL_ARG_CHILD(struct options
, isl
, "isl", &isl_options_args
, "isl options")
53 ISL_ARG_BOOL(struct options
, tree
, 0, "tree", 0,
54 "input schedule is specified as schedule tree")
55 ISL_ARG_BOOL(struct options
, atomic
, 0, "atomic", 0,
56 "globally set the atomic option")
57 ISL_ARG_BOOL(struct options
, separate
, 0, "separate", 0,
58 "globally set the separate option")
59 ISL_ARG_BOOL(struct options
, read_options
, 0, "read-options", 0,
60 "read options from standard input")
63 ISL_ARG_DEF(options
, struct options
, options_args
)
65 /* Return a universal, 1-dimensional set with the given name.
67 static __isl_give isl_union_set
*universe(isl_ctx
*ctx
, const char *name
)
71 space
= isl_space_set_alloc(ctx
, 0, 1);
72 space
= isl_space_set_tuple_name(space
, isl_dim_set
, name
);
73 return isl_union_set_from_set(isl_set_universe(space
));
76 /* Set the "name" option for the entire schedule domain.
78 static __isl_give isl_union_map
*set_universe(__isl_take isl_union_map
*opt
,
79 __isl_keep isl_union_map
*schedule
, const char *name
)
82 isl_union_set
*domain
, *target
;
83 isl_union_map
*option
;
85 ctx
= isl_union_map_get_ctx(opt
);
87 domain
= isl_union_map_range(isl_union_map_copy(schedule
));
88 domain
= isl_union_set_universe(domain
);
89 target
= universe(ctx
, name
);
90 option
= isl_union_map_from_domain_and_range(domain
, target
);
91 opt
= isl_union_map_union(opt
, option
);
96 /* Set the build options based on the command line options.
98 * If no command line options are specified, we use default build options.
99 * If --read-options is specified, we read the build options from standard
101 * If --separate or --atomic is specified, we turn on the corresponding
102 * build option over the entire schedule domain.
104 static __isl_give isl_ast_build
*set_options(__isl_take isl_ast_build
*build
,
105 struct options
*options
, __isl_keep isl_union_map
*schedule
)
109 isl_union_set
*domain
, *separate
;
110 isl_union_map
*opt
, *opt_s
, *opt_a
;
112 if (!options
->separate
&& !options
->atomic
&& !options
->read_options
)
115 ctx
= isl_union_map_get_ctx(schedule
);
117 if (options
->read_options
)
118 opt
= isl_union_map_read_from_file(ctx
, stdin
);
120 opt
= isl_union_map_empty(isl_union_map_get_space(schedule
));
122 if (options
->separate
)
123 opt
= set_universe(opt
, schedule
, "separate");
125 opt
= set_universe(opt
, schedule
, "atomic");
127 build
= isl_ast_build_set_options(build
, opt
);
132 /* Print a function declaration for the domain "set".
134 * In particular, print a declaration of the form
136 * void S(int, ..., int);
138 * where S is the name of the domain and the number of arguments
139 * is equal to the dimension of "set".
141 static isl_stat
print_declaration(__isl_take isl_set
*set
, void *user
)
143 isl_printer
**p
= user
;
146 n
= isl_set_dim(set
, isl_dim_set
);
148 *p
= isl_printer_start_line(*p
);
149 *p
= isl_printer_print_str(*p
, "void ");
150 *p
= isl_printer_print_str(*p
, isl_set_get_tuple_name(set
));
151 *p
= isl_printer_print_str(*p
, "(");
152 for (i
= 0; i
< n
; ++i
) {
154 *p
= isl_printer_print_str(*p
, ", ");
155 *p
= isl_printer_print_str(*p
, "int");
157 *p
= isl_printer_print_str(*p
, ");");
158 *p
= isl_printer_end_line(*p
);
165 /* Print a function declaration for each domain in "uset".
167 static __isl_give isl_printer
*print_declarations(__isl_take isl_printer
*p
,
168 __isl_keep isl_union_set
*uset
)
170 if (isl_union_set_foreach_set(uset
, &print_declaration
, &p
) >= 0)
176 /* Check that the domain of "map" is named.
178 static isl_stat
check_name(__isl_take isl_map
*map
, void *user
)
183 ctx
= isl_map_get_ctx(map
);
184 named
= isl_map_has_tuple_name(map
, isl_dim_in
);
188 return isl_stat_error
;
190 isl_die(ctx
, isl_error_invalid
,
191 "all domains should be named", return isl_stat_error
);
195 /* Given an AST "tree", print out the following code
197 * void foo(<parameters>/)
199 * void S1(int,...,int);
205 * where the declarations are derived from the spaces in "domain".
207 static void print_tree(__isl_take isl_union_set
*domain
,
208 __isl_take isl_ast_node
*tree
)
214 isl_ast_print_options
*print_options
;
216 if (!domain
|| !tree
)
219 ctx
= isl_union_set_get_ctx(domain
);
221 p
= isl_printer_to_file(ctx
, stdout
);
222 p
= isl_printer_set_output_format(p
, ISL_FORMAT_C
);
223 p
= isl_printer_start_line(p
);
224 p
= isl_printer_print_str(p
, "void foo(");
226 space
= isl_union_set_get_space(domain
);
227 n
= isl_space_dim(space
, isl_dim_param
);
228 for (i
= 0; i
< n
; ++i
) {
232 p
= isl_printer_print_str(p
, ", ");
233 name
= isl_space_get_dim_name(space
, isl_dim_param
, i
);
234 p
= isl_printer_print_str(p
, "int ");
235 p
= isl_printer_print_str(p
, name
);
237 isl_space_free(space
);
239 p
= isl_printer_print_str(p
, ")");
240 p
= isl_printer_end_line(p
);
241 p
= isl_printer_start_line(p
);
242 p
= isl_printer_print_str(p
, "{");
243 p
= isl_printer_end_line(p
);
244 p
= isl_printer_start_line(p
);
245 p
= isl_printer_indent(p
, 2);
246 p
= print_declarations(p
, domain
);
247 p
= isl_printer_indent(p
, -2);
248 p
= isl_printer_print_str(p
, "#pragma scop");
249 p
= isl_printer_end_line(p
);
251 p
= isl_printer_indent(p
, 2);
252 print_options
= isl_ast_print_options_alloc(ctx
);
253 p
= isl_ast_node_print(tree
, p
, print_options
);
254 p
= isl_printer_indent(p
, -2);
255 p
= isl_printer_start_line(p
);
256 p
= isl_printer_print_str(p
, "#pragma endscop");
257 p
= isl_printer_end_line(p
);
258 p
= isl_printer_start_line(p
);
259 p
= isl_printer_print_str(p
, "}");
260 p
= isl_printer_end_line(p
);
264 isl_union_set_free(domain
);
265 isl_ast_node_free(tree
);
268 /* If "node" is a band node, then replace the AST build options
271 static __isl_give isl_schedule_node
*node_set_options(
272 __isl_take isl_schedule_node
*node
, void *user
)
274 enum isl_ast_loop_type
*type
= user
;
277 if (isl_schedule_node_get_type(node
) != isl_schedule_node_band
)
280 n
= isl_schedule_node_band_n_member(node
);
281 for (i
= 0; i
< n
; ++i
)
282 node
= isl_schedule_node_band_member_set_ast_loop_type(node
,
287 /* Replace the AST build options on all band nodes if requested
290 static __isl_give isl_schedule
*schedule_set_options(
291 __isl_take isl_schedule
*schedule
, struct options
*options
)
293 enum isl_ast_loop_type type
;
295 if (!options
->separate
&& !options
->atomic
)
298 type
= options
->separate
? isl_ast_loop_separate
: isl_ast_loop_atomic
;
299 schedule
= isl_schedule_map_schedule_node_bottom_up(schedule
,
300 &node_set_options
, &type
);
305 /* Read a schedule tree, generate an AST and print the result
306 * in a form that is readable by pet.
308 static int print_schedule_tree(isl_ctx
*ctx
, struct options
*options
)
310 isl_union_set
*domain
;
311 isl_schedule
*schedule
;
312 isl_ast_build
*build
;
315 schedule
= isl_schedule_read_from_file(ctx
, stdin
);
316 domain
= isl_schedule_get_domain(schedule
);
318 build
= isl_ast_build_alloc(ctx
);
319 schedule
= schedule_set_options(schedule
, options
);
320 tree
= isl_ast_build_node_from_schedule(build
, schedule
);
321 isl_ast_build_free(build
);
323 print_tree(domain
, tree
);
328 /* Read a schedule, a context and (optionally) build options,
329 * generate an AST and print the result in a form that is readable
332 static int print_schedule_map(isl_ctx
*ctx
, struct options
*options
)
335 isl_union_set
*domain
;
336 isl_union_map
*schedule
;
337 isl_ast_build
*build
;
340 schedule
= isl_union_map_read_from_file(ctx
, stdin
);
341 if (isl_union_map_foreach_map(schedule
, &check_name
, NULL
) < 0) {
342 isl_union_map_free(schedule
);
345 context
= isl_set_read_from_file(ctx
, stdin
);
347 domain
= isl_union_map_domain(isl_union_map_copy(schedule
));
348 domain
= isl_union_set_align_params(domain
, isl_set_get_space(context
));
350 build
= isl_ast_build_from_context(context
);
351 build
= set_options(build
, options
, schedule
);
352 tree
= isl_ast_build_node_from_schedule_map(build
, schedule
);
353 isl_ast_build_free(build
);
355 print_tree(domain
, tree
);
361 * - a schedule tree or
362 * - a schedule, a context and (optionally) build options,
363 * generate an AST and print the result in a form that is readable
366 int main(int argc
, char **argv
)
369 struct options
*options
;
372 options
= options_new_with_defaults();
374 argc
= options_parse(options
, argc
, argv
, ISL_ARG_ALL
);
376 ctx
= isl_ctx_alloc_with_options(&options_args
, options
);
379 r
= print_schedule_tree(ctx
, options
);
381 r
= print_schedule_map(ctx
, options
);