Coverage Report

Created: 2017-06-23 12:40

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/polly/lib/External/isl/isl_band.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2011      INRIA Saclay
3
 * Copyright 2012-2013 Ecole Normale Superieure
4
 *
5
 * Use of this software is governed by the MIT license
6
 *
7
 * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
8
 * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
9
 * 91893 Orsay, France
10
 * and Ecole Normale Superieure, 45 rue d'Ulm, 75230 Paris, France
11
 */
12
13
#include <isl_band_private.h>
14
#include <isl_schedule_private.h>
15
16
#undef BASE
17
#define BASE band
18
19
#include <isl_list_templ.c>
20
21
isl_ctx *isl_band_get_ctx(__isl_keep isl_band *band)
22
6
{
23
6
  return band ? isl_union_pw_multi_aff_get_ctx(band->pma) : NULL;
24
6
}
25
26
__isl_give isl_band *isl_band_alloc(isl_ctx *ctx)
27
6
{
28
6
  isl_band *band;
29
6
30
6
  band = isl_calloc_type(ctx, isl_band);
31
6
  if (!band)
32
0
    return NULL;
33
6
34
6
  band->ref = 1;
35
6
36
6
  return band;
37
6
}
38
39
/* Create a duplicate of the given band.  The duplicate refers
40
 * to the same schedule and parent as the input, but does not
41
 * increment their reference counts.
42
 */
43
__isl_give isl_band *isl_band_dup(__isl_keep isl_band *band)
44
0
{
45
0
  int i;
46
0
  isl_ctx *ctx;
47
0
  isl_band *dup;
48
0
49
0
  if (!band)
50
0
    return NULL;
51
0
52
0
  ctx = isl_band_get_ctx(band);
53
0
  dup = isl_band_alloc(ctx);
54
0
  if (!dup)
55
0
    return NULL;
56
0
57
0
  dup->n = band->n;
58
0
  dup->coincident = isl_alloc_array(ctx, int, band->n);
59
0
  if (
band->n && 0
!dup->coincident0
)
60
0
    goto error;
61
0
62
0
  
for (i = 0; 0
i < band->n0
;
++i0
)
63
0
    dup->coincident[i] = band->coincident[i];
64
0
65
0
  dup->pma = isl_union_pw_multi_aff_copy(band->pma);
66
0
  dup->schedule = band->schedule;
67
0
  dup->parent = band->parent;
68
0
69
0
  if (!dup->pma)
70
0
    goto error;
71
0
72
0
  return dup;
73
0
error:
74
0
  isl_band_free(dup);
75
0
  return NULL;
76
0
}
77
78
/* We not only increment the reference count of the band,
79
 * but also that of the schedule that contains this band.
80
 * This ensures that the schedule won't disappear while there
81
 * is still a reference to the band outside of the schedule.
82
 * There is no need to increment the reference count of the parent
83
 * band as the parent band is part of the same schedule.
84
 */
85
__isl_give isl_band *isl_band_copy(__isl_keep isl_band *band)
86
18
{
87
18
  if (!band)
88
0
    return NULL;
89
18
90
18
  band->ref++;
91
18
  band->schedule->ref++;
92
18
  return band;
93
18
}
94
95
/* If this is not the last reference to the band (the one from within the
96
 * schedule), then we also need to decrement the reference count of the
97
 * containing schedule as it was incremented in isl_band_copy.
98
 */
99
__isl_null isl_band *isl_band_free(__isl_take isl_band *band)
100
24
{
101
24
  if (!band)
102
0
    return NULL;
103
24
104
24
  
if (24
--band->ref > 024
)
{18
105
18
    isl_schedule_free(band->schedule);
106
18
    return NULL;
107
18
  }
108
24
109
6
  isl_union_pw_multi_aff_free(band->pma);
110
6
  isl_band_list_free(band->children);
111
6
  free(band->coincident);
112
6
  free(band);
113
6
114
6
  return NULL;
115
24
}
116
117
int isl_band_has_children(__isl_keep isl_band *band)
118
6
{
119
6
  if (!band)
120
0
    return -1;
121
6
122
6
  return band->children != NULL;
123
6
}
124
125
__isl_give isl_band_list *isl_band_get_children(
126
  __isl_keep isl_band *band)
