ppcg.c: eliminate_dead_code: also intersect range of dataflow dependences
[ppcg.git] / gpu_print.c
blob2bf246bf54190bab4baa56f18006f152434cfd5e
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 "schedule.h"
17 static int print_macro(enum isl_ast_op_type type, void *user)
19 isl_printer **p = user;
21 if (type == isl_ast_op_fdiv_q)
22 return 0;
24 *p = isl_ast_op_type_print_macro(type, *p);
26 return 0;
29 /* Print the required macros for "node", including one for floord.
30 * We always print a macro for floord as it may also appear in the statements.
32 __isl_give isl_printer *gpu_print_macros(__isl_take isl_printer *p,
33 __isl_keep isl_ast_node *node)
35 p = isl_ast_op_type_print_macro(isl_ast_op_fdiv_q, p);
36 if (isl_ast_node_foreach_ast_op_type(node, &print_macro, &p) < 0)
37 return isl_printer_free(p);
38 return p;
41 /* Print an expression for the size of "array" in bytes.
43 __isl_give isl_printer *gpu_array_info_print_size(__isl_take isl_printer *prn,
44 struct gpu_array_info *array)
46 int i;
48 for (i = 0; i < array->n_index; ++i) {
49 prn = isl_printer_print_str(prn, "(");
50 prn = isl_printer_print_pw_aff(prn, array->bound[i]);
51 prn = isl_printer_print_str(prn, ") * ");
53 prn = isl_printer_print_str(prn, "sizeof(");
54 prn = isl_printer_print_str(prn, array->type);
55 prn = isl_printer_print_str(prn, ")");
57 return prn;
60 /* Print the declaration of a non-linearized array argument.
62 static __isl_give isl_printer *print_non_linearized_declaration_argument(
63 __isl_take isl_printer *p, struct gpu_array_info *array)
65 int i;
67 p = isl_printer_print_str(p, array->type);
68 p = isl_printer_print_str(p, " ");
70 p = isl_printer_print_str(p, array->name);
72 for (i = 0; i < array->n_index; i++) {
73 p = isl_printer_print_str(p, "[");
74 p = isl_printer_print_pw_aff(p, array->bound[i]);
75 p = isl_printer_print_str(p, "]");
78 return p;
81 /* Print the declaration of an array argument.
82 * "memory_space" allows to specify a memory space prefix.
84 __isl_give isl_printer *gpu_array_info_print_declaration_argument(
85 __isl_take isl_printer *p, struct gpu_array_info *array,
86 const char *memory_space)
88 if (gpu_array_is_read_only_scalar(array)) {
89 p = isl_printer_print_str(p, array->type);
90 p = isl_printer_print_str(p, " ");
91 p = isl_printer_print_str(p, array->name);
92 return p;
95 if (memory_space) {
96 p = isl_printer_print_str(p, memory_space);
97 p = isl_printer_print_str(p, " ");
100 if (array->n_index != 0 && !array->linearize)
101 return print_non_linearized_declaration_argument(p, array);
103 p = isl_printer_print_str(p, array->type);
104 p = isl_printer_print_str(p, " ");
105 p = isl_printer_print_str(p, "*");
106 p = isl_printer_print_str(p, array->name);
108 return p;
111 /* Print the call of an array argument.
113 __isl_give isl_printer *gpu_array_info_print_call_argument(
114 __isl_take isl_printer *p, struct gpu_array_info *array)
116 if (gpu_array_is_read_only_scalar(array))
117 return isl_printer_print_str(p, array->name);
119 p = isl_printer_print_str(p, "dev_");
120 p = isl_printer_print_str(p, array->name);
122 return p;
125 /* Print an access to the element in the private/shared memory copy
126 * described by "stmt". The index of the copy is recorded in
127 * stmt->local_index as an access to the array.
129 static __isl_give isl_printer *stmt_print_local_index(__isl_take isl_printer *p,
130 struct ppcg_kernel_stmt *stmt)
132 return isl_printer_print_ast_expr(p, stmt->u.c.local_index);
135 /* Print an access to the element in the global memory copy
136 * described by "stmt". The index of the copy is recorded in
137 * stmt->index as an access to the array.
139 * The copy in global memory has been linearized, so we need to take
140 * the array size into account.
142 static __isl_give isl_printer *stmt_print_global_index(
143 __isl_take isl_printer *p, struct ppcg_kernel_stmt *stmt)
145 int i;
146 struct gpu_array_info *array = stmt->u.c.array;
147 struct gpu_local_array_info *local = stmt->u.c.local_array;
148 isl_ast_expr *index;
150 if (gpu_array_is_scalar(array)) {
151 if (!gpu_array_is_read_only_scalar(array))
152 p = isl_printer_print_str(p, "*");
153 p = isl_printer_print_str(p, array->name);
154 return p;
157 index = isl_ast_expr_copy(stmt->u.c.index);
158 if (array->linearize)
159 index = gpu_local_array_info_linearize_index(local, index);
161 p = isl_printer_print_ast_expr(p, index);
162 isl_ast_expr_free(index);
164 return p;
167 /* Print a copy statement.
169 * A read copy statement is printed as
171 * local = global;
173 * while a write copy statement is printed as
175 * global = local;
177 __isl_give isl_printer *ppcg_kernel_print_copy(__isl_take isl_printer *p,
178 struct ppcg_kernel_stmt *stmt)
180 p = isl_printer_start_line(p);
181 if (stmt->u.c.read) {
182 p = stmt_print_local_index(p, stmt);
183 p = isl_printer_print_str(p, " = ");
184 p = stmt_print_global_index(p, stmt);
185 } else {
186 p = stmt_print_global_index(p, stmt);
187 p = isl_printer_print_str(p, " = ");
188 p = stmt_print_local_index(p, stmt);
190 p = isl_printer_print_str(p, ";");
191 p = isl_printer_end_line(p);
193 return p;
196 __isl_give isl_printer *ppcg_kernel_print_domain(__isl_take isl_printer *p,
197 struct ppcg_kernel_stmt *stmt)
199 return pet_stmt_print_body(stmt->u.d.stmt->stmt, p, stmt->u.d.ref2expr);
202 /* Was the definition of "type" printed before?
203 * That is, does its name appear in the list of printed types "types"?
205 static int already_printed(struct gpu_types *types,
206 struct pet_type *type)
208 int i;
210 for (i = 0; i < types->n; ++i)
211 if (!strcmp(types->name[i], type->name))
212 return 1;
214 return 0;
217 /* Print the definitions of all types prog->scop that have not been
218 * printed before (according to "types") on "p".
219 * Extend the list of printed types "types" with the newly printed types.
221 __isl_give isl_printer *gpu_print_types(__isl_take isl_printer *p,
222 struct gpu_types *types, struct gpu_prog *prog)
224 int i, n;
225 isl_ctx *ctx;
226 char **name;
228 n = prog->scop->pet->n_type;
230 if (n == 0)
231 return p;
233 ctx = isl_printer_get_ctx(p);
234 name = isl_realloc_array(ctx, types->name, char *, types->n + n);
235 if (!name)
236 return isl_printer_free(p);
237 types->name = name;
239 for (i = 0; i < n; ++i) {
240 struct pet_type *type = prog->scop->pet->types[i];
242 if (already_printed(types, type))
243 continue;
245 p = isl_printer_start_line(p);
246 p = isl_printer_print_str(p, type->definition);
247 p = isl_printer_print_str(p, ";");
248 p = isl_printer_end_line(p);
250 types->name[types->n++] = strdup(type->name);
253 return p;