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
14 #include "gpu_print.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
)
24 *p
= isl_ast_op_type_print_macro(type
, *p
);
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
);
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
)
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
, ")");
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
)
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
, "]");
81 /* Print the declaration of an array argument.
83 __isl_give isl_printer
*gpu_array_info_print_declaration_argument(
84 __isl_take isl_printer
*p
, struct gpu_array_info
*array
)
86 if (gpu_array_is_read_only_scalar(array
)) {
87 p
= isl_printer_print_str(p
, array
->type
);
88 p
= isl_printer_print_str(p
, " ");
89 p
= isl_printer_print_str(p
, array
->name
);
93 if (array
->n_index
!= 0 && !array
->linearize
)
94 return print_non_linearized_declaration_argument(p
, array
);
96 p
= isl_printer_print_str(p
, array
->type
);
97 p
= isl_printer_print_str(p
, " ");
98 p
= isl_printer_print_str(p
, "*");
99 p
= isl_printer_print_str(p
, array
->name
);
104 /* Print the call of an array argument.
106 __isl_give isl_printer
*gpu_array_info_print_call_argument(
107 __isl_take isl_printer
*p
, struct gpu_array_info
*array
)
109 if (gpu_array_is_read_only_scalar(array
))
110 return isl_printer_print_str(p
, array
->name
);
112 p
= isl_printer_print_str(p
, "dev_");
113 p
= isl_printer_print_str(p
, array
->name
);
118 /* Print an access to the element in the private/shared memory copy
119 * described by "stmt". The index of the copy is recorded in
120 * stmt->local_index as an access to the array.
122 static __isl_give isl_printer
*stmt_print_local_index(__isl_take isl_printer
*p
,
123 struct ppcg_kernel_stmt
*stmt
)
125 return isl_printer_print_ast_expr(p
, stmt
->u
.c
.local_index
);
128 /* Print an access to the element in the global memory copy
129 * described by "stmt". The index of the copy is recorded in
130 * stmt->index as an access to the array.
132 * The copy in global memory has been linearized, so we need to take
133 * the array size into account.
135 static __isl_give isl_printer
*stmt_print_global_index(
136 __isl_take isl_printer
*p
, struct ppcg_kernel_stmt
*stmt
)
139 struct gpu_array_info
*array
= stmt
->u
.c
.array
;
140 struct gpu_local_array_info
*local
= stmt
->u
.c
.local_array
;
143 if (gpu_array_is_scalar(array
)) {
144 if (!gpu_array_is_read_only_scalar(array
))
145 p
= isl_printer_print_str(p
, "*");
146 p
= isl_printer_print_str(p
, array
->name
);
150 index
= isl_ast_expr_copy(stmt
->u
.c
.index
);
151 if (array
->linearize
)
152 index
= gpu_local_array_info_linearize_index(local
, index
);
154 p
= isl_printer_print_ast_expr(p
, index
);
155 isl_ast_expr_free(index
);
160 /* Print a copy statement.
162 * A read copy statement is printed as
166 * while a write copy statement is printed as
170 __isl_give isl_printer
*ppcg_kernel_print_copy(__isl_take isl_printer
*p
,
171 struct ppcg_kernel_stmt
*stmt
)
173 p
= isl_printer_start_line(p
);
174 if (stmt
->u
.c
.read
) {
175 p
= stmt_print_local_index(p
, stmt
);
176 p
= isl_printer_print_str(p
, " = ");
177 p
= stmt_print_global_index(p
, stmt
);
179 p
= stmt_print_global_index(p
, stmt
);
180 p
= isl_printer_print_str(p
, " = ");
181 p
= stmt_print_local_index(p
, stmt
);
183 p
= isl_printer_print_str(p
, ";");
184 p
= isl_printer_end_line(p
);
189 __isl_give isl_printer
*ppcg_kernel_print_domain(__isl_take isl_printer
*p
,
190 struct ppcg_kernel_stmt
*stmt
)
192 return pet_stmt_print_body(stmt
->u
.d
.stmt
->stmt
, p
, stmt
->u
.d
.ref2expr
);
195 /* Was the definition of "type" printed before?
196 * That is, does its name appear in the list of printed types "types"?
198 static int already_printed(struct gpu_types
*types
,
199 struct pet_type
*type
)
203 for (i
= 0; i
< types
->n
; ++i
)
204 if (!strcmp(types
->name
[i
], type
->name
))
210 /* Print the definitions of all types prog->scop that have not been
211 * printed before (according to "types") on "p".
212 * Extend the list of printed types "types" with the newly printed types.
214 __isl_give isl_printer
*gpu_print_types(__isl_take isl_printer
*p
,
215 struct gpu_types
*types
, struct gpu_prog
*prog
)
221 n
= prog
->scop
->n_type
;
226 ctx
= isl_printer_get_ctx(p
);
227 name
= isl_realloc_array(ctx
, types
->name
, char *, types
->n
+ n
);
229 return isl_printer_free(p
);
232 for (i
= 0; i
< n
; ++i
) {
233 struct pet_type
*type
= prog
->scop
->types
[i
];
235 if (already_printed(types
, type
))
238 p
= isl_printer_start_line(p
);
239 p
= isl_printer_print_str(p
, type
->definition
);
240 p
= isl_printer_print_str(p
, ";");
241 p
= isl_printer_end_line(p
);
243 types
->name
[types
->n
++] = strdup(type
->name
);