Coverage Report

Created: 2018-02-20 23:11

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