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"
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
)
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
)
34 p
= ppcg_print_declaration(p
, prog
->scop
->pet
->arrays
[i
],
37 isl_ast_build_free(build
);
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
)
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
, ")");
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
)
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
, "]");
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
);
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
);
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
);
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
)
147 struct gpu_array_info
*array
= stmt
->u
.c
.array
;
148 struct gpu_local_array_info
*local
= stmt
->u
.c
.local_array
;
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
);
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
);
168 /* Print a copy statement.
170 * A read copy statement is printed as
174 * while a write copy statement is printed as
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
);
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
);
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
)
211 for (i
= 0; i
< types
->n
; ++i
)
212 if (!strcmp(types
->name
[i
], type
->name
))
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
)
229 n
= prog
->scop
->pet
->n_type
;
234 ctx
= isl_printer_get_ctx(p
);
235 name
= isl_realloc_array(ctx
, types
->name
, char *, types
->n
+ n
);
237 return isl_printer_free(p
);
240 for (i
= 0; i
< n
; ++i
) {
241 struct pet_type
*type
= prog
->scop
->pet
->types
[i
];
243 if (already_printed(types
, type
))
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
);