]>
Commit | Line | Data |
---|---|---|
b60cc080 | 1 | /* A scheduling optimizer for Graphite |
5624e564 | 2 | Copyright (C) 2012-2015 Free Software Foundation, Inc. |
b60cc080 TG |
3 | Contributed by Tobias Grosser <tobias@grosser.es>. |
4 | ||
5 | This file is part of GCC. | |
6 | ||
7 | GCC is free software; you can redistribute it and/or modify | |
8 | it under the terms of the GNU General Public License as published by | |
9 | the Free Software Foundation; either version 3, or (at your option) | |
10 | any later version. | |
11 | ||
12 | GCC is distributed in the hope that it will be useful, | |
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | GNU General Public License for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
18 | along with GCC; see the file COPYING3. If not see | |
19 | <http://www.gnu.org/licenses/>. */ | |
20 | ||
21 | #include "config.h" | |
22 | ||
eae1a5d4 | 23 | #ifdef HAVE_isl |
4bc190dc JW |
24 | /* Workaround for GMP 5.1.3 bug, see PR56019. */ |
25 | #include <stddef.h> | |
26 | ||
b60cc080 TG |
27 | #include <isl/set.h> |
28 | #include <isl/map.h> | |
29 | #include <isl/union_map.h> | |
30 | #include <isl/schedule.h> | |
31 | #include <isl/band.h> | |
32 | #include <isl/aff.h> | |
33 | #include <isl/options.h> | |
02663f24 | 34 | #endif |
b60cc080 TG |
35 | |
36 | #include "system.h" | |
37 | #include "coretypes.h" | |
40e23961 | 38 | #include "alias.h" |
c7131fb2 | 39 | #include "backend.h" |
9fdcd34e | 40 | #include "cfghooks.h" |
40e23961 | 41 | #include "tree.h" |
c7131fb2 | 42 | #include "gimple.h" |
60393bbc | 43 | #include "hard-reg-set.h" |
c7131fb2 AM |
44 | #include "options.h" |
45 | #include "fold-const.h" | |
2fb9a547 | 46 | #include "internal-fn.h" |
5be5c238 | 47 | #include "gimple-iterator.h" |
442b4905 | 48 | #include "tree-ssa-loop.h" |
7ee2468b | 49 | #include "dumpfile.h" |
b60cc080 TG |
50 | #include "cfgloop.h" |
51 | #include "tree-chrec.h" | |
52 | #include "tree-data-ref.h" | |
53 | #include "tree-scalar-evolution.h" | |
54 | #include "sese.h" | |
55 | ||
eae1a5d4 | 56 | #ifdef HAVE_isl |
b60cc080 TG |
57 | #include "graphite-poly.h" |
58 | ||
59 | static isl_union_set * | |
60 | scop_get_domains (scop_p scop ATTRIBUTE_UNUSED) | |
61 | { | |
62 | int i; | |
63 | poly_bb_p pbb; | |
64 | isl_space *space = isl_set_get_space (scop->context); | |
65 | isl_union_set *res = isl_union_set_empty (space); | |
66 | ||
9771b263 | 67 | FOR_EACH_VEC_ELT (scop->bbs, i, pbb) |
b60cc080 TG |
68 | res = isl_union_set_add_set (res, isl_set_copy (pbb->domain)); |
69 | ||
70 | return res; | |
71 | } | |
72 | ||
b60cc080 TG |
73 | /* getTileMap - Create a map that describes a n-dimensonal tiling. |
74 | ||
75 | getTileMap creates a map from a n-dimensional scattering space into an | |
76 | 2*n-dimensional scattering space. The map describes a rectangular tiling. | |
77 | ||
78 | Example: | |
79 | scheduleDimensions = 2, parameterDimensions = 1, tileSize = 32 | |
80 | ||
81 | tileMap := [p0] -> {[s0, s1] -> [t0, t1, s0, s1]: | |
82 | t0 % 32 = 0 and t0 <= s0 < t0 + 32 and | |
83 | t1 % 32 = 0 and t1 <= s1 < t1 + 32} | |
84 | ||
85 | Before tiling: | |
86 | ||
87 | for (i = 0; i < N; i++) | |
88 | for (j = 0; j < M; j++) | |
89 | S(i,j) | |
90 | ||
91 | After tiling: | |
92 | ||
93 | for (t_i = 0; t_i < N; i+=32) | |
94 | for (t_j = 0; t_j < M; j+=32) | |
95 | for (i = t_i; i < min(t_i + 32, N); i++) | Unknown that N % 32 = 0 | |
96 | for (j = t_j; j < t_j + 32; j++) | Known that M % 32 = 0 | |
97 | S(i,j) | |
98 | */ | |
99 | ||
100 | static isl_basic_map * | |
c3284718 | 101 | getTileMap (isl_ctx *ctx, int scheduleDimensions, int tileSize) |
b60cc080 TG |
102 | { |
103 | int x; | |
104 | /* We construct | |
105 | ||
106 | tileMap := [p0] -> {[s0, s1] -> [t0, t1, p0, p1, a0, a1]: | |
107 | s0 = a0 * 32 and s0 = p0 and t0 <= p0 < t0 + 32 and | |
108 | s1 = a1 * 32 and s1 = p1 and t1 <= p1 < t1 + 32} | |
109 | ||
110 | and project out the auxilary dimensions a0 and a1. */ | |
c3284718 RS |
111 | isl_space *Space = isl_space_alloc (ctx, 0, scheduleDimensions, |
112 | scheduleDimensions * 3); | |
113 | isl_basic_map *tileMap = isl_basic_map_universe (isl_space_copy (Space)); | |
b60cc080 | 114 | |
c3284718 | 115 | isl_local_space *LocalSpace = isl_local_space_from_space (Space); |
b60cc080 TG |
116 | |
117 | for (x = 0; x < scheduleDimensions; x++) | |
118 | { | |
119 | int sX = x; | |
120 | int tX = x; | |
121 | int pX = scheduleDimensions + x; | |
122 | int aX = 2 * scheduleDimensions + x; | |
123 | ||
124 | isl_constraint *c; | |
125 | ||
126 | /* sX = aX * tileSize; */ | |
c3284718 RS |
127 | c = isl_equality_alloc (isl_local_space_copy (LocalSpace)); |
128 | isl_constraint_set_coefficient_si (c, isl_dim_out, sX, 1); | |
129 | isl_constraint_set_coefficient_si (c, isl_dim_out, aX, -tileSize); | |
130 | tileMap = isl_basic_map_add_constraint (tileMap, c); | |
b60cc080 TG |
131 | |
132 | /* pX = sX; */ | |
c3284718 RS |
133 | c = isl_equality_alloc (isl_local_space_copy (LocalSpace)); |
134 | isl_constraint_set_coefficient_si (c, isl_dim_out, pX, 1); | |
135 | isl_constraint_set_coefficient_si (c, isl_dim_in, sX, -1); | |
136 | tileMap = isl_basic_map_add_constraint (tileMap, c); | |
b60cc080 TG |
137 | |
138 | /* tX <= pX */ | |
c3284718 RS |
139 | c = isl_inequality_alloc (isl_local_space_copy (LocalSpace)); |
140 | isl_constraint_set_coefficient_si (c, isl_dim_out, pX, 1); | |
141 | isl_constraint_set_coefficient_si (c, isl_dim_out, tX, -1); | |
142 | tileMap = isl_basic_map_add_constraint (tileMap, c); | |
b60cc080 TG |
143 | |
144 | /* pX <= tX + (tileSize - 1) */ | |
c3284718 RS |
145 | c = isl_inequality_alloc (isl_local_space_copy (LocalSpace)); |
146 | isl_constraint_set_coefficient_si (c, isl_dim_out, tX, 1); | |
147 | isl_constraint_set_coefficient_si (c, isl_dim_out, pX, -1); | |
148 | isl_constraint_set_constant_si (c, tileSize - 1); | |
149 | tileMap = isl_basic_map_add_constraint (tileMap, c); | |
b60cc080 TG |
150 | } |
151 | ||
688010ba | 152 | /* Project out auxiliary dimensions. |
b60cc080 | 153 | |
688010ba | 154 | The auxiliary dimensions are transformed into existentially quantified ones. |
b60cc080 TG |
155 | This reduces the number of visible scattering dimensions and allows Cloog |
156 | to produces better code. */ | |
c3284718 RS |
157 | tileMap = isl_basic_map_project_out (tileMap, isl_dim_out, |
158 | 2 * scheduleDimensions, | |
159 | scheduleDimensions); | |
160 | isl_local_space_free (LocalSpace); | |
b60cc080 TG |
161 | return tileMap; |
162 | } | |
163 | ||
164 | /* getScheduleForBand - Get the schedule for this band. | |
165 | ||
166 | Polly applies transformations like tiling on top of the isl calculated value. | |
167 | This can influence the number of scheduling dimension. The number of | |
168 | schedule dimensions is returned in the parameter 'Dimension'. */ | |
169 | static bool DisableTiling = false; | |
170 | ||
171 | static isl_union_map * | |
c3284718 | 172 | getScheduleForBand (isl_band *Band, int *Dimensions) |
b60cc080 TG |
173 | { |
174 | isl_union_map *PartialSchedule; | |
175 | isl_ctx *ctx; | |
176 | isl_space *Space; | |
177 | isl_basic_map *TileMap; | |
178 | isl_union_map *TileUMap; | |
179 | ||
c3284718 RS |
180 | PartialSchedule = isl_band_get_partial_schedule (Band); |
181 | *Dimensions = isl_band_n_member (Band); | |
b60cc080 | 182 | |
20d3465b | 183 | if (DisableTiling || flag_loop_unroll_jam) |
b60cc080 TG |
184 | return PartialSchedule; |
185 | ||
186 | /* It does not make any sense to tile a band with just one dimension. */ | |
187 | if (*Dimensions == 1) | |
188 | return PartialSchedule; | |
189 | ||
c3284718 RS |
190 | ctx = isl_union_map_get_ctx (PartialSchedule); |
191 | Space = isl_union_map_get_space (PartialSchedule); | |
b60cc080 | 192 | |
c3284718 RS |
193 | TileMap = getTileMap (ctx, *Dimensions, 32); |
194 | TileUMap = isl_union_map_from_map (isl_map_from_basic_map (TileMap)); | |
195 | TileUMap = isl_union_map_align_params (TileUMap, Space); | |
b60cc080 TG |
196 | *Dimensions = 2 * *Dimensions; |
197 | ||
c3284718 | 198 | return isl_union_map_apply_range (PartialSchedule, TileUMap); |
b60cc080 TG |
199 | } |
200 | ||
201 | /* Create a map that pre-vectorizes one scheduling dimension. | |
202 | ||
203 | getPrevectorMap creates a map that maps each input dimension to the same | |
204 | output dimension, except for the dimension DimToVectorize. DimToVectorize is | |
205 | strip mined by 'VectorWidth' and the newly created point loop of | |
206 | DimToVectorize is moved to the innermost level. | |
207 | ||
208 | Example (DimToVectorize=0, ScheduleDimensions=2, VectorWidth=4): | |
209 | ||
210 | | Before transformation | |
211 | | | |
212 | | A[i,j] -> [i,j] | |
213 | | | |
214 | | for (i = 0; i < 128; i++) | |
215 | | for (j = 0; j < 128; j++) | |
216 | | A(i,j); | |
217 | ||
218 | Prevector map: | |
219 | [i,j] -> [it,j,ip] : it % 4 = 0 and it <= ip <= it + 3 and i = ip | |
220 | ||
221 | | After transformation: | |
222 | | | |
223 | | A[i,j] -> [it,j,ip] : it % 4 = 0 and it <= ip <= it + 3 and i = ip | |
224 | | | |
225 | | for (it = 0; it < 128; it+=4) | |
226 | | for (j = 0; j < 128; j++) | |
227 | | for (ip = max(0,it); ip < min(128, it + 3); ip++) | |
228 | | A(ip,j); | |
229 | ||
230 | The goal of this transformation is to create a trivially vectorizable loop. | |
231 | This means a parallel loop at the innermost level that has a constant number | |
232 | of iterations corresponding to the target vector width. | |
233 | ||
234 | This transformation creates a loop at the innermost level. The loop has a | |
235 | constant number of iterations, if the number of loop iterations at | |
236 | DimToVectorize can be devided by VectorWidth. The default VectorWidth is | |
237 | currently constant and not yet target specific. This function does not reason | |
20d3465b MN |
238 | about parallelism. |
239 | ||
240 | */ | |
b60cc080 | 241 | static isl_map * |
c3284718 RS |
242 | getPrevectorMap (isl_ctx *ctx, int DimToVectorize, |
243 | int ScheduleDimensions, | |
244 | int VectorWidth) | |
b60cc080 TG |
245 | { |
246 | isl_space *Space; | |
247 | isl_local_space *LocalSpace, *LocalSpaceRange; | |
248 | isl_set *Modulo; | |
249 | isl_map *TilingMap; | |
250 | isl_constraint *c; | |
251 | isl_aff *Aff; | |
252 | int PointDimension; /* ip */ | |
253 | int TileDimension; /* it */ | |
b47595f7 | 254 | isl_val *VectorWidthMP; |
b60cc080 TG |
255 | int i; |
256 | ||
257 | /* assert (0 <= DimToVectorize && DimToVectorize < ScheduleDimensions);*/ | |
258 | ||
c3284718 RS |
259 | Space = isl_space_alloc (ctx, 0, ScheduleDimensions, ScheduleDimensions + 1); |
260 | TilingMap = isl_map_universe (isl_space_copy (Space)); | |
261 | LocalSpace = isl_local_space_from_space (Space); | |
b60cc080 TG |
262 | PointDimension = ScheduleDimensions; |
263 | TileDimension = DimToVectorize; | |
264 | ||
265 | /* Create an identity map for everything except DimToVectorize and map | |
266 | DimToVectorize to the point loop at the innermost dimension. */ | |
267 | for (i = 0; i < ScheduleDimensions; i++) | |
268 | { | |
c3284718 RS |
269 | c = isl_equality_alloc (isl_local_space_copy (LocalSpace)); |
270 | isl_constraint_set_coefficient_si (c, isl_dim_in, i, -1); | |
b60cc080 TG |
271 | |
272 | if (i == DimToVectorize) | |
c3284718 | 273 | isl_constraint_set_coefficient_si (c, isl_dim_out, PointDimension, 1); |
b60cc080 | 274 | else |
c3284718 | 275 | isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1); |
b60cc080 | 276 | |
c3284718 | 277 | TilingMap = isl_map_add_constraint (TilingMap, c); |
b60cc080 TG |
278 | } |
279 | ||
280 | /* it % 'VectorWidth' = 0 */ | |
c3284718 RS |
281 | LocalSpaceRange = isl_local_space_range (isl_local_space_copy (LocalSpace)); |
282 | Aff = isl_aff_zero_on_domain (LocalSpaceRange); | |
283 | Aff = isl_aff_set_constant_si (Aff, VectorWidth); | |
284 | Aff = isl_aff_set_coefficient_si (Aff, isl_dim_in, TileDimension, 1); | |
b47595f7 MN |
285 | |
286 | VectorWidthMP = isl_val_int_from_si (ctx, VectorWidth); | |
287 | Aff = isl_aff_mod_val (Aff, VectorWidthMP); | |
c3284718 RS |
288 | Modulo = isl_pw_aff_zero_set (isl_pw_aff_from_aff (Aff)); |
289 | TilingMap = isl_map_intersect_range (TilingMap, Modulo); | |
b60cc080 TG |
290 | |
291 | /* it <= ip */ | |
c3284718 RS |
292 | c = isl_inequality_alloc (isl_local_space_copy (LocalSpace)); |
293 | isl_constraint_set_coefficient_si (c, isl_dim_out, TileDimension, -1); | |
294 | isl_constraint_set_coefficient_si (c, isl_dim_out, PointDimension, 1); | |
295 | TilingMap = isl_map_add_constraint (TilingMap, c); | |
b60cc080 TG |
296 | |
297 | /* ip <= it + ('VectorWidth' - 1) */ | |
c3284718 RS |
298 | c = isl_inequality_alloc (LocalSpace); |
299 | isl_constraint_set_coefficient_si (c, isl_dim_out, TileDimension, 1); | |
300 | isl_constraint_set_coefficient_si (c, isl_dim_out, PointDimension, -1); | |
301 | isl_constraint_set_constant_si (c, VectorWidth - 1); | |
302 | TilingMap = isl_map_add_constraint (TilingMap, c); | |
b60cc080 | 303 | |
20d3465b MN |
304 | return TilingMap; |
305 | } | |
306 | ||
307 | /* Compute an auxiliary map to getPrevectorMap, for computing the separating | |
308 | class defined by full tiles. Used in graphite_isl_ast_to_gimple.c to set the | |
309 | corresponding option for AST build. | |
310 | ||
311 | The map (for VectorWidth=4): | |
312 | ||
313 | [i,j] -> [it,j,ip] : it % 4 = 0 and it <= ip <= it + 3 and it + 3 = i and | |
314 | ip >= 0 | |
315 | ||
316 | The image of this map is the separation class. The range of this map includes | |
46cdd0c8 | 317 | all the i multiple of 4 in the domain such as i + 3 is in the domain too. |
20d3465b MN |
318 | |
319 | */ | |
320 | static isl_map * | |
321 | getPrevectorMap_full (isl_ctx *ctx, int DimToVectorize, | |
322 | int ScheduleDimensions, | |
323 | int VectorWidth) | |
324 | { | |
325 | isl_space *Space; | |
326 | isl_local_space *LocalSpace, *LocalSpaceRange; | |
327 | isl_set *Modulo; | |
328 | isl_map *TilingMap; | |
329 | isl_constraint *c; | |
330 | isl_aff *Aff; | |
331 | int PointDimension; /* ip */ | |
332 | int TileDimension; /* it */ | |
333 | isl_val *VectorWidthMP; | |
334 | int i; | |
335 | ||
336 | /* assert (0 <= DimToVectorize && DimToVectorize < ScheduleDimensions);*/ | |
337 | ||
338 | Space = isl_space_alloc (ctx, 0, ScheduleDimensions, ScheduleDimensions + 1); | |
339 | TilingMap = isl_map_universe (isl_space_copy (Space)); | |
340 | LocalSpace = isl_local_space_from_space (Space); | |
341 | PointDimension = ScheduleDimensions; | |
342 | TileDimension = DimToVectorize; | |
343 | ||
344 | /* Create an identity map for everything except DimToVectorize and the | |
345 | point loop. */ | |
346 | for (i = 0; i < ScheduleDimensions; i++) | |
347 | { | |
348 | if (i == DimToVectorize) | |
349 | continue; | |
350 | ||
351 | c = isl_equality_alloc (isl_local_space_copy (LocalSpace)); | |
352 | ||
353 | isl_constraint_set_coefficient_si (c, isl_dim_in, i, -1); | |
354 | isl_constraint_set_coefficient_si (c, isl_dim_out, i, 1); | |
355 | ||
356 | TilingMap = isl_map_add_constraint (TilingMap, c); | |
357 | } | |
358 | ||
359 | /* it % 'VectorWidth' = 0 */ | |
360 | LocalSpaceRange = isl_local_space_range (isl_local_space_copy (LocalSpace)); | |
361 | Aff = isl_aff_zero_on_domain (LocalSpaceRange); | |
362 | Aff = isl_aff_set_constant_si (Aff, VectorWidth); | |
363 | Aff = isl_aff_set_coefficient_si (Aff, isl_dim_in, TileDimension, 1); | |
364 | ||
365 | VectorWidthMP = isl_val_int_from_si (ctx, VectorWidth); | |
366 | Aff = isl_aff_mod_val (Aff, VectorWidthMP); | |
367 | Modulo = isl_pw_aff_zero_set (isl_pw_aff_from_aff (Aff)); | |
368 | TilingMap = isl_map_intersect_range (TilingMap, Modulo); | |
369 | ||
370 | /* it + ('VectorWidth' - 1) = i0 */ | |
371 | c = isl_equality_alloc (isl_local_space_copy(LocalSpace)); | |
372 | isl_constraint_set_coefficient_si (c, isl_dim_out, TileDimension,-1); | |
373 | isl_constraint_set_coefficient_si (c, isl_dim_in, TileDimension, 1); | |
374 | isl_constraint_set_constant_si (c, -VectorWidth + 1); | |
375 | TilingMap = isl_map_add_constraint (TilingMap, c); | |
376 | ||
377 | /* ip >= 0 */ | |
378 | c = isl_inequality_alloc (isl_local_space_copy (LocalSpace)); | |
379 | isl_constraint_set_coefficient_si (c, isl_dim_out, PointDimension, 1); | |
380 | isl_constraint_set_constant_si (c, 0); | |
381 | TilingMap = isl_map_add_constraint (TilingMap, c); | |
382 | ||
383 | /* it <= ip */ | |
384 | c = isl_inequality_alloc (isl_local_space_copy (LocalSpace)); | |
385 | isl_constraint_set_coefficient_si (c, isl_dim_out, TileDimension, -1); | |
386 | isl_constraint_set_coefficient_si (c, isl_dim_out, PointDimension, 1); | |
387 | TilingMap = isl_map_add_constraint (TilingMap, c); | |
388 | ||
389 | /* ip <= it + ('VectorWidth' - 1) */ | |
390 | c = isl_inequality_alloc (LocalSpace); | |
391 | isl_constraint_set_coefficient_si (c, isl_dim_out, TileDimension, 1); | |
392 | isl_constraint_set_coefficient_si (c, isl_dim_out, PointDimension, -1); | |
393 | isl_constraint_set_constant_si (c, VectorWidth - 1); | |
394 | TilingMap = isl_map_add_constraint (TilingMap, c); | |
b60cc080 TG |
395 | |
396 | return TilingMap; | |
397 | } | |
398 | ||
399 | static bool EnablePollyVector = false; | |
400 | ||
401 | /* getScheduleForBandList - Get the scheduling map for a list of bands. | |
402 | ||
403 | We walk recursively the forest of bands to combine the schedules of the | |
404 | individual bands to the overall schedule. In case tiling is requested, | |
20d3465b MN |
405 | the individual bands are tiled. |
406 | For unroll and jam the map the schedule for full tiles of the unrolled | |
407 | dimnesion is computed. */ | |
b60cc080 | 408 | static isl_union_map * |
20d3465b | 409 | getScheduleForBandList (isl_band_list *BandList, isl_union_map **map_sepcl) |
b60cc080 TG |
410 | { |
411 | int NumBands, i; | |
412 | isl_union_map *Schedule; | |
413 | isl_ctx *ctx; | |
414 | ||
c3284718 RS |
415 | ctx = isl_band_list_get_ctx (BandList); |
416 | NumBands = isl_band_list_n_band (BandList); | |
417 | Schedule = isl_union_map_empty (isl_space_params_alloc (ctx, 0)); | |
b60cc080 TG |
418 | |
419 | for (i = 0; i < NumBands; i++) | |
420 | { | |
421 | isl_band *Band; | |
422 | isl_union_map *PartialSchedule; | |
423 | int ScheduleDimensions; | |
424 | isl_space *Space; | |
425 | ||
20d3465b MN |
426 | isl_union_map *PartialSchedule_f; |
427 | ||
c3284718 RS |
428 | Band = isl_band_list_get_band (BandList, i); |
429 | PartialSchedule = getScheduleForBand (Band, &ScheduleDimensions); | |
430 | Space = isl_union_map_get_space (PartialSchedule); | |
b60cc080 | 431 | |
20d3465b MN |
432 | PartialSchedule_f = NULL; |
433 | ||
c3284718 | 434 | if (isl_band_has_children (Band)) |
b60cc080 TG |
435 | { |
436 | isl_band_list *Children; | |
437 | isl_union_map *SuffixSchedule; | |
438 | ||
c3284718 | 439 | Children = isl_band_get_children (Band); |
20d3465b | 440 | SuffixSchedule = getScheduleForBandList (Children, map_sepcl); |
c3284718 RS |
441 | PartialSchedule = isl_union_map_flat_range_product (PartialSchedule, |
442 | SuffixSchedule); | |
443 | isl_band_list_free (Children); | |
b60cc080 | 444 | } |
20d3465b | 445 | else if (EnablePollyVector || flag_loop_unroll_jam) |
b60cc080 | 446 | { |
20d3465b MN |
447 | int i; |
448 | int depth; | |
449 | ||
450 | depth = PARAM_VALUE (PARAM_LOOP_UNROLL_JAM_DEPTH); | |
451 | ||
b60cc080 TG |
452 | for (i = ScheduleDimensions - 1 ; i >= 0 ; i--) |
453 | { | |
20d3465b MN |
454 | if (flag_loop_unroll_jam && (i != (ScheduleDimensions - depth))) |
455 | continue; | |
456 | ||
797d8858 TB |
457 | #ifdef HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE |
458 | if (isl_band_member_is_coincident (Band, i)) | |
459 | #else | |
c3284718 | 460 | if (isl_band_member_is_zero_distance (Band, i)) |
797d8858 | 461 | #endif |
b60cc080 TG |
462 | { |
463 | isl_map *TileMap; | |
464 | isl_union_map *TileUMap; | |
20d3465b MN |
465 | int stride; |
466 | ||
467 | stride = PARAM_VALUE (PARAM_LOOP_UNROLL_JAM_SIZE); | |
468 | ||
469 | TileMap = getPrevectorMap_full (ctx, i, ScheduleDimensions, | |
470 | stride); | |
471 | TileUMap = isl_union_map_from_map (TileMap); | |
472 | TileUMap = isl_union_map_align_params | |
473 | (TileUMap, isl_space_copy (Space)); | |
474 | PartialSchedule_f = isl_union_map_apply_range | |
475 | (isl_union_map_copy (PartialSchedule), TileUMap); | |
b60cc080 | 476 | |
20d3465b | 477 | TileMap = getPrevectorMap (ctx, i, ScheduleDimensions, stride); |
c3284718 RS |
478 | TileUMap = isl_union_map_from_map (TileMap); |
479 | TileUMap = isl_union_map_align_params | |
480 | (TileUMap, isl_space_copy (Space)); | |
481 | PartialSchedule = isl_union_map_apply_range | |
482 | (PartialSchedule, TileUMap); | |
b60cc080 | 483 | break; |
20d3465b | 484 | } |
b60cc080 TG |
485 | } |
486 | } | |
46cdd0c8 MN |
487 | Schedule = isl_union_map_union (Schedule, |
488 | isl_union_map_copy(PartialSchedule)); | |
b60cc080 | 489 | |
c3284718 RS |
490 | isl_band_free (Band); |
491 | isl_space_free (Space); | |
20d3465b MN |
492 | |
493 | if (!flag_loop_unroll_jam) | |
46cdd0c8 MN |
494 | { |
495 | isl_union_map_free (PartialSchedule); | |
496 | continue; | |
497 | } | |
20d3465b MN |
498 | |
499 | if (PartialSchedule_f) | |
46cdd0c8 MN |
500 | { |
501 | *map_sepcl = isl_union_map_union (*map_sepcl, PartialSchedule_f); | |
502 | isl_union_map_free (PartialSchedule); | |
503 | } | |
20d3465b | 504 | else |
46cdd0c8 | 505 | *map_sepcl = isl_union_map_union (*map_sepcl, PartialSchedule); |
b60cc080 TG |
506 | } |
507 | ||
508 | return Schedule; | |
509 | } | |
510 | ||
511 | static isl_union_map * | |
20d3465b | 512 | getScheduleMap (isl_schedule *Schedule, isl_union_map **map_sepcl) |
b60cc080 | 513 | { |
c3284718 | 514 | isl_band_list *BandList = isl_schedule_get_band_forest (Schedule); |
20d3465b | 515 | isl_union_map *ScheduleMap = getScheduleForBandList (BandList, map_sepcl); |
c3284718 | 516 | isl_band_list_free (BandList); |
b60cc080 TG |
517 | return ScheduleMap; |
518 | } | |
519 | ||
520 | static int | |
c3284718 | 521 | getSingleMap (__isl_take isl_map *map, void *user) |
b60cc080 TG |
522 | { |
523 | isl_map **singleMap = (isl_map **) user; | |
524 | *singleMap = map; | |
525 | ||
526 | return 0; | |
527 | } | |
528 | ||
529 | static void | |
20d3465b | 530 | apply_schedule_map_to_scop (scop_p scop, isl_union_map *schedule_map, bool sepcl) |
b60cc080 TG |
531 | { |
532 | int i; | |
533 | poly_bb_p pbb; | |
534 | ||
9771b263 | 535 | FOR_EACH_VEC_ELT (scop->bbs, i, pbb) |
b60cc080 TG |
536 | { |
537 | isl_set *domain = isl_set_copy (pbb->domain); | |
538 | isl_union_map *stmtBand; | |
539 | isl_map *stmtSchedule; | |
540 | ||
c3284718 RS |
541 | stmtBand = isl_union_map_intersect_domain |
542 | (isl_union_map_copy (schedule_map), | |
543 | isl_union_set_from_set (domain)); | |
544 | isl_union_map_foreach_map (stmtBand, getSingleMap, &stmtSchedule); | |
20d3465b MN |
545 | |
546 | if (!sepcl) | |
547 | { | |
548 | isl_map_free (pbb->transformed); | |
549 | pbb->transformed = stmtSchedule; | |
550 | } | |
551 | else | |
552 | pbb->map_sepclass = stmtSchedule; | |
553 | ||
c3284718 | 554 | isl_union_map_free (stmtBand); |
b60cc080 TG |
555 | } |
556 | } | |
557 | ||
558 | static const int CONSTANT_BOUND = 20; | |
559 | ||
560 | bool | |
561 | optimize_isl (scop_p scop) | |
562 | { | |
563 | ||
564 | isl_schedule *schedule; | |
797d8858 TB |
565 | #ifdef HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE |
566 | isl_schedule_constraints *schedule_constraints; | |
567 | #endif | |
b60cc080 TG |
568 | isl_union_set *domain; |
569 | isl_union_map *validity, *proximity, *dependences; | |
570 | isl_union_map *schedule_map; | |
20d3465b | 571 | isl_union_map *schedule_map_f; |
b60cc080 TG |
572 | |
573 | domain = scop_get_domains (scop); | |
574 | dependences = scop_get_dependences (scop); | |
c3284718 RS |
575 | dependences = isl_union_map_gist_domain (dependences, |
576 | isl_union_set_copy (domain)); | |
577 | dependences = isl_union_map_gist_range (dependences, | |
578 | isl_union_set_copy (domain)); | |
b60cc080 TG |
579 | validity = dependences; |
580 | ||
581 | proximity = isl_union_map_copy (validity); | |
582 | ||
797d8858 TB |
583 | #ifdef HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE |
584 | schedule_constraints = isl_schedule_constraints_on_domain (domain); | |
585 | schedule_constraints | |
586 | = isl_schedule_constraints_set_proximity (schedule_constraints, | |
587 | proximity); | |
588 | schedule_constraints | |
589 | = isl_schedule_constraints_set_validity (schedule_constraints, | |
590 | isl_union_map_copy (validity)); | |
591 | schedule_constraints | |
592 | = isl_schedule_constraints_set_coincidence (schedule_constraints, | |
593 | validity); | |
594 | #endif | |
595 | ||
c3284718 RS |
596 | isl_options_set_schedule_max_constant_term (scop->ctx, CONSTANT_BOUND); |
597 | isl_options_set_schedule_maximize_band_depth (scop->ctx, 1); | |
598 | isl_options_set_schedule_fuse (scop->ctx, ISL_SCHEDULE_FUSE_MIN); | |
599 | isl_options_set_on_error (scop->ctx, ISL_ON_ERROR_CONTINUE); | |
797d8858 TB |
600 | |
601 | #ifdef HAVE_ISL_SCHED_CONSTRAINTS_COMPUTE_SCHEDULE | |
602 | schedule = isl_schedule_constraints_compute_schedule(schedule_constraints); | |
603 | #else | |
b60cc080 | 604 | schedule = isl_union_set_compute_schedule (domain, validity, proximity); |
797d8858 TB |
605 | #endif |
606 | ||
c3284718 | 607 | isl_options_set_on_error (scop->ctx, ISL_ON_ERROR_ABORT); |
b60cc080 TG |
608 | |
609 | if (!schedule) | |
610 | return false; | |
611 | ||
20d3465b MN |
612 | schedule_map_f = isl_union_map_empty (isl_space_params_alloc (scop->ctx, 0)); |
613 | schedule_map = getScheduleMap (schedule, &schedule_map_f); | |
b60cc080 | 614 | |
20d3465b MN |
615 | apply_schedule_map_to_scop (scop, schedule_map, false); |
616 | if (!isl_union_map_is_empty (schedule_map_f)) | |
617 | apply_schedule_map_to_scop (scop, schedule_map_f, true); | |
618 | isl_union_map_free (schedule_map_f); | |
b60cc080 TG |
619 | |
620 | isl_schedule_free (schedule); | |
621 | isl_union_map_free (schedule_map); | |
622 | ||
623 | return true; | |
624 | } | |
625 | ||
626 | #endif |