127
2
{
128
2
  if (!band)
129
0
    return NULL;
130
2
  
if (2
!band->children2
)
131
0
    isl_die(isl_band_get_ctx(band), isl_error_invalid,
132
2
      "band has no children", return NULL);
133
2
  return isl_band_list_dup(band->children);
134
2
}
135
136
int isl_band_n_member(__isl_keep isl_band *band)
137
0
{
138
0
  return band ? 
band->n0
:
00
;
139
0
}
140
141
/* Is the given scheduling dimension coincident within the band and
142
 * with respect to the coincidence constraints.
143
 */
144
int isl_band_member_is_coincident(__isl_keep isl_band *band, int pos)
145
0
{
146
0
  if (!band)
147
0
    return -1;
148
0
149
0
  
if (0
pos < 0 || 0
pos >= band->n0
)
150
0
    isl_die(isl_band_get_ctx(band), isl_error_invalid,
151
0
      "invalid member position", return -1);
152
0
153
0
  return band->coincident[pos];
154
0
}
155
156
/* Return the schedule that leads up to this band.
157
 */
158
__isl_give isl_union_map *isl_band_get_prefix_schedule(
159
  __isl_keep isl_band *band)
160
0
{
161
0
  isl_union_set *domain;
162
0
  isl_union_pw_multi_aff *prefix;
163
0
  isl_band *a;
164
0
165
0
  if (!band)
166
0
    return NULL;
167
0
168
0
  prefix = isl_union_pw_multi_aff_copy(band->pma);
169
0
  domain = isl_union_pw_multi_aff_domain(prefix);
170
0
  prefix = isl_union_pw_multi_aff_from_domain(domain);
171
0
172
0
  for (a = band->parent; 
a0
;
a = a->parent0
)
{0
173
0
    isl_union_pw_multi_aff *partial;
174
0
175
0
    partial = isl_union_pw_multi_aff_copy(a->pma);
176
0
    prefix = isl_union_pw_multi_aff_flat_range_product(partial,
177
0
                   prefix);
178
0
  }
179
0
180
0
  return isl_union_map_from_union_pw_multi_aff(prefix);
181
0
}
182
183
/* Return the schedule of the band in isolation.
184
 */
185
__isl_give isl_union_pw_multi_aff *
186
isl_band_get_partial_schedule_union_pw_multi_aff(__isl_keep isl_band *band)
187
6
{
188
6
  return band ? isl_union_pw_multi_aff_copy(band->pma) : NULL;
189
6
}
190
191
/* Return the schedule of the band in isolation.
192
 */
193
__isl_give isl_union_map *isl_band_get_partial_schedule(
194
  __isl_keep isl_band *band)
195
0
{
196
0
  isl_union_pw_multi_aff *sched;
197
0
198
0
  sched = isl_band_get_partial_schedule_union_pw_multi_aff(band);
199
0
  return isl_union_map_from_union_pw_multi_aff(sched);
200
0
}
201
202
__isl_give isl_union_pw_multi_aff *
203
isl_band_get_suffix_schedule_union_pw_multi_aff(__isl_keep isl_band *band);
204
205
/* Return the schedule for the given band list.
206
 * For each band in the list, the schedule is composed of the partial
207
 * and suffix schedules of that band.
208
 */
209
__isl_give isl_union_pw_multi_aff *
210
isl_band_list_get_suffix_schedule_union_pw_multi_aff(
211
  __isl_keep isl_band_list *list)
