Remove unused variable never used
[ppcg.git] / gpu_print.c
blob19285f86fe37a586ec721dc9f567c07235de8048
1 /*
2 * Copyright 2012 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 <string.h>
12 #include <isl/aff.h>
14 #include "gpu_print.h"
15 #include "print.h"
16 #include "schedule.h"
18 /* Print declarations to "p" for arrays that are local to "prog"
19 * but that are used on the host and therefore require a declaration.
21 __isl_give isl_printer *gpu_print_local_declarations(__isl_take isl_printer *p,
22 struct gpu_prog *prog)
24 int i;
26 if (!prog)
27 return isl_printer_free(p);
29 for (i = 0; i < prog->n_array; ++i) {
30 isl_ast_expr *size;
32 if (!prog->array[i].declare_local)
33 continue;
34 size = prog->array[i].declared_size;
35 p = ppcg_print_declaration_with_size(p,
36 prog->scop->pet->arrays[i], size);
39 return p;
42 /* Print an expression for the size of "array" in bytes.
44 __isl_give isl_printer *gpu_array_info_print_size(__isl_take isl_printer *prn,
45 struct gpu_array_info *array)
47 int i;
49 for (i = 0; i < array->n_index; ++i) {
50 isl_ast_expr *bound;
52 prn = isl_printer_print_str(prn, "(");
53 bound = isl_ast_expr_get_op_arg(array->bound_expr, 1 + i);
54 prn = isl_printer_print_ast_expr(prn, bound);
55 isl_ast_expr_free(bound);
56 prn = isl_printer_print_str(prn, ") * ");
58 prn = isl_printer_print_str(prn, "sizeof(");
59 prn = isl_printer_print_str(prn, array->type);
60 prn = isl_printer_print_str(prn, ")");
62 return prn;
65 /* Print the declaration of a non-linearized array argument.
67 static __isl_give isl_printer *print_non_linearized_declaration_argument(
68 __isl_take isl_printer *p, struct gpu_array_info *array)
70 p = isl_printer_print_str(p, array->type);
71 p = isl_printer_print_str(p, " ");
73 p = isl_printer_print_ast_expr(p, array->bound_expr);
75 return p;
78 /* Print the declaration of an array argument.
79 * "memory_space" allows to specify a memory space prefix.
81 __isl_give isl_printer *gpu_array_info_print_declaration_argument(
82 __isl_take isl_printer *p, struct gpu_array_info *array,
83 const char *memory_space)
85 if (gpu_array_is_read_only_scalar(array)) {
86 p = isl_printer_print_str(p, array->type);
87 p = isl_printer_print_str(p, " ");
88 p = isl_printer_print_str(p, array->name);
89 return p;
92 if (memory_space) {
93 p = isl_printer_print_str(p, memory_space);
94 p = isl_printer_print_str(p, " ");
97 if (array->n_index != 0 && !array->linearize)
98 return print_non_linearized_declaration_argument(p, array);
100 p = isl_printer_print_str(p, array->type);
101 p = isl_printer_print_str(p, " ");
102 p = isl_printer_print_str(p, "*");
103 p = isl_printer_print_str(p, array->name);
105 return p;
108 /* Print the call of an array argument.
110 __isl_give isl_printer *gpu_array_info_print_call_argument(
111 __isl_take isl_printer *p, struct gpu_array_info *array)
113 if (gpu_array_is_read_only_scalar(array))
114 return isl_printer_print_str(p, array->name);
116 p = isl_printer_print_str(p, "dev_");
117 p = isl_printer_print_str(p, array->name);
119 return p;
122 /* Print an access to the element in the private/shared memory copy
123 * described by "stmt". The index of the copy is recorded in
124 * stmt->local_index as an access to the array.
126 static __isl_give isl_printer *stmt_print_local_index(__isl_take isl_printer *p,
127 struct ppcg_kernel_stmt *stmt)
129 return isl_printer_print_ast_expr(p, stmt->u.c.local_index);
132 /* Print an access to the element in the global memory copy
133 * described by "stmt". The index of the copy is recorded in
134 * stmt->index as an access to the array.
136 static __isl_give isl_printer *stmt_print_global_index(
137 __isl_take isl_printer *p, struct ppcg_kernel_stmt *stmt)
139 int i;
140 struct gpu_array_info *array = stmt->u.c.array;
141 struct gpu_local_array_info *local = stmt->u.c.local_array;
142 isl_ast_expr *index;
144 if (gpu_array_is_scalar(array)) {
145 if (!gpu_array_is_read_only_scalar(array))
146 p = isl_printer_print_str(p, "*");
147 p = isl_printer_print_str(p, array->name);
148 return p;
151 index = isl_ast_expr_copy(stmt->u.c.index);
153 p = isl_printer_print_ast_expr(p, index);
154 isl_ast_expr_free(index);
156 return p;
159 /* Print a copy statement.
161 * A read copy statement is printed as
163 * local = global;
165 * while a write copy statement is printed as
167 * global = local;
169 __isl_give isl_printer *ppcg_kernel_print_copy(__isl_take isl_printer *p,
170 struct ppcg_kernel_stmt *stmt)
172 p = isl_printer_start_line(p);
173 if (stmt->u.c.read) {
174 p = stmt_print_local_index(p, stmt);
175 p = isl_printer_print_str(p, " = ");
176 p = stmt_print_global_index(p, stmt);
177 } else {
178 p = stmt_print_global_index(p, stmt);
179 p = isl_printer_print_str(p, " = ");
180 p = stmt_print_local_index(p, stmt);
182 p = isl_printer_print_str(p, ";");
183 p = isl_printer_end_line(p);
185 return p;
188 __isl_give isl_printer *ppcg_kernel_print_domain(__isl_take isl_printer *p,
189 struct ppcg_kernel_stmt *stmt)
191 return pet_stmt_print_body(stmt->u.d.stmt->stmt, p, stmt->u.d.ref2expr);
194 /* This function is called for each node in a GPU AST.
195 * In case of a user node, print the macro definitions required
196 * for printing the AST expressions in the annotation, if any.
197 * For other nodes, return true such that descendants are also
198 * visited.
200 * In particular, for a kernel launch, print the macro definitions
201 * needed for the grid size.
202 * For a copy statement, print the macro definitions needed
203 * for the two index expressions.
204 * For an original user statement, print the macro definitions
205 * needed for the substitutions.
207 static isl_bool at_node(__isl_keep isl_ast_node *node, void *user)
209 const char *name;
210 isl_id *id;
211 int is_kernel;
212 struct ppcg_kernel *kernel;
213 struct ppcg_kernel_stmt *stmt;
214 isl_printer **p = user;
216 if (isl_ast_node_get_type(node) != isl_ast_node_user)
217 return isl_bool_true;
219 id = isl_ast_node_get_annotation(node);
220 if (!id)
221 return isl_bool_false;
223 name = isl_id_get_name(id);
224 if (!name)
225 return isl_bool_error;
226 is_kernel = !strcmp(name, "kernel");
227 kernel = is_kernel ? isl_id_get_user(id) : NULL;
228 stmt = is_kernel ? NULL : isl_id_get_user(id);
229 isl_id_free(id);
231 if ((is_kernel && !kernel) || (!is_kernel && !stmt))
232 return isl_bool_error;
234 if (is_kernel) {
235 *p = ppcg_ast_expr_print_macros(kernel->grid_size_expr, *p);
236 } else if (stmt->type == ppcg_kernel_copy) {
237 *p = ppcg_ast_expr_print_macros(stmt->u.c.index, *p);
238 *p = ppcg_ast_expr_print_macros(stmt->u.c.local_index, *p);
239 } else if (stmt->type == ppcg_kernel_domain) {
240 *p = ppcg_print_body_macros(*p, stmt->u.d.ref2expr);
242 if (!*p)
243 return isl_bool_error;
245 return isl_bool_false;
248 /* Print the required macros for the GPU AST "node" to "p",
249 * including those needed for the user statements inside the AST.
251 __isl_give isl_printer *gpu_print_macros(__isl_take isl_printer *p,
252 __isl_keep isl_ast_node *node)
254 if (isl_ast_node_foreach_descendant_top_down(node, &at_node, &p) < 0)
255 return isl_printer_free(p);
256 p = ppcg_print_macros(p, node);
257 return p;
260 /* Was the definition of "type" printed before?
261 * That is, does its name appear in the list of printed types "types"?
263 static int already_printed(struct gpu_types *types,
264 struct pet_type *type)
266 int i;
268 for (i = 0; i < types->n; ++i)
269 if (!strcmp(types->name[i], type->name))
270 return 1;
272 return 0;
275 /* Print the definitions of all types prog->scop that have not been
276 * printed before (according to "types") on "p".
277 * Extend the list of printed types "types" with the newly printed types.
279 __isl_give isl_printer *gpu_print_types(__isl_take isl_printer *p,
280 struct gpu_types *types, struct gpu_prog *prog)
282 int i, n;
283 isl_ctx *ctx;
284 char **name;
286 n = prog->scop->pet->n_type;
288 if (n == 0)
289 return p;
291 ctx = isl_printer_get_ctx(p);
292 name = isl_realloc_array(ctx, types->name, char *, types->n + n);
293 if (!name)
294 return isl_printer_free(p);
295 types->name = name;
297 for (i = 0; i < n; ++i) {
298 struct pet_type *type = prog->scop->pet->types[i];
300 if (already_printed(types, type))
301 continue;
303 p = isl_printer_start_line(p);
304 p = isl_printer_print_str(p, type->definition);
305 p = isl_printer_print_str(p, ";");
306 p = isl_printer_end_line(p);
308 types->name[types->n++] = strdup(type->name);
311 return p;