summaryrefslogtreecommitdiff
path: root/polly/lib/External/isl/isl_ast_build_private.h
blob: 1128e632c3ac8561e304eb07ccd4e8490fc38611 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
#ifndef ISL_AST_BUILD_PRIVATE_H
#define ISL_AST_BUILD_PRIVATE_H

#include <isl/aff.h>
#include <isl/ast.h>
#include <isl/ast_build.h>
#include <isl/set.h>
#include <isl/list.h>
#include <isl/schedule_node.h>

/* An isl_ast_build represents the context in which AST is being
 * generated.  That is, it (mostly) contains information about outer
 * loops that can be used to simplify inner loops.
 *
 * "domain" represents constraints on the internal schedule domain,
 * corresponding to the context of the AST generation and the constraints
 * implied by the loops that have already been generated.
 * When an isl_ast_build is first created, outside any AST generation,
 * the domain is typically a parameter set.  It is only when a AST
 * generation phase is initiated that the domain of the isl_ast_build
 * is changed to refer to the internal schedule domain.
 * The domain then lives in a space of the form
 *
 *	S
 *
 *  or
 *
 *	[O -> S]
 *
 * O represents the loops generated in outer AST generations.
 * S represents the loops (both generated and to be generated)
 * of the current AST generation.
 * Both include eliminated loops.
 * "domain" is expected not to have any unknown divs because
 * it is used as the context argument in a call to isl_basic_set_gist
 * in isl_ast_build_compute_gist_basic_set.
 *
 * "depth" is equal to the number of loops that have already
 * been generated (including those in outer AST generations).
 * "outer_pos" is equal to the number of loops in outer AST generations.
 *
 * "generated" is a superset of "domain" corresponding to those
 * constraints that were either given by the user or that have
 * effectively been generated (as bounds on a for loop).
 *
 * "pending" is a superset of "domain" corresponding to the constraints
 * that still need to be generated (as guards), but that may end up
 * not getting generated if they are implied by any constraints
 * enforced by inner loops.
 *
 * "strides" contains the stride of each loop.  The number of elements
 * is equal to the number of dimensions in "domain".
 * "offsets" contains the offsets of strided loops.  If s is the stride
 * for a given dimension and f is the corresponding offset, then the
 * dimension takes on values
 *
 *	f + s a
 *
 * with a an integer.  For non-strided loops, the offset is zero.
 *
 * "iterators" contains the loop iterators of both generated and
 * to be generated loops.  The number of elements is at least as
 * large as the dimension of the internal schedule domain.  The
 * number may be larger, in which case the additional ids can be
 * used in a nested AST generation should the schedule be non-injective.
 *
 * "values" lives in the space
 *
 *	[O -> S] -> [O -> S]		(or S -> S)
 *
 * and expresses (if possible) loop iterators in terms of parameters
 * and outer loop iterators.  If the value of a given loop iterator
 * cannot be expressed as an affine expression (either because the iterator
 * attains multiple values or because the single value is a piecewise
 * affine expression), then it is expressed in "values" as being equal
 * to itself.
 *
 * "value" is the value of the loop iterator at the current depth.
 * It is NULL if it has not been computed yet or if the value of the
 * given loop iterator cannot be expressed as a piecewise affine expression
 * (because the iterator attains multiple values).
 *
 * "schedule_map" maps the internal schedule domain to the external schedule
 * domain.  It may be NULL if it hasn't been computed yet.
 * See isl_ast_build_get_schedule_map_multi_aff.
 *
 * "internal2input" maps the internal schedule domain to the original
 * input schedule domain.  In case of a schedule tree input, the original
 * input schedule domain consist of the flat product of all outer
 * band node spaces, including the current band node.
 * It may be NULL if there no longer is such a uniform mapping
 * (because different iterations have been rescheduled differently).
 *
 * "options" contains the AST build options in case we are generating
 * an AST from a flat schedule map.  When creating an AST from a schedule
 * tree, this field is ignored.
 *
 * The "create_leaf" callback is called for every leaf in the generated AST.
 * The callback is responsible for creating the node to be placed at those
 * leaves.  If this callback is not set, then isl will generated user
 * nodes with call expressions corresponding to an element of the domain.
 *
 * The "at_each_domain" callback is called on every node created to represent
 * an element of the domain.  Each of these nodes is a user node
 * with as expression a call expression.
 *
 * The "before_each_for" callback is called on each for node before
 * its children have been created.
 *
 * The "after_each_for" callback is called on each for node after
 * its children have been created.
 *
 * The "before_each_mark" callback is called before we handle the subtree
 * of an isl_schedule_node_mark node.
 *
 * The "after_each_mark" callback is called after we have handled the subtree
 * of an isl_schedule_node_mark node.
 *
 * "executed" contains the inverse schedule at this point
 * of the AST generation.
 * It is currently only used in isl_ast_build_get_schedule, which is
 * in turn only used by user code from within a callback.
 * The value is set right before we may be calling such a callback.
 *
 * "single_valued" is set if the current inverse schedule (which may or may
 * not be stored in "executed") is known to be single valued, specifically
 * an inverse schedule that was not (appeared not to be) single valued
 * is extended to a single valued inverse schedule.  This is mainly used
 * to avoid an infinite recursion when we fail to detect later on that
 * the extended inverse schedule is single valued.
 *
 * "node" points to the current band node in case we are generating
 * an AST from a schedule tree.  It may be NULL if we are not generating
 * an AST from a schedule tree or if we are not inside a band node.
 *
 * "loop_type" originally contains loop AST generation types for
 * the "n" members of "node" and it is updated (along with "n") when
 * a schedule dimension is inserted.
 * It is NULL if "node" is NULL.
 *
 * "isolated" is the piece of the schedule domain isolated by the isolate
 * option on the current band.  This set may be NULL if we have not checked
 * for the isolate option yet.
 */
