/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/polly/lib/External/isl/isl_schedule_constraints.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2012 Ecole Normale Superieure |
3 | | * Copyright 2015-2016 Sven Verdoolaege |
4 | | * |
5 | | * Use of this software is governed by the MIT license |
6 | | * |
7 | | * Written by Sven Verdoolaege, |
8 | | * Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France |
9 | | */ |
10 | | |
11 | | #include <isl_schedule_constraints.h> |
12 | | #include <isl/schedule.h> |
13 | | #include <isl/set.h> |
14 | | #include <isl/map.h> |
15 | | #include <isl/union_set.h> |
16 | | #include <isl/union_map.h> |
17 | | #include <isl/stream.h> |
18 | | |
19 | | /* The constraints that need to be satisfied by a schedule on "domain". |
20 | | * |
21 | | * "context" specifies extra constraints on the parameters. |
22 | | * |
23 | | * "validity" constraints map domain elements i to domain elements |
24 | | * that should be scheduled after i. (Hard constraint) |
25 | | * "proximity" constraints map domain elements i to domains elements |
26 | | * that should be scheduled as early as possible after i (or before i). |
27 | | * (Soft constraint) |
28 | | * |
29 | | * "condition" and "conditional_validity" constraints map possibly "tagged" |
30 | | * domain elements i -> s to "tagged" domain elements j -> t. |
31 | | * The elements of the "conditional_validity" constraints, but without the |
32 | | * tags (i.e., the elements i -> j) are treated as validity constraints, |
33 | | * except that during the construction of a tilable band, |
34 | | * the elements of the "conditional_validity" constraints may be violated |
35 | | * provided that all adjacent elements of the "condition" constraints |
36 | | * are local within the band. |
37 | | * A dependence is local within a band if domain and range are mapped |
38 | | * to the same schedule point by the band. |
39 | | */ |
40 | | struct isl_schedule_constraints { |
41 | | isl_union_set *domain; |
42 | | isl_set *context; |
43 | | |
44 | | isl_union_map *constraint[isl_edge_last + 1]; |
45 | | }; |
46 | | |
47 | | __isl_give isl_schedule_constraints *isl_schedule_constraints_copy( |
48 | | __isl_keep isl_schedule_constraints *sc) |
49 | 152 | { |
50 | 152 | isl_ctx *ctx; |
51 | 152 | isl_schedule_constraints *sc_copy; |
52 | 152 | enum isl_edge_type i; |
53 | 152 | |
54 | 152 | ctx = isl_union_set_get_ctx(sc->domain); |
55 | 152 | sc_copy = isl_calloc_type(ctx, struct isl_schedule_constraints); |
56 | 152 | if (!sc_copy) |
57 | 0 | return NULL; |
58 | 152 | |
59 | 152 | sc_copy->domain = isl_union_set_copy(sc->domain); |
60 | 152 | sc_copy->context = isl_set_copy(sc->context); |
61 | 152 | if (!sc_copy->domain || 152 !sc_copy->context152 ) |
62 | 0 | return isl_schedule_constraints_free(sc_copy); |
63 | 152 | |
64 | 912 | for (i = isl_edge_first; 152 i <= isl_edge_last912 ; ++i760 ) { |
65 | 760 | sc_copy->constraint[i] = isl_union_map_copy(sc->constraint[i]); |
66 | 760 | if (!sc_copy->constraint[i]) |
67 | 0 | return isl_schedule_constraints_free(sc_copy); |
68 | 760 | } |
69 | 152 | |
70 | 152 | return sc_copy; |
71 | 152 | } |
72 | | |
73 | | /* Construct an empty (invalid) isl_schedule_constraints object. |
74 | | * The caller is responsible for setting the domain and initializing |
75 | | * all the other fields, e.g., by calling isl_schedule_constraints_init. |
76 | | */ |
77 | | static __isl_give isl_schedule_constraints *isl_schedule_constraints_alloc( |
78 | | isl_ctx *ctx) |
79 | 141 | { |
80 | 141 | return isl_calloc_type(ctx, struct isl_schedule_constraints); |
81 | 141 | } |
82 | | |
83 | | /* Initialize all the fields of "sc", except domain, which is assumed |
84 | | * to have been set by the caller. |
85 | | */ |
86 | | static __isl_give isl_schedule_constraints *isl_schedule_constraints_init( |
87 | | __isl_take isl_schedule_constraints *sc) |
88 | 141 | { |
89 | 141 | isl_space *space; |
90 | 141 | isl_union_map *empty; |
91 | 141 | enum isl_edge_type i; |
92 | 141 | |
93 | 141 | if (!sc) |
94 | 0 | return NULL; |
95 | 141 | if (141 !sc->domain141 ) |
96 | 0 | return isl_schedule_constraints_free(sc); |
97 | 141 | space = isl_union_set_get_space(sc->domain); |
98 | 141 | if (!sc->context) |
99 | 141 | sc->context = isl_set_universe(isl_space_copy(space)); |
100 | 141 | empty = isl_union_map_empty(space); |
101 | 846 | for (i = isl_edge_first; i <= isl_edge_last846 ; ++i705 ) { |
102 | 705 | if (sc->constraint[i]) |
103 | 0 | continue; |
104 | 705 | sc->constraint[i] = isl_union_map_copy(empty); |
105 | 705 | if (!sc->constraint[i]) |
106 | 0 | sc->domain = isl_union_set_free(sc->domain); |
107 | 705 | } |
108 | 141 | isl_union_map_free(empty); |
109 | 141 | |
110 | 141 | if (!sc->domain || 141 !sc->context141 ) |
111 | 0 | return isl_schedule_constraints_free(sc); |
112 | 141 | |
113 | 141 | return sc; |
114 | 141 | } |
115 | | |
116 | | /* Construct an isl_schedule_constraints object for computing a schedule |
117 | | * on "domain". The initial object does not impose any constraints. |
118 | | */ |
119 | | __isl_give isl_schedule_constraints *isl_schedule_constraints_on_domain( |
120 | | __isl_take isl_union_set *domain) |
121 | 141 | { |
122 | 141 | isl_ctx *ctx; |
123 | 141 | isl_schedule_constraints *sc; |
124 | 141 | |
125 | 141 | if (!domain) |
126 | 0 | return NULL; |
127 | 141 | |
128 | 141 | ctx = isl_union_set_get_ctx(domain); |
129 | 141 | sc = isl_schedule_constraints_alloc(ctx); |
130 | 141 | if (!sc) |
131 | 0 | goto error; |
132 | 141 | |
133 | 141 | sc->domain = domain; |
134 | 141 | return isl_schedule_constraints_init(sc); |
135 | 0 | error: |
136 | 0 | isl_union_set_free(domain); |
137 | 0 | return NULL; |
138 | 141 | } |
139 | | |
140 | | /* Replace the domain of "sc" by "domain". |
141 | | */ |
142 | | static __isl_give isl_schedule_constraints *isl_schedule_constraints_set_domain( |
143 | | __isl_take isl_schedule_constraints *sc, |
144 | | __isl_take isl_union_set *domain) |
145 | 0 | { |
146 | 0 | if (!sc || 0 !domain0 ) |
147 | 0 | goto error; |
148 | 0 |
|
149 | 0 | isl_union_set_free(sc->domain); |
150 | 0 | sc->domain = domain; |
151 | 0 |
|
152 | 0 | return sc; |
153 | 0 | error: |
154 | 0 | isl_schedule_constraints_free(sc); |
155 | 0 | isl_union_set_free(domain); |
156 | 0 | return NULL; |
157 | 0 | } |
158 | | |
159 | | /* Replace the context of "sc" by "context". |
160 | | */ |
161 | | __isl_give isl_schedule_constraints *isl_schedule_constraints_set_context( |
162 | | __isl_take isl_schedule_constraints *sc, __isl_take isl_set *context) |
163 | 22 | { |
164 | 22 | if (!sc || 22 !context22 ) |
165 | 0 | goto error; |
166 | 22 | |
167 | 22 | isl_set_free(sc->context); |
168 | 22 | sc->context = context; |
169 | 22 | |
170 | 22 | return sc; |
171 | 0 | error: |
172 | 0 | isl_schedule_constraints_free(sc); |
173 | 0 | isl_set_free(context); |
174 | 0 | return NULL; |
175 | 22 | } |
176 | | |
177 | | /* Replace the constraints of type "type" in "sc" by "c". |
178 | | */ |
179 | | static __isl_give isl_schedule_constraints *isl_schedule_constraints_set( |
180 | | __isl_take isl_schedule_constraints *sc, enum isl_edge_type type, |
181 | | __isl_take isl_union_map *c) |
182 | 333 | { |
183 | 333 | if (!sc || 333 !c333 ) |
184 | 0 | goto error; |
185 | 333 | |
186 | 333 | isl_union_map_free(sc->constraint[type]); |
187 | 333 | sc->constraint[type] = c; |
188 | 333 | |
189 | 333 | return sc; |
190 | 0 | error: |
191 | 0 | isl_schedule_constraints_free(sc); |
192 | 0 | isl_union_map_free(c); |
193 | 0 | return NULL; |
194 | 333 | } |
195 | | |
196 | | /* Replace the validity constraints of "sc" by "validity". |
197 | | */ |
198 | | __isl_give isl_schedule_constraints *isl_schedule_constraints_set_validity( |
199 | | __isl_take isl_schedule_constraints *sc, |
200 | | __isl_take isl_union_map *validity) |
201 | 117 | { |
202 | 117 | return isl_schedule_constraints_set(sc, isl_edge_validity, validity); |
203 | 117 | } |
204 | | |
205 | | /* Replace the coincidence constraints of "sc" by "coincidence". |
206 | | */ |
207 | | __isl_give isl_schedule_constraints *isl_schedule_constraints_set_coincidence( |
208 | | __isl_take isl_schedule_constraints *sc, |
209 | | __isl_take isl_union_map *coincidence) |
210 | 80 | { |
211 | 80 | return isl_schedule_constraints_set(sc, isl_edge_coincidence, |
212 | 80 | coincidence); |
213 | 80 | } |
214 | | |
215 | | /* Replace the proximity constraints of "sc" by "proximity". |
216 | | */ |
217 | | __isl_give isl_schedule_constraints *isl_schedule_constraints_set_proximity( |
218 | | __isl_take isl_schedule_constraints *sc, |
219 | | __isl_take isl_union_map *proximity) |
220 | 112 | { |
221 | 112 | return isl_schedule_constraints_set(sc, isl_edge_proximity, proximity); |
222 | 112 | } |
223 | | |
224 | | /* Replace the conditional validity constraints of "sc" by "condition" |
225 | | * and "validity". |
226 | | */ |
227 | | __isl_give isl_schedule_constraints * |
228 | | isl_schedule_constraints_set_conditional_validity( |
229 | | __isl_take isl_schedule_constraints *sc, |
230 | | __isl_take isl_union_map *condition, |
231 | | __isl_take isl_union_map *validity) |
232 | 12 | { |
233 | 12 | sc = isl_schedule_constraints_set(sc, isl_edge_condition, condition); |
234 | 12 | sc = isl_schedule_constraints_set(sc, isl_edge_conditional_validity, |
235 | 12 | validity); |
236 | 12 | return sc; |
237 | 12 | } |
238 | | |
239 | | __isl_null isl_schedule_constraints *isl_schedule_constraints_free( |
240 | | __isl_take isl_schedule_constraints *sc) |
241 | 293 | { |
242 | 293 | enum isl_edge_type i; |
243 | 293 | |
244 | 293 | if (!sc) |
245 | 0 | return NULL; |
246 | 293 | |
247 | 293 | isl_union_set_free(sc->domain); |
248 | 293 | isl_set_free(sc->context); |
249 | 1.75k | for (i = isl_edge_first; i <= isl_edge_last1.75k ; ++i1.46k ) |
250 | 1.46k | isl_union_map_free(sc->constraint[i]); |
251 | 293 | |
252 | 293 | free(sc); |
253 | 293 | |
254 | 293 | return NULL; |
255 | 293 | } |
256 | | |
257 | | isl_ctx *isl_schedule_constraints_get_ctx( |
258 | | __isl_keep isl_schedule_constraints *sc) |
259 | 260 | { |
260 | 260 | return sc ? isl_union_set_get_ctx(sc->domain) : NULL; |
261 | 260 | } |
262 | | |
263 | | /* Return the domain of "sc". |
264 | | */ |
265 | | __isl_give isl_union_set *isl_schedule_constraints_get_domain( |
266 | | __isl_keep isl_schedule_constraints *sc) |
267 | 542 | { |
268 | 542 | if (!sc) |
269 | 0 | return NULL; |
270 | 542 | |
271 | 542 | return isl_union_set_copy(sc->domain); |
272 | 542 | } |
273 | | |
274 | | /* Return the context of "sc". |
275 | | */ |
276 | | __isl_give isl_set *isl_schedule_constraints_get_context( |
277 | | __isl_keep isl_schedule_constraints *sc) |
278 | 141 | { |
279 | 141 | if (!sc) |
280 | 0 | return NULL; |
281 | 141 | |
282 | 141 | return isl_set_copy(sc->context); |
283 | 141 | } |
284 | | |
285 | | /* Return the constraints of type "type" in "sc". |
286 | | */ |
287 | | __isl_give isl_union_map *isl_schedule_constraints_get( |
288 | | __isl_keep isl_schedule_constraints *sc, enum isl_edge_type type) |
289 | 1.41k | { |
290 | 1.41k | if (!sc) |
291 | 0 | return NULL; |
292 | 1.41k | |
293 | 1.41k | return isl_union_map_copy(sc->constraint[type]); |
294 | 1.41k | } |
295 | | |
296 | | /* Return the validity constraints of "sc". |
297 | | */ |
298 | | __isl_give isl_union_map *isl_schedule_constraints_get_validity( |
299 | | __isl_keep isl_schedule_constraints *sc) |
300 | 0 | { |
301 | 0 | return isl_schedule_constraints_get(sc, isl_edge_validity); |
302 | 0 | } |
303 | | |
304 | | /* Return the coincidence constraints of "sc". |
305 | | */ |
306 | | __isl_give isl_union_map *isl_schedule_constraints_get_coincidence( |
307 | | __isl_keep isl_schedule_constraints *sc) |
308 | 0 | { |
309 | 0 | return isl_schedule_constraints_get(sc, isl_edge_coincidence); |
310 | 0 | } |
311 | | |
312 | | /* Return the proximity constraints of "sc". |
313 | | */ |
314 | | __isl_give isl_union_map *isl_schedule_constraints_get_proximity( |
315 | | __isl_keep isl_schedule_constraints *sc) |
316 | 0 | { |
317 | 0 | return isl_schedule_constraints_get(sc, isl_edge_proximity); |
318 | 0 | } |
319 | | |
320 | | /* Return the conditional validity constraints of "sc". |
321 | | */ |
322 | | __isl_give isl_union_map *isl_schedule_constraints_get_conditional_validity( |
323 | | __isl_keep isl_schedule_constraints *sc) |
324 | 0 | { |
325 | 0 | return isl_schedule_constraints_get(sc, isl_edge_conditional_validity); |
326 | 0 | } |
327 | | |
328 | | /* Return the conditions for the conditional validity constraints of "sc". |
329 | | */ |
330 | | __isl_give isl_union_map * |
331 | | isl_schedule_constraints_get_conditional_validity_condition( |
332 | | __isl_keep isl_schedule_constraints *sc) |
333 | 0 | { |
334 | 0 | return isl_schedule_constraints_get(sc, isl_edge_condition); |
335 | 0 | } |
336 | | |
337 | | /* Add "c" to the constraints of type "type" in "sc". |
338 | | */ |
339 | | __isl_give isl_schedule_constraints *isl_schedule_constraints_add( |
340 | | __isl_take isl_schedule_constraints *sc, enum isl_edge_type type, |
341 | | __isl_take isl_union_map *c) |
342 | 148 | { |
343 | 148 | if (!sc || 148 !c148 ) |
344 | 0 | goto error; |
345 | 148 | |
346 | 148 | c = isl_union_map_union(sc->constraint[type], c); |
347 | 148 | sc->constraint[type] = c; |
348 | 148 | if (!c) |
349 | 0 | return isl_schedule_constraints_free(sc); |
350 | 148 | |
351 | 148 | return sc; |
352 | 0 | error: |
353 | 0 | isl_schedule_constraints_free(sc); |
354 | 0 | isl_union_map_free(c); |
355 | 0 | return NULL; |
356 | 148 | } |
357 | | |
358 | | /* Can a schedule constraint of type "type" be tagged? |
359 | | */ |
360 | | static int may_be_tagged(enum isl_edge_type type) |
361 | 0 | { |
362 | 0 | if (type == isl_edge_condition || 0 type == isl_edge_conditional_validity0 ) |
363 | 0 | return 1; |
364 | 0 | return 0; |
365 | 0 | } |
366 | | |
367 | | /* Apply "umap" to the domains of the wrapped relations |
368 | | * inside the domain and range of "c". |
369 | | * |
370 | | * That is, for each map of the form |
371 | | * |
372 | | * [D -> S] -> [E -> T] |
373 | | * |
374 | | * in "c", apply "umap" to D and E. |
375 | | * |
376 | | * D is exposed by currying the relation to |
377 | | * |
378 | | * D -> [S -> [E -> T]] |
379 | | * |
380 | | * E is exposed by doing the same to the inverse of "c". |
381 | | */ |
382 | | static __isl_give isl_union_map *apply_factor_domain( |
383 | | __isl_take isl_union_map *c, __isl_keep isl_union_map *umap) |
384 | 0 | { |
385 | 0 | c = isl_union_map_curry(c); |
386 | 0 | c = isl_union_map_apply_domain(c, isl_union_map_copy(umap)); |
387 | 0 | c = isl_union_map_uncurry(c); |
388 | 0 |
|
389 | 0 | c = isl_union_map_reverse(c); |
390 | 0 | c = isl_union_map_curry(c); |
391 | 0 | c = isl_union_map_apply_domain(c, isl_union_map_copy(umap)); |
392 | 0 | c = isl_union_map_uncurry(c); |
393 | 0 | c = isl_union_map_reverse(c); |
394 | 0 |
|
395 | 0 | return c; |
396 | 0 | } |
397 | | |
398 | | /* Apply "umap" to domain and range of "c". |
399 | | * If "tag" is set, then "c" may contain tags and then "umap" |
400 | | * needs to be applied to the domains of the wrapped relations |
401 | | * inside the domain and range of "c". |
402 | | */ |
403 | | static __isl_give isl_union_map *apply(__isl_take isl_union_map *c, |
404 | | __isl_keep isl_union_map *umap, int tag) |
405 | 0 | { |
406 | 0 | isl_union_map *t; |
407 | 0 |
|
408 | 0 | if (tag) |
409 | 0 | t = isl_union_map_copy(c); |
410 | 0 | c = isl_union_map_apply_domain(c, isl_union_map_copy(umap)); |
411 | 0 | c = isl_union_map_apply_range(c, isl_union_map_copy(umap)); |
412 | 0 | if (!tag) |
413 | 0 | return c; |
414 | 0 | t = apply_factor_domain(t, umap); |
415 | 0 | c = isl_union_map_union(c, t); |
416 | 0 | return c; |
417 | 0 | } |
418 | | |
419 | | /* Apply "umap" to the domain of the schedule constraints "sc". |
420 | | * |
421 | | * The two sides of the various schedule constraints are adjusted |
422 | | * accordingly. |
423 | | */ |
424 | | __isl_give isl_schedule_constraints *isl_schedule_constraints_apply( |
425 | | __isl_take isl_schedule_constraints *sc, |
426 | | __isl_take isl_union_map *umap) |
427 | 0 | { |
428 | 0 | enum isl_edge_type i; |
429 | 0 |
|
430 | 0 | if (!sc || 0 !umap0 ) |
431 | 0 | goto error; |
432 | 0 |
|
433 | 0 | for (i = isl_edge_first; 0 i <= isl_edge_last0 ; ++i0 ) { |
434 | 0 | int tag = may_be_tagged(i); |
435 | 0 |
|
436 | 0 | sc->constraint[i] = apply(sc->constraint[i], umap, tag); |
437 | 0 | if (!sc->constraint[i]) |
438 | 0 | goto error; |
439 | 0 | } |
440 | 0 | sc->domain = isl_union_set_apply(sc->domain, umap); |
441 | 0 | if (!sc->domain) |
442 | 0 | return isl_schedule_constraints_free(sc); |
443 | 0 |
|
444 | 0 | return sc; |
445 | 0 | error: |
446 | 0 | isl_schedule_constraints_free(sc); |
447 | 0 | isl_union_map_free(umap); |
448 | 0 | return NULL; |
449 | 0 | } |
450 | | |
451 | | /* An enumeration of the various keys that may appear in a YAML mapping |
452 | | * of an isl_schedule_constraints object. |
453 | | * The keys for the edge types are assumed to have the same values |
454 | | * as the edge types in isl_edge_type. |
455 | | */ |
456 | | enum isl_sc_key { |
457 | | isl_sc_key_error = -1, |
458 | | isl_sc_key_validity = isl_edge_validity, |
459 | | isl_sc_key_coincidence = isl_edge_coincidence, |
460 | | isl_sc_key_condition = isl_edge_condition, |
461 | | isl_sc_key_conditional_validity = isl_edge_conditional_validity, |
462 | | isl_sc_key_proximity = isl_edge_proximity, |
463 | | isl_sc_key_domain, |
464 | | isl_sc_key_context, |
465 | | isl_sc_key_end |
466 | | }; |
467 | | |
468 | | /* Textual representations of the YAML keys for an isl_schedule_constraints |
469 | | * object. |
470 | | */ |
471 | | static char *key_str[] = { |
472 | | [isl_sc_key_validity] = "validity", |
473 | | [isl_sc_key_coincidence] = "coincidence", |
474 | | [isl_sc_key_condition] = "condition", |
475 | | [isl_sc_key_conditional_validity] = "conditional_validity", |
476 | | [isl_sc_key_proximity] = "proximity", |
477 | | [isl_sc_key_domain] = "domain", |
478 | | [isl_sc_key_context] = "context", |
479 | | }; |
480 | | |
481 | | /* Print a key, value pair for the edge of type "type" in "sc" to "p". |
482 | | */ |
483 | | static __isl_give isl_printer *print_constraint(__isl_take isl_printer *p, |
484 | | __isl_keep isl_schedule_constraints *sc, enum isl_edge_type type) |
485 | 0 | { |
486 | 0 | p = isl_printer_print_str(p, key_str[type]); |
487 | 0 | p = isl_printer_yaml_next(p); |
488 | 0 | p = isl_printer_print_union_map(p, sc->constraint[type]); |
489 | 0 | p = isl_printer_yaml_next(p); |
490 | 0 |
|
491 | 0 | return p; |
492 | 0 | } |
493 | | |
494 | | /* Print "sc" to "p" |
495 | | * |
496 | | * In particular, print the isl_schedule_constraints object as a YAML document. |
497 | | */ |
498 | | __isl_give isl_printer *isl_printer_print_schedule_constraints( |
499 | | __isl_take isl_printer *p, __isl_keep isl_schedule_constraints *sc) |
500 | 0 | { |
501 | 0 | if (!sc) |
502 | 0 | return isl_printer_free(p); |
503 | 0 |
|
504 | 0 | p = isl_printer_yaml_start_mapping(p); |
505 | 0 | p = isl_printer_print_str(p, key_str[isl_sc_key_domain]); |
506 | 0 | p = isl_printer_yaml_next(p); |
507 | 0 | p = isl_printer_print_union_set(p, sc->domain); |
508 | 0 | p = isl_printer_yaml_next(p); |
509 | 0 | p = isl_printer_print_str(p, key_str[isl_sc_key_context]); |
510 | 0 | p = isl_printer_yaml_next(p); |
511 | 0 | p = isl_printer_print_set(p, sc->context); |
512 | 0 | p = isl_printer_yaml_next(p); |
513 | 0 | p = print_constraint(p, sc, isl_edge_validity); |
514 | 0 | p = print_constraint(p, sc, isl_edge_proximity); |
515 | 0 | p = print_constraint(p, sc, isl_edge_coincidence); |
516 | 0 | p = print_constraint(p, sc, isl_edge_condition); |
517 | 0 | p = print_constraint(p, sc, isl_edge_conditional_validity); |
518 | 0 | p = isl_printer_yaml_end_mapping(p); |
519 | 0 |
|
520 | 0 | return p; |
521 | 0 | } |
522 | | |
523 | | #undef BASE |
524 | | #define BASE schedule_constraints |
525 | | #include <print_templ_yaml.c> |
526 | | |
527 | | #undef KEY |
528 | 0 | #define KEY enum isl_sc_key |
529 | | #undef KEY_ERROR |
530 | 0 | #define KEY_ERROR isl_sc_key_error |
531 | | #undef KEY_END |
532 | 0 | #define KEY_END isl_sc_key_end |
533 | | #include "extract_key.c" |
534 | | |
535 | | #undef BASE |
536 | | #define BASE set |
537 | | #include "read_in_string_templ.c" |
538 | | |
539 | | #undef BASE |
540 | | #define BASE union_set |
541 | | #include "read_in_string_templ.c" |
542 | | |
543 | | #undef BASE |
544 | | #define BASE union_map |
545 | | #include "read_in_string_templ.c" |
546 | | |
547 | | /* Read an isl_schedule_constraints object from "s". |
548 | | * |
549 | | * Start off with an empty (invalid) isl_schedule_constraints object and |
550 | | * then fill up the fields based on the input. |
551 | | * The input needs to contain at least a description of the domain. |
552 | | * The other fields are set to defaults by isl_schedule_constraints_init |
553 | | * if they are not specified in the input. |
554 | | */ |
555 | | __isl_give isl_schedule_constraints *isl_stream_read_schedule_constraints( |
556 | | isl_stream *s) |
557 | 0 | { |
558 | 0 | isl_ctx *ctx; |
559 | 0 | isl_schedule_constraints *sc; |
560 | 0 | int more; |
561 | 0 | int domain_set = 0; |
562 | 0 |
|
563 | 0 | if (isl_stream_yaml_read_start_mapping(s)) |
564 | 0 | return NULL; |
565 | 0 |
|
566 | 0 | ctx = isl_stream_get_ctx(s); |
567 | 0 | sc = isl_schedule_constraints_alloc(ctx); |
568 | 0 | while ((more = isl_stream_yaml_next(s)) > 00 ) { |
569 | 0 | enum isl_sc_key key; |
570 | 0 | isl_set *context; |
571 | 0 | isl_union_set *domain; |
572 | 0 | isl_union_map *constraints; |
573 | 0 |
|
574 | 0 | key = get_key(s); |
575 | 0 | if (isl_stream_yaml_next(s) < 0) |
576 | 0 | return isl_schedule_constraints_free(sc); |
577 | 0 | switch (key) { |
578 | 0 | case isl_sc_key_end: |
579 | 0 | case isl_sc_key_error: |
580 | 0 | return isl_schedule_constraints_free(sc); |
581 | 0 | case isl_sc_key_domain: |
582 | 0 | domain_set = 1; |
583 | 0 | domain = read_union_set(s); |
584 | 0 | sc = isl_schedule_constraints_set_domain(sc, domain); |
585 | 0 | if (!sc) |
586 | 0 | return NULL; |
587 | 0 | break; |
588 | 0 | case isl_sc_key_context: |
589 | 0 | context = read_set(s); |
590 | 0 | sc = isl_schedule_constraints_set_context(sc, context); |
591 | 0 | if (!sc) |
592 | 0 | return NULL; |
593 | 0 | break; |
594 | 0 | default: |
595 | 0 | constraints = read_union_map(s); |
596 | 0 | sc = isl_schedule_constraints_set(sc, key, constraints); |
597 | 0 | if (!sc) |
598 | 0 | return NULL; |
599 | 0 | break; |
600 | 0 | } |
601 | 0 | } |
602 | 0 | if (0 more < 00 ) |
603 | 0 | return isl_schedule_constraints_free(sc); |
604 | 0 |
|
605 | 0 | if (0 isl_stream_yaml_read_end_mapping(s) < 00 ) { |
606 | 0 | isl_stream_error(s, NULL, "unexpected extra elements"); |
607 | 0 | return isl_schedule_constraints_free(sc); |
608 | 0 | } |
609 | 0 |
|
610 | 0 | if (0 !domain_set0 ) { |
611 | 0 | isl_stream_error(s, NULL, "no domain specified"); |
612 | 0 | return isl_schedule_constraints_free(sc); |
613 | 0 | } |
614 | 0 |
|
615 | 0 | return isl_schedule_constraints_init(sc); |
616 | 0 | } |
617 | | |
618 | | /* Read an isl_schedule_constraints object from the file "input". |
619 | | */ |
620 | | __isl_give isl_schedule_constraints *isl_schedule_constraints_read_from_file( |
621 | | isl_ctx *ctx, FILE *input) |
622 | 0 | { |
623 | 0 | struct isl_stream *s; |
624 | 0 | isl_schedule_constraints *sc; |
625 | 0 |
|
626 | 0 | s = isl_stream_new_file(ctx, input); |
627 | 0 | if (!s) |
628 | 0 | return NULL; |
629 | 0 | sc = isl_stream_read_schedule_constraints(s); |
630 | 0 | isl_stream_free(s); |
631 | 0 |
|
632 | 0 | return sc; |
633 | 0 | } |
634 | | |
635 | | /* Read an isl_schedule_constraints object from the string "str". |
636 | | */ |
637 | | __isl_give isl_schedule_constraints *isl_schedule_constraints_read_from_str( |
638 | | isl_ctx *ctx, const char *str) |
639 | 0 | { |
640 | 0 | struct isl_stream *s; |
641 | 0 | isl_schedule_constraints *sc; |
642 | 0 |
|
643 | 0 | s = isl_stream_new_str(ctx, str); |
644 | 0 | if (!s) |
645 | 0 | return NULL; |
646 | 0 | sc = isl_stream_read_schedule_constraints(s); |
647 | 0 | isl_stream_free(s); |
648 | 0 |
|
649 | 0 | return sc; |
650 | 0 | } |
651 | | |
652 | | /* Align the parameters of the fields of "sc". |
653 | | */ |
654 | | __isl_give isl_schedule_constraints * |
655 | | isl_schedule_constraints_align_params(__isl_take isl_schedule_constraints *sc) |
656 | 119 | { |
657 | 119 | isl_space *space; |
658 | 119 | enum isl_edge_type i; |
659 | 119 | |
660 | 119 | if (!sc) |
661 | 0 | return NULL; |
662 | 119 | |
663 | 119 | space = isl_union_set_get_space(sc->domain); |
664 | 119 | space = isl_space_align_params(space, isl_set_get_space(sc->context)); |
665 | 714 | for (i = isl_edge_first; i <= isl_edge_last714 ; ++i595 ) |
666 | 595 | space = isl_space_align_params(space, |
667 | 595 | isl_union_map_get_space(sc->constraint[i])); |
668 | 119 | |
669 | 714 | for (i = isl_edge_first; i <= isl_edge_last714 ; ++i595 ) { |
670 | 595 | sc->constraint[i] = isl_union_map_align_params( |
671 | 595 | sc->constraint[i], isl_space_copy(space)); |
672 | 595 | if (!sc->constraint[i]) |
673 | 0 | space = isl_space_free(space); |
674 | 595 | } |
675 | 119 | sc->context = isl_set_align_params(sc->context, isl_space_copy(space)); |
676 | 119 | sc->domain = isl_union_set_align_params(sc->domain, space); |
677 | 119 | if (!sc->context || 119 !sc->domain119 ) |
678 | 0 | return isl_schedule_constraints_free(sc); |
679 | 119 | |
680 | 119 | return sc; |
681 | 119 | } |
682 | | |
683 | | /* Add the number of basic maps in "map" to *n. |
684 | | */ |
685 | | static isl_stat add_n_basic_map(__isl_take isl_map *map, void *user) |
686 | 636 | { |
687 | 636 | int *n = user; |
688 | 636 | |
689 | 636 | *n += isl_map_n_basic_map(map); |
690 | 636 | isl_map_free(map); |
691 | 636 | |
692 | 636 | return isl_stat_ok; |
693 | 636 | } |
694 | | |
695 | | /* Return the total number of isl_basic_maps in the constraints of "sc". |
696 | | * Return -1 on error. |
697 | | */ |
698 | | int isl_schedule_constraints_n_basic_map( |
699 | | __isl_keep isl_schedule_constraints *sc) |
700 | 141 | { |
701 | 141 | enum isl_edge_type i; |
702 | 141 | int n = 0; |
703 | 141 | |
704 | 141 | if (!sc) |
705 | 0 | return -1; |
706 | 846 | for (i = isl_edge_first; 141 i <= isl_edge_last846 ; ++i705 ) |
707 | 705 | if (705 isl_union_map_foreach_map(sc->constraint[i], |
708 | 705 | &add_n_basic_map, &n) < 0) |
709 | 0 | return -1; |
710 | 141 | |
711 | 141 | return n; |
712 | 141 | } |
713 | | |
714 | | /* Return the total number of isl_maps in the constraints of "sc". |
715 | | */ |
716 | | int isl_schedule_constraints_n_map(__isl_keep isl_schedule_constraints *sc) |
717 | 141 | { |
718 | 141 | enum isl_edge_type i; |
719 | 141 | int n = 0; |
720 | 141 | |
721 | 846 | for (i = isl_edge_first; i <= isl_edge_last846 ; ++i705 ) |
722 | 705 | n += isl_union_map_n_map(sc->constraint[i]); |
723 | 141 | |
724 | 141 | return n; |
725 | 141 | } |