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_band.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2013-2014 Ecole Normale Superieure
3
 * Copyright 2014      INRIA Rocquencourt
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
 * and Inria Paris - Rocquencourt, Domaine de Voluceau - Rocquencourt,
10
 * B.P. 105 - 78153 Le Chesnay, France
11
 */
12
13
#include <string.h>
14
#include <isl/map.h>
15
#include <isl/schedule_node.h>
16
#include <isl_schedule_band.h>
17
#include <isl_schedule_private.h>
18
19
isl_ctx *isl_schedule_band_get_ctx(__isl_keep isl_schedule_band *band)
20
2.58k
{
21
2.58k
  return band ? isl_multi_union_pw_aff_get_ctx(band->mupa) : NULL;
22
2.58k
}
23
24
/* Return a new uninitialized isl_schedule_band.
25
 */
26
static __isl_give isl_schedule_band *isl_schedule_band_alloc(isl_ctx *ctx)
27
2.46k
{
28
2.46k
  isl_schedule_band *band;
29
2.46k
30
2.46k
  band = isl_calloc_type(ctx, isl_schedule_band);
31
2.46k
  if (!band)
32
0
    return NULL;
33
2.46k
34
2.46k
  band->ref = 1;
35
2.46k
36
2.46k
  return band;
37
2.46k
}
38
39
/* Return a new isl_schedule_band with partial schedule "mupa".
40
 * First replace "mupa" by its greatest integer part to ensure
41
 * that the schedule is always integral.
42
 * The band is not marked permutable, the dimensions are not
43
 * marked coincident and the AST build options are empty.
44
 * Since there are no build options, the node is not anchored.
45
 */
46
__isl_give isl_schedule_band *isl_schedule_band_from_multi_union_pw_aff(
47
  __isl_take isl_multi_union_pw_aff *mupa)
48
1.51k
{
49
1.51k
  isl_ctx *ctx;
50
1.51k
  isl_schedule_band *band;
51
1.51k
  isl_space *space;
52
1.51k
53
1.51k
  mupa = isl_multi_union_pw_aff_floor(mupa);
54
1.51k
  if (!mupa)
55
0
    return NULL;
56
1.51k
  ctx = isl_multi_union_pw_aff_get_ctx(mupa);
57
1.51k
  band = isl_schedule_band_alloc(ctx);
58
1.51k
  if (!band)
59
0
    goto error;
60
1.51k
61
1.51k
  band->n = isl_multi_union_pw_aff_dim(mupa, isl_dim_set);
62
1.51k
  band->coincident = isl_calloc_array(ctx, int, band->n);
63
1.51k
  band->mupa = mupa;
64
1.51k
  space = isl_space_params_alloc(ctx, 0);
65
1.51k
  band->ast_build_options = isl_union_set_empty(space);
66
1.51k
  band->anchored = 0;
67
1.51k
68
1.51k
  if (
(band->n && 1.51k
!band->coincident1.51k
) ||
!band->ast_build_options1.51k
)
69
0
    return isl_schedule_band_free(band);
70
1.51k
71
1.51k
  return band;
72
0
error:
73
0
  isl_multi_union_pw_aff_free(mupa);
74
0
  return NULL;
75
1.51k
}
76
77
/* Create a duplicate of the given isl_schedule_band.
78
 */
79
__isl_give isl_schedule_band *isl_schedule_band_dup(
80
  __isl_keep isl_schedule_band *band)
81
950
{
82
950
  int i;
83
950
  isl_ctx *ctx;
84
950
  isl_schedule_band *dup;
85
950
86
950
  if (!band)
87
0
    return NULL;
88
950
89
950
  ctx = isl_schedule_band_get_ctx(band);
90
950
  dup = isl_schedule_band_alloc(ctx);
91
950
  if (!dup)
92
0
    return NULL;
93
950
94
950
  dup->n = band->n;
95
950
  dup->coincident = isl_alloc_array(ctx, int, band->n);
96
950
  if (
band->n && 950
!dup->coincident950
)
97
0
    return isl_schedule_band_free(dup);
98
950
99
2.45k
  
for (i = 0; 950
i < band->n2.45k
;
++i1.50k
)
100
1.50k
    dup->coincident[i] = band->coincident[i];
101
950
  dup->permutable = band->permutable;
102
950
103
950
  dup->mupa = isl_multi_union_pw_aff_copy(band->mupa);
104
950
  dup->ast_build_options = isl_union_set_copy(band->ast_build_options);
105
950
  if (
!dup->mupa || 950
!dup->ast_build_options950
)
106
0
    return isl_schedule_band_free(dup);
107
950
108
950
  
if (950
band->loop_type950
)
{15
109
15
    dup->loop_type = isl_alloc_array(ctx,
110
15
              enum isl_ast_loop_type, band->n);
111
15
    if (
band->n && 15
!dup->loop_type15
)
112
0
      return isl_schedule_band_free(dup);
113
50
    
for (i = 0; 15
i < band->n50
;
++i35
)
114
35
      dup->loop_type[i] = band->loop_type[i];
115
15
  }
116
950
  
if (950
band->isolate_loop_type950
)
{0
117
0
    dup->isolate_loop_type = isl_alloc_array(ctx,
118
0
              enum isl_ast_loop_type, band->n);
119
0
    if (
band->n && 0
!dup->isolate_loop_type0
)
120
0
      return isl_schedule_band_free(dup);
121
0
    
for (i = 0; 0
i < band->n0
;
++i0
)
122
0
      dup->isolate_loop_type[i] = band->isolate_loop_type[i];
123
0
  }
124
950
125
950
  return dup;
126
950
}
127
128
/* Return an isl_schedule_band that is equal to "band" and that has only
129
 * a single reference.
130
 */
131
__isl_give isl_schedule_band *isl_schedule_band_cow(
132
  __isl_take isl_schedule_band *band)
133
1.01k
{
134
1.01k
  if (!band)
135
0
    return NULL;
136
1.01k
137
1.01k
  
if (1.01k
band->ref == 11.01k
)
138
62
    return band;
139
950
  band->ref--;
140
950
  return isl_schedule_band_dup(band);
141
1.01k
}
142
143
/* Return a new reference to "band".
144
 */
145
__isl_give isl_schedule_band *isl_schedule_band_copy(
146
  __isl_keep isl_schedule_band *band)
147
2.33k
{
148
2.33k
  if (!band)
149
0
    return NULL;
150
2.33k
151
2.33k
  band->ref++;
152
2.33k
  return band;
153
2.33k
}
154
155
/* Free a reference to "band" and return NULL.
156
 */
