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