212
4
{
213
4
  isl_ctx *ctx;
214
4
  int i, n;
215
4
  isl_space *space;
216
4
  isl_union_pw_multi_aff *suffix;
217
4
218
4
  if (!list)
219
0
    return NULL;
220
4
221
4
  ctx = isl_band_list_get_ctx(list);
222
4
  space = isl_space_alloc(ctx, 0, 0, 0);
223
4
  suffix = isl_union_pw_multi_aff_empty(space);
224
4
  n = isl_band_list_n_band(list);
225
10
  for (i = 0; 
i < n10
;
++i6
)
{6
226
6
    isl_band *el;
227
6
    isl_union_pw_multi_aff *partial;
228
6
    isl_union_pw_multi_aff *suffix_i;
229
6
230
6
    el = isl_band_list_get_band(list, i);
231
6
    partial = isl_band_get_partial_schedule_union_pw_multi_aff(el);
232
6
    suffix_i = isl_band_get_suffix_schedule_union_pw_multi_aff(el);
233
6
    suffix_i = isl_union_pw_multi_aff_flat_range_product(
234
6
        partial, suffix_i);
235
6
    suffix = isl_union_pw_multi_aff_union_add(suffix, suffix_i);
236
6
237
6
    isl_band_free(el);
238
6
  }
239
4
240
4
  return suffix;
241
4
}
242
243
/* Return the schedule for the given band list.
244
 * For each band in the list, the schedule is composed of the partial
245
 * and suffix schedules of that band.
246
 */
247
__isl_give isl_union_map *isl_band_list_get_suffix_schedule(
248
  __isl_keep isl_band_list *list)
249
2
{
250
2
  isl_union_pw_multi_aff *suffix;
251
2
252
2
  suffix = isl_band_list_get_suffix_schedule_union_pw_multi_aff(list);
253
2
  return isl_union_map_from_union_pw_multi_aff(suffix);
254
2
}
255
256
/* Return the schedule for the forest underneath the given band.
257
 */
258
__isl_give isl_union_pw_multi_aff *
259
isl_band_get_suffix_schedule_union_pw_multi_aff(__isl_keep isl_band *band)
260
6
{
261
6
  isl_union_pw_multi_aff *suffix;
262
6
263
6
  if (!band)
264
0
    return NULL;
265
6
266
6
  
if (6
!isl_band_has_children(band)6
)
{4
267
4
    isl_union_set *domain;
268
4
269
4
    suffix = isl_union_pw_multi_aff_copy(band->pma);
270
4
    domain = isl_union_pw_multi_aff_domain(suffix);
271
4
    suffix = isl_union_pw_multi_aff_from_domain(domain);
272
2
  } else {
273
2
    isl_band_list *list;
274
2
275
2
    list = isl_band_get_children(band);
276
2
    suffix =
277
2
        isl_band_list_get_suffix_schedule_union_pw_multi_aff(list);
278
2
    isl_band_list_free(list);
279
2
  }
280
6
281
6
  return suffix;
282
6
}
283
284
/* Return the schedule for the forest underneath the given band.
285
 */
286
__isl_give isl_union_map *isl_band_get_suffix_schedule(
287
  __isl_keep isl_band *band)
288
0
{
289
0
  isl_union_pw_multi_aff *suffix;
290
0
291
0
  suffix = isl_band_get_suffix_schedule_union_pw_multi_aff(band);
292
0
  return isl_union_map_from_union_pw_multi_aff(suffix);
293
0
}
294
295
/* Call "fn" on each band (recursively) in the list
296
 * in depth-first post-order.
297
 */
298
int isl_band_list_foreach_band(__isl_keep isl_band_list *list,
299
  int (*fn)(__isl_keep isl_band *band, void *user), void *user)
300
0
{
301
0
  int i, n;
302
0
303
0
  if (!list)
304
0
    return -1;
305
0
306
0
  n = isl_band_list_n_band(list);
307
0
  for (i = 0; 
i < n0
;
++i0
)
{0
308
0
    isl_band *band;
309
0
    int r = 0;
310
0
311
0
    band = isl_band_list_get_band(list, i);
312
0
    if (
isl_band_has_children(band)0
)
{0
313
0
      isl_band_list *children;
314
0
315
0
      children = isl_band_get_children(band);
316
0
      r = isl_band_list_foreach_band(children, fn, user);
317
0
      isl_band_list_free(children);
318
0
    }
319
0
320
0
    if (!band)
321
0
      r = -1;
322
0
    if (r == 0)
323
0
      r = fn(band, user);
324
0
325
0
    isl_band_free(band);
326
0
    if (r)
327
0
      return r;
328
0
  }
329
0
330
0
  return 0;
331
0
}
332
333
/* Internal data used during the construction of the schedule
334
 * for the tile loops.
335
 *
336
 * sizes contains the tile sizes
337
 * scale is set if the tile loops should be scaled
338
 * tiled collects the result for a single statement
339
 * res collects the result for all statements
340
 */