157
__isl_null isl_schedule_band *isl_schedule_band_free(
158
  __isl_take isl_schedule_band *band)
159
3.85k
{
160
3.85k
  if (!band)
161
0
    return NULL;
162
3.85k
163
3.85k
  
if (3.85k
--band->ref > 03.85k
)
164
1.38k
    return NULL;
165
3.85k
166
2.46k
  isl_multi_union_pw_aff_free(band->mupa);
167
2.46k
  isl_union_set_free(band->ast_build_options);
168
2.46k
  free(band->loop_type);
169
2.46k
  free(band->isolate_loop_type);
170
2.46k
  free(band->coincident);
171
2.46k
  free(band);
172
2.46k
173
2.46k
  return NULL;
174
3.85k
}
175
176
/* Are "band1" and "band2" obviously equal?
177
 */
178
isl_bool isl_schedule_band_plain_is_equal(__isl_keep isl_schedule_band *band1,
179
  __isl_keep isl_schedule_band *band2)
180
0
{
181
0
  int i;
182
0
  isl_bool equal;
183
0
184
0
  if (
!band1 || 0
!band20
)
185
0
    return isl_bool_error;
186
0
  
if (0
band1 == band20
)
187
0
    return isl_bool_true;
188
0
189
0
  
if (0
band1->n != band2->n0
)
190
0
    return isl_bool_false;
191
0
  
for (i = 0; 0
i < band1->n0
;
++i0
)
192
0
    
if (0
band1->coincident[i] != band2->coincident[i]0
)
193
0
      return isl_bool_false;
194
0
  
if (0
band1->permutable != band2->permutable0
)
195
0
    return isl_bool_false;
196
0
197
0
  equal = isl_multi_union_pw_aff_plain_is_equal(band1->mupa, band2->mupa);
198
0
  if (
equal < 0 || 0
!equal0
)
199
0
    return equal;
200
0
201
0
  
if (0
!band1->loop_type != !band2->loop_type0
)
202
0
    return isl_bool_false;
203
0
  
if (0
band1->loop_type0
)
204
0
    
for (i = 0; 0
i < band1->n0
;
++i0
)
205
0
      
if (0
band1->loop_type[i] != band2->loop_type[i]0
)
206
0
        return isl_bool_false;
207
0
208
0
  
if (0
!band1->isolate_loop_type != !band2->isolate_loop_type0
)
209
0
    return isl_bool_false;
210
0
  
if (0
band1->isolate_loop_type0
)
211
0
    
for (i = 0; 0
i < band1->n0
;
++i0
)
212
0
      
if (0
band1->isolate_loop_type[i] !=0
213
0
            band2->isolate_loop_type[i])
214
0
        return isl_bool_false;
215
0
216
0
  return isl_union_set_is_equal(band1->ast_build_options,
217
0
          band2->ast_build_options);
218
0
}
219
220
/* Return the number of scheduling dimensions in the band.
221
 */
222
int isl_schedule_band_n_member(__isl_keep isl_schedule_band *band)
223
28.8k
{
224
28.8k
  return band ? 
band->n28.8k
:
00
;
225
28.8k
}
226
227
/* Is the given scheduling dimension coincident within the band and
228
 * with respect to the coincidence constraints?
229
 */
230
isl_bool isl_schedule_band_member_get_coincident(
231
  __isl_keep isl_schedule_band *band, int pos)
232
587
{
233
587
  if (!band)
234
0
    return isl_bool_error;
235
587
236
587
  
if (587
pos < 0 || 587
pos >= band->n587
)
237
0
    isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid,
238
587
      "invalid member position", return isl_bool_error);
239
587
240
587
  return band->coincident[pos];
241
587
}
242
243
/* Mark the given scheduling dimension as being coincident or not
244
 * according to "coincident".
245
 */
246
__isl_give isl_schedule_band *isl_schedule_band_member_set_coincident(
247
  __isl_take isl_schedule_band *band, int pos, int coincident)
248
158
{
249
158
  if (!band)
250
0
    return NULL;
251
158
  
if (158
isl_schedule_band_member_get_coincident(band, pos) == coincident158
)
252
0
    return band;
253
158
  band = isl_schedule_band_cow(band);
254
158
  if (!band)
255
0
    return NULL;
256
158
257
158
  
if (158
pos < 0 || 158
pos >= band->n158
)
258
0
    isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid,
259
158
      "invalid member position",
260
158
      return isl_schedule_band_free(band));
261
158
262
158
  band->coincident[pos] = coincident;
263
158
264
158
  return band;
265
158
}
266
267
/* Is the schedule band mark permutable?
268
 */
269
isl_bool isl_schedule_band_get_permutable(__isl_keep isl_schedule_band *band)
270
418
{
271
418
  if (!band)
272
0
    return isl_bool_error;
273
418
  return band->permutable;
274
418
}
275
276
/* Mark the schedule band permutable or not according to "permutable"?
277
 */
278
__isl_give isl_schedule_band *isl_schedule_band_set_permutable(
279
  __isl_take isl_schedule_band *band, int permutable)
280
125
{
281
125
  if (!band)
282
0
    return NULL;
283
125
  
if (125
band->permutable == permutable125
)
284
0
    return band;
285
125
  band = isl_schedule_band_cow(band);
286
125
  if (!band)
287
0
    return NULL;
288
125
289
125
  band->permutable = permutable;
290
125
291
125
  return band;
292
125
}
293
294
/* Is the band node "node" anchored?  That is, does it reference
295
 * the outer band nodes?
296
 */
297
int isl_schedule_band_is_anchored(__isl_keep isl_schedule_band *band)
298
3.59k
{
299
3.59k
  return band ? 
band->anchored3.59k
:
-10
;
300
3.59k
}
301
302
/* Return the schedule space of the band.
303
 */
304
__isl_give isl_space *isl_schedule_band_get_space(
305
  __isl_keep isl_schedule_band *band)
306
1.57k
{
307
1.57k
  if (!band)
308
0
    return NULL;
309
1.57k
  return isl_multi_union_pw_aff_get_space(band->mupa);
310
1.57k
}
311
312
/* Intersect the domain of the band schedule of "band" with "domain".
313
 */
314
__isl_give isl_schedule_band *isl_schedule_band_intersect_domain(
315
  __isl_take isl_schedule_band *band, __isl_take isl_union_set *domain)