struct isl_ast_build {
	int ref;

	int outer_pos;
	int depth;

	isl_id_list *iterators;

	isl_set *domain;
	isl_set *generated;
	isl_set *pending;
	isl_multi_aff *values;

	isl_pw_aff *value;

	isl_vec *strides;
	isl_multi_aff *offsets;

	isl_multi_aff *schedule_map;
	isl_multi_aff *internal2input;

	isl_union_map *options;

	__isl_give isl_ast_node *(*at_each_domain)(
		__isl_take isl_ast_node *node,
		__isl_keep isl_ast_build *build, void *user);
	void *at_each_domain_user;

	__isl_give isl_id *(*before_each_for)(
		__isl_keep isl_ast_build *context, void *user);
	void *before_each_for_user;
	__isl_give isl_ast_node *(*after_each_for)(
		__isl_take isl_ast_node *node,
		__isl_keep isl_ast_build *context, void *user);
	void *after_each_for_user;

	isl_stat (*before_each_mark)(__isl_keep isl_id *mark,
		__isl_keep isl_ast_build *build, void *user);
	void *before_each_mark_user;
	__isl_give isl_ast_node *(*after_each_mark)(
		__isl_take isl_ast_node *node,
		__isl_keep isl_ast_build *context, void *user);
	void *after_each_mark_user;

	__isl_give isl_ast_node *(*create_leaf)(
		__isl_take isl_ast_build *build, void *user);
	void *create_leaf_user;

	isl_union_map *executed;
	int single_valued;

	isl_schedule_node *node;
	int n;
	enum isl_ast_loop_type *loop_type;
	isl_set *isolated;
};

__isl_give isl_ast_build *isl_ast_build_clear_local_info(
	__isl_take isl_ast_build *build);
__isl_give isl_ast_build *isl_ast_build_increase_depth(
	__isl_take isl_ast_build *build);
isl_size isl_ast_build_get_depth(__isl_keep isl_ast_build *build);
isl_size isl_ast_build_dim(__isl_keep isl_ast_build *build,
	enum isl_dim_type type);
__isl_give isl_space *isl_ast_build_get_space(
	__isl_keep isl_ast_build *build, int internal);
__isl_give isl_ast_build *isl_ast_build_align_params(
	__isl_take isl_ast_build *build, __isl_take isl_space *model);
__isl_give isl_ast_build *isl_ast_build_cow(
	__isl_take isl_ast_build *build);
__isl_give isl_ast_build *isl_ast_build_insert_dim(
	__isl_take isl_ast_build *build, int pos);
__isl_give isl_ast_build *isl_ast_build_scale_down(
	__isl_take isl_ast_build *build, __isl_take isl_val *m,
	__isl_take isl_union_map *umap);
__isl_give isl_ast_build *isl_ast_build_product(
	__isl_take isl_ast_build *build, __isl_take isl_space *embedding);
__isl_give isl_ast_build *isl_ast_build_set_loop_bounds(
	__isl_take isl_ast_build *build, __isl_take isl_basic_set *bounds);
__isl_give isl_ast_build *isl_ast_build_set_pending_generated(
	__isl_take isl_ast_build *build, __isl_take isl_basic_set *bounds);
__isl_give isl_ast_build *isl_ast_build_detect_strides(
	__isl_take isl_ast_build *build, __isl_take isl_set *set);
__isl_give isl_ast_build *isl_ast_build_include_stride(
	__isl_take isl_ast_build *build);
__isl_give isl_ast_build *isl_ast_build_set_executed(
	__isl_take isl_ast_build *build,
	__isl_take isl_union_map *executed);
__isl_give isl_ast_build *isl_ast_build_set_single_valued(
	__isl_take isl_ast_build *build, int sv);
__isl_give isl_multi_aff *isl_ast_build_get_internal2input(
	__isl_keep isl_ast_build *build);
__isl_give isl_set *isl_ast_build_get_domain(
	__isl_keep isl_ast_build *build);
__isl_give isl_set *isl_ast_build_get_pending(
	__isl_keep isl_ast_build *build);
__isl_give isl_set *isl_ast_build_get_generated(
	__isl_keep isl_ast_build *build);
