2 * Copyright 2012-2013 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
11 #include <isl/ast_build.h>
16 __isl_give isl_printer
*ppcg_start_block(__isl_take isl_printer
*p
)
18 p
= isl_printer_start_line(p
);
19 p
= isl_printer_print_str(p
, "{");
20 p
= isl_printer_end_line(p
);
21 p
= isl_printer_indent(p
, 2);
25 __isl_give isl_printer
*ppcg_end_block(__isl_take isl_printer
*p
)
27 p
= isl_printer_indent(p
, -2);
28 p
= isl_printer_start_line(p
);
29 p
= isl_printer_print_str(p
, "}");
30 p
= isl_printer_end_line(p
);
34 static int print_macro(enum isl_ast_op_type type
, void *user
)
36 isl_printer
**p
= user
;
38 if (type
== isl_ast_op_fdiv_q
)
41 *p
= isl_ast_op_type_print_macro(type
, *p
);
46 /* Print the required macros for "node", except one for floord.
47 * The caller is assumed to have printed a macro for floord already
48 * as it may also appear in the declarations and the statements.
50 __isl_give isl_printer
*ppcg_print_macros(__isl_take isl_printer
*p
,
51 __isl_keep isl_ast_node
*node
)
53 if (isl_ast_node_foreach_ast_op_type(node
, &print_macro
, &p
) < 0)
54 return isl_printer_free(p
);
58 /* Names used for the macros that may appear in a printed isl AST.
60 const char *ppcg_min
= "ppcg_min";
61 const char *ppcg_max
= "ppcg_max";
62 const char *ppcg_fdiv_q
= "ppcg_fdiv_q";
64 /* Set the names of the macros that may appear in a printed isl AST.
66 __isl_give isl_printer
*ppcg_set_macro_names(__isl_take isl_printer
*p
)
68 p
= isl_ast_op_type_set_print_name(p
, isl_ast_op_min
, ppcg_min
);
69 p
= isl_ast_op_type_set_print_name(p
, isl_ast_op_max
, ppcg_max
);
70 p
= isl_ast_op_type_set_print_name(p
, isl_ast_op_fdiv_q
, ppcg_fdiv_q
);
75 /* Given a multi affine expression "mpa" without domain, modify it to have
76 * the schedule space of "build" as domain.
78 * If the schedule space of "build" is a parameter space, then nothing
80 * Otherwise, "mpa" is first given a 0D domain and then it is combined
81 * with a mapping from the schedule space of "build" to the same 0D domain.
83 __isl_give isl_multi_pw_aff
*ppcg_attach_multi_pw_aff(
84 __isl_take isl_multi_pw_aff
*mpa
, __isl_keep isl_ast_build
*build
)
90 space
= isl_ast_build_get_schedule_space(build
);
91 params
= isl_space_is_params(space
);
92 if (params
< 0 || params
) {
93 isl_space_free(space
);
95 return isl_multi_pw_aff_free(mpa
);
98 space
= isl_space_from_domain(space
);
99 ma
= isl_multi_aff_zero(space
);
100 mpa
= isl_multi_pw_aff_from_range(mpa
);
101 mpa
= isl_multi_pw_aff_pullback_multi_aff(mpa
, ma
);
106 /* Build an access AST expression from "size" using "build".
107 * "size" does not have a domain, but "build" may have a proper schedule space.
108 * First modify "size" to have that schedule space as domain.
110 __isl_give isl_ast_expr
*ppcg_build_size_expr(__isl_take isl_multi_pw_aff
*size
,
111 __isl_keep isl_ast_build
*build
)
113 size
= ppcg_attach_multi_pw_aff(size
, build
);
114 return isl_ast_build_access_from_multi_pw_aff(build
, size
);
117 /* Print a declaration for array "array" with size "size" to "p".
119 __isl_give isl_printer
*ppcg_print_declaration_with_size(
120 __isl_take isl_printer
*p
, struct pet_array
*array
,
121 __isl_keep isl_ast_expr
*size
)
124 return isl_printer_free(p
);
126 p
= isl_printer_start_line(p
);
127 p
= isl_printer_print_str(p
, array
->element_type
);
128 p
= isl_printer_print_str(p
, " ");
129 p
= isl_printer_print_ast_expr(p
, size
);
130 p
= isl_printer_print_str(p
, ";");
131 p
= isl_printer_end_line(p
);
136 /* Print a declaration for array "array" to "p", using "build"
137 * to simplify any size expressions.
139 * The size is computed from the extent of the array and is
140 * subsequently converted to an "access expression" by "build".
142 __isl_give isl_printer
*ppcg_print_declaration(__isl_take isl_printer
*p
,
143 struct pet_array
*array
, __isl_keep isl_ast_build
*build
)
145 isl_multi_pw_aff
*size
;
149 return isl_printer_free(p
);
151 size
= ppcg_size_from_extent(isl_set_copy(array
->extent
));
152 expr
= isl_ast_build_access_from_multi_pw_aff(build
, size
);
153 p
= ppcg_print_declaration_with_size(p
, array
, expr
);
154 isl_ast_expr_free(expr
);
159 /* Print declarations for the arrays in "scop" that are declared
160 * and that are exposed (if exposed == 1) or not exposed (if exposed == 0).
162 static __isl_give isl_printer
*print_declarations(__isl_take isl_printer
*p
,
163 struct ppcg_scop
*scop
, int exposed
)
166 isl_ast_build
*build
;
169 return isl_printer_free(p
);
171 build
= isl_ast_build_from_context(isl_set_copy(scop
->context
));
172 for (i
= 0; i
< scop
->pet
->n_array
; ++i
) {
173 struct pet_array
*array
= scop
->pet
->arrays
[i
];
175 if (!array
->declared
)
177 if (array
->exposed
!= exposed
)
180 p
= ppcg_print_declaration(p
, array
, build
);
182 isl_ast_build_free(build
);
187 /* Print declarations for the arrays in "scop" that are declared
188 * and exposed to the code after the scop.
190 __isl_give isl_printer
*ppcg_print_exposed_declarations(
191 __isl_take isl_printer
*p
, struct ppcg_scop
*scop
)
193 return print_declarations(p
, scop
, 1);
196 /* Print declarations for the arrays in "scop" that are declared,
197 * but not exposed to the code after the scop.
199 __isl_give isl_printer
*ppcg_print_hidden_declarations(
200 __isl_take isl_printer
*p
, struct ppcg_scop
*scop
)
202 return print_declarations(p
, scop
, 0);