316
2
{
317
2
  band = isl_schedule_band_cow(band);
318
2
  if (
!band || 2
!domain2
)
319
0
    goto error;
320
2
321
2
  band->mupa = isl_multi_union_pw_aff_intersect_domain(band->mupa,
322
2
                domain);
323
2
  if (!band->mupa)
324
0
    return isl_schedule_band_free(band);
325
2
326
2
  return band;
327
0
error:
328
0
  isl_schedule_band_free(band);
329
0
  isl_union_set_free(domain);
330
0
  return NULL;
331
2
}
332
333
/* Return the schedule of the band in isolation.
334
 */
335
__isl_give isl_multi_union_pw_aff *isl_schedule_band_get_partial_schedule(
336
  __isl_keep isl_schedule_band *band)
337
6.48k
{
338
6.48k
  return band ? isl_multi_union_pw_aff_copy(band->mupa) : NULL;
339
6.48k
}
340
341
/* Replace the schedule of "band" by "schedule".
342
 */
343
__isl_give isl_schedule_band *isl_schedule_band_set_partial_schedule(
344
  __isl_take isl_schedule_band *band,
345
  __isl_take isl_multi_union_pw_aff *schedule)
346
2
{
347
2
  band = isl_schedule_band_cow(band);
348
2
  if (
!band || 2
!schedule2
)
349
0
    goto error;
350
2
351
2
  isl_multi_union_pw_aff_free(band->mupa);
352
2
  band->mupa = schedule;
353
2
354
2
  return band;
355
0
error:
356
0
  isl_schedule_band_free(band);
357
0
  isl_multi_union_pw_aff_free(schedule);
358
0
  return NULL;
359
2
}
360
361
/* Return the loop AST generation type for the band member of "band"
362
 * at position "pos".
363
 */
364
enum isl_ast_loop_type isl_schedule_band_member_get_ast_loop_type(
365
  __isl_keep isl_schedule_band *band, int pos)
366
694
{
367
694
  if (!band)
368
0
    return isl_ast_loop_error;
369
694
370
694
  
if (694
pos < 0 || 694
pos >= band->n694
)
371
0
    isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid,
372
694
      "invalid member position", return -1);
373
694
374
694
  
if (694
!band->loop_type694
)
375
618
    return isl_ast_loop_default;
376
694
377
76
  return band->loop_type[pos];
378
694
}
379
380
/* Set the loop AST generation type for the band member of "band"
381
 * at position "pos" to "type".
382
 */
383
__isl_give isl_schedule_band *isl_schedule_band_member_set_ast_loop_type(
384
  __isl_take isl_schedule_band *band, int pos,
385
  enum isl_ast_loop_type type)
386
0
{
387
0
  if (!band)
388
0
    return NULL;
389
0
  
if (0
isl_schedule_band_member_get_ast_loop_type(band, pos) == type0
)
390
0
    return band;
391
0
392
0
  
if (0
pos < 0 || 0
pos >= band->n0
)
393
0
    isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid,
394
0
      "invalid member position",
395
0
      return isl_schedule_band_free(band));
396
0
397
0
  band = isl_schedule_band_cow(band);
398
0
  if (!band)
399
0
    return isl_schedule_band_free(band);
400
0
401
0
  
if (0
!band->loop_type0
)
{0
402
0
    isl_ctx *ctx;
403
0
404
0
    ctx = isl_schedule_band_get_ctx(band);
405
0
    band->loop_type = isl_calloc_array(ctx,
406
0
              enum isl_ast_loop_type, band->n);
407
0
    if (
band->n && 0
!band->loop_type0
)
408
0
      return isl_schedule_band_free(band);
409
0
  }
410
0
411
0
  band->loop_type[pos] = type;
412
0
413
0
  return band;
414
0
}
415
416
/* Return the loop AST generation type for the band member of "band"
417
 * at position "pos" for the part that has been isolated by the isolate option.
418
 */
419
enum isl_ast_loop_type isl_schedule_band_member_get_isolate_ast_loop_type(
420
  __isl_keep isl_schedule_band *band, int pos)
421
566
{
422
566
  if (!band)
423
0
    return isl_ast_loop_error;
424
566
425
566
  
if (566
pos < 0 || 566
pos >= band->n566
)
426
0
    isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid,
427
566
      "invalid member position", return -1);
428
566
429
566
  
if (566
!band->isolate_loop_type566
)
430
37
    return isl_ast_loop_default;
431
566
432
529
  return band->isolate_loop_type[pos];
433
566
}
434
435
/* Set the loop AST generation type for the band member of "band"
436
 * at position "pos" to "type" for the part that has been isolated
437
 * by the isolate option.
438
 */
439
__isl_give isl_schedule_band *
440
isl_schedule_band_member_set_isolate_ast_loop_type(
441
  __isl_take isl_schedule_band *band, int pos,
442
  enum isl_ast_loop_type type)
443
0
{
444
0
  if (!band)
445
0
    return NULL;
446
0
  
if (0
isl_schedule_band_member_get_isolate_ast_loop_type(band, pos) ==0
447
0
                  type)
448
0
    return band;
449
0
450
0
  
if (0
pos < 0 || 0
pos >= band->n0
)
451
0
    isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid,
452
0
      "invalid member position",
453
0
      return isl_schedule_band_free(band));
454
0
455
0
  band = isl_schedule_band_cow(band);
456
0
  if (!band)
457
0
    return isl_schedule_band_free(band);
458
0
459
0
  
if (0
!band->isolate_loop_type0
)
{0
460
0
    isl_ctx *ctx;
461
0
462
0
    ctx = isl_schedule_band_get_ctx(band);
463
0
    band->isolate_loop_type = isl_calloc_array(ctx,
464
0
              enum isl_ast_loop_type, band->n);
465
0
    if (
band->n && 0
!band->isolate_loop_type0
)
466
0
      return isl_schedule_band_free(band);
467
0
  }
468
0
469
0
  band->isolate_loop_type[pos] = type;
470
0
471
0
  return band;
472
0
}
473
474
static const char *option_str[] = {
475
  [isl_ast_loop_atomic] = "atomic",
476
  [isl_ast_loop_unroll] = "unroll",
477
  [isl_ast_loop_separate] = "separate"
478
};
479
480
/* Given a parameter space "space", extend it to a set space
481
 *
482
 *  { type[x] }
483
 *
484
 * or
485
 *
486
 *  { [isolate[] -> type[x]] }
487
 *
488
 * depending on whether "isolate" is set.
489
 * These can be used to encode loop AST generation options of the given type.
490
 */
491
static __isl_give isl_space *loop_type_space(__isl_take isl_space *space,
492
  enum isl_ast_loop_type type, int isolate)