__isl_give isl_ast_build *isl_ast_build_restrict_generated(
	__isl_take isl_ast_build *build, __isl_take isl_set *set);
__isl_give isl_ast_build *isl_ast_build_replace_pending_by_guard(
	__isl_take isl_ast_build *build, __isl_take isl_set *guard);
isl_bool isl_ast_build_need_schedule_map(__isl_keep isl_ast_build *build);
__isl_give isl_multi_aff *isl_ast_build_get_schedule_map_multi_aff(
	__isl_keep isl_ast_build *build);
__isl_give isl_map *isl_ast_build_get_schedule_map(
	__isl_keep isl_ast_build *build);
isl_bool isl_ast_build_has_affine_value(__isl_keep isl_ast_build *build,
	int pos);
int isl_ast_build_has_value(__isl_keep isl_ast_build *build);
__isl_give isl_id *isl_ast_build_get_iterator_id(
	__isl_keep isl_ast_build *build, int pos);

int isl_ast_build_has_schedule_node(__isl_keep isl_ast_build *build);
__isl_give isl_schedule_node *isl_ast_build_get_schedule_node(
	__isl_keep isl_ast_build *build);
__isl_give isl_ast_build *isl_ast_build_set_schedule_node(
	__isl_take isl_ast_build *build,
	__isl_take isl_schedule_node *node);
__isl_give isl_ast_build *isl_ast_build_reset_schedule_node(
	__isl_take isl_ast_build *build);

__isl_give isl_ast_build *isl_ast_build_extract_isolated(
	__isl_take isl_ast_build *build);
int isl_ast_build_has_isolated(__isl_keep isl_ast_build *build);
__isl_give isl_set *isl_ast_build_get_isolated(
	__isl_keep isl_ast_build *build);

__isl_give isl_basic_set *isl_ast_build_specialize_basic_set(
	__isl_keep isl_ast_build *build, __isl_take isl_basic_set *bset);
__isl_give isl_basic_set *isl_ast_build_compute_gist_basic_set(
	__isl_keep isl_ast_build *build, __isl_take isl_basic_set *bset);
__isl_give isl_set *isl_ast_build_specialize(__isl_keep isl_ast_build *build,
	__isl_take isl_set *set);
__isl_give isl_set *isl_ast_build_compute_gist(
	__isl_keep isl_ast_build *build, __isl_take isl_set *set);
__isl_give isl_map *isl_ast_build_compute_gist_map_domain(
	__isl_keep isl_ast_build *build, __isl_take isl_map *map);
__isl_give isl_aff *isl_ast_build_compute_gist_aff(
	__isl_keep isl_ast_build *build, __isl_take isl_aff *aff);
__isl_give isl_pw_aff *isl_ast_build_compute_gist_pw_aff(
	__isl_keep isl_ast_build *build, __isl_take isl_pw_aff *pa);
__isl_give isl_pw_multi_aff *isl_ast_build_compute_gist_pw_multi_aff(
	__isl_keep isl_ast_build *build, __isl_take isl_pw_multi_aff *pma);

__isl_give isl_union_map *isl_ast_build_substitute_values_union_map_domain(
	__isl_keep isl_ast_build *build, __isl_take isl_union_map *umap);

int isl_ast_build_aff_is_nonneg(__isl_keep isl_ast_build *build,
	__isl_keep isl_aff *aff);

isl_bool isl_ast_build_has_stride(__isl_keep isl_ast_build *build, int pos);
__isl_give isl_aff *isl_ast_build_get_offset(__isl_keep isl_ast_build *build,
	int pos);
__isl_give isl_val *isl_ast_build_get_stride(__isl_keep isl_ast_build *build,
	int pos);
__isl_give isl_set *isl_ast_build_get_stride_constraint(
	__isl_keep isl_ast_build *build);
__isl_give isl_multi_aff *isl_ast_build_get_stride_expansion(
	__isl_keep isl_ast_build *build);

void isl_ast_build_dump(__isl_keep isl_ast_build *build);

__isl_give isl_set *isl_ast_build_get_option_domain(
	__isl_keep isl_ast_build *build, enum isl_ast_loop_type type);
__isl_give isl_map *isl_ast_build_get_separation_class(
	__isl_keep isl_ast_build *build);
__isl_give isl_set *isl_ast_build_eliminate(
	__isl_keep isl_ast_build *build, __isl_take isl_set *domain);
__isl_give isl_set *isl_ast_build_eliminate_inner(
	__isl_keep isl_ast_build *build, __isl_take isl_set *set);
__isl_give isl_set *isl_ast_build_eliminate_divs(
	__isl_keep isl_ast_build *build, __isl_take isl_set *set);

enum isl_ast_loop_type isl_ast_build_get_loop_type(
	__isl_keep isl_ast_build *build, int isolated);

__isl_give isl_map *isl_ast_build_map_to_iterator(
	__isl_keep isl_ast_build *build, __isl_take isl_set *set);

int isl_ast_build_options_involve_depth(__isl_keep isl_ast_build *build);

#endif