341
struct isl_band_tile_data {
342
  isl_multi_val *sizes;
343
  isl_union_pw_multi_aff *res;
344
  isl_pw_multi_aff *tiled;
345
  int scale;
346
};
347
348
/* Given part of the schedule of a band, construct the corresponding
349
 * schedule for the tile loops based on the tile sizes in data->sizes
350
 * and add the result to data->tiled.
351
 *
352
 * If data->scale is set, then dimension i of the schedule will be
353
 * of the form
354
 *
355
 *  m_i * floor(s_i(x) / m_i)
356
 *
357
 * where s_i(x) refers to the original schedule and m_i is the tile size.
358
 * If data->scale is not set, then dimension i of the schedule will be
359
 * of the form
360
 *
361
 *  floor(s_i(x) / m_i)
362
 *
363
 */
364
static isl_stat multi_aff_tile(__isl_take isl_set *set,
365
  __isl_take isl_multi_aff *ma, void *user)
366
0
{
367
0
  struct isl_band_tile_data *data = user;
368
0
  isl_pw_multi_aff *pma;
369
0
  int i, n;
370
0
  isl_val *v;
371
0
372
0
  n = isl_multi_aff_dim(ma, isl_dim_out);
373
0
374
0
  for (i = 0; 
i < n0
;
++i0
)
{0
375
0
    isl_aff *aff;
376
0
377
0
    aff = isl_multi_aff_get_aff(ma, i);
378
0
    v = isl_multi_val_get_val(data->sizes, i);
379
0
380
0
    aff = isl_aff_scale_down_val(aff, isl_val_copy(v));
381
0
    aff = isl_aff_floor(aff);
382
0
    if (data->scale)
383
0
      aff = isl_aff_scale_val(aff, isl_val_copy(v));
384
0
    isl_val_free(v);
385
0
386
0
    ma = isl_multi_aff_set_aff(ma, i, aff);
387
0
  }
388
0
389
0
  pma = isl_pw_multi_aff_alloc(set, ma);
390
0
  data->tiled = isl_pw_multi_aff_union_add(data->tiled, pma);
391
0
392
0
  return isl_stat_ok;
393
0
}
394
395
/* Given part of the schedule of a band, construct the corresponding
396
 * schedule for the tile loops based on the tile sizes in data->sizes
397
 * and add the result to data->res.
398
 */
399
static isl_stat pw_multi_aff_tile(__isl_take isl_pw_multi_aff *pma, void *user)
400
0
{
401
0
  struct isl_band_tile_data *data = user;
402
0
403
0
  data->tiled = isl_pw_multi_aff_empty(isl_pw_multi_aff_get_space(pma));
404
0
405
0
  if (isl_pw_multi_aff_foreach_piece(pma, &multi_aff_tile, data) < 0)
406
0
    goto error;
407
0
408
0
  isl_pw_multi_aff_free(pma);
409
0
  data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res,
410
0
                data->tiled);
411
0
412
0
  return isl_stat_ok;
413
0
error:
414
0
  isl_pw_multi_aff_free(pma);
415
0
  isl_pw_multi_aff_free(data->tiled);
416
0
  return isl_stat_error;
417
0
}
418
419
/* Given the schedule of a band, construct the corresponding
420
 * schedule for the tile loops based on the given tile sizes
421
 * and return the result.
422
 */
423
static isl_union_pw_multi_aff *isl_union_pw_multi_aff_tile(
424
  __isl_take isl_union_pw_multi_aff *sched,
425
  __isl_keep isl_multi_val *sizes)
