update pet for killing temporary variables declared outside scop
[ppcg.git] / gpu_print.c
blobd7c83f6fbabc85b00a69670f5bc8ab141c37317d
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;
25 isl_ast_build *build;
27 if (!prog)
28 return isl_printer_free(p);
30 build = isl_ast_build_from_context(isl_set_copy(prog->scop->context));
31 for (i = 0; i < prog->n_array; ++i) {
32 if (!prog->array[i].declare_local)
33 continue;
34 p = ppcg_print_declaration(p, prog->scop->pet->arrays[i],
35 build);
37 isl_ast_build_free(build);
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 prn = isl_printer_print_str(prn, "(");
51 prn = isl_printer_print_pw_aff(prn, array->bound[i]);
52 prn = isl_printer_print_str(prn, ") * ");
54 prn = isl_printer_print_str(prn, "sizeof(");
55 prn = isl_printer_print_str(prn, array->type);
56 prn = isl_printer_print_str(prn, ")");
58 return prn;
61 /* Print the declaration of a non-linearized array argument.
63 static __isl_give isl_printer *print_non_linearized_declaration_argument(
64 __isl_take isl_printer *p, struct gpu_array_info *array)
66 int i;
68 p = isl_printer_print_str(p, array->type);
69 p = isl_printer_print_str(p, " ");
71 p = isl_printer_print_str(p, array->name);
73 for (i = 0; i < array->n_index; i++) {
74 p = isl_printer_print_str(p, "[");
75 p = isl_printer_print_pw_aff(p, array->bound[i]);
76 p = isl_printer_print_str(p, "]");
79 return p;
82 /* Print the declaration of an array argument.
83 * "memory_space" allows to specify a memory space prefix.
85 __isl_give isl_printer *gpu_array_info_print_declaration_argument(
86 __isl_take isl_printer *p, struct gpu_array_info *array,
87 const char *memory_space)
89 if (gpu_array_is_read_only_scalar(array)) {
90 p = isl_printer_print_str(p, array->type);
91 p = isl_printer_print_str(p, " ");
92 p = isl_printer_print_str(p, array->name);
93 return p;
96 if (memory_space) {
97 p = isl_printer_print_str(p, memory_space);
98 p = isl_printer_print_str(p, " ");
101 if (array->n_index != 0 && !array->linearize)
102 return print_non_linearized_declaration_argument(p, array);
104 p = isl_printer_print_str(p, array->type);
105 p = isl_printer_print_str(p, " ");
106 p = isl_printer_print_str(p, "*");
107 p = isl_printer_print_str(p, array->name);
109 return p;
112 /* Print the call of an array argument.
114 __isl_give isl_printer *gpu_array_info_print_call_argument(
115 __isl_take isl_printer *p, struct gpu_array_info *array)
117 if (gpu_array_is_read_only_scalar(array))
118 return isl_printer_print_str(p, array->name);
120 p = isl_printer_print_str(p, "dev_");
121 p = isl_printer_print_str(p, array->name);
123 return p;
126 /* Print an access to the element in the private/shared memory copy
127 * described by "stmt". The index of the copy is recorded in
128 * stmt->local_index as an access to the array.
130 static __isl_give isl_printer *stmt_print_local_index(__isl_take isl_printer *p,
131 struct ppcg_kernel_stmt *stmt)
133 return isl_printer_print_ast_expr(p, stmt->u.c.local_index);
136 /* Print an access to the element in the global memory copy
137 * described by "stmt". The index of the copy is recorded in
138 * stmt->index as an access to the array.
140 * The copy in global memory has been linearized, so we need to take
141 * the array size into account.
143 static __isl_give isl_printer *stmt_print_global_index(
144 __isl_take isl_printer *p, struct ppcg_kernel_stmt *stmt)
146 int i;
147 struct gpu_array_info *array = stmt->u.c.array;
148 struct gpu_local_array_info *local = stmt->u.c.local_array;
149 isl_ast_expr *index;
151 if (gpu_array_is_scalar(array)) {
152 if (!gpu_array_is_read_only_scalar(array))
153 p = isl_printer_print_str(p, "*");
154 p = isl_printer_print_str(p, array->name);
155 return p;
158 index = isl_ast_expr_copy(stmt->u.c.index);
159 if (array->linearize)
160 index = gpu_local_array_info_linearize_index(local, index);
162 p = isl_printer_print_ast_expr(p, index);
163 isl_ast_expr_free(index);
165 return p;
168 /* Print a copy statement.
170 * A read copy statement is printed as
172 * local = global;
174 * while a write copy statement is printed as
176 * global = local;
178 __isl_give isl_printer *ppcg_kernel_print_copy(__isl_take isl_printer *p,
179 struct ppcg_kernel_stmt *stmt)
181 p = isl_printer_start_line(p);
182 if (stmt->u.c.read) {
183 p = stmt_print_local_index(p, stmt);
184 p = isl_printer_print_str(p, " = ");
185 p = stmt_print_global_index(p, stmt);
186 } else {
187 p = stmt_print_global_index(p, stmt);
188 p = isl_printer_print_str(p, " = ");
189 p = stmt_print_local_index(p, stmt);
191 p = isl_printer_print_str(p, ";");
192 p = isl_printer_end_line(p);
194 return p;
197 __isl_give isl_printer *ppcg_kernel_print_domain(__isl_take isl_printer *p,
198 struct ppcg_kernel_stmt *stmt)
200 return pet_stmt_print_body(stmt->u.d.stmt->stmt, p, stmt->u.d.ref2expr);
203 /* Was the definition of "type" printed before?
204 * That is, does its name appear in the list of printed types "types"?
206 static int already_printed(struct gpu_types *types,
207 struct pet_type *type)
209 int i;
211 for (i = 0; i < types->n; ++i)
212 if (!strcmp(types->name[i], type->name))
213 return 1;
215 return 0;
218 /* Print the definitions of all types prog->scop that have not been
219 * printed before (according to "types") on "p".
220 * Extend the list of printed types "types" with the newly printed types.
222 __isl_give isl_printer *gpu_print_types(__isl_take isl_printer *p,
223 struct gpu_types *types, struct gpu_prog *prog)
225 int i, n;
226 isl_ctx *ctx;
227 char **name;
229 n = prog->scop->pet->n_type;
231 if (n == 0)
232 return p;
234 ctx = isl_printer_get_ctx(p);
235 name = isl_realloc_array(ctx, types->name, char *, types->n + n);
236 if (!name)
237 return isl_printer_free(p);
238 types->name = name;
240 for (i = 0; i < n; ++i) {
241 struct pet_type *type = prog->scop->pet->types[i];
243 if (already_printed(types, type))
244 continue;
246 p = isl_printer_start_line(p);
247 p = isl_printer_print_str(p, type->definition);
248 p = isl_printer_print_str(p, ";");
249 p = isl_printer_end_line(p);
251 types->name[types->n++] = strdup(type->name);
254 return p;