493
552
{
494
552
  const char *name;
495
552
496
552
  name = option_str[type];
497
552
  space = isl_space_set_from_params(space);
498
552
  space = isl_space_add_dims(space, isl_dim_set, 1);
499
552
  space = isl_space_set_tuple_name(space, isl_dim_set, name);
500
552
  if (!isolate)
501
444
    return space;
502
108
  space = isl_space_from_range(space);
503
108
  space = isl_space_set_tuple_name(space, isl_dim_in, "isolate");
504
108
  space = isl_space_wrap(space);
505
108
506
108
  return space;
507
552
}
508
509
/* Add encodings of the "n" loop AST generation options "type" to "options".
510
 * If "isolate" is set, then these options refer to the isolated part.
511
 *
512
 * In particular, for each sequence of consecutive identical types "t",
513
 * different from the default, add an option
514
 *
515
 *  { t[x] : first <= x <= last }
516
 *
517
 * or
518
 *
519
 *  { [isolate[] -> t[x]] : first <= x <= last }
520
 */
521
static __isl_give isl_union_set *add_loop_types(
522
  __isl_take isl_union_set *options, int n, enum isl_ast_loop_type *type,
523
  int isolate)
524
0
{
525
0
  int i;
526
0
527
0
  if (!type)
528
0
    return options;
529
0
  
if (0
!options0
)
530
0
    return NULL;
531
0
532
0
  
for (i = 0; 0
i < n0
;
++i0
)
{0
533
0
    int first;
534
0
    isl_space *space;
535
0
    isl_set *option;
536
0
537
0
    if (type[i] == isl_ast_loop_default)
538
0
      continue;
539
0
540
0
    first = i;
541
0
    while (
i + 1 < n && 0
type[i + 1] == type[i]0
)
542
0
      ++i;
543
0
544
0
    space = isl_union_set_get_space(options);
545
0
    space = loop_type_space(space, type[i], isolate);
546
0
    option = isl_set_universe(space);
547
0
    option = isl_set_lower_bound_si(option, isl_dim_set, 0, first);
548
0
    option = isl_set_upper_bound_si(option, isl_dim_set, 0, i);
549
0
    options = isl_union_set_add_set(options, option);
550
0
  }
551
0
552
0
  return options;
553
0
}
554
555
/* Return the AST build options associated to "band".
556
 */
557
__isl_give isl_union_set *isl_schedule_band_get_ast_build_options(
558
  __isl_keep isl_schedule_band *band)
559
0
{
560
0
  isl_union_set *options;
561
0
562
0
  if (!band)
563
0
    return NULL;
564
0
565
0
  options = isl_union_set_copy(band->ast_build_options);
566
0
  options = add_loop_types(options, band->n, band->loop_type, 0);
567
0
  options = add_loop_types(options, band->n, band->isolate_loop_type, 1);
568
0
569
0
  return options;
570
0
}
571
572
/* Does "uset" contain any set that satisfies "is"?
573
 * "is" is assumed to set its integer argument to 1 if it is satisfied.
574
 */
575
static int has_any(__isl_keep isl_union_set *uset,
576
  isl_stat (*is)(__isl_take isl_set *set, void *user))
577
180
{
578
180
  int found = 0;
579
180
580
180
  if (
isl_union_set_foreach_set(uset, is, &found) < 0 && 180
!found87
)
581
0
    return -1;
582
180
583
180
  return found;
584
180
}
585
586
/* Does "set" live in a space of the form
587
 *
588
 *  isolate[[...] -> [...]]
589
 *
590
 * ?
591
 *
592
 * If so, set *found and abort the search.
593
 */
594
static isl_stat is_isolate(__isl_take isl_set *set, void *user)
595
56
{
596
56
  int *found = user;
597
56
598
56
  if (
isl_set_has_tuple_name(set)56
)
{48
599
48
    const char *name;
600
48
    name = isl_set_get_tuple_name(set);
601
48
    if (
isl_set_is_wrapping(set) && 48
!strcmp(name, "isolate")33
)
602
33
      *found = 1;
603
48
  }
604
56
  isl_set_free(set);
605
56
606
33
  return *found ? 
isl_stat_error33
:
isl_stat_ok23
;
607
56
}
608
609
/* Does "options" include an option of the ofrm
610
 *
611
 *  isolate[[...] -> [...]]
612
 *
613
 * ?
614
 */
615
static int has_isolate_option(__isl_keep isl_union_set *options)
616
60
{
617
60
  return has_any(options, &is_isolate);
618
60
}
619
620
/* Does "set" encode a loop AST generation option?
621
 */
622
static isl_stat is_loop_type_option(__isl_take isl_set *set, void *user)
623
83
{
624
83
  int *found = user;
625
83
626
83
  if (isl_set_dim(set, isl_dim_set) == 1 &&
627
53
      
isl_set_has_tuple_name(set)53
)
{45
628
45
    const char *name;
629
45
    enum isl_ast_loop_type type;
630
45
    name = isl_set_get_tuple_name(set);
631
45
    for (type = isl_ast_loop_atomic;
632
57
        
type <= isl_ast_loop_separate57
;
++type12
)
{57
633
57
      if (strcmp(name, option_str[type]))
634
12
        continue;
635
45
      *found = 1;
636
45
      break;
637
57
    }
638
45
  }
639
83
  isl_set_free(set);
640
83
641
45
  return *found ? 
isl_stat_error45
:
isl_stat_ok38
;
642
83
}
643
644
/* Does "set" encode a loop AST generation option for the isolated part?
645
 * That is, is of the form
646
 *
647
 *  { [isolate[] -> t[x]] }
648
 *
649
 * with t equal to "atomic", "unroll" or "separate"?
650
 */
651
static isl_stat is_isolate_loop_type_option(__isl_take isl_set *set, void *user)
652
71
{
653
71
  int *found = user;
654
71
  const char *name;
655
71
  enum isl_ast_loop_type type;
656
71
  isl_map *map;
657
71
658
71
  if (
!isl_set_is_wrapping(set)71
)
{37
659
37
    isl_set_free(set);
660
37
    return isl_stat_ok;
661
37
  }
662
34
  map = isl_set_unwrap(set);
663
34
  if (!isl_map_has_tuple_name(map, isl_dim_in) ||
664
25
      
!isl_map_has_tuple_name(map, isl_dim_out)9
)
{25
665
25
    isl_map_free(map);
666
25
    return isl_stat_ok;
667
25
  }
668
9
  name = isl_map_get_tuple_name(map, isl_dim_in);
669
9
  if (
!strcmp(name, "isolate")9
)
{9
670
9
    name = isl_map_get_tuple_name(map, isl_dim_out);
671
9
    for (type = isl_ast_loop_atomic;
672
18
        
type <= isl_ast_loop_separate18
;
++type9
)
{18
673
18
      if (strcmp(name, option_str[type]))
674
9
        continue;
675
9
      *found = 1;
676
9
      break;
677
18
    }
678
9
  }
679
9
  isl_map_free(map);
680
9
681
9
  return *found ? 
isl_stat_error9
:
isl_stat_ok0
;
682
34
}
683
684
/* Does "options" encode any loop AST generation options
685
 * for the isolated part?
686
 */