426
0
{
427
0
  isl_ctx *ctx;
428
0
  isl_space *space;
429
0
  struct isl_band_tile_data data = { sizes };
430
0
431
0
  ctx = isl_multi_val_get_ctx(sizes);
432
0
433
0
  space = isl_union_pw_multi_aff_get_space(sched);
434
0
  data.res = isl_union_pw_multi_aff_empty(space);
435
0
  data.scale = isl_options_get_tile_scale_tile_loops(ctx);
436
0
437
0
  if (isl_union_pw_multi_aff_foreach_pw_multi_aff(sched,
438
0
            &pw_multi_aff_tile, &data) < 0)
439
0
    goto error;
440
0
441
0
  isl_union_pw_multi_aff_free(sched);
442
0
  return data.res;
443
0
error:
444
0
  isl_union_pw_multi_aff_free(sched);
445
0
  isl_union_pw_multi_aff_free(data.res);
446
0
  return NULL;
447
0
}
448
449
/* Extract the range space from "pma" and store it in *user.
450
 * All entries are expected to have the same range space, so we can
451
 * stop after extracting the range space from the first entry.
452
 */
453
static isl_stat extract_range_space(__isl_take isl_pw_multi_aff *pma,
454
  void *user)
455
0
{
456
0
  isl_space **space = user;
457
0
458
0
  *space = isl_space_range(isl_pw_multi_aff_get_space(pma));
459
0
  isl_pw_multi_aff_free(pma);
460
0
461
0
  return isl_stat_error;
462
0
}
463
464
/* Extract the range space of "band".  All entries in band->pma should
465
 * have the same range space.  Furthermore, band->pma should have at least
466
 * one entry.
467
 */
468
static __isl_give isl_space *band_get_range_space(__isl_keep isl_band *band)
469
0
{
470
0
  isl_space *space;
471
0
472
0
  if (!band)
473
0
    return NULL;
474
0
475
0
  space = NULL;
476
0
  isl_union_pw_multi_aff_foreach_pw_multi_aff(band->pma,
477
0
            &extract_range_space, &space);
478
0
479
0
  return space;
480
0
}
481
482
/* Construct and return an isl_multi_val in the given space, with as entries
483
 * the first elements of "v", padded with ones if the size of "v" is smaller
484
 * than the dimension of "space".
485
 */
486
static __isl_give isl_multi_val *multi_val_from_vec(__isl_take isl_space *space,
487
  __isl_take isl_vec *v)
488
0
{
489
0
  isl_ctx *ctx;
490
0
  isl_multi_val *mv;
491
0
  int i, n, size;
492
0
493
0
  if (
!space || 0
!v0
)
494
0
    goto error;
495
0
496
0
  ctx = isl_space_get_ctx(space);
497
0
  mv = isl_multi_val_zero(space);
498
0
  n = isl_multi_val_dim(mv, isl_dim_set);
499
0
  size = isl_vec_size(v);
500
0
  if (n < size)
501
0
    size = n;
502
0
503
0
  for (i = 0; 
i < size0
;
++i0
)
{0
504
0
    isl_val *val = isl_vec_get_element_val(v, i);
505
0
    mv = isl_multi_val_set_val(mv, i, val);
506
0
  }
507
0
  for (i = size; 
i < n0
;
++i0
)
508
0
    mv = isl_multi_val_set_val(mv, i, isl_val_one(ctx));
509
0
510
0
  isl_vec_free(v);
511
0
  return mv;
512
0
error:
513
0
  isl_space_free(space);
514
0
  isl_vec_free(v);
515
0
  return NULL;
516
0
}
517
518
/* Tile the given band using the specified tile sizes.
519
 * The given band is modified to refer to the tile loops and
520
 * a child band is created to refer to the point loops.
521
 * The children of this point loop band are the children
522
 * of the original band.
523
 *
524
 * If the scale tile loops option is set, then the tile loops
525
 * are scaled by the tile sizes.  If the shift point loops option is set,
526
 * then the point loops are shifted to start at zero.
527
 * In particular, these options affect the tile and point loop schedules
528
 * as follows
529
 *
530
 *  scale shift original  tile    point
531
 *
532
 *  0 0 i   floor(i/s)  i
533
 *  1 0 i   s * floor(i/s)  i
534
 *  0 1 i   floor(i/s)  i - s * floor(i/s)
535
 *  1 1 i   s * floor(i/s)  i - s * floor(i/s)
536
 */
