2 * Copyright 2012-2013 Ecole Normale Superieure
4 * Use of this software is governed by the MIT license
6 * Written by Sven Verdoolaege,
7 * Ecole Normale Superieure, 45 rue d’Ulm, 75230 Paris, France
11 #include <isl/ast_build.h>
15 __isl_give isl_printer
*ppcg_start_block(__isl_take isl_printer
*p
)
17 p
= isl_printer_start_line(p
);
18 p
= isl_printer_print_str(p
, "{");
19 p
= isl_printer_end_line(p
);
20 p
= isl_printer_indent(p
, 2);
24 __isl_give isl_printer
*ppcg_end_block(__isl_take isl_printer
*p
)
26 p
= isl_printer_indent(p
, -2);
27 p
= isl_printer_start_line(p
);
28 p
= isl_printer_print_str(p
, "}");
29 p
= isl_printer_end_line(p
);
33 static int print_macro(enum isl_ast_op_type type
, void *user
)
35 isl_printer
**p
= user
;
37 if (type
== isl_ast_op_fdiv_q
)
40 *p
= isl_ast_op_type_print_macro(type
, *p
);
45 /* Print the required macros for "node", except one for floord.
46 * The caller is assumed to have printed a macro for floord already
47 * as it may also appear in the declarations and the statements.
49 __isl_give isl_printer
*ppcg_print_macros(__isl_take isl_printer
*p
,
50 __isl_keep isl_ast_node
*node
)
52 if (isl_ast_node_foreach_ast_op_type(node
, &print_macro
, &p
) < 0)
53 return isl_printer_free(p
);
57 /* Print "extent" as a sequence of
61 * one for each dimension.
62 * "build" is used to simplify the size expressions, if any.
64 static __isl_give isl_printer
*print_extent(__isl_take isl_printer
*p
,
65 __isl_keep isl_set
*extent
, __isl_keep isl_ast_build
*build
)
69 n
= isl_set_dim(extent
, isl_dim_set
);
73 for (i
= 0; i
< n
; ++i
) {
80 bound
= isl_set_dim_max(isl_set_copy(extent
), i
);
81 dom
= isl_pw_aff_domain(isl_pw_aff_copy(bound
));
82 ls
= isl_local_space_from_space(isl_set_get_space(dom
));
83 one
= isl_aff_zero_on_domain(ls
);
84 one
= isl_aff_add_constant_si(one
, 1);
85 bound
= isl_pw_aff_add(bound
, isl_pw_aff_alloc(dom
, one
));
87 p
= isl_printer_print_str(p
, "[");
88 expr
= isl_ast_build_expr_from_pw_aff(build
, bound
);
89 p
= isl_printer_print_ast_expr(p
, expr
);
90 p
= isl_printer_print_str(p
, "]");
92 isl_ast_expr_free(expr
);
98 /* Print a declaration for array "array" to "p", using "build"
99 * to simplify any size expressions.
101 __isl_give isl_printer
*ppcg_print_declaration(__isl_take isl_printer
*p
,
102 struct pet_array
*array
, __isl_keep isl_ast_build
*build
)
107 return isl_printer_free(p
);
109 name
= isl_set_get_tuple_name(array
->extent
);
111 p
= isl_printer_start_line(p
);
112 p
= isl_printer_print_str(p
, array
->element_type
);
113 p
= isl_printer_print_str(p
, " ");
114 p
= isl_printer_print_str(p
, name
);
115 p
= print_extent(p
, array
->extent
, build
);
116 p
= isl_printer_print_str(p
, ";");
117 p
= isl_printer_end_line(p
);
122 /* Print declarations for the arrays in "scop" that are declared
123 * and that are exposed (if exposed == 1) or not exposed (if exposed == 0).
125 static __isl_give isl_printer
*print_declarations(__isl_take isl_printer
*p
,
126 struct ppcg_scop
*scop
, int exposed
)
129 isl_ast_build
*build
;
132 return isl_printer_free(p
);
134 build
= isl_ast_build_from_context(isl_set_copy(scop
->context
));
135 for (i
= 0; i
< scop
->pet
->n_array
; ++i
) {
136 struct pet_array
*array
= scop
->pet
->arrays
[i
];
138 if (!array
->declared
)
140 if (array
->exposed
!= exposed
)
143 p
= ppcg_print_declaration(p
, array
, build
);
145 isl_ast_build_free(build
);
150 /* Print declarations for the arrays in "scop" that are declared
151 * and exposed to the code after the scop.
153 __isl_give isl_printer
*ppcg_print_exposed_declarations(
154 __isl_take isl_printer
*p
, struct ppcg_scop
*scop
)
156 return print_declarations(p
, scop
, 1);
159 /* Print declarations for the arrays in "scop" that are declared,
160 * but not exposed to the code after the scop.
162 __isl_give isl_printer
*ppcg_print_hidden_declarations(
163 __isl_take isl_printer
*p
, struct ppcg_scop
*scop
)
165 return print_declarations(p
, scop
, 0);
168 /* Internal data structure for print_guarded_user.
170 * fn is the function that should be called to print the body.
171 * user is the argument that should be passed to this function.
173 struct ppcg_print_guarded_data
{
174 __isl_give isl_printer
*(*fn
)(__isl_take isl_printer
*p
, void *user
);
178 /* Print the body of the if statement expressing the guard passed
179 * to "ppcg_print_guarded" by calling data->fn.
181 static __isl_give isl_printer
*print_guarded_user(__isl_take isl_printer
*p
,
182 __isl_take isl_ast_print_options
*options
,
183 __isl_keep isl_ast_node
*node
, void *user
)
185 struct ppcg_print_guarded_data
*data
= user
;
187 p
= data
->fn(p
, data
->user
);
189 isl_ast_print_options_free(options
);
193 /* Print a condition for the given "guard" within the given "context"
194 * on "p", calling "fn" with "user" to print the body of the if statement.
195 * If the guard is implied by the context, then no if statement is printed
196 * and the body is printed directly to "p".
198 * Both "guard" and "context" are assumed to be parameter sets.
200 * We slightly abuse the AST generator to print this guard.
201 * In particular, we create a trivial schedule for an iteration
202 * domain with a single instance, restricted by the guard.
204 __isl_give isl_printer
*ppcg_print_guarded(__isl_take isl_printer
*p
,
205 __isl_take isl_set
*guard
, __isl_take isl_set
*context
,
206 __isl_give isl_printer
*(*fn
)(__isl_take isl_printer
*p
, void *user
),
209 struct ppcg_print_guarded_data data
= { fn
, user
};
211 isl_union_map
*schedule
;
212 isl_ast_build
*build
;
214 isl_ast_print_options
*options
;
216 ctx
= isl_printer_get_ctx(p
);
217 guard
= isl_set_from_params(guard
);
218 schedule
= isl_union_map_from_map(isl_map_from_domain(guard
));
219 build
= isl_ast_build_from_context(context
);
220 tree
= isl_ast_build_node_from_schedule_map(build
, schedule
);
221 isl_ast_build_free(build
);
223 options
= isl_ast_print_options_alloc(ctx
);
224 options
= isl_ast_print_options_set_print_user(options
,
225 &print_guarded_user
, &data
);
226 p
= isl_ast_node_print(tree
, p
, options
);
227 isl_ast_node_free(tree
);