687
static int has_isolate_loop_type_options(__isl_keep isl_union_set *options)
688
60
{
689
60
  return has_any(options, &is_isolate_loop_type_option);
690
60
}
691
692
/* Does "options" encode any loop AST generation options?
693
 */
694
static int has_loop_type_options(__isl_keep isl_union_set *options)
695
60
{
696
60
  return has_any(options, &is_loop_type_option);
697
60
}
698
699
/* Extract the loop AST generation type for the band member
700
 * at position "pos" from "options".
701
 * If "isolate" is set, then extract the loop types for the isolated part.
702
 */
703
static enum isl_ast_loop_type extract_loop_type(
704
  __isl_keep isl_union_set *options, int pos, int isolate)
705
130
{
706
130
  isl_ctx *ctx;
707
130
  enum isl_ast_loop_type type, res = isl_ast_loop_default;
708
130
709
130
  ctx = isl_union_set_get_ctx(options);
710
130
  for (type = isl_ast_loop_atomic;
711
520
      
type <= isl_ast_loop_separate520
;
++type390
)
{390
712
390
    isl_space *space;
713
390
    isl_set *option;
714
390
    int empty;
715
390
716
390
    space = isl_union_set_get_space(options);
717
390
    space = loop_type_space(space, type, isolate);
718
390
    option = isl_union_set_extract_set(options, space);
719
390
    option = isl_set_fix_si(option, isl_dim_set, 0, pos);
720
390
    empty = isl_set_is_empty(option);
721
390
    isl_set_free(option);
722
390
723
390
    if (empty < 0)
724
0
      return isl_ast_loop_error;
725
390
    
if (390
empty390
)
726
260
      continue;
727
130
    
if (130
res != isl_ast_loop_default130
)
728
0
      isl_die(ctx, isl_error_invalid,
729
130
        "conflicting loop type options",
730
130
        return isl_ast_loop_error);
731
130
    res = type;
732
130
  }
733
130
734
130
  return res;
735
130
}
736
737
/* Extract the loop AST generation types for the members of "band"
738
 * from "options" and store them in band->loop_type.
739
 * Return -1 on error.
740
 */
741
static int extract_loop_types(__isl_keep isl_schedule_band *band,
742
  __isl_keep isl_union_set *options)
743
45
{
744
45
  int i;
745
45
746
45
  if (
!band->loop_type45
)
{35
747
35
    isl_ctx *ctx = isl_schedule_band_get_ctx(band);
748
35
    band->loop_type = isl_alloc_array(ctx,
749
35
              enum isl_ast_loop_type, band->n);
750
35
    if (
band->n && 35
!band->loop_type35
)
751
0
      return -1;
752
35
  }
753
148
  
for (i = 0; 45
i < band->n148
;
++i103
)
{103
754
103
    band->loop_type[i] = extract_loop_type(options, i, 0);
755
103
    if (band->loop_type[i] == isl_ast_loop_error)
756
0
      return -1;
757
103
  }
758
45
759
45
  return 0;
760
45
}
761
762
/* Extract the loop AST generation types for the members of "band"
763
 * from "options" for the isolated part and
764
 * store them in band->isolate_loop_type.
765
 * Return -1 on error.
766
 */
767
static int extract_isolate_loop_types(__isl_keep isl_schedule_band *band,
768
  __isl_keep isl_union_set *options)
769
9
{
770
9
  int i;
771
9
772
9
  if (
!band->isolate_loop_type9
)
{9
773
9
    isl_ctx *ctx = isl_schedule_band_get_ctx(band);
774
9
    band->isolate_loop_type = isl_alloc_array(ctx,
775
9
              enum isl_ast_loop_type, band->n);
776
9
    if (
band->n && 9
!band->isolate_loop_type9
)
777
0
      return -1;
778
9
  }
779
36
  
for (i = 0; 9
i < band->n36
;
++i27
)
{27
780
27
    band->isolate_loop_type[i] = extract_loop_type(options, i, 1);
781
27
    if (band->isolate_loop_type[i] == isl_ast_loop_error)
782
0
      return -1;
783
27
  }
784
9
785
9
  return 0;
786
9
}
787
788
/* Construct universe sets of the spaces that encode loop AST generation
789
 * types (for the isolated part if "isolate" is set).  That is, construct
790
 *
791
 *  { atomic[x]; separate[x]; unroll[x] }
792
 *
793
 * or
794
 *
795
 *  { [isolate[] -> atomic[x]]; [isolate[] -> separate[x]];
796
 *    [isolate[] -> unroll[x]] }
797
 */
798
static __isl_give isl_union_set *loop_types(__isl_take isl_space *space,
799
  int isolate)
800
54
{
801
54
  enum isl_ast_loop_type type;
802
54
  isl_union_set *types;
803
54
804
54
  types = isl_union_set_empty(space);
805
54
  for (type = isl_ast_loop_atomic;
806
216
      
type <= isl_ast_loop_separate216
;
++type162
)
{162
807
162
    isl_set *set;
808
162
809
162
    space = isl_union_set_get_space(types);
810
162
    space = loop_type_space(space, type, isolate);
811
162
    set = isl_set_universe(space);
812
162
    types = isl_union_set_add_set(types, set);
813
162
  }
814
54
815
54
  return types;
816
54
}
817
818
/* Remove all elements from spaces that encode loop AST generation types
819
 * from "options".
820
 */
821
static __isl_give isl_union_set *clear_loop_types(
822
  __isl_take isl_union_set *options)
823
45
{
824
45
  isl_union_set *types;
825
45
826
45
  types = loop_types(isl_union_set_get_space(options), 0);
827
45
  options = isl_union_set_subtract(options, types);
828
45
829
45
  return options;
830
45
}
831
832
/* Remove all elements from spaces that encode loop AST generation types
833
 * for the isolated part from "options".
834
 */
835
static __isl_give isl_union_set *clear_isolate_loop_types(
836
  __isl_take isl_union_set *options)
