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