1 #ifndef ISL_AST_BUILD_PRIVATE_H
2 #define ISL_AST_BUILD_PRIVATE_H
6 #include <isl/ast_build.h>
9 #include <isl/schedule_node.h>
11 /* An isl_ast_build represents the context in which AST is being
12 * generated. That is, it (mostly) contains information about outer
13 * loops that can be used to simplify inner loops.
15 * "domain" represents constraints on the internal schedule domain,
16 * corresponding to the context of the AST generation and the constraints
17 * implied by the loops that have already been generated.
18 * When an isl_ast_build is first created, outside any AST generation,
19 * the domain is typically a parameter set. It is only when a AST
20 * generation phase is initiated that the domain of the isl_ast_build
21 * is changed to refer to the internal schedule domain.
22 * The domain then lives in a space of the form
30 * O represents the loops generated in outer AST generations.
31 * S represents the loops (both generated and to be generated)
32 * of the current AST generation.
33 * Both include eliminated loops.
34 * "domain" is expected not to have any unknown divs because
35 * it is used as the context argument in a call to isl_basic_set_gist
36 * in isl_ast_build_compute_gist_basic_set.
38 * "depth" is equal to the number of loops that have already
39 * been generated (including those in outer AST generations).
40 * "outer_pos" is equal to the number of loops in outer AST generations.
42 * "generated" is a superset of "domain" corresponding to those
43 * constraints that were either given by the user or that have
44 * effectively been generated (as bounds on a for loop).
46 * "pending" is a superset of "domain" corresponding to the constraints
47 * that still need to be generated (as guards), but that may end up
48 * not getting generated if they are implied by any constraints
49 * enforced by inner loops.
51 * "strides" contains the stride of each loop. The number of elements
52 * is equal to the number of dimensions in "domain".
53 * "offsets" contains the offsets of strided loops. If s is the stride
54 * for a given dimension and f is the corresponding offset, then the
55 * dimension takes on values
59 * with a an integer. For non-strided loops, the offset is zero.
61 * "iterators" contains the loop iterators of both generated and
62 * to be generated loops. The number of elements is at least as
63 * large as the dimension of the internal schedule domain. The
64 * number may be larger, in which case the additional ids can be
65 * used in a nested AST generation should the schedule be non-injective.
67 * "values" lives in the space
69 * [O -> S] -> [O -> S] (or S -> S)
71 * and expresses (if possible) loop iterators in terms of parameters
72 * and outer loop iterators. If the value of a given loop iterator
73 * cannot be expressed as an affine expression (either because the iterator
74 * attains multiple values or because the single value is a piecewise
75 * affine expression), then it is expressed in "values" as being equal
78 * "value" is the value of the loop iterator at the current depth.
79 * It is NULL if it has not been computed yet or if the value of the
80 * given loop iterator cannot be expressed as a piecewise affine expression
81 * (because the iterator attains multiple values).
83 * "schedule_map" maps the internal schedule domain to the external schedule
84 * domain. It may be NULL if it hasn't been computed yet.
85 * See isl_ast_build_get_schedule_map_multi_aff.
87 * "internal2input" maps the internal schedule domain to the original
88 * input schedule domain. In case of a schedule tree input, the original
89 * input schedule domain consist of the flat product of all outer
90 * band node spaces, including the current band node.
91 * It may be NULL if there no longer is such a uniform mapping
92 * (because different iterations have been rescheduled differently).
94 * "options" contains the AST build options in case we are generating
95 * an AST from a flat schedule map. When creating an AST from a schedule
96 * tree, this field is ignored.
98 * The "create_leaf" callback is called for every leaf in the generated AST.
99 * The callback is responsible for creating the node to be placed at those
100 * leaves. If this callback is not set, then isl will generated user
101 * nodes with call expressions corresponding to an element of the domain.
103 * The "at_each_domain" callback is called on every node created to represent
104 * an element of the domain. Each of these nodes is a user node
105 * with as expression a call expression.
107 * The "before_each_for" callback is called on each for node before
108 * its children have been created.
110 * The "after_each_for" callback is called on each for node after
111 * its children have been created.
113 * The "before_each_mark" callback is called before we handle the subtree
114 * of an isl_schedule_node_mark node.
116 * The "after_each_mark" callback is called after we have handled the subtree
117 * of an isl_schedule_node_mark node.
119 * "executed" contains the inverse schedule at this point
120 * of the AST generation.
121 * It is currently only used in isl_ast_build_get_schedule, which is
122 * in turn only used by user code from within a callback.
123 * The value is set right before we may be calling such a callback.
125 * "node" points to the current band node in case we are generating
126 * an AST from a schedule tree. It may be NULL if we are not generating
127 * an AST from a schedule tree or if we are not inside a band node.
129 * "loop_type" originally contains loop AST generation types for
130 * the "n" members of "node" and it is updated (along with "n") when
131 * a schedule dimension is inserted.
132 * It is NULL if "node" is NULL.
134 * "isolated" is the piece of the schedule domain isolated by the isolate
135 * option on the current band. This set may be NULL if we have not checked
136 * for the isolate option yet.
138 struct isl_ast_build
{
144 isl_id_list
*iterators
;
149 isl_multi_aff
*values
;
154 isl_multi_aff
*offsets
;
156 isl_multi_aff
*schedule_map
;
157 isl_multi_aff
*internal2input
;
159 isl_union_map
*options
;
161 __isl_give isl_ast_node
*(*at_each_domain
)(
162 __isl_take isl_ast_node
*node
,
163 __isl_keep isl_ast_build
*build
, void *user
);
164 void *at_each_domain_user
;
166 __isl_give isl_id
*(*before_each_for
)(
167 __isl_keep isl_ast_build
*context
, void *user
);
168 void *before_each_for_user
;
169 __isl_give isl_ast_node
*(*after_each_for
)(
170 __isl_take isl_ast_node
*node
,
171 __isl_keep isl_ast_build
*context
, void *user
);
172 void *after_each_for_user
;
174 isl_stat (*before_each_mark
)(__isl_keep isl_id
*mark
,
175 __isl_keep isl_ast_build
*build
, void *user
);
176 void *before_each_mark_user
;
177 __isl_give isl_ast_node
*(*after_each_mark
)(
178 __isl_take isl_ast_node
*node
,
179 __isl_keep isl_ast_build
*context
, void *user
);
180 void *after_each_mark_user
;
182 __isl_give isl_ast_node
*(*create_leaf
)(
183 __isl_take isl_ast_build
*build
, void *user
);
184 void *create_leaf_user
;
186 isl_union_map
*executed
;
188 isl_schedule_node
*node
;
190 enum isl_ast_loop_type
*loop_type
;
194 __isl_give isl_ast_build
*isl_ast_build_clear_local_info(
195 __isl_take isl_ast_build
*build
);
196 __isl_give isl_ast_build
*isl_ast_build_increase_depth(
197 __isl_take isl_ast_build
*build
);
198 isl_size
isl_ast_build_get_depth(__isl_keep isl_ast_build
*build
);
199 isl_size
isl_ast_build_dim(__isl_keep isl_ast_build
*build
,
200 enum isl_dim_type type
);
201 __isl_give isl_space
*isl_ast_build_get_space(
202 __isl_keep isl_ast_build
*build
, int internal
);
203 __isl_give isl_ast_build
*isl_ast_build_align_params(
204 __isl_take isl_ast_build
*build
, __isl_take isl_space
*model
);
205 __isl_give isl_ast_build
*isl_ast_build_cow(
206 __isl_take isl_ast_build
*build
);
207 __isl_give isl_ast_build
*isl_ast_build_insert_dim(
208 __isl_take isl_ast_build
*build
, int pos
);
209 __isl_give isl_ast_build
*isl_ast_build_scale_down(
210 __isl_take isl_ast_build
*build
, __isl_take isl_val
*m
,
211 __isl_take isl_union_map
*umap
);
212 __isl_give isl_ast_build
*isl_ast_build_product(
213 __isl_take isl_ast_build
*build
, __isl_take isl_space
*embedding
);
214 __isl_give isl_ast_build
*isl_ast_build_set_loop_bounds(
215 __isl_take isl_ast_build
*build
, __isl_take isl_basic_set
*bounds
);
216 __isl_give isl_ast_build
*isl_ast_build_set_pending_generated(
217 __isl_take isl_ast_build
*build
, __isl_take isl_basic_set
*bounds
);
218 __isl_give isl_ast_build
*isl_ast_build_detect_strides(
219 __isl_take isl_ast_build
*build
, __isl_take isl_set
*set
);
220 __isl_give isl_ast_build
*isl_ast_build_include_stride(
221 __isl_take isl_ast_build
*build
);
222 __isl_give isl_ast_build
*isl_ast_build_set_executed(
223 __isl_take isl_ast_build
*build
,
224 __isl_take isl_union_map
*executed
);
225 __isl_give isl_multi_aff
*isl_ast_build_get_internal2input(
226 __isl_keep isl_ast_build
*build
);
227 __isl_give isl_set
*isl_ast_build_get_domain(
228 __isl_keep isl_ast_build
*build
);
229 __isl_give isl_set
*isl_ast_build_get_pending(
230 __isl_keep isl_ast_build
*build
);
231 __isl_give isl_set
*isl_ast_build_get_generated(
232 __isl_keep isl_ast_build
*build
);
233 __isl_give isl_ast_build
*isl_ast_build_restrict_generated(
234 __isl_take isl_ast_build
*build
, __isl_take isl_set
*set
);
235 __isl_give isl_ast_build
*isl_ast_build_replace_pending_by_guard(
236 __isl_take isl_ast_build
*build
, __isl_take isl_set
*guard
);
237 isl_bool
isl_ast_build_need_schedule_map(__isl_keep isl_ast_build
*build
);
238 __isl_give isl_multi_aff
*isl_ast_build_get_schedule_map_multi_aff(
239 __isl_keep isl_ast_build
*build
);
240 __isl_give isl_map
*isl_ast_build_get_schedule_map(
241 __isl_keep isl_ast_build
*build
);
242 isl_bool
isl_ast_build_has_affine_value(__isl_keep isl_ast_build
*build
,
244 int isl_ast_build_has_value(__isl_keep isl_ast_build
*build
);
245 __isl_give isl_id
*isl_ast_build_get_iterator_id(
246 __isl_keep isl_ast_build
*build
, int pos
);
248 int isl_ast_build_has_schedule_node(__isl_keep isl_ast_build
*build
);
249 __isl_give isl_schedule_node
*isl_ast_build_get_schedule_node(
250 __isl_keep isl_ast_build
*build
);
251 __isl_give isl_ast_build
*isl_ast_build_set_schedule_node(
252 __isl_take isl_ast_build
*build
,
253 __isl_take isl_schedule_node
*node
);
254 __isl_give isl_ast_build
*isl_ast_build_reset_schedule_node(
255 __isl_take isl_ast_build
*build
);
257 __isl_give isl_ast_build
*isl_ast_build_extract_isolated(
258 __isl_take isl_ast_build
*build
);
259 int isl_ast_build_has_isolated(__isl_keep isl_ast_build
*build
);
260 __isl_give isl_set
*isl_ast_build_get_isolated(
261 __isl_keep isl_ast_build
*build
);
263 __isl_give isl_basic_set
*isl_ast_build_specialize_basic_set(
264 __isl_keep isl_ast_build
*build
, __isl_take isl_basic_set
*bset
);
265 __isl_give isl_basic_set
*isl_ast_build_compute_gist_basic_set(
266 __isl_keep isl_ast_build
*build
, __isl_take isl_basic_set
*bset
);
267 __isl_give isl_set
*isl_ast_build_specialize(__isl_keep isl_ast_build
*build
,
268 __isl_take isl_set
*set
);
269 __isl_give isl_set
*isl_ast_build_compute_gist(
270 __isl_keep isl_ast_build
*build
, __isl_take isl_set
*set
);
271 __isl_give isl_map
*isl_ast_build_compute_gist_map_domain(
272 __isl_keep isl_ast_build
*build
, __isl_take isl_map
*map
);
273 __isl_give isl_aff
*isl_ast_build_compute_gist_aff(
274 __isl_keep isl_ast_build
*build
, __isl_take isl_aff
*aff
);
275 __isl_give isl_pw_aff
*isl_ast_build_compute_gist_pw_aff(
276 __isl_keep isl_ast_build
*build
, __isl_take isl_pw_aff
*pa
);
277 __isl_give isl_pw_multi_aff
*isl_ast_build_compute_gist_pw_multi_aff(
278 __isl_keep isl_ast_build
*build
, __isl_take isl_pw_multi_aff
*pma
);
280 __isl_give isl_union_map
*isl_ast_build_substitute_values_union_map_domain(
281 __isl_keep isl_ast_build
*build
, __isl_take isl_union_map
*umap
);
283 isl_bool
isl_ast_build_aff_is_nonneg(__isl_keep isl_ast_build
*build
,
284 __isl_keep isl_aff
*aff
);
286 isl_bool
isl_ast_build_has_stride(__isl_keep isl_ast_build
*build
, int pos
);
287 __isl_give isl_aff
*isl_ast_build_get_offset(__isl_keep isl_ast_build
*build
,
289 __isl_give isl_val
*isl_ast_build_get_stride(__isl_keep isl_ast_build
*build
,
291 __isl_give isl_set
*isl_ast_build_get_stride_constraint(
292 __isl_keep isl_ast_build
*build
);
293 __isl_give isl_multi_aff
*isl_ast_build_get_stride_expansion(
294 __isl_keep isl_ast_build
*build
);
296 void isl_ast_build_dump(__isl_keep isl_ast_build
*build
);
298 __isl_give isl_set
*isl_ast_build_get_option_domain(
299 __isl_keep isl_ast_build
*build
, enum isl_ast_loop_type type
);
300 __isl_give isl_map
*isl_ast_build_get_separation_class(
301 __isl_keep isl_ast_build
*build
);
302 __isl_give isl_set
*isl_ast_build_eliminate(
303 __isl_keep isl_ast_build
*build
, __isl_take isl_set
*domain
);
304 __isl_give isl_set
*isl_ast_build_eliminate_inner(
305 __isl_keep isl_ast_build
*build
, __isl_take isl_set
*set
);
306 __isl_give isl_set
*isl_ast_build_eliminate_divs(
307 __isl_keep isl_ast_build
*build
, __isl_take isl_set
*set
);
309 enum isl_ast_loop_type
isl_ast_build_get_loop_type(
310 __isl_keep isl_ast_build
*build
, int isolated
);
312 __isl_give isl_map
*isl_ast_build_map_to_iterator(
313 __isl_keep isl_ast_build
*build
, __isl_take isl_set
*set
);
315 int isl_ast_build_options_involve_depth(__isl_keep isl_ast_build
*build
);