837
9
{
838
9
  isl_union_set *types;
839
9
840
9
  types = loop_types(isl_union_set_get_space(options), 1);
841
9
  options = isl_union_set_subtract(options, types);
842
9
843
9
  return options;
844
9
}
845
846
/* Replace the AST build options associated to "band" by "options".
847
 * If there are any loop AST generation type options, then they
848
 * are extracted and stored in band->loop_type.  Otherwise,
849
 * band->loop_type is removed to indicate that the default applies
850
 * to all members.  Similarly for the loop AST generation type options
851
 * for the isolated part, which are stored in band->isolate_loop_type.
852
 * The remaining options are stored in band->ast_build_options.
853
 *
854
 * Set anchored if the options include an isolate option since the
855
 * domain of the wrapped map references the outer band node schedules.
856
 */
857
__isl_give isl_schedule_band *isl_schedule_band_set_ast_build_options(
858
  __isl_take isl_schedule_band *band, __isl_take isl_union_set *options)
859
60
{
860
60
  int has_isolate, has_loop_type, has_isolate_loop_type;
861
60
862
60
  band = isl_schedule_band_cow(band);
863
60
  if (
!band || 60
!options60
)
864
0
    goto error;
865
60
  has_isolate = has_isolate_option(options);
866
60
  if (has_isolate < 0)
867
0
    goto error;
868
60
  has_loop_type = has_loop_type_options(options);
869
60
  if (has_loop_type < 0)
870
0
    goto error;
871
60
  has_isolate_loop_type = has_isolate_loop_type_options(options);
872
60
  if (has_isolate_loop_type < 0)
873
0
    goto error;
874
60
875
60
  
if (60
!has_loop_type60
)
{15
876
15
    free(band->loop_type);
877
15
    band->loop_type = NULL;
878
45
  } else {
879
45
    if (extract_loop_types(band, options) < 0)
880
0
      goto error;
881
45
    options = clear_loop_types(options);
882
45
    if (!options)
883
0
      goto error;
884
45
  }
885
60
886
60
  
if (60
!has_isolate_loop_type60
)
{51
887
51
    free(band->isolate_loop_type);
888
51
    band->isolate_loop_type = NULL;
889
9
  } else {
890
9
    if (extract_isolate_loop_types(band, options) < 0)
891
0
      goto error;
892
9
    options = clear_isolate_loop_types(options);
893
9
    if (!options)
894
0
      goto error;
895
9
  }
896
60
897
60
  isl_union_set_free(band->ast_build_options);
898
60
  band->ast_build_options = options;
899
60
  band->anchored = has_isolate;
900
60
901
60
  return band;
902
0
error:
903
0
  isl_schedule_band_free(band);
904
0
  isl_union_set_free(options);
905
0
  return NULL;
906
60
}
907
908
/* Return the "isolate" option associated to "band", assuming
909
 * it at appears at schedule depth "depth".
910
 *
911
 * The isolate option is of the form
912
 *
913
 *  isolate[[flattened outer bands] -> band]
914
 */
915
__isl_give isl_set *isl_schedule_band_get_ast_isolate_option(
916
  __isl_keep isl_schedule_band *band, int depth)
917
1.30k
{
918
1.30k
  isl_space *space;
919
1.30k
  isl_set *isolate;
920
1.30k
921
1.30k
  if (!band)
922
0
    return NULL;
923
1.30k
924
1.30k
  space = isl_schedule_band_get_space(band);
925
1.30k
  space = isl_space_from_range(space);
926
1.30k
  space = isl_space_add_dims(space, isl_dim_in, depth);
927
1.30k
  space = isl_space_wrap(space);
928
1.30k
  space = isl_space_set_tuple_name(space, isl_dim_set, "isolate");
929
1.30k
930
1.30k
  isolate = isl_union_set_extract_set(band->ast_build_options, space);
931
1.30k
932
1.30k
  return isolate;
933
1.30k
}
934
935
/* Replace the option "drop" in the AST build options by "add".
936
 * That is, remove "drop" and add "add".
937
 */
938
__isl_give isl_schedule_band *isl_schedule_band_replace_ast_build_option(
939
  __isl_take isl_schedule_band *band, __isl_take isl_set *drop,
940
  __isl_take isl_set *add)
941
60
{
942
60
  isl_union_set *options;
943
60
944
60
  band = isl_schedule_band_cow(band);
945
60
  if (!band)
946
0
    goto error;
947
60
948
60
  options = band->ast_build_options;
949
60
  options = isl_union_set_subtract(options, isl_union_set_from_set(drop));
950
60
  options = isl_union_set_union(options, isl_union_set_from_set(add));
951
60
  band->ast_build_options = options;
952
60
953
60
  if (!band->ast_build_options)
954
0
    return isl_schedule_band_free(band);
955
60
956
60
  return band;
957
0
error:
958
0
  isl_schedule_band_free(band);
959
0
  isl_set_free(drop);
960
0
  isl_set_free(add);
961
0
  return NULL;
962
60
}
963
964
/* Multiply the partial schedule of "band" with the factors in "mv".
965
 * Replace the result by its greatest integer part to ensure
966
 * that the schedule is always integral.
967
 */
968
__isl_give isl_schedule_band *isl_schedule_band_scale(
969
  __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv)
970
0
{
971
0
  band = isl_schedule_band_cow(band);
972
0
  if (
!band || 0
!mv0
)
973
0
    goto error;
974
0
  band->mupa = isl_multi_union_pw_aff_scale_multi_val(band->mupa, mv);
975
0
  band->mupa = isl_multi_union_pw_aff_floor(band->mupa);
976
0
  if (!band->mupa)
977
0
    return isl_schedule_band_free(band);
978
0
  return band;
979
0
error:
980
0
  isl_schedule_band_free(band);
981
0
  isl_multi_val_free(mv);
982
0
  return NULL;
983
0
}
984
985
/* Divide the partial schedule of "band" by the factors in "mv".
986
 * Replace the result by its greatest integer part to ensure
987
 * that the schedule is always integral.
988
 */
989
__isl_give isl_schedule_band *isl_schedule_band_scale_down(
990
  __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv)
991
0
{
992
0
  band = isl_schedule_band_cow(band);
993
0
  if (
!band || 0
!mv0
)
994
0
    goto error;
995
0
  band->mupa = isl_multi_union_pw_aff_scale_down_multi_val(band->mupa,
996
0
                mv);
997
0
  band->mupa = isl_multi_union_pw_aff_floor(band->mupa);
998
0
  if (!band->mupa)
999
0
    return isl_schedule_band_free(band);
1000
0
  return band;
1001
0
error:
1002
0
  isl_schedule_band_free(band);
1003
0
  isl_multi_val_free(mv);
1004
0
  return NULL;
1005
0
}
1006
1007
/* Reduce the partial schedule of "band" modulo the factors in "mv".
1008
 */
