gpu_print: make linearization of fixed sized arrays optional
[ppcg.git] / gpu_print.c
bloba9aae29a22a0e1c22610d89f57c39d19a6c51bdd
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 <isl/aff.h>
12 #include "gpu_print.h"
13 #include "schedule.h"
15 static int print_macro(enum isl_ast_op_type type, void *user)
17 isl_printer **p = user;
19 if (type == isl_ast_op_fdiv_q)
20 return 0;
22 *p = isl_ast_op_type_print_macro(type, *p);
24 return 0;
27 /* Print the required macros for "node", including one for floord.
28 * We always print a macro for floord as it may also appear in the statements.
30 __isl_give isl_printer *gpu_print_macros(__isl_take isl_printer *p,
31 __isl_keep isl_ast_node *node)
33 p = isl_ast_op_type_print_macro(isl_ast_op_fdiv_q, p);
34 if (isl_ast_node_foreach_ast_op_type(node, &print_macro, &p) < 0)
35 return isl_printer_free(p);
36 return p;
39 /* Print an expression for the size of "array" in bytes.
41 __isl_give isl_printer *gpu_array_info_print_size(__isl_take isl_printer *prn,
42 struct gpu_array_info *array)
44 int i;
46 for (i = 0; i < array->n_index; ++i) {
47 prn = isl_printer_print_str(prn, "(");
48 prn = isl_printer_print_pw_aff(prn, array->bound[i]);
49 prn = isl_printer_print_str(prn, ") * ");
51 prn = isl_printer_print_str(prn, "sizeof(");
52 prn = isl_printer_print_str(prn, array->type);
53 prn = isl_printer_print_str(prn, ")");
55 return prn;
58 /* Print the declaration of a non-linearized array argument.
60 static __isl_give isl_printer *print_non_linearized_declaration_argument(
61 __isl_take isl_printer *p, struct gpu_array_info *array)
63 int i;
65 p = isl_printer_print_str(p, array->type);
66 p = isl_printer_print_str(p, " ");
68 p = isl_printer_print_str(p, array->name);
70 for (i = 0; i < array->n_index; i++) {
71 p = isl_printer_print_str(p, "[");
72 p = isl_printer_print_pw_aff(p, array->bound[i]);
73 p = isl_printer_print_str(p, "]");
76 return p;
79 /* Print the declaration of an array argument.
81 __isl_give isl_printer *gpu_array_info_print_declaration_argument(
82 __isl_take isl_printer *p, struct gpu_array_info *array)
84 if (gpu_array_is_read_only_scalar(array)) {
85 p = isl_printer_print_str(p, array->type);
86 p = isl_printer_print_str(p, " ");
87 p = isl_printer_print_str(p, array->name);
88 return p;
91 if (array->n_index != 0 && !array->linearize)
92 return print_non_linearized_declaration_argument(p, array);
94 p = isl_printer_print_str(p, array->type);
95 p = isl_printer_print_str(p, " ");
96 p = isl_printer_print_str(p, "*");
97 p = isl_printer_print_str(p, array->name);
99 return p;
102 /* Print the call of an array argument.
104 __isl_give isl_printer *gpu_array_info_print_call_argument(
105 __isl_take isl_printer *p, struct gpu_array_info *array)
107 if (gpu_array_is_read_only_scalar(array))
108 return isl_printer_print_str(p, array->name);
110 p = isl_printer_print_str(p, "dev_");
111 p = isl_printer_print_str(p, array->name);
113 return p;
116 /* Print an access to the element in the private/shared memory copy
117 * described by "stmt". The index of the copy is recorded in
118 * stmt->local_index as an access to the array.
120 static __isl_give isl_printer *stmt_print_local_index(__isl_take isl_printer *p,
121 struct ppcg_kernel_stmt *stmt)
123 return isl_printer_print_ast_expr(p, stmt->u.c.local_index);
126 /* Print an access to the element in the global memory copy
127 * described by "stmt". The index of the copy is recorded in
128 * stmt->index as an access to the array.
130 * The copy in global memory has been linearized, so we need to take
131 * the array size into account.
133 static __isl_give isl_printer *stmt_print_global_index(
134 __isl_take isl_printer *p, struct ppcg_kernel_stmt *stmt)
136 int i;
137 struct gpu_array_info *array = stmt->u.c.array;
138 struct gpu_local_array_info *local = stmt->u.c.local_array;
139 isl_ast_expr *index;
141 if (gpu_array_is_scalar(array)) {
142 if (!gpu_array_is_read_only_scalar(array))
143 p = isl_printer_print_str(p, "*");
144 p = isl_printer_print_str(p, array->name);
145 return p;
148 index = isl_ast_expr_copy(stmt->u.c.index);
149 if (array->linearize)
150 index = gpu_local_array_info_linearize_index(local, index);
152 p = isl_printer_print_ast_expr(p, index);
153 isl_ast_expr_free(index);
155 return p;
158 /* Print a copy statement.
160 * A read copy statement is printed as
162 * local = global;
164 * while a write copy statement is printed as
166 * global = local;
168 __isl_give isl_printer *ppcg_kernel_print_copy(__isl_take isl_printer *p,
169 struct ppcg_kernel_stmt *stmt)
171 p = isl_printer_start_line(p);
172 if (stmt->u.c.read) {
173 p = stmt_print_local_index(p, stmt);
174 p = isl_printer_print_str(p, " = ");
175 p = stmt_print_global_index(p, stmt);
176 } else {
177 p = stmt_print_global_index(p, stmt);
178 p = isl_printer_print_str(p, " = ");
179 p = stmt_print_local_index(p, stmt);
181 p = isl_printer_print_str(p, ";");
182 p = isl_printer_end_line(p);
184 return p;
187 __isl_give isl_printer *ppcg_kernel_print_domain(__isl_take isl_printer *p,
188 struct ppcg_kernel_stmt *stmt)
190 return pet_stmt_print_body(stmt->u.d.stmt->stmt, p, stmt->u.d.ref2expr);