537
int isl_band_tile(__isl_keep isl_band *band, __isl_take isl_vec *sizes)
538
0
{
539
0
  isl_ctx *ctx;
540
0
  isl_band *child;
541
0
  isl_band_list *list = NULL;
542
0
  isl_union_pw_multi_aff *sched = NULL, *child_sched = NULL;
543
0
  isl_space *space;
544
0
  isl_multi_val *mv_sizes;
545
0
546
0
  if (
!band || 0
!sizes0
)
547
0
    goto error;
548
0
549
0
  ctx = isl_vec_get_ctx(sizes);
550
0
  child = isl_band_dup(band);
551
0
  list = isl_band_list_alloc(ctx, 1);
552
0
  list = isl_band_list_add(list, child);
553
0
  if (!list)
554
0
    goto error;
555
0
556
0
  space = band_get_range_space(band);
557
0
  mv_sizes = multi_val_from_vec(space, isl_vec_copy(sizes));
558
0
  sched = isl_union_pw_multi_aff_copy(band->pma);
559
0
  sched = isl_union_pw_multi_aff_tile(sched, mv_sizes);
560
0
561
0
  child_sched = isl_union_pw_multi_aff_copy(child->pma);
562
0
  if (
isl_options_get_tile_shift_point_loops(ctx)0
)
{0
563
0
    isl_union_pw_multi_aff *scaled;
564
0
    scaled = isl_union_pw_multi_aff_copy(sched);
565
0
    if (!isl_options_get_tile_scale_tile_loops(ctx))
566
0
      scaled = isl_union_pw_multi_aff_scale_multi_val(scaled,
567
0
            isl_multi_val_copy(mv_sizes));
568
0
    child_sched = isl_union_pw_multi_aff_sub(child_sched, scaled);
569
0
  }
570
0
  isl_multi_val_free(mv_sizes);
571
0
  if (
!sched || 0
!child_sched0
)
572
0
    goto error;
573
0
574
0
  child->children = band->children;
575
0
  band->children = list;
576
0
  child->parent = band;
577
0
  isl_union_pw_multi_aff_free(band->pma);
578
0
  band->pma = sched;
579
0
  isl_union_pw_multi_aff_free(child->pma);
580
0
  child->pma = child_sched;
581
0
582
0
  isl_vec_free(sizes);
583
0
  return 0;
584
0
error:
585
0
  isl_union_pw_multi_aff_free(sched);
586
0
  isl_union_pw_multi_aff_free(child_sched);
587
0
  isl_band_list_free(list);
588
0
  isl_vec_free(sizes);
589
0
  return -1;
590
0
}
591
592
/* Internal data structure used inside isl_union_pw_multi_aff_drop.
593
 *
594
 * "pos" is the position of the first dimension to drop.
595
 * "n" is the number of dimensions to drop.
596
 * "res" accumulates the result.
597
 */
598
struct isl_union_pw_multi_aff_drop_data {
599
  int pos;
600
  int n;
601
  isl_union_pw_multi_aff *res;
602
};
603
604
/* Drop the data->n output dimensions starting at data->pos from "pma"
605
 * and add the result to data->res.
606
 */
607
static isl_stat pw_multi_aff_drop(__isl_take isl_pw_multi_aff *pma, void *user)
608
0
{
609
0
  struct isl_union_pw_multi_aff_drop_data *data = user;
610
0
611
0
  pma = isl_pw_multi_aff_drop_dims(pma, isl_dim_out, data->pos, data->n);
612
0
613
0
  data->res = isl_union_pw_multi_aff_add_pw_multi_aff(data->res, pma);
614
0
  if (!data->res)
615
0
    return isl_stat_error;
616
0
617
0
  return isl_stat_ok;
618
0
}
619
620
/* Drop the "n" output dimensions starting at "pos" from "sched".
621
 */
622
static isl_union_pw_multi_aff *isl_union_pw_multi_aff_drop(
623
  __isl_take isl_union_pw_multi_aff *sched, int pos, int n)
