Coverage Report

Created: 2017-03-28 09:59

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