#include "isl_map_private.h"#include "isl_tab.h"Go to the source code of this file.
Defines | |
| #define | STATUS_ERROR -1 |
| #define | STATUS_REDUNDANT 1 |
| #define | STATUS_VALID 2 |
| #define | STATUS_SEPARATE 3 |
| #define | STATUS_CUT 4 |
| #define | STATUS_ADJ_EQ 5 |
| #define | STATUS_ADJ_INEQ 6 |
Functions | |
| static int | status_in (struct isl_ctx *ctx, isl_int *ineq, struct isl_tab *tab) |
| static int * | eq_status_in (struct isl_map *map, int i, int j, struct isl_tab **tabs) |
| static int * | ineq_status_in (struct isl_map *map, int i, int j, struct isl_tab **tabs) |
| static int | any (int *con, unsigned len, int status) |
| static int | count (int *con, unsigned len, int status) |
| static int | all (int *con, unsigned len, int status) |
| static void | drop (struct isl_map *map, int i, struct isl_tab **tabs) |
| static int | fuse (struct isl_map *map, int i, int j, struct isl_tab **tabs, int *ineq_i, int *ineq_j) |
| static int | check_facets (struct isl_map *map, int i, int j, struct isl_tab **tabs, int *ineq_i, int *ineq_j) |
| static int | check_adj_ineq (struct isl_map *map, int i, int j, struct isl_tab **tabs, int *ineq_i, int *ineq_j) |
| static int | contains (struct isl_map *map, int i, int *ineq_i, struct isl_tab *tab) |
| static int | check_adj_eq (struct isl_map *map, int i, int j, struct isl_tab **tabs, int *eq_i, int *ineq_i, int *eq_j, int *ineq_j) |
| static int | coalesce_pair (struct isl_map *map, int i, int j, struct isl_tab **tabs) |
| static struct isl_map * | coalesce (struct isl_map *map, struct isl_tab **tabs) |
| struct isl_map * | isl_map_coalesce (struct isl_map *map) |
| struct isl_set * | isl_set_coalesce (struct isl_set *set) |
| #define STATUS_ERROR -1 |
Definition at line 4 of file isl_coalesce.c.
| #define STATUS_REDUNDANT 1 |
Definition at line 5 of file isl_coalesce.c.
| #define STATUS_VALID 2 |
Definition at line 6 of file isl_coalesce.c.
| #define STATUS_SEPARATE 3 |
Definition at line 7 of file isl_coalesce.c.
| #define STATUS_CUT 4 |
Definition at line 8 of file isl_coalesce.c.
| #define STATUS_ADJ_EQ 5 |
Definition at line 9 of file isl_coalesce.c.
| #define STATUS_ADJ_INEQ 6 |
Definition at line 10 of file isl_coalesce.c.
Definition at line 12 of file isl_coalesce.c.
00013 { 00014 enum isl_ineq_type type = isl_tab_ineq_type(ctx, tab, ineq); 00015 switch (type) { 00016 case isl_ineq_error: return STATUS_ERROR; 00017 case isl_ineq_redundant: return STATUS_VALID; 00018 case isl_ineq_separate: return STATUS_SEPARATE; 00019 case isl_ineq_cut: return STATUS_CUT; 00020 case isl_ineq_adj_eq: return STATUS_ADJ_EQ; 00021 case isl_ineq_adj_ineq: return STATUS_ADJ_INEQ; 00022 } 00023 }
Definition at line 31 of file isl_coalesce.c.
00033 { 00034 int k, l; 00035 int *eq = isl_calloc_array(map->ctx, int, 2 * map->p[i]->n_eq); 00036 unsigned dim; 00037 00038 dim = isl_basic_map_total_dim(map->p[i]); 00039 for (k = 0; k < map->p[i]->n_eq; ++k) { 00040 for (l = 0; l < 2; ++l) { 00041 isl_seq_neg(map->p[i]->eq[k], map->p[i]->eq[k], 1+dim); 00042 eq[2 * k + l] = status_in(map->ctx, map->p[i]->eq[k], 00043 tabs[j]); 00044 if (eq[2 * k + l] == STATUS_ERROR) 00045 goto error; 00046 } 00047 if (eq[2 * k] == STATUS_SEPARATE || 00048 eq[2 * k + 1] == STATUS_SEPARATE) 00049 break; 00050 } 00051 00052 return eq; 00053 error: 00054 free(eq); 00055 return NULL; 00056 }
Definition at line 61 of file isl_coalesce.c.
00063 { 00064 int k; 00065 unsigned n_eq = map->p[i]->n_eq; 00066 int *ineq = isl_calloc_array(map->ctx, int, map->p[i]->n_ineq); 00067 00068 for (k = 0; k < map->p[i]->n_ineq; ++k) { 00069 if (isl_tab_is_redundant(map->ctx, tabs[i], n_eq + k)) { 00070 ineq[k] = STATUS_REDUNDANT; 00071 continue; 00072 } 00073 ineq[k] = status_in(map->ctx, map->p[i]->ineq[k], tabs[j]); 00074 if (ineq[k] == STATUS_ERROR) 00075 goto error; 00076 if (ineq[k] == STATUS_SEPARATE) 00077 break; 00078 } 00079 00080 return ineq; 00081 error: 00082 free(ineq); 00083 return NULL; 00084 }
| static int any | ( | int * | con, | |
| unsigned | len, | |||
| int | status | |||
| ) | [static] |
Definition at line 86 of file isl_coalesce.c.
00087 { 00088 int i; 00089 00090 for (i = 0; i < len ; ++i) 00091 if (con[i] == status) 00092 return 1; 00093 return 0; 00094 }
| static int count | ( | int * | con, | |
| unsigned | len, | |||
| int | status | |||
| ) | [static] |
Definition at line 96 of file isl_coalesce.c.
00097 { 00098 int i; 00099 int c = 0; 00100 00101 for (i = 0; i < len ; ++i) 00102 if (con[i] == status) 00103 c++; 00104 return c; 00105 }
| static int all | ( | int * | con, | |
| unsigned | len, | |||
| int | status | |||
| ) | [static] |
Definition at line 107 of file isl_coalesce.c.
00108 { 00109 int i; 00110 00111 for (i = 0; i < len ; ++i) { 00112 if (con[i] == STATUS_REDUNDANT) 00113 continue; 00114 if (con[i] != status) 00115 return 0; 00116 } 00117 return 1; 00118 }
Definition at line 120 of file isl_coalesce.c.
00121 { 00122 isl_basic_map_free(map->p[i]); 00123 isl_tab_free(map->ctx, tabs[i]); 00124 00125 if (i != map->n - 1) { 00126 map->p[i] = map->p[map->n - 1]; 00127 tabs[i] = tabs[map->n - 1]; 00128 } 00129 tabs[map->n - 1] = NULL; 00130 map->n--; 00131 }
| static int fuse | ( | struct isl_map * | map, | |
| int | i, | |||
| int | j, | |||
| struct isl_tab ** | tabs, | |||
| int * | ineq_i, | |||
| int * | ineq_j | |||
| ) | [static] |
Definition at line 136 of file isl_coalesce.c.
00138 { 00139 int k, l; 00140 struct isl_basic_map *fused = NULL; 00141 struct isl_tab *fused_tab = NULL; 00142 unsigned total = isl_basic_map_total_dim(map->p[i]); 00143 00144 fused = isl_basic_map_alloc_dim(isl_dim_copy(map->p[i]->dim), 00145 map->p[i]->n_div, 00146 map->p[i]->n_eq + map->p[j]->n_eq, 00147 map->p[i]->n_ineq + map->p[j]->n_ineq); 00148 if (!fused) 00149 goto error; 00150 00151 for (k = 0; k < map->p[i]->n_eq; ++k) { 00152 int l = isl_basic_map_alloc_equality(fused); 00153 isl_seq_cpy(fused->eq[l], map->p[i]->eq[k], 1 + total); 00154 } 00155 00156 for (k = 0; k < map->p[j]->n_eq; ++k) { 00157 int l = isl_basic_map_alloc_equality(fused); 00158 isl_seq_cpy(fused->eq[l], map->p[j]->eq[k], 1 + total); 00159 } 00160 00161 for (k = 0; k < map->p[i]->n_ineq; ++k) { 00162 if (ineq_i[k] != STATUS_VALID) 00163 continue; 00164 l = isl_basic_map_alloc_inequality(fused); 00165 isl_seq_cpy(fused->ineq[l], map->p[i]->ineq[k], 1 + total); 00166 } 00167 00168 for (k = 0; k < map->p[j]->n_ineq; ++k) { 00169 if (ineq_j[k] != STATUS_VALID) 00170 continue; 00171 l = isl_basic_map_alloc_inequality(fused); 00172 isl_seq_cpy(fused->ineq[l], map->p[j]->ineq[k], 1 + total); 00173 } 00174 00175 for (k = 0; k < map->p[i]->n_div; ++k) { 00176 int l = isl_basic_map_alloc_div(fused); 00177 isl_seq_cpy(fused->div[l], map->p[i]->div[k], 1 + 1 + total); 00178 } 00179 00180 fused = isl_basic_map_gauss(fused, NULL); 00181 ISL_F_SET(fused, ISL_BASIC_MAP_FINAL); 00182 00183 fused_tab = isl_tab_from_basic_map(fused); 00184 fused_tab = isl_tab_detect_redundant(map->ctx, fused_tab); 00185 if (!fused_tab) 00186 goto error; 00187 00188 isl_basic_map_free(map->p[i]); 00189 map->p[i] = fused; 00190 isl_tab_free(map->ctx, tabs[i]); 00191 tabs[i] = fused_tab; 00192 drop(map, j, tabs); 00193 00194 return 1; 00195 error: 00196 isl_basic_map_free(fused); 00197 return -1; 00198 }
| static int check_facets | ( | struct isl_map * | map, | |
| int | i, | |||
| int | j, | |||
| struct isl_tab ** | tabs, | |||
| int * | ineq_i, | |||
| int * | ineq_j | |||
| ) | [static] |
Definition at line 219 of file isl_coalesce.c.
00221 { 00222 int k, l; 00223 struct isl_tab_undo *snap; 00224 unsigned n_eq = map->p[i]->n_eq; 00225 00226 snap = isl_tab_snap(map->ctx, tabs[i]); 00227 00228 for (k = 0; k < map->p[i]->n_ineq; ++k) { 00229 if (ineq_i[k] != STATUS_CUT) 00230 continue; 00231 tabs[i] = isl_tab_select_facet(map->ctx, tabs[i], n_eq + k); 00232 for (l = 0; l < map->p[j]->n_ineq; ++l) { 00233 int stat; 00234 if (ineq_j[l] != STATUS_CUT) 00235 continue; 00236 stat = status_in(map->ctx, map->p[j]->ineq[l], tabs[i]); 00237 if (stat != STATUS_VALID) 00238 break; 00239 } 00240 isl_tab_rollback(map->ctx, tabs[i], snap); 00241 if (l < map->p[j]->n_ineq) 00242 break; 00243 } 00244 00245 if (k < map->p[i]->n_ineq) 00246 /* BAD CUT PAIR */ 00247 return 0; 00248 return fuse(map, i, j, tabs, ineq_i, ineq_j); 00249 }
| static int check_adj_ineq | ( | struct isl_map * | map, | |
| int | i, | |||
| int | j, | |||
| struct isl_tab ** | tabs, | |||
| int * | ineq_i, | |||
| int * | ineq_j | |||
| ) | [static] |
Definition at line 278 of file isl_coalesce.c.
00280 { 00281 int changed = 0; 00282 00283 if (any(ineq_i, map->p[i]->n_ineq, STATUS_CUT) || 00284 any(ineq_j, map->p[j]->n_ineq, STATUS_CUT)) 00285 /* ADJ INEQ CUT */ 00286 ; 00287 else if (count(ineq_i, map->p[i]->n_ineq, STATUS_ADJ_INEQ) == 1 && 00288 count(ineq_j, map->p[j]->n_ineq, STATUS_ADJ_INEQ) == 1) 00289 changed = fuse(map, i, j, tabs, ineq_i, ineq_j); 00290 /* else ADJ INEQ TOO MANY */ 00291 00292 return changed; 00293 }
Definition at line 298 of file isl_coalesce.c.
00300 { 00301 int k, l; 00302 unsigned dim; 00303 00304 dim = isl_basic_map_total_dim(map->p[i]); 00305 for (k = 0; k < map->p[i]->n_eq; ++k) { 00306 for (l = 0; l < 2; ++l) { 00307 int stat; 00308 isl_seq_neg(map->p[i]->eq[k], map->p[i]->eq[k], 1+dim); 00309 stat = status_in(map->ctx, map->p[i]->eq[k], tab); 00310 if (stat != STATUS_VALID) 00311 return 0; 00312 } 00313 } 00314 00315 for (k = 0; k < map->p[i]->n_ineq; ++k) { 00316 int stat; 00317 if (ineq_i[l] == STATUS_REDUNDANT) 00318 continue; 00319 stat = status_in(map->ctx, map->p[i]->ineq[k], tab); 00320 if (stat != STATUS_VALID) 00321 return 0; 00322 } 00323 return 1; 00324 }
| static int check_adj_eq | ( | struct isl_map * | map, | |
| int | i, | |||
| int | j, | |||
| struct isl_tab ** | tabs, | |||
| int * | eq_i, | |||
| int * | ineq_i, | |||
| int * | eq_j, | |||
| int * | ineq_j | |||
| ) | [static] |
Definition at line 349 of file isl_coalesce.c.
00351 { 00352 int changed = 0; 00353 int super; 00354 int k; 00355 struct isl_tab_undo *snap, *snap2; 00356 unsigned n_eq = map->p[i]->n_eq; 00357 00358 if (any(eq_i, 2 * map->p[i]->n_eq, STATUS_ADJ_INEQ) && 00359 any(eq_j, 2 * map->p[j]->n_eq, STATUS_ADJ_INEQ)) 00360 /* ADJ EQ TOO MANY */ 00361 return 0; 00362 00363 if (any(eq_i, 2 * map->p[i]->n_eq, STATUS_ADJ_INEQ)) 00364 return check_adj_eq(map, j, i, tabs, 00365 eq_j, ineq_j, eq_i, ineq_i); 00366 00367 /* j has an equality adjacent to an inequality in i */ 00368 00369 if (any(ineq_i, map->p[i]->n_ineq, STATUS_CUT)) 00370 /* ADJ EQ CUT */ 00371 return 0; 00372 if (count(eq_j, 2 * map->p[j]->n_eq, STATUS_ADJ_INEQ) != 1 || 00373 count(ineq_i, map->p[i]->n_ineq, STATUS_ADJ_EQ) != 1 || 00374 any(ineq_j, map->p[j]->n_ineq, STATUS_ADJ_EQ) || 00375 any(ineq_i, map->p[i]->n_ineq, STATUS_ADJ_INEQ) || 00376 any(ineq_j, map->p[j]->n_ineq, STATUS_ADJ_INEQ)) 00377 /* ADJ EQ TOO MANY */ 00378 return 0; 00379 00380 for (k = 0; k < map->p[i]->n_ineq ; ++k) 00381 if (ineq_i[k] == STATUS_ADJ_EQ) 00382 break; 00383 00384 snap = isl_tab_snap(map->ctx, tabs[i]); 00385 tabs[i] = isl_tab_relax(map->ctx, tabs[i], n_eq + k); 00386 snap2 = isl_tab_snap(map->ctx, tabs[i]); 00387 tabs[i] = isl_tab_select_facet(map->ctx, tabs[i], n_eq + k); 00388 super = contains(map, j, ineq_j, tabs[i]); 00389 if (super) { 00390 isl_tab_rollback(map->ctx, tabs[i], snap2); 00391 map->p[i] = isl_basic_map_cow(map->p[i]); 00392 if (!map->p[i]) 00393 return -1; 00394 isl_int_add_ui(map->p[i]->ineq[k][0], map->p[i]->ineq[k][0], 1); 00395 ISL_F_SET(map->p[i], ISL_BASIC_MAP_FINAL); 00396 drop(map, j, tabs); 00397 changed = 1; 00398 } else 00399 isl_tab_rollback(map->ctx, tabs[i], snap); 00400 00401 return changed; 00402 }
Definition at line 455 of file isl_coalesce.c.
00457 { 00458 int changed = 0; 00459 int *eq_i = NULL; 00460 int *eq_j = NULL; 00461 int *ineq_i = NULL; 00462 int *ineq_j = NULL; 00463 00464 eq_i = eq_status_in(map, i, j, tabs); 00465 if (any(eq_i, 2 * map->p[i]->n_eq, STATUS_ERROR)) 00466 goto error; 00467 if (any(eq_i, 2 * map->p[i]->n_eq, STATUS_SEPARATE)) 00468 goto done; 00469 00470 eq_j = eq_status_in(map, j, i, tabs); 00471 if (any(eq_j, 2 * map->p[j]->n_eq, STATUS_ERROR)) 00472 goto error; 00473 if (any(eq_j, 2 * map->p[j]->n_eq, STATUS_SEPARATE)) 00474 goto done; 00475 00476 ineq_i = ineq_status_in(map, i, j, tabs); 00477 if (any(ineq_i, map->p[i]->n_ineq, STATUS_ERROR)) 00478 goto error; 00479 if (any(ineq_i, map->p[i]->n_ineq, STATUS_SEPARATE)) 00480 goto done; 00481 00482 ineq_j = ineq_status_in(map, j, i, tabs); 00483 if (any(ineq_j, map->p[j]->n_ineq, STATUS_ERROR)) 00484 goto error; 00485 if (any(ineq_j, map->p[j]->n_ineq, STATUS_SEPARATE)) 00486 goto done; 00487 00488 if (all(eq_i, 2 * map->p[i]->n_eq, STATUS_VALID) && 00489 all(ineq_i, map->p[i]->n_ineq, STATUS_VALID)) { 00490 drop(map, j, tabs); 00491 changed = 1; 00492 } else if (all(eq_j, 2 * map->p[j]->n_eq, STATUS_VALID) && 00493 all(ineq_j, map->p[j]->n_ineq, STATUS_VALID)) { 00494 drop(map, i, tabs); 00495 changed = 1; 00496 } else if (any(eq_i, 2 * map->p[i]->n_eq, STATUS_CUT) || 00497 any(eq_j, 2 * map->p[j]->n_eq, STATUS_CUT)) { 00498 /* BAD CUT */ 00499 } else if (any(eq_i, 2 * map->p[i]->n_eq, STATUS_ADJ_EQ) || 00500 any(eq_j, 2 * map->p[j]->n_eq, STATUS_ADJ_EQ)) { 00501 /* ADJ EQ PAIR */ 00502 } else if (any(eq_i, 2 * map->p[i]->n_eq, STATUS_ADJ_INEQ) || 00503 any(eq_j, 2 * map->p[j]->n_eq, STATUS_ADJ_INEQ)) { 00504 changed = check_adj_eq(map, i, j, tabs, 00505 eq_i, ineq_i, eq_j, ineq_j); 00506 } else if (any(ineq_i, map->p[i]->n_ineq, STATUS_ADJ_EQ) || 00507 any(ineq_j, map->p[j]->n_ineq, STATUS_ADJ_EQ)) { 00508 /* Can't happen */ 00509 /* BAD ADJ INEQ */ 00510 } else if (any(ineq_i, map->p[i]->n_ineq, STATUS_ADJ_INEQ) || 00511 any(ineq_j, map->p[j]->n_ineq, STATUS_ADJ_INEQ)) { 00512 changed = check_adj_ineq(map, i, j, tabs, ineq_i, ineq_j); 00513 } else 00514 changed = check_facets(map, i, j, tabs, ineq_i, ineq_j); 00515 00516 done: 00517 free(eq_i); 00518 free(eq_j); 00519 free(ineq_i); 00520 free(ineq_j); 00521 return changed; 00522 error: 00523 free(eq_i); 00524 free(eq_j); 00525 free(ineq_i); 00526 free(ineq_j); 00527 return -1; 00528 }
Definition at line 530 of file isl_coalesce.c.
00531 { 00532 int i, j; 00533 00534 for (i = 0; i < map->n - 1; ++i) 00535 for (j = i + 1; j < map->n; ++j) { 00536 int changed; 00537 changed = coalesce_pair(map, i, j, tabs); 00538 if (changed < 0) 00539 goto error; 00540 if (changed) 00541 return coalesce(map, tabs); 00542 } 00543 return map; 00544 error: 00545 isl_map_free(map); 00546 return NULL; 00547 }
Definition at line 553 of file isl_coalesce.c.
00554 { 00555 int i; 00556 unsigned n; 00557 struct isl_ctx *ctx; 00558 struct isl_tab **tabs = NULL; 00559 00560 if (!map) 00561 return NULL; 00562 00563 if (map->n <= 1) 00564 return map; 00565 00566 map = isl_map_align_divs(map); 00567 00568 tabs = isl_calloc_array(map->ctx, struct isl_tab *, map->n); 00569 if (!tabs) 00570 goto error; 00571 00572 n = map->n; 00573 ctx = map->ctx; 00574 for (i = 0; i < map->n; ++i) { 00575 tabs[i] = isl_tab_from_basic_map(map->p[i]); 00576 if (!tabs[i]) 00577 goto error; 00578 if (!ISL_F_ISSET(map->p[i], ISL_BASIC_MAP_NO_IMPLICIT)) 00579 tabs[i] = isl_tab_detect_equalities(map->ctx, tabs[i]); 00580 if (!ISL_F_ISSET(map->p[i], ISL_BASIC_MAP_NO_REDUNDANT)) 00581 tabs[i] = isl_tab_detect_redundant(map->ctx, tabs[i]); 00582 } 00583 for (i = map->n - 1; i >= 0; --i) 00584 if (tabs[i]->empty) 00585 drop(map, i, tabs); 00586 00587 map = coalesce(map, tabs); 00588 00589 if (map) 00590 for (i = 0; i < map->n; ++i) { 00591 map->p[i] = isl_basic_map_update_from_tab(map->p[i], 00592 tabs[i]); 00593 map->p[i] = isl_basic_map_finalize(map->p[i]); 00594 if (!map->p[i]) 00595 goto error; 00596 ISL_F_SET(map->p[i], ISL_BASIC_MAP_NO_IMPLICIT); 00597 ISL_F_SET(map->p[i], ISL_BASIC_MAP_NO_REDUNDANT); 00598 } 00599 00600 for (i = 0; i < n; ++i) 00601 isl_tab_free(ctx, tabs[i]); 00602 00603 free(tabs); 00604 00605 return map; 00606 error: 00607 if (tabs) 00608 for (i = 0; i < n; ++i) 00609 isl_tab_free(ctx, tabs[i]); 00610 free(tabs); 00611 return NULL; 00612 }
Definition at line 618 of file isl_coalesce.c.
00619 { 00620 (struct isl_set *)isl_map_coalesce((struct isl_map *)set); 00621 }
1.5.9