Coverage Report

Created: 2017-08-21 19:50

/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
148
{
50
148
  isl_ctx *ctx;
51
148
  isl_schedule_constraints *sc_copy;
52
148
  enum isl_edge_type i;
53
148
54
148
  ctx = isl_union_set_get_ctx(sc->domain);
55
148
  sc_copy = isl_calloc_type(ctx, struct isl_schedule_constraints);
56
148
  if (!sc_copy)
57
0
    return NULL;
58
148
59
148
  sc_copy->domain = isl_union_set_copy(sc->domain);
60
148
  sc_copy->context = isl_set_copy(sc->context);
61
148
  if (
!sc_copy->domain || 148
!sc_copy->context148
)
62
0
    return isl_schedule_constraints_free(sc_copy);
63
148
64
888
  
for (i = isl_edge_first; 148
i <= isl_edge_last888
;
++i740
)
{740
65
740
    sc_copy->constraint[i] = isl_union_map_copy(sc->constraint[i]);
66
740
    if (!sc_copy->constraint[i])
67
0
      return isl_schedule_constraints_free(sc_copy);
68
740
  }
69
148
70
148
  return sc_copy;
71
148
}
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
140
{
80
140
  return isl_calloc_type(ctx, struct isl_schedule_constraints);
81
140
}
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
140
{
89
140
  isl_space *space;
90
140
  isl_union_map *empty;
91
140
  enum isl_edge_type i;
92
140
93
140
  if (!sc)
94
0
    return NULL;
95
140
  
if (140
!sc->domain140
)
96
0
    return isl_schedule_constraints_free(sc);
97
140
  space = isl_union_set_get_space(sc->domain);
98
140
  if (!sc->context)
99
140
    sc->context = isl_set_universe(isl_space_copy(space));
100
140
  empty = isl_union_map_empty(space);
101
840
  for (i = isl_edge_first; 
i <= isl_edge_last840
;
++i700
)
{700
102
700
    if (sc->constraint[i])
103
0
      continue;
104
700
    sc->constraint[i] = isl_union_map_copy(empty);
105
700
    if (!sc->constraint[i])
106
0
      sc->domain = isl_union_set_free(sc->domain);
107
700
  }
108
140
  isl_union_map_free(empty);
109
140
110
140
  if (
!sc->domain || 140
!sc->context140
)
111
0
    return isl_schedule_constraints_free(sc);
112
140
113
140
  return sc;
114
140
}
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
140
{
122
140
  isl_ctx *ctx;
123
140
  isl_schedule_constraints *sc;
124
140
125
140
  if (!domain)
126
0
    return NULL;
127
140
128
140
  ctx = isl_union_set_get_ctx(domain);
129
140
  sc = isl_schedule_constraints_alloc(ctx);
130
140
  if (!sc)
131
0
    goto error;
132
140
133
140
  sc->domain = domain;
134
140
  return isl_schedule_constraints_init(sc);
135
140
error:
136
0
  isl_union_set_free(domain);
137
140
  return NULL;
138
140
}
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
22
error:
172
0
  isl_schedule_constraints_free(sc);
173
0
  isl_set_free(context);
174
22
  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
330
{
183
330
  if (
!sc || 330
!c330
)
184
0
    goto error;
185
330
186
330
  isl_union_map_free(sc->constraint[type]);
187
330
  sc->constraint[type] = c;
188
330
189
330
  return sc;
190
330
error:
191
0
  isl_schedule_constraints_free(sc);
192
0
  isl_union_map_free(c);
193
330
  return NULL;
194
330
}
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
116
{
202
116
  return isl_schedule_constraints_set(sc, isl_edge_validity, validity);
203
116
}
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
79
{
211
79
  return isl_schedule_constraints_set(sc, isl_edge_coincidence,
212
79
            coincidence);
213
79
}
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
111
{
221
111
  return isl_schedule_constraints_set(sc, isl_edge_proximity, proximity);
222
111
}
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
288
{
242
288
  enum isl_edge_type i;
243
288
244
288
  if (!sc)
245
0
    return NULL;
246
288
247
288
  isl_union_set_free(sc->domain);
248
288
  isl_set_free(sc->context);
249
1.72k
  for (i = isl_edge_first; 
i <= isl_edge_last1.72k
;
++i1.44k
)
250
1.44k
    isl_union_map_free(sc->constraint[i]);
251
288
252
288
  free(sc);
253
288
254
288
  return NULL;
255
288
}
256
257
isl_ctx *isl_schedule_constraints_get_ctx(
258
  __isl_keep isl_schedule_constraints *sc)
259
258
{
260
258
  return sc ? isl_union_set_get_ctx(sc->domain) : NULL;
261
258
}
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
538
{
268
538
  if (!sc)
269
0
    return NULL;
270
538
271
538
  return isl_union_set_copy(sc->domain);
272
538
}
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
140
{
279
140
  if (!sc)
280
0
    return NULL;
281
140
282
140
  return isl_set_copy(sc->context);
283
140
}
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.40k
{
290
1.40k
  if (!sc)
291
0
    return NULL;
292
1.40k
293
1.40k
  return isl_union_map_copy(sc->constraint[type]);
294
1.40k
}
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
148
error:
353
0
  isl_schedule_constraints_free(sc);
354
0
  isl_union_map_free(c);
355
148
  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
)
{0
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
)
{0
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
)
{0
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
)
{0
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
118
{
657
118
  isl_space *space;
658
118
  enum isl_edge_type i;
659
118
660
118
  if (!sc)
661
0
    return NULL;
662
118
663
118
  space = isl_union_set_get_space(sc->domain);
664
118
  space = isl_space_align_params(space, isl_set_get_space(sc->context));
665
708
  for (i = isl_edge_first; 
i <= isl_edge_last708
;
++i590
)
666
590
    space = isl_space_align_params(space,
667
590
            isl_union_map_get_space(sc->constraint[i]));
668
118
669
708
  for (i = isl_edge_first; 
i <= isl_edge_last708
;
++i590
)
{590
670
590
    sc->constraint[i] = isl_union_map_align_params(
671
590
            sc->constraint[i], isl_space_copy(space));
672
590
    if (!sc->constraint[i])
673
0
      space = isl_space_free(space);
674
590
  }
675
118
  sc->context = isl_set_align_params(sc->context, isl_space_copy(space));
676
118
  sc->domain = isl_union_set_align_params(sc->domain, space);
677
118
  if (
!sc->context || 118
!sc->domain118
)
678
0
    return isl_schedule_constraints_free(sc);
679
118
680
118
  return sc;
681
118
}
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
630
{
687
630
  int *n = user;
688
630
689
630
  *n += isl_map_n_basic_map(map);
690
630
  isl_map_free(map);
691
630
692
630
  return isl_stat_ok;
693
630
}
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
140
{
701
140
  enum isl_edge_type i;
702
140
  int n = 0;
703
140
704
140
  if (!sc)
705
0
    return -1;
706
840
  
for (i = isl_edge_first; 140
i <= isl_edge_last840
;
++i700
)
707
700
    
if (700
isl_union_map_foreach_map(sc->constraint[i],700
708
700
            &add_n_basic_map, &n) < 0)
709
0
      return -1;
710
140
711
140
  return n;
712
140
}
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
140
{
718
140
  enum isl_edge_type i;
719
140
  int n = 0;
720
140
721
840
  for (i = isl_edge_first; 
i <= isl_edge_last840
;
++i700
)
722
700
    n += isl_union_map_n_map(sc->constraint[i]);
723
140
724
140
  return n;
725
140
}