README: update latest release of clang
[ppcg.git] / print.c
blob799da76829c039124c21b5d132fb43ff5a653905
1 /*
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
8 */
10 #include <isl/aff.h>
11 #include <isl/ast_build.h>
13 #include "print.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);
21 return p;
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);
30 return 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)
38 return 0;
40 *p = isl_ast_op_type_print_macro(type, *p);
42 return 0;
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);
54 return p;
57 /* Print "extent" as a sequence of
59 * [1 + maximal_value]
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)
67 int i, n;
69 n = isl_set_dim(extent, isl_dim_set);
70 if (n == 0)
71 return p;
73 for (i = 0; i < n; ++i) {
74 isl_set *dom;
75 isl_local_space *ls;
76 isl_aff *one;
77 isl_pw_aff *bound;
78 isl_ast_expr *expr;
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);
95 return p;
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)
104 const char *name;
106 if (!array)
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);
119 return 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)
128 int i;
129 isl_ast_build *build;
131 if (!scop)
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)
139 continue;
140 if (array->exposed != exposed)
141 continue;
143 p = ppcg_print_declaration(p, array, build);
145 isl_ast_build_free(build);
147 return p;
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);
175 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);
190 return p;
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),
207 void *user)
209 struct ppcg_print_guarded_data data = { fn, user };
210 isl_ctx *ctx;
211 isl_union_map *schedule;
212 isl_ast_build *build;
213 isl_ast_node *tree;
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);
229 return p;