624
0
{
625
0
  isl_space *space;
626
0
  struct isl_union_pw_multi_aff_drop_data data = { pos, n };
627
0
628
0
  space = isl_union_pw_multi_aff_get_space(sched);
629
0
  data.res = isl_union_pw_multi_aff_empty(space);
630
0
631
0
  if (isl_union_pw_multi_aff_foreach_pw_multi_aff(sched,
632
0
            &pw_multi_aff_drop, &data) < 0)
633
0
    data.res = isl_union_pw_multi_aff_free(data.res);
634
0
635
0
  isl_union_pw_multi_aff_free(sched);
636
0
  return data.res;
637
0
}
638
639
/* Drop the "n" dimensions starting at "pos" from "band".
640
 */
641
static int isl_band_drop(__isl_keep isl_band *band, int pos, int n)
642
0
{
643
0
  int i;
644
0
  isl_union_pw_multi_aff *sched;
645
0
646
0
  if (!band)
647
0
    return -1;
648
0
  
if (0
n == 00
)
649
0
    return 0;
650
0
651
0
  sched = isl_union_pw_multi_aff_copy(band->pma);
652
0
  sched = isl_union_pw_multi_aff_drop(sched, pos, n);
653
0
  if (!sched)
654
0
    return -1;
655
0
656
0
  isl_union_pw_multi_aff_free(band->pma);
657
0
  band->pma = sched;
658
0
659
0
  for (i = pos + n; 
i < band->n0
;
++i0
)
660
0
    band->coincident[i - n] = band->coincident[i];
661
0
662
0
  band->n -= n;
663
0
664
0
  return 0;
665
0
}
666
667
/* Split the given band into two nested bands, one with the first "pos"
668
 * dimensions of "band" and one with the remaining band->n - pos dimensions.
669
 */
670
int isl_band_split(__isl_keep isl_band *band, int pos)
671
0
{
672
0
  isl_ctx *ctx;
673
0
  isl_band *child;
674
0
  isl_band_list *list;
675
0
676
0
  if (!band)
677
0
    return -1;
678
0
679
0
  ctx = isl_band_get_ctx(band);
680
0
681
0
  if (
pos < 0 || 0
pos > band->n0
)
682
0
    isl_die(ctx, isl_error_invalid, "position out of bounds",
683
0
      return -1);
684
0
685
0
  child = isl_band_dup(band);
686
0
  if (isl_band_drop(child, 0, pos) < 0)
687
0
    child = isl_band_free(child);
688
0
  list = isl_band_list_alloc(ctx, 1);
689
0
  list = isl_band_list_add(list, child);
690
0
  if (!list)
691
0
    return -1;
692
0
693
0
  
if (0
isl_band_drop(band, pos, band->n - pos) < 00
)
{0
694
0
    isl_band_list_free(list);
695
0
    return -1;
696
0
  }
697
0
698
0
  child->children = band->children;
699
0
  band->children = list;
700
0
  child->parent = band;
701
0
702
0
  return 0;
703
0
}
704
705
__isl_give isl_printer *isl_printer_print_band(__isl_take isl_printer *p,
706
  __isl_keep isl_band *band)
707
0
{
708
0
  isl_union_map *prefix, *partial, *suffix;
709
0
710
0
  prefix = isl_band_get_prefix_schedule(band);
711
0
  partial = isl_band_get_partial_schedule(band);
712
0
  suffix = isl_band_get_suffix_schedule(band);
713
0
714
0
  p = isl_printer_print_str(p, "(");
715
0
  p = isl_printer_print_union_map(p, prefix);
716
0
  p = isl_printer_print_str(p, ",");
717
0
  p = isl_printer_print_union_map(p, partial);
718
0
  p = isl_printer_print_str(p, ",");
719
0
  p = isl_printer_print_union_map(p, suffix);
720
0
  p = isl_printer_print_str(p, ")");
721
0
722
0
  isl_union_map_free(prefix);
723
0
  isl_union_map_free(partial);
724
0
  isl_union_map_free(suffix);
725
0
726
0
  return p;
727
0
}