Merge branch 'maint'
[platform/upstream/isl.git] / isl_band.c
1 /*
2  * Copyright 2011      INRIA Saclay
3  *
4  * Use of this software is governed by the GNU LGPLv2.1 license
5  *
6  * Written by Sven Verdoolaege, INRIA Saclay - Ile-de-France,
7  * Parc Club Orsay Universite, ZAC des vignes, 4 rue Jacques Monod,
8  * 91893 Orsay, France
9  */
10
11 #include <isl_band_private.h>
12 #include <isl_schedule_private.h>
13
14 isl_ctx *isl_band_get_ctx(__isl_keep isl_band *band)
15 {
16         return band ? isl_union_map_get_ctx(band->map) : NULL;
17 }
18
19 /* We not only increment the reference count of the band,
20  * but also that of the schedule that contains this band.
21  * This ensures that the schedule won't disappear while there
22  * is still a reference to the band outside of the schedule.
23  * There is no need to increment the reference count of the parent
24  * band as the parent band is part of the same schedule.
25  */
26 __isl_give isl_band *isl_band_copy(__isl_keep isl_band *band)
27 {
28         if (!band)
29                 return NULL;
30
31         band->ref++;
32         band->schedule->ref++;
33         return band;
34 }
35
36 /* If this is not the last reference to the band (the one from within the
37  * schedule), then we also need to decrement the reference count of the
38  * containing schedule as it was incremented in isl_band_copy.
39  */
40 void *isl_band_free(__isl_take isl_band *band)
41 {
42         if (!band)
43                 return NULL;
44
45         if (--band->ref > 0)
46                 return isl_schedule_free(band->schedule);
47
48         isl_union_map_free(band->map);
49         isl_band_list_free(band->children);
50         free(band->zero);
51         free(band);
52
53         return NULL;
54 }
55
56 int isl_band_has_children(__isl_keep isl_band *band)
57 {
58         if (!band)
59                 return -1;
60
61         return band->children != NULL;
62 }
63
64 __isl_give isl_band_list *isl_band_get_children(
65         __isl_keep isl_band *band)
66 {
67         if (!band)
68                 return NULL;
69         if (!band->children)
70                 isl_die(isl_band_get_ctx(band), isl_error_invalid,
71                         "band has no children", return NULL);
72         return isl_band_list_copy(band->children);
73 }
74
75 int isl_band_n_member(__isl_keep isl_band *band)
76 {
77         return band ? band->n : 0;
78 }
79
80 /* Is the given scheduling dimension zero distance within the band and
81  * with respect to the proximity dependences.
82  */
83 int isl_band_member_is_zero_distance(__isl_keep isl_band *band, int pos)
84 {
85         if (!band)
86                 return -1;
87
88         if (pos < 0 || pos >= band->n)
89                 isl_die(isl_band_get_ctx(band), isl_error_invalid,
90                         "invalid member position", return -1);
91
92         return band->zero[pos];
93 }
94
95 /* Return the schedule that leads up to this band.
96  */
97 __isl_give isl_union_map *isl_band_get_prefix_schedule(
98         __isl_keep isl_band *band)
99 {
100         isl_union_map *prefix;
101         isl_band *a;
102
103         if (!band)
104                 return NULL;
105
106         prefix = isl_union_map_copy(band->map);
107         prefix = isl_union_map_from_domain(isl_union_map_domain(prefix));
108
109         for (a = band->parent; a; a = a->parent) {
110                 isl_union_map *partial = isl_union_map_copy(a->map);
111                 prefix = isl_union_map_flat_range_product(partial, prefix);
112         }
113
114         return prefix;
115 }
116
117 /* Return the schedule of the band in isolation.
118  */
119 __isl_give isl_union_map *isl_band_get_partial_schedule(
120         __isl_keep isl_band *band)
121 {
122         return band ? isl_union_map_copy(band->map) : NULL;
123 }
124
125 /* Return the schedule for the forest underneath the given band.
126  */
127 __isl_give isl_union_map *isl_band_get_suffix_schedule(
128         __isl_keep isl_band *band)
129 {
130         isl_union_map *suffix;
131
132         if (!band)
133                 return NULL;
134
135         if (!isl_band_has_children(band)) {
136                 suffix = isl_union_map_copy(band->map);
137                 suffix = isl_union_map_from_domain(isl_union_map_domain(suffix));
138         } else {
139                 int i, n;
140                 isl_band_list *children;
141
142                 suffix = isl_union_map_empty(isl_union_map_get_dim(band->map));
143                 children = isl_band_get_children(band);
144                 n = isl_band_list_n_band(children);
145                 for (i = 0; i < n; ++i) {
146                         isl_band *child;
147                         isl_union_map *partial_i;
148                         isl_union_map *suffix_i;
149
150                         child = isl_band_list_get_band(children, i);
151                         partial_i = isl_band_get_partial_schedule(child);
152                         suffix_i = isl_band_get_suffix_schedule(child);
153                         suffix_i = isl_union_map_flat_range_product(partial_i,
154                                                                     suffix_i);
155                         suffix = isl_union_map_union(suffix, suffix_i);
156
157                         isl_band_free(child);
158                 }
159                 isl_band_list_free(children);
160         }
161
162         return suffix;
163 }
164
165 __isl_give isl_printer *isl_printer_print_band(__isl_take isl_printer *p,
166         __isl_keep isl_band *band)
167 {
168         isl_union_map *prefix, *partial, *suffix;
169
170         prefix = isl_band_get_prefix_schedule(band);
171         partial = isl_band_get_partial_schedule(band);
172         suffix = isl_band_get_suffix_schedule(band);
173
174         p = isl_printer_print_str(p, "(");
175         p = isl_printer_print_union_map(p, prefix);
176         p = isl_printer_print_str(p, ",");
177         p = isl_printer_print_union_map(p, partial);
178         p = isl_printer_print_str(p, ",");
179         p = isl_printer_print_union_map(p, suffix);
180         p = isl_printer_print_str(p, ")");
181
182         isl_union_map_free(prefix);
183         isl_union_map_free(partial);
184         isl_union_map_free(suffix);
185
186         return p;
187 }
188
189 void isl_band_dump(__isl_keep isl_band *band)
190 {
191         isl_printer *printer;
192
193         if (!band)
194                 return;
195
196         printer = isl_printer_to_file(isl_band_get_ctx(band), stderr);
197         printer = isl_printer_print_band(printer, band);
198         printer = isl_printer_end_line(printer);
199
200         isl_printer_free(printer);
201 }