1009
__isl_give isl_schedule_band *isl_schedule_band_mod(
1010
  __isl_take isl_schedule_band *band, __isl_take isl_multi_val *mv)
1011
0
{
1012
0
  band = isl_schedule_band_cow(band);
1013
0
  if (
!band || 0
!mv0
)
1014
0
    goto error;
1015
0
  band->mupa = isl_multi_union_pw_aff_mod_multi_val(band->mupa, mv);
1016
0
  if (!band->mupa)
1017
0
    return isl_schedule_band_free(band);
1018
0
  return band;
1019
0
error:
1020
0
  isl_schedule_band_free(band);
1021
0
  isl_multi_val_free(mv);
1022
0
  return NULL;
1023
0
}
1024
1025
/* Shift the partial schedule of "band" by "shift" after checking
1026
 * that the domain of the partial schedule would not be affected
1027
 * by this shift.
1028
 */
1029
__isl_give isl_schedule_band *isl_schedule_band_shift(
1030
  __isl_take isl_schedule_band *band,
1031
  __isl_take isl_multi_union_pw_aff *shift)
1032
0
{
1033
0
  isl_union_set *dom1, *dom2;
1034
0
  isl_bool subset;
1035
0
1036
0
  band = isl_schedule_band_cow(band);
1037
0
  if (
!band || 0
!shift0
)
1038
0
    goto error;
1039
0
  dom1 = isl_multi_union_pw_aff_domain(
1040
0
        isl_multi_union_pw_aff_copy(band->mupa));
1041
0
  dom2 = isl_multi_union_pw_aff_domain(
1042
0
        isl_multi_union_pw_aff_copy(shift));
1043
0
  subset = isl_union_set_is_subset(dom1, dom2);
1044
0
  isl_union_set_free(dom1);
1045
0
  isl_union_set_free(dom2);
1046
0
  if (subset < 0)
1047
0
    goto error;
1048
0
  
if (0
!subset0
)
1049
0
    isl_die(isl_schedule_band_get_ctx(band), isl_error_invalid,
1050
0
      "domain of shift needs to include domain of "
1051
0
      "partial schedule", goto error);
1052
0
  band->mupa = isl_multi_union_pw_aff_add(band->mupa, shift);
1053
0
  if (!band->mupa)
1054
0
    return isl_schedule_band_free(band);
1055
0
  return band;
1056
0
error:
1057
0
  isl_schedule_band_free(band);
1058
0
  isl_multi_union_pw_aff_free(shift);
1059
0
  return NULL;
1060
0
}
1061
1062
/* Given the schedule of a band, construct the corresponding
1063
 * schedule for the tile loops based on the given tile sizes
1064
 * and return the result.
1065
 *
1066
 * If the scale tile loops options is set, then the tile loops
1067
 * are scaled by the tile sizes.
1068
 *
1069
 * That is replace each schedule dimension "i" by either
1070
 * "floor(i/s)" or "s * floor(i/s)".
1071
 */
1072
static isl_multi_union_pw_aff *isl_multi_union_pw_aff_tile(
1073
  __isl_take isl_multi_union_pw_aff *sched,
1074
  __isl_take isl_multi_val *sizes)
1075
68
{
1076
68
  isl_ctx *ctx;
1077
68
  int i, n;
1078
68
  isl_val *v;
1079
68
  int scale;
1080
68
1081
68
  ctx = isl_multi_val_get_ctx(sizes);
1082
68
  scale = isl_options_get_tile_scale_tile_loops(ctx);
1083
68
1084
68
  n = isl_multi_union_pw_aff_dim(sched, isl_dim_set);
1085
214
  for (i = 0; 
i < n214
;
++i146
)
{146
1086
146
    isl_union_pw_aff *upa;
1087
146
1088
146
    upa = isl_multi_union_pw_aff_get_union_pw_aff(sched, i);
1089
146
    v = isl_multi_val_get_val(sizes, i);
1090
146
1091
146
    upa = isl_union_pw_aff_scale_down_val(upa, isl_val_copy(v));
1092
146
    upa = isl_union_pw_aff_floor(upa);
1093
146
    if (scale)
1094
4
      upa = isl_union_pw_aff_scale_val(upa, isl_val_copy(v));
1095
146
    isl_val_free(v);
1096
146
1097
146
    sched = isl_multi_union_pw_aff_set_union_pw_aff(sched, i, upa);
1098
146
  }
1099
68
1100
68
  isl_multi_val_free(sizes);
1101
68
  return sched;
1102
68
}
1103
1104
/* Replace "band" by a band corresponding to the tile loops of a tiling
1105
 * with the given tile sizes.
1106
 */
1107
__isl_give isl_schedule_band *isl_schedule_band_tile(
1108
  __isl_take isl_schedule_band *band, __isl_take isl_multi_val *sizes)
1109
68
{
1110
68
  band = isl_schedule_band_cow(band);
1111
68
  if (
!band || 68
!sizes68
)
1112
0
    goto error;
1113
68
  band->mupa = isl_multi_union_pw_aff_tile(band->mupa, sizes);
1114
68
  if (!band->mupa)
1115
0
    return isl_schedule_band_free(band);
1116
68
  return band;
1117
0
error:
1118
0
  isl_schedule_band_free(band);
1119
0
  isl_multi_val_free(sizes);
1120
0
  return NULL;
1121
68
}
1122
1123
/* Replace "band" by a band corresponding to the point loops of a tiling
1124
 * with the given tile sizes.
1125
 * "tile" is the corresponding tile loop band.
1126
 *
1127
 * If the shift point loops option is set, then the point loops
1128
 * are shifted to start at zero.  That is, each schedule dimension "i"
1129
 * is replaced by "i - s * floor(i/s)".
1130
 * The expression "floor(i/s)" (or "s * floor(i/s)") is extracted from
1131
 * the tile band.
1132
 *
1133
 * Otherwise, the band is left untouched.
1134
 */
1135
__isl_give isl_schedule_band *isl_schedule_band_point(
1136
  __isl_take isl_schedule_band *band, __isl_keep isl_schedule_band *tile,
1137
  __isl_take isl_multi_val *sizes)
