gpu: build AST expression for local array sizes during AST generation
[ppcg.git] / print.c
blob3c7f390c23ba8e4b0ef09aef9ab369f2cbf84f66
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"
14 #include "util.h"
16 __isl_give isl_printer *ppcg_start_block(__isl_take isl_printer *p)
18 p = isl_printer_start_line(p);
19 p = isl_printer_print_str(p, "{");
20 p = isl_printer_end_line(p);
21 p = isl_printer_indent(p, 2);
22 return p;
25 __isl_give isl_printer *ppcg_end_block(__isl_take isl_printer *p)
27 p = isl_printer_indent(p, -2);
28 p = isl_printer_start_line(p);
29 p = isl_printer_print_str(p, "}");
30 p = isl_printer_end_line(p);
31 return p;
34 static int print_macro(enum isl_ast_op_type type, void *user)
36 isl_printer **p = user;
38 if (type == isl_ast_op_fdiv_q)
39 return 0;
41 *p = isl_ast_op_type_print_macro(type, *p);
43 return 0;
46 /* Print the required macros for "node", except one for floord.
47 * The caller is assumed to have printed a macro for floord already
48 * as it may also appear in the declarations and the statements.
50 __isl_give isl_printer *ppcg_print_macros(__isl_take isl_printer *p,
51 __isl_keep isl_ast_node *node)
53 if (isl_ast_node_foreach_ast_op_type(node, &print_macro, &p) < 0)
54 return isl_printer_free(p);
55 return p;
58 /* Names used for the macros that may appear in a printed isl AST.
60 const char *ppcg_min = "ppcg_min";
61 const char *ppcg_max = "ppcg_max";
62 const char *ppcg_fdiv_q = "ppcg_fdiv_q";
64 /* Set the names of the macros that may appear in a printed isl AST.
66 __isl_give isl_printer *ppcg_set_macro_names(__isl_take isl_printer *p)
68 p = isl_ast_op_type_set_print_name(p, isl_ast_op_min, ppcg_min);
69 p = isl_ast_op_type_set_print_name(p, isl_ast_op_max, ppcg_max);
70 p = isl_ast_op_type_set_print_name(p, isl_ast_op_fdiv_q, ppcg_fdiv_q);
72 return p;
75 /* Given a multi affine expression "mpa" without domain, modify it to have
76 * the schedule space of "build" as domain.
78 * If the schedule space of "build" is a parameter space, then nothing
79 * needs to be done.
80 * Otherwise, "mpa" is first given a 0D domain and then it is combined
81 * with a mapping from the schedule space of "build" to the same 0D domain.
83 __isl_give isl_multi_pw_aff *ppcg_attach_multi_pw_aff(
84 __isl_take isl_multi_pw_aff *mpa, __isl_keep isl_ast_build *build)
86 isl_bool params;
87 isl_space *space;
88 isl_multi_aff *ma;
90 space = isl_ast_build_get_schedule_space(build);
91 params = isl_space_is_params(space);
92 if (params < 0 || params) {
93 isl_space_free(space);
94 if (params < 0)
95 return isl_multi_pw_aff_free(mpa);
96 return mpa;
98 space = isl_space_from_domain(space);
99 ma = isl_multi_aff_zero(space);
100 mpa = isl_multi_pw_aff_from_range(mpa);
101 mpa = isl_multi_pw_aff_pullback_multi_aff(mpa, ma);
103 return mpa;
106 /* Build an access AST expression from "size" using "build".
107 * "size" does not have a domain, but "build" may have a proper schedule space.
108 * First modify "size" to have that schedule space as domain.
110 __isl_give isl_ast_expr *ppcg_build_size_expr(__isl_take isl_multi_pw_aff *size,
111 __isl_keep isl_ast_build *build)
113 size = ppcg_attach_multi_pw_aff(size, build);
114 return isl_ast_build_access_from_multi_pw_aff(build, size);
117 /* Print a declaration for array "array" with size "size" to "p".
119 __isl_give isl_printer *ppcg_print_declaration_with_size(
120 __isl_take isl_printer *p, struct pet_array *array,
121 __isl_keep isl_ast_expr *size)
123 if (!array || !size)
124 return isl_printer_free(p);
126 p = isl_printer_start_line(p);
127 p = isl_printer_print_str(p, array->element_type);
128 p = isl_printer_print_str(p, " ");
129 p = isl_printer_print_ast_expr(p, size);
130 p = isl_printer_print_str(p, ";");
131 p = isl_printer_end_line(p);
133 return p;
136 /* Print a declaration for array "array" to "p", using "build"
137 * to simplify any size expressions.
139 * The size is computed from the extent of the array and is
140 * subsequently converted to an "access expression" by "build".
142 __isl_give isl_printer *ppcg_print_declaration(__isl_take isl_printer *p,
143 struct pet_array *array, __isl_keep isl_ast_build *build)
145 isl_multi_pw_aff *size;
146 isl_ast_expr *expr;
148 if (!array)
149 return isl_printer_free(p);
151 size = ppcg_size_from_extent(isl_set_copy(array->extent));
152 expr = isl_ast_build_access_from_multi_pw_aff(build, size);
153 p = ppcg_print_declaration_with_size(p, array, expr);
154 isl_ast_expr_free(expr);
156 return p;
159 /* Print declarations for the arrays in "scop" that are declared
160 * and that are exposed (if exposed == 1) or not exposed (if exposed == 0).
162 static __isl_give isl_printer *print_declarations(__isl_take isl_printer *p,
163 struct ppcg_scop *scop, int exposed)
165 int i;
166 isl_ast_build *build;
168 if (!scop)
169 return isl_printer_free(p);
171 build = isl_ast_build_from_context(isl_set_copy(scop->context));
172 for (i = 0; i < scop->pet->n_array; ++i) {
173 struct pet_array *array = scop->pet->arrays[i];
175 if (!array->declared)
176 continue;
177 if (array->exposed != exposed)
178 continue;
180 p = ppcg_print_declaration(p, array, build);
182 isl_ast_build_free(build);
184 return p;
187 /* Print declarations for the arrays in "scop" that are declared
188 * and exposed to the code after the scop.
190 __isl_give isl_printer *ppcg_print_exposed_declarations(
191 __isl_take isl_printer *p, struct ppcg_scop *scop)
193 return print_declarations(p, scop, 1);
196 /* Print declarations for the arrays in "scop" that are declared,
197 * but not exposed to the code after the scop.
199 __isl_give isl_printer *ppcg_print_hidden_declarations(
200 __isl_take isl_printer *p, struct ppcg_scop *scop)
202 return print_declarations(p, scop, 0);