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
12 #include "gpu_print.h"
13 #include "pet_printer.h"
16 static int print_macro(enum isl_ast_op_type type
, void *user
)
18 isl_printer
**p
= user
;
20 if (type
== isl_ast_op_fdiv_q
)
23 *p
= isl_ast_op_type_print_macro(type
, *p
);
28 /* Print the required macros for "node", including one for floord.
29 * We always print a macro for floord as it may also appear in the statements.
31 __isl_give isl_printer
*gpu_print_macros(__isl_take isl_printer
*p
,
32 __isl_keep isl_ast_node
*node
)
34 p
= isl_ast_op_type_print_macro(isl_ast_op_fdiv_q
, p
);
35 if (isl_ast_node_foreach_ast_op_type(node
, &print_macro
, &p
) < 0)
36 return isl_printer_free(p
);
40 /* Print an expression for the size of "array" in bytes.
42 __isl_give isl_printer
*gpu_array_info_print_size(__isl_take isl_printer
*prn
,
43 struct gpu_array_info
*array
)
47 for (i
= 0; i
< array
->n_index
; ++i
) {
48 prn
= isl_printer_print_str(prn
, "(");
49 prn
= isl_printer_print_pw_aff(prn
, array
->bound
[i
]);
50 prn
= isl_printer_print_str(prn
, ") * ");
52 prn
= isl_printer_print_str(prn
, "sizeof(");
53 prn
= isl_printer_print_str(prn
, array
->type
);
54 prn
= isl_printer_print_str(prn
, ")");
59 /* Print an access to the element in the private/shared memory copy
60 * described by "stmt". The index of the copy is recorded in
61 * stmt->local_index as a "call" to the array.
63 static __isl_give isl_printer
*stmt_print_local_index(__isl_take isl_printer
*p
,
64 struct ppcg_kernel_stmt
*stmt
)
68 struct gpu_array_info
*array
= stmt
->u
.c
.array
;
70 expr
= isl_ast_expr_get_op_arg(stmt
->u
.c
.local_index
, 0);
71 p
= isl_printer_print_ast_expr(p
, expr
);
72 isl_ast_expr_free(expr
);
74 for (i
= 0; i
< array
->n_index
; ++i
) {
75 expr
= isl_ast_expr_get_op_arg(stmt
->u
.c
.local_index
, 1 + i
);
77 p
= isl_printer_print_str(p
, "[");
78 p
= isl_printer_print_ast_expr(p
, expr
);
79 p
= isl_printer_print_str(p
, "]");
81 isl_ast_expr_free(expr
);
87 /* Print an access to the element in the global memory copy
88 * described by "stmt". The index of the copy is recorded in
89 * stmt->index as a "call" to the array.
91 * The copy in global memory has been linearized, so we need to take
92 * the array size into account.
94 static __isl_give isl_printer
*stmt_print_global_index(
95 __isl_take isl_printer
*p
, struct ppcg_kernel_stmt
*stmt
)
98 struct gpu_array_info
*array
= stmt
->u
.c
.array
;
99 isl_pw_aff_list
*bound
= stmt
->u
.c
.local_array
->bound
;
101 if (gpu_array_is_scalar(array
)) {
102 if (!array
->read_only
)
103 p
= isl_printer_print_str(p
, "*");
104 p
= isl_printer_print_str(p
, array
->name
);
108 p
= isl_printer_print_str(p
, array
->name
);
109 p
= isl_printer_print_str(p
, "[");
110 for (i
= 0; i
+ 1 < array
->n_index
; ++i
)
111 p
= isl_printer_print_str(p
, "(");
112 for (i
= 0; i
< array
->n_index
; ++i
) {
114 expr
= isl_ast_expr_get_op_arg(stmt
->u
.c
.index
, 1 + i
);
117 bound_i
= isl_pw_aff_list_get_pw_aff(bound
, i
);
118 p
= isl_printer_print_str(p
, ") * (");
119 p
= isl_printer_print_pw_aff(p
, bound_i
);
120 p
= isl_printer_print_str(p
, ") + (");
121 isl_pw_aff_free(bound_i
);
123 p
= isl_printer_print_ast_expr(p
, expr
);
125 p
= isl_printer_print_str(p
, ")");
126 isl_ast_expr_free(expr
);
128 p
= isl_printer_print_str(p
, "]");
133 /* Print a copy statement.
135 * A read copy statement is printed as
139 * while a write copy statement is printed as
143 __isl_give isl_printer
*ppcg_kernel_print_copy(__isl_take isl_printer
*p
,
144 struct ppcg_kernel_stmt
*stmt
)
146 p
= isl_printer_start_line(p
);
147 if (stmt
->u
.c
.read
) {
148 p
= stmt_print_local_index(p
, stmt
);
149 p
= isl_printer_print_str(p
, " = ");
150 p
= stmt_print_global_index(p
, stmt
);
152 p
= stmt_print_global_index(p
, stmt
);
153 p
= isl_printer_print_str(p
, " = ");
154 p
= stmt_print_local_index(p
, stmt
);
156 p
= isl_printer_print_str(p
, ";");
157 p
= isl_printer_end_line(p
);
162 /* Print an access based on the information in "access".
163 * If this an access to global memory, then the index expression
166 * If access->array is NULL, then we are
167 * accessing an iterator in the original program.
169 static __isl_give isl_printer
*print_access(__isl_take isl_printer
*p
,
170 struct ppcg_kernel_access
*access
)
174 struct gpu_array_info
*array
;
175 isl_pw_aff_list
*bound
;
177 array
= access
->array
;
178 bound
= array
? access
->local_array
->bound
: NULL
;
180 p
= isl_printer_print_str(p
, "(");
182 if (access
->type
== ppcg_access_global
&&
183 gpu_array_is_scalar(array
) && !array
->read_only
)
184 p
= isl_printer_print_str(p
, "*");
185 p
= isl_printer_print_str(p
, access
->local_name
);
186 if (gpu_array_is_scalar(array
))
188 p
= isl_printer_print_str(p
, "[");
191 n_index
= isl_ast_expr_list_n_ast_expr(access
->index
);
192 if (access
->type
== ppcg_access_global
)
193 for (i
= 0; i
+ 1 < n_index
; ++i
)
194 p
= isl_printer_print_str(p
, "(");
196 for (i
= 0; i
< n_index
; ++i
) {
199 index
= isl_ast_expr_list_get_ast_expr(access
->index
, i
);
201 if (access
->type
== ppcg_access_global
) {
203 bound_i
= isl_pw_aff_list_get_pw_aff(bound
, i
);
204 p
= isl_printer_print_str(p
, ") * (");
205 p
= isl_printer_print_pw_aff(p
, bound_i
);
206 p
= isl_printer_print_str(p
, ") + ");
207 isl_pw_aff_free(bound_i
);
209 p
= isl_printer_print_str(p
, "][");
211 p
= isl_printer_print_ast_expr(p
, index
);
212 isl_ast_expr_free(index
);
215 p
= isl_printer_print_str(p
, ")");
217 p
= isl_printer_print_str(p
, "]");
222 struct gpu_access_print_info
{
224 struct ppcg_kernel_stmt
*stmt
;
227 /* To print the gpu accesses we walk the list of gpu accesses simultaneously
228 * with the pet printer. This means that whenever the pet printer prints a
229 * pet access expression we have the corresponding gpu access available and can
230 * print the modified access.
232 static __isl_give isl_printer
*print_gpu_access(__isl_take isl_printer
*p
,
233 struct pet_expr
*expr
, void *usr
)
235 struct gpu_access_print_info
*info
=
236 (struct gpu_access_print_info
*) usr
;
238 p
= print_access(p
, &info
->stmt
->u
.d
.access
[info
->i
]);
244 __isl_give isl_printer
*ppcg_kernel_print_domain(__isl_take isl_printer
*p
,
245 struct ppcg_kernel_stmt
*stmt
)
247 struct gpu_access_print_info info
;
252 p
= isl_printer_start_line(p
);
253 p
= print_pet_expr(p
, stmt
->u
.d
.stmt
->body
, &print_gpu_access
, &info
);
254 p
= isl_printer_print_str(p
, ";");
255 p
= isl_printer_end_line(p
);