1138
68
{
1139
68
  isl_ctx *ctx;
1140
68
  isl_multi_union_pw_aff *scaled;
1141
68
1142
68
  if (
!band || 68
!sizes68
)
1143
0
    goto error;
1144
68
1145
68
  ctx = isl_schedule_band_get_ctx(band);
1146
68
  if (
!isl_options_get_tile_shift_point_loops(ctx)68
)
{2
1147
2
    isl_multi_val_free(sizes);
1148
2
    return band;
1149
2
  }
1150
66
  band = isl_schedule_band_cow(band);
1151
66
  if (!band)
1152
0
    goto error;
1153
66
1154
66
  scaled = isl_schedule_band_get_partial_schedule(tile);
1155
66
  if (!isl_options_get_tile_scale_tile_loops(ctx))
1156
65
    scaled = isl_multi_union_pw_aff_scale_multi_val(scaled, sizes);
1157
66
  else
1158
1
    isl_multi_val_free(sizes);
1159
66
  band->mupa = isl_multi_union_pw_aff_sub(band->mupa, scaled);
1160
66
  if (!band->mupa)
1161
0
    return isl_schedule_band_free(band);
1162
66
  return band;
1163
0
error:
1164
0
  isl_schedule_band_free(band);
1165
0
  isl_multi_val_free(sizes);
1166
0
  return NULL;
1167
66
}
1168
1169
/* Drop the "n" dimensions starting at "pos" from "band".
1170
 *
1171
 * We apply the transformation even if "n" is zero to ensure consistent
1172
 * behavior with respect to changes in the schedule space.
1173
 *
1174
 * The caller is responsible for updating the isolate option.
1175
 */
1176
__isl_give isl_schedule_band *isl_schedule_band_drop(
1177
  __isl_take isl_schedule_band *band, int pos, int n)
1178
60
{
1179
60
  int i;
1180
60
1181
60
  if (
pos < 0 || 60
n < 060
||
pos + n > band->n60
)
1182
0
    isl_die(isl_schedule_band_get_ctx(band), isl_error_internal,
1183
60
      "range out of bounds",
1184
60
      return isl_schedule_band_free(band));
1185
60
1186
60
  band = isl_schedule_band_cow(band);
1187
60
  if (!band)
1188
0
    return NULL;
1189
60
1190
60
  band->mupa = isl_multi_union_pw_aff_drop_dims(band->mupa,
1191
60
              isl_dim_set, pos, n);
1192
60
  if (!band->mupa)
1193
0
    return isl_schedule_band_free(band);
1194
60
1195
96
  
for (i = pos + n; 60
i < band->n96
;
++i36
)
1196
36
    band->coincident[i - n] = band->coincident[i];
1197
60
  if (band->loop_type)
1198
3
    
for (i = pos + n; 2
i < band->n3
;
++i1
)
1199
1
      band->loop_type[i - n] = band->loop_type[i];
1200
60
  if (band->isolate_loop_type)
1201
0
    
for (i = pos + n; 0
i < band->n0
;
++i0
)
1202
0
      band->isolate_loop_type[i - n] =
1203
0
                band->isolate_loop_type[i];
1204
60
1205
60
  band->n -= n;
1206
60
1207
60
  return band;
1208
60
}
1209
1210
/* Reset the user pointer on all identifiers of parameters and tuples
1211
 * in "band".
1212
 */
1213
__isl_give isl_schedule_band *isl_schedule_band_reset_user(
1214
  __isl_take isl_schedule_band *band)
1215
0
{
1216
0
  band = isl_schedule_band_cow(band);
1217
0
  if (!band)
1218
0
    return NULL;
1219
0
1220
0
  band->mupa = isl_multi_union_pw_aff_reset_user(band->mupa);
1221
0
  band->ast_build_options =
1222
0
    isl_union_set_reset_user(band->ast_build_options);
1223
0
  if (
!band->mupa || 0
!band->ast_build_options0
)
1224
0
    return isl_schedule_band_free(band);
1225
0
1226
0
  return band;
1227
0
}
1228
1229
/* Align the parameters of "band" to those of "space".
1230
 */
1231
__isl_give isl_schedule_band *isl_schedule_band_align_params(
1232
  __isl_take isl_schedule_band *band, __isl_take isl_space *space)
1233
0
{
1234
0
  band = isl_schedule_band_cow(band);
1235
0
  if (
!band || 0
!space0
)
1236
0
    goto error;
1237
0
1238
0
  band->mupa = isl_multi_union_pw_aff_align_params(band->mupa,
1239
0
            isl_space_copy(space));
1240
0
  band->ast_build_options =
1241
0
    isl_union_set_align_params(band->ast_build_options, space);
1242
0
  if (
!band->mupa || 0
!band->ast_build_options0
)
1243
0
    return isl_schedule_band_free(band);
1244
0
1245
0
  return band;
1246
0
error:
1247
0
  isl_space_free(space);
1248
0
  isl_schedule_band_free(band);
1249
0
  return NULL;
1250
0
}
1251
1252
/* Compute the pullback of "band" by the function represented by "upma".
1253
 * In other words, plug in "upma" in the iteration domains of "band".
1254
 */
1255
__isl_give isl_schedule_band *isl_schedule_band_pullback_union_pw_multi_aff(
1256
  __isl_take isl_schedule_band *band,
1257
  __isl_take isl_union_pw_multi_aff *upma)
1258
234
{
1259
234
  band = isl_schedule_band_cow(band);
1260
234
  if (
!band || 234
!upma234
)
1261
0
    goto error;
1262
234
1263
234
  band->mupa =
1264
234
    isl_multi_union_pw_aff_pullback_union_pw_multi_aff(band->mupa,
1265
234
                  upma);
1266
234
  if (!band->mupa)
1267
0
    return isl_schedule_band_free(band);
1268
234
1269
234
  return band;
1270
0
error:
1271
0
  isl_union_pw_multi_aff_free(upma);
1272
0
  isl_schedule_band_free(band);
1273
0
  return NULL;
1274
234
}
1275
1276
/* Compute the gist of "band" with respect to "context".
1277
 * In particular, compute the gist of the associated partial schedule.
1278
 */
1279
__isl_give isl_schedule_band *isl_schedule_band_gist(
1280
  __isl_take isl_schedule_band *band, __isl_take isl_union_set *context)
1281
177
{
1282
177
  if (
!band || 177
!context177
)
1283
0
    goto error;
1284
177
  
if (177
band->n == 0177
)
{0
1285
0
    isl_union_set_free(context);
1286
0
    return band;
1287
0
  }
1288
177
  band = isl_schedule_band_cow(band);
1289
177
  if (!band)
1290
0
    goto error;
1291
177
  band->mupa = isl_multi_union_pw_aff_gist(band->mupa, context);
1292
177
  if (!band->mupa)
1293
0
    return isl_schedule_band_free(band);
1294
177
  return band;
1295
0
error:
1296
0
  isl_union_set_free(context);
1297
0
  isl_schedule_band_free(band);
1298
0
  return NULL;
1299
177
}