]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/graphite-optimize-isl.c
gimple-predict.h: New file.
[thirdparty/gcc.git] / gcc / graphite-optimize-isl.c
CommitLineData
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
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 3, or (at your option)
10any later version.
11
12GCC is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along 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
59static isl_union_set *
60scop_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
100static isl_basic_map *
c3284718 101getTileMap (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'. */
169static bool DisableTiling = false;
170
171static isl_union_map *
c3284718 172getScheduleForBand (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 241static isl_map *
c3284718
RS
242getPrevectorMap (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 */
320static isl_map *
321getPrevectorMap_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
399static 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 408static isl_union_map *
20d3465b 409getScheduleForBandList (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
511static isl_union_map *
20d3465b 512getScheduleMap (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
520static int
c3284718 521getSingleMap (__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
529static void
20d3465b 530apply_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
558static const int CONSTANT_BOUND = 20;
559
560bool
561optimize_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