00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "errors.h"
00027 #include "ggc.h"
00028 #include "tree.h"
00029 #include "target.h"
00030 #include "rtl.h"
00031 #include "basic-block.h"
00032 #include "diagnostic.h"
00033 #include "tree-flow.h"
00034 #include "tree-dump.h"
00035 #include "timevar.h"
00036 #include "cfgloop.h"
00037 #include "expr.h"
00038 #include "optabs.h"
00039 #include "tree-chrec.h"
00040 #include "tree-data-ref.h"
00041 #include "tree-pass.h"
00042 #include "tree-scalar-evolution.h"
00043 #include "vec.h"
00044 #include "lambda.h"
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 DEF_VEC_GC_P(int);
00120
00121 static bool perfect_nestify (struct loops *,
00122 struct loop *, VEC (tree) *,
00123 VEC (tree) *, VEC (int) *, VEC (tree) *);
00124
00125
00126 typedef struct
00127 {
00128
00129 lambda_matrix base;
00130
00131 int dimension;
00132
00133 lambda_vector origin;
00134
00135 lambda_matrix origin_invariants;
00136
00137 int invariants;
00138 } *lambda_lattice;
00139
00140 #define LATTICE_BASE(T) ((T)->base)
00141 #define LATTICE_DIMENSION(T) ((T)->dimension)
00142 #define LATTICE_ORIGIN(T) ((T)->origin)
00143 #define LATTICE_ORIGIN_INVARIANTS(T) ((T)->origin_invariants)
00144 #define LATTICE_INVARIANTS(T) ((T)->invariants)
00145
00146 static bool lle_equal (lambda_linear_expression, lambda_linear_expression,
00147 int, int);
00148 static lambda_lattice lambda_lattice_new (int, int);
00149 static lambda_lattice lambda_lattice_compute_base (lambda_loopnest);
00150
00151 static tree find_induction_var_from_exit_cond (struct loop *);
00152
00153
00154
00155 lambda_body_vector
00156 lambda_body_vector_new (int size)
00157 {
00158 lambda_body_vector ret;
00159
00160 ret = ggc_alloc (sizeof (*ret));
00161 LBV_COEFFICIENTS (ret) = lambda_vector_new (size);
00162 LBV_SIZE (ret) = size;
00163 LBV_DENOMINATOR (ret) = 1;
00164 return ret;
00165 }
00166
00167
00168
00169
00170 lambda_body_vector
00171 lambda_body_vector_compute_new (lambda_trans_matrix transform,
00172 lambda_body_vector vect)
00173 {
00174 lambda_body_vector temp;
00175 int depth;
00176
00177
00178 gcc_assert (LTM_ROWSIZE (transform) == LTM_COLSIZE (transform));
00179
00180 depth = LTM_ROWSIZE (transform);
00181
00182 temp = lambda_body_vector_new (depth);
00183 LBV_DENOMINATOR (temp) =
00184 LBV_DENOMINATOR (vect) * LTM_DENOMINATOR (transform);
00185 lambda_vector_matrix_mult (LBV_COEFFICIENTS (vect), depth,
00186 LTM_MATRIX (transform), depth,
00187 LBV_COEFFICIENTS (temp));
00188 LBV_SIZE (temp) = LBV_SIZE (vect);
00189 return temp;
00190 }
00191
00192
00193
00194 void
00195 print_lambda_body_vector (FILE * outfile, lambda_body_vector body)
00196 {
00197 print_lambda_vector (outfile, LBV_COEFFICIENTS (body), LBV_SIZE (body));
00198 }
00199
00200
00201
00202 static bool
00203 lle_equal (lambda_linear_expression lle1, lambda_linear_expression lle2,
00204 int depth, int invariants)
00205 {
00206 int i;
00207
00208 if (lle1 == NULL || lle2 == NULL)
00209 return false;
00210 if (LLE_CONSTANT (lle1) != LLE_CONSTANT (lle2))
00211 return false;
00212 if (LLE_DENOMINATOR (lle1) != LLE_DENOMINATOR (lle2))
00213 return false;
00214 for (i = 0; i < depth; i++)
00215 if (LLE_COEFFICIENTS (lle1)[i] != LLE_COEFFICIENTS (lle2)[i])
00216 return false;
00217 for (i = 0; i < invariants; i++)
00218 if (LLE_INVARIANT_COEFFICIENTS (lle1)[i] !=
00219 LLE_INVARIANT_COEFFICIENTS (lle2)[i])
00220 return false;
00221 return true;
00222 }
00223
00224
00225
00226
00227 lambda_linear_expression
00228 lambda_linear_expression_new (int dim, int invariants)
00229 {
00230 lambda_linear_expression ret;
00231
00232 ret = ggc_alloc_cleared (sizeof (*ret));
00233
00234 LLE_COEFFICIENTS (ret) = lambda_vector_new (dim);
00235 LLE_CONSTANT (ret) = 0;
00236 LLE_INVARIANT_COEFFICIENTS (ret) = lambda_vector_new (invariants);
00237 LLE_DENOMINATOR (ret) = 1;
00238 LLE_NEXT (ret) = NULL;
00239
00240 return ret;
00241 }
00242
00243
00244
00245
00246 static void
00247 print_linear_expression (FILE * outfile, lambda_vector expr, int size,
00248 char start)
00249 {
00250 int i;
00251 bool first = true;
00252 for (i = 0; i < size; i++)
00253 {
00254 if (expr[i] != 0)
00255 {
00256 if (first)
00257 {
00258 if (expr[i] < 0)
00259 fprintf (outfile, "-");
00260 first = false;
00261 }
00262 else if (expr[i] > 0)
00263 fprintf (outfile, " + ");
00264 else
00265 fprintf (outfile, " - ");
00266 if (abs (expr[i]) == 1)
00267 fprintf (outfile, "%c", start + i);
00268 else
00269 fprintf (outfile, "%d%c", abs (expr[i]), start + i);
00270 }
00271 }
00272 }
00273
00274
00275
00276
00277
00278
00279 void
00280 print_lambda_linear_expression (FILE * outfile,
00281 lambda_linear_expression expr,
00282 int depth, int invariants, char start)
00283 {
00284 fprintf (outfile, "\tLinear expression: ");
00285 print_linear_expression (outfile, LLE_COEFFICIENTS (expr), depth, start);
00286 fprintf (outfile, " constant: %d ", LLE_CONSTANT (expr));
00287 fprintf (outfile, " invariants: ");
00288 print_linear_expression (outfile, LLE_INVARIANT_COEFFICIENTS (expr),
00289 invariants, 'A');
00290 fprintf (outfile, " denominator: %d\n", LLE_DENOMINATOR (expr));
00291 }
00292
00293
00294
00295
00296
00297
00298 void
00299 print_lambda_loop (FILE * outfile, lambda_loop loop, int depth,
00300 int invariants, char start)
00301 {
00302 int step;
00303 lambda_linear_expression expr;
00304
00305 gcc_assert (loop);
00306
00307 expr = LL_LINEAR_OFFSET (loop);
00308 step = LL_STEP (loop);
00309 fprintf (outfile, " step size = %d \n", step);
00310
00311 if (expr)
00312 {
00313 fprintf (outfile, " linear offset: \n");
00314 print_lambda_linear_expression (outfile, expr, depth, invariants,
00315 start);
00316 }
00317
00318 fprintf (outfile, " lower bound: \n");
00319 for (expr = LL_LOWER_BOUND (loop); expr != NULL; expr = LLE_NEXT (expr))
00320 print_lambda_linear_expression (outfile, expr, depth, invariants, start);
00321 fprintf (outfile, " upper bound: \n");
00322 for (expr = LL_UPPER_BOUND (loop); expr != NULL; expr = LLE_NEXT (expr))
00323 print_lambda_linear_expression (outfile, expr, depth, invariants, start);
00324 }
00325
00326
00327
00328
00329 lambda_loopnest
00330 lambda_loopnest_new (int depth, int invariants)
00331 {
00332 lambda_loopnest ret;
00333 ret = ggc_alloc (sizeof (*ret));
00334
00335 LN_LOOPS (ret) = ggc_alloc_cleared (depth * sizeof (lambda_loop));
00336 LN_DEPTH (ret) = depth;
00337 LN_INVARIANTS (ret) = invariants;
00338
00339 return ret;
00340 }
00341
00342
00343
00344
00345 void
00346 print_lambda_loopnest (FILE * outfile, lambda_loopnest nest, char start)
00347 {
00348 int i;
00349 for (i = 0; i < LN_DEPTH (nest); i++)
00350 {
00351 fprintf (outfile, "Loop %c\n", start + i);
00352 print_lambda_loop (outfile, LN_LOOPS (nest)[i], LN_DEPTH (nest),
00353 LN_INVARIANTS (nest), 'i');
00354 fprintf (outfile, "\n");
00355 }
00356 }
00357
00358
00359
00360
00361 static lambda_lattice
00362 lambda_lattice_new (int depth, int invariants)
00363 {
00364 lambda_lattice ret;
00365 ret = ggc_alloc (sizeof (*ret));
00366 LATTICE_BASE (ret) = lambda_matrix_new (depth, depth);
00367 LATTICE_ORIGIN (ret) = lambda_vector_new (depth);
00368 LATTICE_ORIGIN_INVARIANTS (ret) = lambda_matrix_new (depth, invariants);
00369 LATTICE_DIMENSION (ret) = depth;
00370 LATTICE_INVARIANTS (ret) = invariants;
00371 return ret;
00372 }
00373
00374
00375
00376
00377
00378
00379
00380
00381 static lambda_lattice
00382 lambda_lattice_compute_base (lambda_loopnest nest)
00383 {
00384 lambda_lattice ret;
00385 int depth, invariants;
00386 lambda_matrix base;
00387
00388 int i, j, step;
00389 lambda_loop loop;
00390 lambda_linear_expression expression;
00391
00392 depth = LN_DEPTH (nest);
00393 invariants = LN_INVARIANTS (nest);
00394
00395 ret = lambda_lattice_new (depth, invariants);
00396 base = LATTICE_BASE (ret);
00397 for (i = 0; i < depth; i++)
00398 {
00399 loop = LN_LOOPS (nest)[i];
00400 gcc_assert (loop);
00401 step = LL_STEP (loop);
00402
00403
00404 if (step == 1)
00405 {
00406 for (j = 0; j < depth; j++)
00407 base[i][j] = 0;
00408 base[i][i] = 1;
00409 LATTICE_ORIGIN (ret)[i] = 0;
00410 for (j = 0; j < invariants; j++)
00411 LATTICE_ORIGIN_INVARIANTS (ret)[i][j] = 0;
00412 }
00413 else
00414 {
00415
00416
00417 expression = LL_LOWER_BOUND (loop);
00418 gcc_assert (expression && !LLE_NEXT (expression)
00419 && LLE_DENOMINATOR (expression) == 1);
00420
00421
00422
00423 for (j = 0; j < i; j++)
00424 base[i][j] = LLE_COEFFICIENTS (expression)[j]
00425 * LL_STEP (LN_LOOPS (nest)[j]);
00426 base[i][i] = step;
00427 for (j = i + 1; j < depth; j++)
00428 base[i][j] = 0;
00429
00430
00431
00432 LATTICE_ORIGIN (ret)[i] = LLE_CONSTANT (expression);
00433
00434
00435
00436 for (j = 0; j < invariants; j++)
00437 LATTICE_ORIGIN_INVARIANTS (ret)[i][j] =
00438 LLE_INVARIANT_COEFFICIENTS (expression)[j];
00439 }
00440 }
00441 return ret;
00442 }
00443
00444
00445
00446
00447 static int
00448 gcd (int a, int b)
00449 {
00450
00451 int x, y, z;
00452
00453 x = abs (a);
00454 y = abs (b);
00455
00456 while (x > 0)
00457 {
00458 z = y % x;
00459 y = x;
00460 x = z;
00461 }
00462
00463 return (y);
00464 }
00465
00466
00467
00468 static int
00469 gcd_vector (lambda_vector vector, int size)
00470 {
00471 int i;
00472 int gcd1 = 0;
00473
00474 if (size > 0)
00475 {
00476 gcd1 = vector[0];
00477 for (i = 1; i < size; i++)
00478 gcd1 = gcd (gcd1, vector[i]);
00479 }
00480 return gcd1;
00481 }
00482
00483
00484
00485 static int
00486 lcm (int a, int b)
00487 {
00488 return (abs (a) * abs (b) / gcd (a, b));
00489 }
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518 static lambda_loopnest
00519 compute_nest_using_fourier_motzkin (int size,
00520 int depth,
00521 int invariants,
00522 lambda_matrix A,
00523 lambda_matrix B,
00524 lambda_vector a)
00525 {
00526
00527 int multiple, f1, f2;
00528 int i, j, k;
00529 lambda_linear_expression expression;
00530 lambda_loop loop;
00531 lambda_loopnest auxillary_nest;
00532 lambda_matrix swapmatrix, A1, B1;
00533 lambda_vector swapvector, a1;
00534 int newsize;
00535
00536 A1 = lambda_matrix_new (128, depth);
00537 B1 = lambda_matrix_new (128, invariants);
00538 a1 = lambda_vector_new (128);
00539
00540 auxillary_nest = lambda_loopnest_new (depth, invariants);
00541
00542 for (i = depth - 1; i >= 0; i--)
00543 {
00544 loop = lambda_loop_new ();
00545 LN_LOOPS (auxillary_nest)[i] = loop;
00546 LL_STEP (loop) = 1;
00547
00548 for (j = 0; j < size; j++)
00549 {
00550 if (A[j][i] < 0)
00551 {
00552
00553
00554 expression = lambda_linear_expression_new (depth, invariants);
00555
00556 for (k = 0; k < i; k++)
00557 LLE_COEFFICIENTS (expression)[k] = A[j][k];
00558
00559 for (k = 0; k < invariants; k++)
00560 LLE_INVARIANT_COEFFICIENTS (expression)[k] = -1 * B[j][k];
00561
00562 LLE_DENOMINATOR (expression) = -1 * A[j][i];
00563 LLE_CONSTANT (expression) = -1 * a[j];
00564
00565
00566 if (!lle_equal (LL_LOWER_BOUND (loop),
00567 expression, depth, invariants))
00568 {
00569 LLE_NEXT (expression) = LL_LOWER_BOUND (loop);
00570 LL_LOWER_BOUND (loop) = expression;
00571 }
00572
00573 }
00574 else if (A[j][i] > 0)
00575 {
00576
00577
00578 expression = lambda_linear_expression_new (depth, invariants);
00579 for (k = 0; k < i; k++)
00580 LLE_COEFFICIENTS (expression)[k] = -1 * A[j][k];
00581
00582 for (k = 0; k < invariants; k++)
00583 LLE_INVARIANT_COEFFICIENTS (expression)[k] = B[j][k];
00584
00585 LLE_DENOMINATOR (expression) = A[j][i];
00586 LLE_CONSTANT (expression) = a[j];
00587
00588
00589 if (!lle_equal (LL_UPPER_BOUND (loop),
00590 expression, depth, invariants))
00591 {
00592 LLE_NEXT (expression) = LL_UPPER_BOUND (loop);
00593 LL_UPPER_BOUND (loop) = expression;
00594 }
00595
00596 }
00597 }
00598
00599
00600
00601 newsize = 0;
00602 for (j = 0; j < size; j++)
00603 {
00604
00605
00606
00607 if (A[j][i] == 0)
00608 {
00609 lambda_vector_copy (A[j], A1[newsize], depth);
00610 lambda_vector_copy (B[j], B1[newsize], invariants);
00611 a1[newsize] = a[j];
00612 newsize++;
00613 }
00614 else if (A[j][i] > 0)
00615 {
00616 for (k = 0; k < size; k++)
00617 {
00618 if (A[k][i] < 0)
00619 {
00620 multiple = lcm (A[j][i], A[k][i]);
00621 f1 = multiple / A[j][i];
00622 f2 = -1 * multiple / A[k][i];
00623
00624 lambda_vector_add_mc (A[j], f1, A[k], f2,
00625 A1[newsize], depth);
00626 lambda_vector_add_mc (B[j], f1, B[k], f2,
00627 B1[newsize], invariants);
00628 a1[newsize] = f1 * a[j] + f2 * a[k];
00629 newsize++;
00630 }
00631 }
00632 }
00633 }
00634
00635 swapmatrix = A;
00636 A = A1;
00637 A1 = swapmatrix;
00638
00639 swapmatrix = B;
00640 B = B1;
00641 B1 = swapmatrix;
00642
00643 swapvector = a;
00644 a = a1;
00645 a1 = swapvector;
00646
00647 size = newsize;
00648 }
00649
00650 return auxillary_nest;
00651 }
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 static lambda_loopnest
00669 lambda_compute_auxillary_space (lambda_loopnest nest,
00670 lambda_trans_matrix trans)
00671 {
00672 lambda_matrix A, B, A1, B1;
00673 lambda_vector a, a1;
00674 lambda_matrix invertedtrans;
00675 int determinant, depth, invariants, size;
00676 int i, j;
00677 lambda_loop loop;
00678 lambda_linear_expression expression;
00679 lambda_lattice lattice;
00680
00681 depth = LN_DEPTH (nest);
00682 invariants = LN_INVARIANTS (nest);
00683
00684
00685
00686
00687 A = lambda_matrix_new (128, depth);
00688 B = lambda_matrix_new (128, invariants);
00689 a = lambda_vector_new (128);
00690
00691 A1 = lambda_matrix_new (128, depth);
00692 B1 = lambda_matrix_new (128, invariants);
00693 a1 = lambda_vector_new (128);
00694
00695
00696
00697
00698
00699 size = 0;
00700 for (i = 0; i < depth; i++)
00701 {
00702 loop = LN_LOOPS (nest)[i];
00703
00704
00705 if (LL_STEP (loop) > 0)
00706 expression = LL_LOWER_BOUND (loop);
00707 else
00708 expression = LL_UPPER_BOUND (loop);
00709
00710 for (; expression != NULL; expression = LLE_NEXT (expression))
00711 {
00712
00713 for (j = 0; j < i; j++)
00714 A[size][j] = LLE_COEFFICIENTS (expression)[j];
00715
00716
00717 for (j = 0; j < invariants; j++)
00718 B[size][j] = LLE_INVARIANT_COEFFICIENTS (expression)[j];
00719
00720
00721 a[size] = LLE_CONSTANT (expression);
00722
00723
00724
00725 A[size][i] = -1 * LLE_DENOMINATOR (expression);
00726 a[size] *= -1;
00727 for (j = 0; j < invariants; j++)
00728 B[size][j] *= -1;
00729
00730 size++;
00731
00732 gcc_assert (size <= 127);
00733
00734 }
00735
00736
00737 if (LL_STEP (loop) > 0)
00738 expression = LL_UPPER_BOUND (loop);
00739 else
00740 expression = LL_LOWER_BOUND (loop);
00741
00742 for (; expression != NULL; expression = LLE_NEXT (expression))
00743 {
00744
00745 for (j = 0; j < i; j++)
00746 A[size][j] = LLE_COEFFICIENTS (expression)[j];
00747
00748
00749 for (j = 0; j < invariants; j++)
00750 B[size][j] = LLE_INVARIANT_COEFFICIENTS (expression)[j];
00751
00752
00753 a[size] = LLE_CONSTANT (expression);
00754
00755
00756 for (j = 0; j < i; j++)
00757 A[size][j] *= -1;
00758 A[size][i] = LLE_DENOMINATOR (expression);
00759 size++;
00760
00761 gcc_assert (size <= 127);
00762
00763 }
00764 }
00765
00766
00767
00768 lattice = lambda_lattice_compute_base (nest);
00769
00770
00771
00772
00773 lambda_matrix_mult (A, LATTICE_BASE (lattice), A1, size, depth, depth);
00774
00775
00776 lambda_matrix_vector_mult (A, size, depth, LATTICE_ORIGIN (lattice), a1);
00777 lambda_vector_add_mc (a, 1, a1, -1, a1, size);
00778
00779
00780 lambda_matrix_mult (A, LATTICE_ORIGIN_INVARIANTS (lattice), B1, size, depth,
00781 invariants);
00782 lambda_matrix_add_mc (B, 1, B1, -1, B1, size, invariants);
00783
00784
00785
00786
00787 invertedtrans = lambda_matrix_new (depth, depth);
00788
00789
00790 determinant = lambda_matrix_inverse (LTM_MATRIX (trans),
00791 invertedtrans, depth);
00792
00793
00794 lambda_matrix_mult (A1, invertedtrans, A, size, depth, depth);
00795
00796 return compute_nest_using_fourier_motzkin (size, depth, invariants,
00797 A, B1, a1);
00798 }
00799
00800
00801
00802
00803
00804
00805
00806
00807
00808 static lambda_loopnest
00809 lambda_compute_target_space (lambda_loopnest auxillary_nest,
00810 lambda_trans_matrix H, lambda_vector stepsigns)
00811 {
00812 lambda_matrix inverse, H1;
00813 int determinant, i, j;
00814 int gcd1, gcd2;
00815 int factor;
00816
00817 lambda_loopnest target_nest;
00818 int depth, invariants;
00819 lambda_matrix target;
00820
00821 lambda_loop auxillary_loop, target_loop;
00822 lambda_linear_expression expression, auxillary_expr, target_expr, tmp_expr;
00823
00824 depth = LN_DEPTH (auxillary_nest);
00825 invariants = LN_INVARIANTS (auxillary_nest);
00826
00827 inverse = lambda_matrix_new (depth, depth);
00828 determinant = lambda_matrix_inverse (LTM_MATRIX (H), inverse, depth);
00829
00830
00831 H1 = lambda_matrix_new (depth, depth);
00832 lambda_matrix_copy (LTM_MATRIX (H), H1, depth, depth);
00833
00834 for (i = 0; i < depth; i++)
00835 H1[i][i] = 0;
00836
00837
00838 target = lambda_matrix_new (depth, depth);
00839 lambda_matrix_mult (H1, inverse, target, depth, depth, depth);
00840
00841 target_nest = lambda_loopnest_new (depth, invariants);
00842
00843 for (i = 0; i < depth; i++)
00844 {
00845
00846
00847 target_loop = lambda_loop_new ();
00848 LN_LOOPS (target_nest)[i] = target_loop;
00849
00850
00851 gcd1 = gcd_vector (target[i], i);
00852
00853
00854 gcd1 = gcd (gcd1, determinant);
00855
00856
00857 for (j = 0; j < i; j++)
00858 target[i][j] = target[i][j] / gcd1;
00859
00860 expression = lambda_linear_expression_new (depth, invariants);
00861 lambda_vector_copy (target[i], LLE_COEFFICIENTS (expression), depth);
00862 LLE_DENOMINATOR (expression) = determinant / gcd1;
00863 LLE_CONSTANT (expression) = 0;
00864 lambda_vector_clear (LLE_INVARIANT_COEFFICIENTS (expression),
00865 invariants);
00866 LL_LINEAR_OFFSET (target_loop) = expression;
00867 }
00868
00869
00870 for (i = 0; i < depth; i++)
00871 {
00872 auxillary_loop = LN_LOOPS (auxillary_nest)[i];
00873 target_loop = LN_LOOPS (target_nest)[i];
00874 LL_STEP (target_loop) = LTM_MATRIX (H)[i][i];
00875 factor = LTM_MATRIX (H)[i][i];
00876
00877
00878 auxillary_expr = LL_LOWER_BOUND (auxillary_loop);
00879
00880 for (; auxillary_expr != NULL;
00881 auxillary_expr = LLE_NEXT (auxillary_expr))
00882 {
00883 target_expr = lambda_linear_expression_new (depth, invariants);
00884 lambda_vector_matrix_mult (LLE_COEFFICIENTS (auxillary_expr),
00885 depth, inverse, depth,
00886 LLE_COEFFICIENTS (target_expr));
00887 lambda_vector_mult_const (LLE_COEFFICIENTS (target_expr),
00888 LLE_COEFFICIENTS (target_expr), depth,
00889 factor);
00890
00891 LLE_CONSTANT (target_expr) = LLE_CONSTANT (auxillary_expr) * factor;
00892 lambda_vector_copy (LLE_INVARIANT_COEFFICIENTS (auxillary_expr),
00893 LLE_INVARIANT_COEFFICIENTS (target_expr),
00894 invariants);
00895 lambda_vector_mult_const (LLE_INVARIANT_COEFFICIENTS (target_expr),
00896 LLE_INVARIANT_COEFFICIENTS (target_expr),
00897 invariants, factor);
00898 LLE_DENOMINATOR (target_expr) = LLE_DENOMINATOR (auxillary_expr);
00899
00900 if (!lambda_vector_zerop (LLE_COEFFICIENTS (target_expr), depth))
00901 {
00902 LLE_CONSTANT (target_expr) = LLE_CONSTANT (target_expr)
00903 * determinant;
00904 lambda_vector_mult_const (LLE_INVARIANT_COEFFICIENTS
00905 (target_expr),
00906 LLE_INVARIANT_COEFFICIENTS
00907 (target_expr), invariants,
00908 determinant);
00909 LLE_DENOMINATOR (target_expr) =
00910 LLE_DENOMINATOR (target_expr) * determinant;
00911 }
00912
00913
00914 gcd1 = gcd_vector (LLE_COEFFICIENTS (target_expr), depth);
00915 gcd2 = gcd_vector (LLE_INVARIANT_COEFFICIENTS (target_expr),
00916 invariants);
00917 gcd1 = gcd (gcd1, gcd2);
00918 gcd1 = gcd (gcd1, LLE_CONSTANT (target_expr));
00919 gcd1 = gcd (gcd1, LLE_DENOMINATOR (target_expr));
00920 for (j = 0; j < depth; j++)
00921 LLE_COEFFICIENTS (target_expr)[j] /= gcd1;
00922 for (j = 0; j < invariants; j++)
00923 LLE_INVARIANT_COEFFICIENTS (target_expr)[j] /= gcd1;
00924 LLE_CONSTANT (target_expr) /= gcd1;
00925 LLE_DENOMINATOR (target_expr) /= gcd1;
00926
00927 if (!lle_equal (LL_LOWER_BOUND (target_loop), target_expr, depth,
00928 invariants))
00929 {
00930 LLE_NEXT (target_expr) = LL_LOWER_BOUND (target_loop);
00931 LL_LOWER_BOUND (target_loop) = target_expr;
00932 }
00933 }
00934
00935 auxillary_expr = LL_UPPER_BOUND (auxillary_loop);
00936
00937 for (; auxillary_expr != NULL;
00938 auxillary_expr = LLE_NEXT (auxillary_expr))
00939 {
00940 target_expr = lambda_linear_expression_new (depth, invariants);
00941 lambda_vector_matrix_mult (LLE_COEFFICIENTS (auxillary_expr),
00942 depth, inverse, depth,
00943 LLE_COEFFICIENTS (target_expr));
00944 lambda_vector_mult_const (LLE_COEFFICIENTS (target_expr),
00945 LLE_COEFFICIENTS (target_expr), depth,
00946 factor);
00947 LLE_CONSTANT (target_expr) = LLE_CONSTANT (auxillary_expr) * factor;
00948 lambda_vector_copy (LLE_INVARIANT_COEFFICIENTS (auxillary_expr),
00949 LLE_INVARIANT_COEFFICIENTS (target_expr),
00950 invariants);
00951 lambda_vector_mult_const (LLE_INVARIANT_COEFFICIENTS (target_expr),
00952 LLE_INVARIANT_COEFFICIENTS (target_expr),
00953 invariants, factor);
00954 LLE_DENOMINATOR (target_expr) = LLE_DENOMINATOR (auxillary_expr);
00955
00956 if (!lambda_vector_zerop (LLE_COEFFICIENTS (target_expr), depth))
00957 {
00958 LLE_CONSTANT (target_expr) = LLE_CONSTANT (target_expr)
00959 * determinant;
00960 lambda_vector_mult_const (LLE_INVARIANT_COEFFICIENTS
00961 (target_expr),
00962 LLE_INVARIANT_COEFFICIENTS
00963 (target_expr), invariants,
00964 determinant);
00965 LLE_DENOMINATOR (target_expr) =
00966 LLE_DENOMINATOR (target_expr) * determinant;
00967 }
00968
00969
00970 gcd1 = gcd_vector (LLE_COEFFICIENTS (target_expr), depth);
00971 gcd2 = gcd_vector (LLE_INVARIANT_COEFFICIENTS (target_expr),
00972 invariants);
00973 gcd1 = gcd (gcd1, gcd2);
00974 gcd1 = gcd (gcd1, LLE_CONSTANT (target_expr));
00975 gcd1 = gcd (gcd1, LLE_DENOMINATOR (target_expr));
00976 for (j = 0; j < depth; j++)
00977 LLE_COEFFICIENTS (target_expr)[j] /= gcd1;
00978 for (j = 0; j < invariants; j++)
00979 LLE_INVARIANT_COEFFICIENTS (target_expr)[j] /= gcd1;
00980 LLE_CONSTANT (target_expr) /= gcd1;
00981 LLE_DENOMINATOR (target_expr) /= gcd1;
00982
00983 if (!lle_equal (LL_UPPER_BOUND (target_loop), target_expr, depth,
00984 invariants))
00985 {
00986 LLE_NEXT (target_expr) = LL_UPPER_BOUND (target_loop);
00987 LL_UPPER_BOUND (target_loop) = target_expr;
00988 }
00989 }
00990 }
00991 for (i = 0; i < depth; i++)
00992 {
00993 target_loop = LN_LOOPS (target_nest)[i];
00994
00995
00996 if (stepsigns[i] < 0)
00997 {
00998 LL_STEP (target_loop) *= -1;
00999 tmp_expr = LL_LOWER_BOUND (target_loop);
01000 LL_LOWER_BOUND (target_loop) = LL_UPPER_BOUND (target_loop);
01001 LL_UPPER_BOUND (target_loop) = tmp_expr;
01002 }
01003 }
01004 return target_nest;
01005 }
01006
01007
01008
01009
01010 static lambda_vector
01011 lambda_compute_step_signs (lambda_trans_matrix trans, lambda_vector stepsigns)
01012 {
01013 lambda_matrix matrix, H;
01014 int size;
01015 lambda_vector newsteps;
01016 int i, j, factor, minimum_column;
01017 int temp;
01018
01019 matrix = LTM_MATRIX (trans);
01020 size = LTM_ROWSIZE (trans);
01021 H = lambda_matrix_new (size, size);
01022
01023 newsteps = lambda_vector_new (size);
01024 lambda_vector_copy (stepsigns, newsteps, size);
01025
01026 lambda_matrix_copy (matrix, H, size, size);
01027
01028 for (j = 0; j < size; j++)
01029 {
01030 lambda_vector row;
01031 row = H[j];
01032 for (i = j; i < size; i++)
01033 if (row[i] < 0)
01034 lambda_matrix_col_negate (H, size, i);
01035 while (lambda_vector_first_nz (row, size, j + 1) < size)
01036 {
01037 minimum_column = lambda_vector_min_nz (row, size, j);
01038 lambda_matrix_col_exchange (H, size, j, minimum_column);
01039
01040 temp = newsteps[j];
01041 newsteps[j] = newsteps[minimum_column];
01042 newsteps[minimum_column] = temp;
01043
01044 for (i = j + 1; i < size; i++)
01045 {
01046 factor = row[i] / row[j];
01047 lambda_matrix_col_add (H, size, j, i, -1 * factor);
01048 }
01049 }
01050 }
01051 return newsteps;
01052 }
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064 lambda_loopnest
01065 lambda_loopnest_transform (lambda_loopnest nest, lambda_trans_matrix trans)
01066 {
01067 lambda_loopnest auxillary_nest, target_nest;
01068
01069 int depth, invariants;
01070 int i, j;
01071 lambda_lattice lattice;
01072 lambda_trans_matrix trans1, H, U;
01073 lambda_loop loop;
01074 lambda_linear_expression expression;
01075 lambda_vector origin;
01076 lambda_matrix origin_invariants;
01077 lambda_vector stepsigns;
01078 int f;
01079
01080 depth = LN_DEPTH (nest);
01081 invariants = LN_INVARIANTS (nest);
01082
01083
01084 stepsigns = lambda_vector_new (depth);
01085 for (i = 0; i < depth; i++)
01086 {
01087 if (LL_STEP (LN_LOOPS (nest)[i]) > 0)
01088 stepsigns[i] = 1;
01089 else
01090 stepsigns[i] = -1;
01091 }
01092
01093
01094 lattice = lambda_lattice_compute_base (nest);
01095 trans1 = lambda_trans_matrix_new (depth, depth);
01096
01097
01098
01099 lambda_matrix_mult (LTM_MATRIX (trans), LATTICE_BASE (lattice),
01100 LTM_MATRIX (trans1), depth, depth, depth);
01101
01102
01103 H = lambda_trans_matrix_new (depth, depth);
01104 U = lambda_trans_matrix_new (depth, depth);
01105 lambda_matrix_hermite (LTM_MATRIX (trans1), depth, LTM_MATRIX (H),
01106 LTM_MATRIX (U));
01107
01108
01109
01110 auxillary_nest = lambda_compute_auxillary_space (nest, U);
01111
01112
01113
01114 stepsigns = lambda_compute_step_signs (trans1, stepsigns);
01115
01116
01117
01118 target_nest = lambda_compute_target_space (auxillary_nest, H, stepsigns);
01119 origin = lambda_vector_new (depth);
01120 origin_invariants = lambda_matrix_new (depth, invariants);
01121 lambda_matrix_vector_mult (LTM_MATRIX (trans), depth, depth,
01122 LATTICE_ORIGIN (lattice), origin);
01123 lambda_matrix_mult (LTM_MATRIX (trans), LATTICE_ORIGIN_INVARIANTS (lattice),
01124 origin_invariants, depth, depth, invariants);
01125
01126 for (i = 0; i < depth; i++)
01127 {
01128 loop = LN_LOOPS (target_nest)[i];
01129 expression = LL_LINEAR_OFFSET (loop);
01130 if (lambda_vector_zerop (LLE_COEFFICIENTS (expression), depth))
01131 f = 1;
01132 else
01133 f = LLE_DENOMINATOR (expression);
01134
01135 LLE_CONSTANT (expression) += f * origin[i];
01136
01137 for (j = 0; j < invariants; j++)
01138 LLE_INVARIANT_COEFFICIENTS (expression)[j] +=
01139 f * origin_invariants[i][j];
01140 }
01141
01142 return target_nest;
01143
01144 }
01145
01146
01147
01148
01149
01150
01151
01152
01153 static lambda_linear_expression
01154 gcc_tree_to_linear_expression (int depth, tree expr,
01155 VEC(tree) *outerinductionvars,
01156 VEC(tree) *invariants, int extra)
01157 {
01158 lambda_linear_expression lle = NULL;
01159 switch (TREE_CODE (expr))
01160 {
01161 case INTEGER_CST:
01162 {
01163 lle = lambda_linear_expression_new (depth, 2 * depth);
01164 LLE_CONSTANT (lle) = TREE_INT_CST_LOW (expr);
01165 if (extra != 0)
01166 LLE_CONSTANT (lle) += extra;
01167
01168 LLE_DENOMINATOR (lle) = 1;
01169 }
01170 break;
01171 case SSA_NAME:
01172 {
01173 tree iv, invar;
01174 size_t i;
01175 for (i = 0; VEC_iterate (tree, outerinductionvars, i, iv); i++)
01176 if (iv != NULL)
01177 {
01178 if (SSA_NAME_VAR (iv) == SSA_NAME_VAR (expr))
01179 {
01180 lle = lambda_linear_expression_new (depth, 2 * depth);
01181 LLE_COEFFICIENTS (lle)[i] = 1;
01182 if (extra != 0)
01183 LLE_CONSTANT (lle) = extra;
01184
01185 LLE_DENOMINATOR (lle) = 1;
01186 }
01187 }
01188 for (i = 0; VEC_iterate (tree, invariants, i, invar); i++)
01189 if (invar != NULL)
01190 {
01191 if (SSA_NAME_VAR (invar) == SSA_NAME_VAR (expr))
01192 {
01193 lle = lambda_linear_expression_new (depth, 2 * depth);
01194 LLE_INVARIANT_COEFFICIENTS (lle)[i] = 1;
01195 if (extra != 0)
01196 LLE_CONSTANT (lle) = extra;
01197 LLE_DENOMINATOR (lle) = 1;
01198 }
01199 }
01200 }
01201 break;
01202 default:
01203 return NULL;
01204 }
01205
01206 return lle;
01207 }
01208
01209
01210
01211 static int
01212 depth_of_nest (struct loop *nest)
01213 {
01214 size_t depth = 0;
01215 while (nest)
01216 {
01217 depth++;
01218 nest = nest->inner;
01219 }
01220 return depth;
01221 }
01222
01223
01224
01225
01226 static bool
01227 invariant_in_loop_and_outer_loops (struct loop *loop, tree op)
01228 {
01229 if (is_gimple_min_invariant (op))
01230 return true;
01231 if (loop->depth == 0)
01232 return true;
01233 if (!expr_invariant_in_loop_p (loop, op))
01234 return false;
01235 if (loop->outer
01236 && !invariant_in_loop_and_outer_loops (loop->outer, op))
01237 return false;
01238 return true;
01239 }
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249 static lambda_loop
01250 gcc_loop_to_lambda_loop (struct loop *loop, int depth,
01251 VEC (tree) ** invariants,
01252 tree * ourinductionvar,
01253 VEC (tree) * outerinductionvars,
01254 VEC (tree) ** lboundvars,
01255 VEC (tree) ** uboundvars,
01256 VEC (int) ** steps)
01257 {
01258 tree phi;
01259 tree exit_cond;
01260 tree access_fn, inductionvar;
01261 tree step;
01262 lambda_loop lloop = NULL;
01263 lambda_linear_expression lbound, ubound;
01264 tree test;
01265 int stepint;
01266 int extra = 0;
01267 tree lboundvar, uboundvar, uboundresult;
01268 use_optype uses;
01269
01270
01271 inductionvar = find_induction_var_from_exit_cond (loop);
01272 exit_cond = get_loop_exit_condition (loop);
01273
01274 if (inductionvar == NULL || exit_cond == NULL)
01275 {
01276 if (dump_file && (dump_flags & TDF_DETAILS))
01277 fprintf (dump_file,
01278 "Unable to convert loop: Cannot determine exit condition or induction variable for loop.\n");
01279 return NULL;
01280 }
01281
01282 test = TREE_OPERAND (exit_cond, 0);
01283
01284 if (SSA_NAME_DEF_STMT (inductionvar) == NULL_TREE)
01285 {
01286
01287 if (dump_file && (dump_flags & TDF_DETAILS))
01288 fprintf (dump_file,
01289 "Unable to convert loop: Cannot find PHI node for induction variable\n");
01290
01291 return NULL;
01292 }
01293
01294 phi = SSA_NAME_DEF_STMT (inductionvar);
01295 if (TREE_CODE (phi) != PHI_NODE)
01296 {
01297 get_stmt_operands (phi);
01298 uses = STMT_USE_OPS (phi);
01299
01300 if (!uses)
01301 {
01302
01303 if (dump_file && (dump_flags & TDF_DETAILS))
01304 fprintf (dump_file,
01305 "Unable to convert loop: Cannot find PHI node for induction variable\n");
01306
01307 return NULL;
01308 }
01309
01310 phi = USE_OP (uses, 0);
01311 phi = SSA_NAME_DEF_STMT (phi);
01312 if (TREE_CODE (phi) != PHI_NODE)
01313 {
01314
01315 if (dump_file && (dump_flags & TDF_DETAILS))
01316 fprintf (dump_file,
01317 "Unable to convert loop: Cannot find PHI node for induction variable\n");
01318 return NULL;
01319 }
01320
01321 }
01322
01323
01324
01325 *ourinductionvar = PHI_RESULT (phi);
01326 access_fn = instantiate_parameters
01327 (loop, analyze_scalar_evolution (loop, PHI_RESULT (phi)));
01328 if (access_fn == chrec_dont_know)
01329 {
01330 if (dump_file && (dump_flags & TDF_DETAILS))
01331 fprintf (dump_file,
01332 "Unable to convert loop: Access function for induction variable phi is unknown\n");
01333
01334 return NULL;
01335 }
01336
01337 step = evolution_part_in_loop_num (access_fn, loop->num);
01338 if (!step || step == chrec_dont_know)
01339 {
01340 if (dump_file && (dump_flags & TDF_DETAILS))
01341 fprintf (dump_file,
01342 "Unable to convert loop: Cannot determine step of loop.\n");
01343
01344 return NULL;
01345 }
01346 if (TREE_CODE (step) != INTEGER_CST)
01347 {
01348
01349 if (dump_file && (dump_flags & TDF_DETAILS))
01350 fprintf (dump_file,
01351 "Unable to convert loop: Step of loop is not integer.\n");
01352 return NULL;
01353 }
01354
01355 stepint = TREE_INT_CST_LOW (step);
01356
01357
01358
01359 if (PHI_NUM_ARGS (phi) != 2)
01360 {
01361 if (dump_file && (dump_flags & TDF_DETAILS))
01362 fprintf (dump_file,
01363 "Unable to convert loop: PHI node for induction variable has >2 arguments\n");
01364 return NULL;
01365 }
01366
01367
01368
01369 if (flow_bb_inside_loop_p (loop, PHI_ARG_EDGE (phi, 0)->src)
01370 && flow_bb_inside_loop_p (loop, PHI_ARG_EDGE (phi, 1)->src))
01371 {
01372
01373 if (dump_file && (dump_flags & TDF_DETAILS))
01374 fprintf (dump_file,
01375 "Unable to convert loop: PHI edges both inside loop, or both outside loop.\n");
01376
01377 return NULL;
01378 }
01379
01380 if (flow_bb_inside_loop_p (loop, PHI_ARG_EDGE (phi, 0)->src))
01381 {
01382 lboundvar = PHI_ARG_DEF (phi, 1);
01383 lbound = gcc_tree_to_linear_expression (depth, lboundvar,
01384 outerinductionvars, *invariants,
01385 0);
01386 }
01387 else
01388 {
01389 lboundvar = PHI_ARG_DEF (phi, 0);
01390 lbound = gcc_tree_to_linear_expression (depth, lboundvar,
01391 outerinductionvars, *invariants,
01392 0);
01393 }
01394
01395 if (!lbound)
01396 {
01397
01398 if (dump_file && (dump_flags & TDF_DETAILS))
01399 fprintf (dump_file,
01400 "Unable to convert loop: Cannot convert lower bound to linear expression\n");
01401
01402 return NULL;
01403 }
01404
01405 if (TREE_CODE (TREE_OPERAND (test, 1)) == SSA_NAME
01406 && invariant_in_loop_and_outer_loops (loop, TREE_OPERAND (test, 1)))
01407 VEC_safe_push (tree, *invariants, TREE_OPERAND (test, 1));
01408 else if (TREE_CODE (TREE_OPERAND (test, 0)) == SSA_NAME
01409 && invariant_in_loop_and_outer_loops (loop, TREE_OPERAND (test, 0)))
01410 VEC_safe_push (tree, *invariants, TREE_OPERAND (test, 0));
01411
01412
01413
01414 if (TREE_OPERAND (test, 0) == inductionvar)
01415 uboundvar = TREE_OPERAND (test, 1);
01416 else
01417 uboundvar = TREE_OPERAND (test, 0);
01418
01419
01420
01421
01422
01423
01424 gcc_assert (VEC_length (tree, *invariants) <= (unsigned int) (2 * depth));
01425
01426
01427
01428 if (TREE_CODE (test) == LT_EXPR)
01429 extra = -1 * stepint;
01430 else if (TREE_CODE (test) == NE_EXPR)
01431 extra = -1 * stepint;
01432 else if (TREE_CODE (test) == GT_EXPR)
01433 extra = -1 * stepint;
01434 else if (TREE_CODE (test) == EQ_EXPR)
01435 extra = 1 * stepint;
01436
01437 ubound = gcc_tree_to_linear_expression (depth, uboundvar,
01438 outerinductionvars,
01439 *invariants, extra);
01440 uboundresult = build (PLUS_EXPR, TREE_TYPE (uboundvar), uboundvar,
01441 build_int_cst (TREE_TYPE (uboundvar), extra));
01442 VEC_safe_push (tree, *uboundvars, uboundresult);
01443 VEC_safe_push (tree, *lboundvars, lboundvar);
01444 VEC_safe_push (int, *steps, stepint);
01445 if (!ubound)
01446 {
01447 if (dump_file && (dump_flags & TDF_DETAILS))
01448 fprintf (dump_file,
01449 "Unable to convert loop: Cannot convert upper bound to linear expression\n");
01450 return NULL;
01451 }
01452
01453 lloop = lambda_loop_new ();
01454 LL_STEP (lloop) = stepint;
01455 LL_LOWER_BOUND (lloop) = lbound;
01456 LL_UPPER_BOUND (lloop) = ubound;
01457 return lloop;
01458 }
01459
01460
01461
01462
01463 static tree
01464 find_induction_var_from_exit_cond (struct loop *loop)
01465 {
01466 tree expr = get_loop_exit_condition (loop);
01467 tree ivarop;
01468 tree test;
01469 if (expr == NULL_TREE)
01470 return NULL_TREE;
01471 if (TREE_CODE (expr) != COND_EXPR)
01472 return NULL_TREE;
01473 test = TREE_OPERAND (expr, 0);
01474 if (!COMPARISON_CLASS_P (test))
01475 return NULL_TREE;
01476
01477
01478
01479
01480 if (expr_invariant_in_loop_p (loop, TREE_OPERAND (test, 0)))
01481 ivarop = TREE_OPERAND (test, 1);
01482 else if (expr_invariant_in_loop_p (loop, TREE_OPERAND (test, 1)))
01483 ivarop = TREE_OPERAND (test, 0);
01484 else
01485 return NULL_TREE;
01486
01487 if (TREE_CODE (ivarop) != SSA_NAME)
01488 return NULL_TREE;
01489 return ivarop;
01490 }
01491
01492 DEF_VEC_GC_P(lambda_loop);
01493
01494
01495
01496
01497
01498
01499
01500 lambda_loopnest
01501 gcc_loopnest_to_lambda_loopnest (struct loops *currloops,
01502 struct loop * loop_nest,
01503 VEC (tree) **inductionvars,
01504 VEC (tree) **invariants,
01505 bool need_perfect_nest)
01506 {
01507 lambda_loopnest ret;
01508 struct loop *temp;
01509 int depth = 0;
01510 size_t i;
01511 VEC (lambda_loop) *loops = NULL;
01512 VEC (tree) *uboundvars = NULL;
01513 VEC (tree) *lboundvars = NULL;
01514 VEC (int) *steps = NULL;
01515 lambda_loop newloop;
01516 tree inductionvar = NULL;
01517
01518 depth = depth_of_nest (loop_nest);
01519 temp = loop_nest;
01520 while (temp)
01521 {
01522 newloop = gcc_loop_to_lambda_loop (temp, depth, invariants,
01523 &inductionvar, *inductionvars,
01524 &lboundvars, &uboundvars,
01525 &steps);
01526 if (!newloop)
01527 return NULL;
01528 VEC_safe_push (tree, *inductionvars, inductionvar);
01529 VEC_safe_push (lambda_loop, loops, newloop);
01530 temp = temp->inner;
01531 }
01532 if (need_perfect_nest)
01533 {
01534 if (!perfect_nestify (currloops, loop_nest,
01535 lboundvars, uboundvars, steps, *inductionvars))
01536 {
01537 if (dump_file)
01538 fprintf (dump_file, "Not a perfect loop nest and couldn't convert to one.\n");
01539 return NULL;
01540 }
01541 else if (dump_file)
01542 fprintf (dump_file, "Successfully converted loop nest to perfect loop nest.\n");
01543
01544
01545 }
01546 ret = lambda_loopnest_new (depth, 2 * depth);
01547 for (i = 0; VEC_iterate (lambda_loop, loops, i, newloop); i++)
01548 LN_LOOPS (ret)[i] = newloop;
01549
01550 return ret;
01551
01552 }
01553
01554
01555
01556
01557
01558
01559
01560
01561 static tree
01562 lbv_to_gcc_expression (lambda_body_vector lbv,
01563 tree type, VEC (tree) *induction_vars,
01564 tree * stmts_to_insert)
01565 {
01566 tree stmts, stmt, resvar, name;
01567 tree iv;
01568 size_t i;
01569 tree_stmt_iterator tsi;
01570
01571
01572 stmts = alloc_stmt_list ();
01573 resvar = create_tmp_var (type, "lbvtmp");
01574 add_referenced_tmp_var (resvar);
01575
01576
01577 stmt = build (MODIFY_EXPR, void_type_node, resvar, integer_zero_node);
01578 name = make_ssa_name (resvar, stmt);
01579 TREE_OPERAND (stmt, 0) = name;
01580 tsi = tsi_last (stmts);
01581 tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
01582
01583 for (i = 0; VEC_iterate (tree, induction_vars, i, iv); i++)
01584 {
01585 if (LBV_COEFFICIENTS (lbv)[i] != 0)
01586 {
01587 tree newname;
01588 tree coeffmult;
01589
01590
01591 coeffmult = build_int_cst (type, LBV_COEFFICIENTS (lbv)[i]);
01592 stmt = build (MODIFY_EXPR, void_type_node, resvar,
01593 fold (build (MULT_EXPR, type, iv, coeffmult)));
01594
01595 newname = make_ssa_name (resvar, stmt);
01596 TREE_OPERAND (stmt, 0) = newname;
01597 fold_stmt (&stmt);
01598 tsi = tsi_last (stmts);
01599 tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
01600
01601
01602 stmt = build (MODIFY_EXPR, void_type_node, resvar,
01603 build (PLUS_EXPR, type, name, newname));
01604 name = make_ssa_name (resvar, stmt);
01605 TREE_OPERAND (stmt, 0) = name;
01606 fold_stmt (&stmt);
01607 tsi = tsi_last (stmts);
01608 tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
01609
01610 }
01611 }
01612
01613
01614 if (LBV_DENOMINATOR (lbv) != 1)
01615 {
01616 tree denominator = build_int_cst (type, LBV_DENOMINATOR (lbv));
01617 stmt = build (MODIFY_EXPR, void_type_node, resvar,
01618 build (CEIL_DIV_EXPR, type, name, denominator));
01619 name = make_ssa_name (resvar, stmt);
01620 TREE_OPERAND (stmt, 0) = name;
01621 fold_stmt (&stmt);
01622 tsi = tsi_last (stmts);
01623 tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
01624 }
01625 *stmts_to_insert = stmts;
01626 return name;
01627 }
01628
01629
01630
01631
01632
01633
01634
01635
01636
01637
01638
01639
01640
01641
01642 static tree
01643 lle_to_gcc_expression (lambda_linear_expression lle,
01644 lambda_linear_expression offset,
01645 tree type,
01646 VEC(tree) *induction_vars,
01647 VEC(tree) *invariants,
01648 enum tree_code wrap, tree * stmts_to_insert)
01649 {
01650 tree stmts, stmt, resvar, name;
01651 size_t i;
01652 tree_stmt_iterator tsi;
01653 tree iv, invar;
01654 VEC(tree) *results = NULL;
01655
01656 name = NULL_TREE;
01657
01658 stmts = alloc_stmt_list ();
01659 resvar = create_tmp_var (type, "lletmp");
01660 add_referenced_tmp_var (resvar);
01661
01662
01663
01664 for (; lle != NULL; lle = LLE_NEXT (lle))
01665 {
01666
01667 stmt = build (MODIFY_EXPR, void_type_node, resvar, integer_zero_node);
01668 name = make_ssa_name (resvar, stmt);
01669 TREE_OPERAND (stmt, 0) = name;
01670 fold_stmt (&stmt);
01671 tsi = tsi_last (stmts);
01672 tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
01673
01674
01675
01676
01677 for (i = 0; VEC_iterate (tree, induction_vars, i, iv); i++)
01678 {
01679 if (LLE_COEFFICIENTS (lle)[i] != 0)
01680 {
01681 tree newname;
01682 tree mult;
01683 tree coeff;
01684
01685
01686 if (LLE_COEFFICIENTS (lle)[i] == 1)
01687 {
01688 mult = VEC_index (tree, induction_vars, i);
01689 }
01690 else
01691 {
01692 coeff = build_int_cst (type,
01693 LLE_COEFFICIENTS (lle)[i]);
01694 mult = fold (build (MULT_EXPR, type, iv, coeff));
01695 }
01696
01697
01698 stmt = build (MODIFY_EXPR, void_type_node, resvar, mult);
01699 newname = make_ssa_name (resvar, stmt);
01700 TREE_OPERAND (stmt, 0) = newname;
01701 fold_stmt (&stmt);
01702 tsi = tsi_last (stmts);
01703 tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
01704
01705
01706 stmt = build (MODIFY_EXPR, void_type_node, resvar,
01707 build (PLUS_EXPR, type, name, newname));
01708 name = make_ssa_name (resvar, stmt);
01709 TREE_OPERAND (stmt, 0) = name;
01710 fold_stmt (&stmt);
01711 tsi = tsi_last (stmts);
01712 tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
01713 }
01714 }
01715
01716
01717
01718
01719 for (i = 0; VEC_iterate (tree, invariants, i, invar); i++)
01720 {
01721 if (LLE_INVARIANT_COEFFICIENTS (lle)[i] != 0)
01722 {
01723 tree newname;
01724 tree mult;
01725 tree coeff;
01726 int invcoeff = LLE_INVARIANT_COEFFICIENTS (lle)[i];
01727
01728 if (invcoeff == 1)
01729 {
01730 mult = invar;
01731 }
01732 else
01733 {
01734 coeff = build_int_cst (type, invcoeff);
01735 mult = fold (build (MULT_EXPR, type, invar, coeff));
01736 }
01737
01738
01739 stmt = build (MODIFY_EXPR, void_type_node, resvar, mult);
01740 newname = make_ssa_name (resvar, stmt);
01741 TREE_OPERAND (stmt, 0) = newname;
01742 fold_stmt (&stmt);
01743 tsi = tsi_last (stmts);
01744 tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
01745
01746
01747 stmt = build (MODIFY_EXPR, void_type_node, resvar,
01748 build (PLUS_EXPR, type, name, newname));
01749 name = make_ssa_name (resvar, stmt);
01750 TREE_OPERAND (stmt, 0) = name;
01751 fold_stmt (&stmt);
01752 tsi = tsi_last (stmts);
01753 tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
01754 }
01755 }
01756
01757
01758
01759 if (LLE_CONSTANT (lle) != 0)
01760 {
01761 stmt = build (MODIFY_EXPR, void_type_node, resvar,
01762 build (PLUS_EXPR, type, name,
01763 build_int_cst (type, LLE_CONSTANT (lle))));
01764 name = make_ssa_name (resvar, stmt);
01765 TREE_OPERAND (stmt, 0) = name;
01766 fold_stmt (&stmt);
01767 tsi = tsi_last (stmts);
01768 tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
01769 }
01770
01771
01772
01773 if (LLE_CONSTANT (offset) != 0)
01774 {
01775 stmt = build (MODIFY_EXPR, void_type_node, resvar,
01776 build (PLUS_EXPR, type, name,
01777 build_int_cst (type, LLE_CONSTANT (offset))));
01778 name = make_ssa_name (resvar, stmt);
01779 TREE_OPERAND (stmt, 0) = name;
01780 fold_stmt (&stmt);
01781 tsi = tsi_last (stmts);
01782 tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
01783 }
01784
01785
01786 if (LLE_DENOMINATOR (lle) != 1)
01787 {
01788 if (wrap == MAX_EXPR)
01789 stmt = build (MODIFY_EXPR, void_type_node, resvar,
01790 build (CEIL_DIV_EXPR, type, name,
01791 build_int_cst (type, LLE_DENOMINATOR (lle))));
01792 else if (wrap == MIN_EXPR)
01793 stmt = build (MODIFY_EXPR, void_type_node, resvar,
01794 build (FLOOR_DIV_EXPR, type, name,
01795 build_int_cst (type, LLE_DENOMINATOR (lle))));
01796 else
01797 gcc_unreachable();
01798
01799
01800 name = make_ssa_name (resvar, stmt);
01801 TREE_OPERAND (stmt, 0) = name;
01802 tsi = tsi_last (stmts);
01803 tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
01804 }
01805 VEC_safe_push (tree, results, name);
01806 }
01807
01808
01809
01810 gcc_assert (VEC_length (tree, results) <= 2);
01811
01812
01813 if (VEC_length (tree, results) > 1)
01814 {
01815 tree op1 = VEC_index (tree, results, 0);
01816 tree op2 = VEC_index (tree, results, 1);
01817 stmt = build (MODIFY_EXPR, void_type_node, resvar,
01818 build (wrap, type, op1, op2));
01819 name = make_ssa_name (resvar, stmt);
01820 TREE_OPERAND (stmt, 0) = name;
01821 tsi = tsi_last (stmts);
01822 tsi_link_after (&tsi, stmt, TSI_CONTINUE_LINKING);
01823 }
01824
01825 *stmts_to_insert = stmts;
01826 return name;
01827 }
01828
01829
01830
01831
01832
01833
01834
01835
01836
01837
01838
01839
01840
01841 void
01842 lambda_loopnest_to_gcc_loopnest (struct loop *old_loopnest,
01843 VEC(tree) *old_ivs,
01844 VEC(tree) *invariants,
01845 lambda_loopnest new_loopnest,
01846 lambda_trans_matrix transform)
01847 {
01848
01849 struct loop *temp;
01850 size_t i = 0;
01851 size_t depth = 0;
01852 VEC(tree) *new_ivs = NULL;
01853 tree oldiv;
01854
01855 block_stmt_iterator bsi;
01856
01857 if (dump_file)
01858 {
01859 transform = lambda_trans_matrix_inverse (transform);
01860 fprintf (dump_file, "Inverse of transformation matrix:\n");
01861 print_lambda_trans_matrix (dump_file, transform);
01862 }
01863 depth = depth_of_nest (old_loopnest);
01864 temp = old_loopnest;
01865
01866 while (temp)
01867 {
01868 lambda_loop newloop;
01869 basic_block bb;
01870 edge exit;
01871 tree ivvar, ivvarinced, exitcond, stmts;
01872 enum tree_code testtype;
01873 tree newupperbound, newlowerbound;
01874 lambda_linear_expression offset;
01875 tree type;
01876 bool insert_after;
01877
01878 oldiv = VEC_index (tree, old_ivs, i);
01879 type = TREE_TYPE (oldiv);
01880
01881
01882
01883 ivvar = create_tmp_var (type, "lnivtmp");
01884 add_referenced_tmp_var (ivvar);
01885
01886 VEC_safe_push (tree, new_ivs, ivvar);
01887
01888 newloop = LN_LOOPS (new_loopnest)[i];
01889
01890
01891
01892 offset = LL_LINEAR_OFFSET (newloop);
01893
01894 gcc_assert (LLE_DENOMINATOR (offset) == 1 &&
01895 lambda_vector_zerop (LLE_COEFFICIENTS (offset), depth));
01896
01897
01898
01899 newlowerbound = lle_to_gcc_expression (LL_LOWER_BOUND (newloop),
01900 LL_LINEAR_OFFSET (newloop),
01901 type,
01902 new_ivs,
01903 invariants, MAX_EXPR, &stmts);
01904 bsi_insert_on_edge (loop_preheader_edge (temp), stmts);
01905 bsi_commit_edge_inserts ();
01906
01907
01908 newupperbound = lle_to_gcc_expression (LL_UPPER_BOUND (newloop),
01909 LL_LINEAR_OFFSET (newloop),
01910 type,
01911 new_ivs,
01912 invariants, MIN_EXPR, &stmts);
01913 exit = temp->single_exit;
01914 exitcond = get_loop_exit_condition (temp);
01915 bb = bb_for_stmt (exitcond);
01916 bsi = bsi_start (bb);
01917 bsi_insert_after (&bsi, stmts, BSI_NEW_STMT);
01918
01919
01920
01921 standard_iv_increment_position (temp, &bsi, &insert_after);
01922 create_iv (newlowerbound,
01923 build_int_cst (type, LL_STEP (newloop)),
01924 ivvar, temp, &bsi, insert_after, &ivvar,
01925 &ivvarinced);
01926
01927
01928
01929
01930 testtype = LL_STEP (newloop) >= 0 ? LE_EXPR : GE_EXPR;
01931
01932
01933
01934
01935
01936 if (exit->flags & EDGE_FALSE_VALUE)
01937 testtype = swap_tree_comparison (testtype);
01938
01939 COND_EXPR_COND (exitcond) = build (testtype,
01940 boolean_type_node,
01941 newupperbound, ivvarinced);
01942 modify_stmt (exitcond);
01943 VEC_replace (tree, new_ivs, i, ivvar);
01944
01945 i++;
01946 temp = temp->inner;
01947 }
01948
01949
01950
01951
01952 for (i = 0; VEC_iterate (tree, old_ivs, i, oldiv); i++)
01953 {
01954 int j;
01955 dataflow_t imm = get_immediate_uses (SSA_NAME_DEF_STMT (oldiv));
01956 for (j = 0; j < num_immediate_uses (imm); j++)
01957 {
01958 tree stmt = immediate_use (imm, j);
01959 use_operand_p use_p;
01960 ssa_op_iter iter;
01961 gcc_assert (TREE_CODE (stmt) != PHI_NODE);
01962 FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)
01963 {
01964 if (USE_FROM_PTR (use_p) == oldiv)
01965 {
01966 tree newiv, stmts;
01967 lambda_body_vector lbv, newlbv;
01968
01969
01970 depth = VEC_length (tree, new_ivs);
01971 lbv = lambda_body_vector_new (depth);
01972 LBV_COEFFICIENTS (lbv)[i] = 1;
01973
01974 newlbv = lambda_body_vector_compute_new (transform, lbv);
01975
01976 newiv = lbv_to_gcc_expression (newlbv, TREE_TYPE (oldiv),
01977 new_ivs, &stmts);
01978 bsi = bsi_for_stmt (stmt);
01979
01980
01981 bsi_insert_before (&bsi, stmts, BSI_SAME_STMT);
01982 propagate_value (use_p, newiv);
01983 modify_stmt (stmt);
01984
01985 }
01986 }
01987 }
01988 }
01989 }
01990
01991
01992
01993
01994
01995 static bool
01996 lambda_vector_lexico_pos (lambda_vector v,
01997 unsigned n)
01998 {
01999 unsigned i;
02000 for (i = 0; i < n; i++)
02001 {
02002 if (v[i] == 0)
02003 continue;
02004 if (v[i] < 0)
02005 return false;
02006 if (v[i] > 0)
02007 return true;
02008 }
02009 return true;
02010 }
02011
02012
02013
02014
02015
02016 static bool
02017 not_interesting_stmt (tree stmt)
02018 {
02019
02020
02021 if (TREE_CODE (stmt) == LABEL_EXPR
02022 || TREE_CODE (stmt) == GOTO_EXPR
02023 || TREE_CODE (stmt) == COND_EXPR)
02024 return true;
02025 return false;
02026 }
02027
02028
02029
02030 static bool
02031 phi_loop_edge_uses_def (struct loop *loop, tree phi, tree def)
02032 {
02033 int i;
02034 for (i = 0; i < PHI_NUM_ARGS (phi); i++)
02035 if (flow_bb_inside_loop_p (loop, PHI_ARG_EDGE (phi, i)->src))
02036 if (PHI_ARG_DEF (phi, i) == def)
02037 return true;
02038 return false;
02039 }
02040
02041
02042
02043 static bool
02044 stmt_uses_phi_result (tree stmt, tree phi_result)
02045 {
02046 use_optype uses = STMT_USE_OPS (stmt);
02047
02048
02049
02050 if (NUM_USES (uses) != 1)
02051 return false;
02052 if (USE_OP (uses, 0) == phi_result)
02053 return true;
02054
02055 return false;
02056 }
02057
02058
02059
02060
02061
02062
02063
02064 static bool
02065 stmt_is_bumper_for_loop (struct loop *loop, tree stmt)
02066 {
02067 tree use;
02068 tree def;
02069 def_optype defs = STMT_DEF_OPS (stmt);
02070 dataflow_t imm;
02071 int i;
02072
02073 if (NUM_DEFS (defs) != 1)
02074 return false;
02075 def = DEF_OP (defs, 0);
02076 imm = get_immediate_uses (stmt);
02077 for (i = 0; i < num_immediate_uses (imm); i++)
02078 {
02079 use = immediate_use (imm, i);
02080 if (TREE_CODE (use) == PHI_NODE)
02081 {
02082 if (phi_loop_edge_uses_def (loop, use, def))
02083 if (stmt_uses_phi_result (stmt, PHI_RESULT (use)))
02084 return true;
02085 }
02086 }
02087 return false;
02088 }
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111
02112
02113
02114
02115
02116
02117 bool
02118 perfect_nest_p (struct loop *loop)
02119 {
02120 basic_block *bbs;
02121 size_t i;
02122 tree exit_cond;
02123
02124 if (!loop->inner)
02125 return true;
02126 bbs = get_loop_body (loop);
02127 exit_cond = get_loop_exit_condition (loop);
02128 for (i = 0; i < loop->num_nodes; i++)
02129 {
02130 if (bbs[i]->loop_father == loop)
02131 {
02132 block_stmt_iterator bsi;
02133 for (bsi = bsi_start (bbs[i]); !bsi_end_p (bsi); bsi_next (&bsi))
02134 {
02135 tree stmt = bsi_stmt (bsi);
02136 if (stmt == exit_cond
02137 || not_interesting_stmt (stmt)
02138 || stmt_is_bumper_for_loop (loop, stmt))
02139 continue;
02140 free (bbs);
02141 return false;
02142 }
02143 }
02144 }
02145 free (bbs);
02146
02147 if (loop->inner)
02148 return perfect_nest_p (loop->inner);
02149 return true;
02150 }
02151
02152
02153
02154 static void
02155 replace_uses_of_x_with_y (tree stmt, tree x, tree y)
02156 {
02157 use_optype uses = STMT_USE_OPS (stmt);
02158 size_t i;
02159 for (i = 0; i < NUM_USES (uses); i++)
02160 {
02161 if (USE_OP (uses, i) == x)
02162 SET_USE_OP (uses, i, y);
02163 }
02164 }
02165
02166
02167
02168 static bool
02169 stmt_uses_op (tree stmt, tree op)
02170 {
02171 use_optype uses = STMT_USE_OPS (stmt);
02172 size_t i;
02173 for (i = 0; i < NUM_USES (uses); i++)
02174 {
02175 if (USE_OP (uses, i) == op)
02176 return true;
02177 }
02178 return false;
02179 }
02180
02181
02182
02183
02184
02185
02186 static bool
02187 can_convert_to_perfect_nest (struct loop *loop,
02188 VEC (tree) *loopivs)
02189 {
02190 basic_block *bbs;
02191 tree exit_condition, phi;
02192 size_t i;
02193 block_stmt_iterator bsi;
02194 basic_block exitdest;
02195
02196
02197 if (!loop->inner || loop->inner->inner)
02198 return false;
02199
02200
02201
02202 bbs = get_loop_body (loop);
02203 exit_condition = get_loop_exit_condition (loop);
02204 for (i = 0; i < loop->num_nodes; i++)
02205 {
02206 if (bbs[i]->loop_father == loop)
02207 {
02208 for (bsi = bsi_start (bbs[i]); !bsi_end_p (bsi); bsi_next (&bsi))
02209 {
02210 size_t j;
02211 tree stmt = bsi_stmt (bsi);
02212 if (stmt == exit_condition
02213 || not_interesting_stmt (stmt)
02214 || stmt_is_bumper_for_loop (loop, stmt))
02215 continue;
02216
02217 for (j = 1; j < VEC_length (tree, loopivs); j++)
02218 if (stmt_uses_op (stmt, VEC_index (tree, loopivs, j)))
02219 {
02220 free (bbs);
02221 return false;
02222 }
02223
02224
02225
02226 if (!dominated_by_p (CDI_DOMINATORS,
02227 bb_for_stmt (stmt),
02228 loop->inner->header))
02229 {
02230 free (bbs);
02231 return false;
02232 }
02233 }
02234 }
02235 }
02236
02237
02238
02239
02240 exitdest = loop->single_exit->dest;
02241
02242 for (phi = phi_nodes (exitdest); phi; phi = PHI_CHAIN (phi))
02243 if (PHI_NUM_ARGS (phi) != 1)
02244 return false;
02245
02246 return true;
02247 }
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285 static bool
02286 perfect_nestify (struct loops *loops,
02287 struct loop *loop,
02288 VEC (tree) *lbounds,
02289 VEC (tree) *ubounds,
02290 VEC (int) *steps,
02291 VEC (tree) *loopivs)
02292 {
02293 basic_block *bbs;
02294 tree exit_condition;
02295 tree then_label, else_label, cond_stmt;
02296 basic_block preheaderbb, headerbb, bodybb, latchbb, olddest;
02297 size_t i;
02298 block_stmt_iterator bsi;
02299 bool insert_after;
02300 edge e;
02301 struct loop *newloop;
02302 tree phi;
02303 tree uboundvar;
02304 tree stmt;
02305 tree oldivvar, ivvar, ivvarinced;
02306 VEC (tree) *phis = NULL;
02307
02308 if (!can_convert_to_perfect_nest (loop, loopivs))
02309 return false;
02310
02311
02312
02313 olddest = loop->single_exit->dest;
02314 preheaderbb = loop_split_edge_with (loop->single_exit, NULL);
02315 headerbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
02316
02317
02318 for (phi = phi_nodes (olddest); phi; phi = PHI_CHAIN (phi))
02319 {
02320 VEC_safe_push (tree, phis, PHI_RESULT (phi));
02321 VEC_safe_push (tree, phis, PHI_ARG_DEF (phi, 0));
02322 }
02323 e = redirect_edge_and_branch (EDGE_SUCC (preheaderbb, 0), headerbb);
02324
02325
02326
02327 while (phi_nodes (olddest) != NULL)
02328 {
02329 SET_PHI_RESULT (phi_nodes (olddest), NULL);
02330 remove_phi_node (phi_nodes (olddest), NULL, olddest);
02331 }
02332
02333
02334 while (VEC_length (tree, phis) != 0)
02335 {
02336 tree def;
02337 tree phiname;
02338 def = VEC_pop (tree, phis);
02339 phiname = VEC_pop (tree, phis);
02340 phi = create_phi_node (phiname, preheaderbb);
02341 add_phi_arg (phi, def, EDGE_PRED (preheaderbb, 0));
02342 }
02343 flush_pending_stmts (e);
02344
02345 bodybb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
02346 latchbb = create_empty_bb (EXIT_BLOCK_PTR->prev_bb);
02347 make_edge (headerbb, bodybb, EDGE_FALLTHRU);
02348 then_label = build1 (GOTO_EXPR, void_type_node, tree_block_label (latchbb));
02349 else_label = build1 (GOTO_EXPR, void_type_node, tree_block_label (olddest));
02350 cond_stmt = build (COND_EXPR, void_type_node,
02351 build (NE_EXPR, boolean_type_node,
02352 integer_one_node,
02353 integer_zero_node),
02354 then_label, else_label);
02355 bsi = bsi_start (bodybb);
02356 bsi_insert_after (&bsi, cond_stmt, BSI_NEW_STMT);
02357 e = make_edge (bodybb, olddest, EDGE_FALSE_VALUE);
02358 make_edge (bodybb, latchbb, EDGE_TRUE_VALUE);
02359 make_edge (latchbb, headerbb, EDGE_FALLTHRU);
02360
02361
02362 newloop = duplicate_loop (loops, loop, olddest->loop_father);
02363 newloop->header = headerbb;
02364 newloop->latch = latchbb;
02365 newloop->single_exit = e;
02366 add_bb_to_loop (latchbb, newloop);
02367 add_bb_to_loop (bodybb, newloop);
02368 add_bb_to_loop (headerbb, newloop);
02369 add_bb_to_loop (preheaderbb, olddest->loop_father);
02370 set_immediate_dominator (CDI_DOMINATORS, bodybb, headerbb);
02371 set_immediate_dominator (CDI_DOMINATORS, headerbb, preheaderbb);
02372 set_immediate_dominator (CDI_DOMINATORS, preheaderbb,
02373 loop->single_exit->src);
02374 set_immediate_dominator (CDI_DOMINATORS, latchbb, bodybb);
02375 set_immediate_dominator (CDI_DOMINATORS, olddest, bodybb);
02376
02377 ivvar = create_tmp_var (integer_type_node, "perfectiv");
02378 add_referenced_tmp_var (ivvar);
02379 standard_iv_increment_position (newloop, &bsi, &insert_after);
02380 create_iv (VEC_index (tree, lbounds, 0),
02381 build_int_cst (integer_type_node, VEC_index (int, steps, 0)),
02382 ivvar, newloop, &bsi, insert_after, &ivvar, &ivvarinced);
02383
02384
02385
02386
02387 exit_condition = get_loop_exit_condition (newloop);
02388 uboundvar = create_tmp_var (integer_type_node, "uboundvar");
02389 add_referenced_tmp_var (uboundvar);
02390 stmt = build (MODIFY_EXPR, void_type_node, uboundvar,
02391 VEC_index (tree, ubounds, 0));
02392 uboundvar = make_ssa_name (uboundvar, stmt);
02393 TREE_OPERAND (stmt, 0) = uboundvar;
02394
02395 if (insert_after)
02396 bsi_insert_after (&bsi, stmt, BSI_SAME_STMT);
02397 else
02398 bsi_insert_before (&bsi, stmt, BSI_SAME_STMT);
02399
02400 COND_EXPR_COND (exit_condition) = build (GE_EXPR,
02401 boolean_type_node,
02402 uboundvar,
02403 ivvarinced);
02404
02405 bbs = get_loop_body (loop);
02406
02407
02408 oldivvar = VEC_index (tree, loopivs, 0);
02409 for (i = 0; i < loop->num_nodes; i++)
02410 {
02411 block_stmt_iterator tobsi = bsi_last (bodybb);
02412 if (bbs[i]->loop_father == loop)
02413 {
02414
02415
02416
02417 for (bsi = bsi_start (bbs[i]); !bsi_end_p (bsi);)
02418 {
02419 tree stmt = bsi_stmt (bsi);
02420 if (stmt == exit_condition
02421 || not_interesting_stmt (stmt)
02422 || stmt_is_bumper_for_loop (loop, stmt))
02423 {
02424 bsi_next (&bsi);
02425 continue;
02426 }
02427 replace_uses_of_x_with_y (stmt, oldivvar, ivvar);
02428 bsi_move_before (&bsi, &tobsi);
02429 }
02430 }
02431 }
02432 free (bbs);
02433 flow_loops_find (loops, LOOP_ALL);
02434 return perfect_nest_p (loop);
02435 }
02436
02437
02438
02439
02440
02441
02442
02443
02444
02445
02446
02447
02448
02449
02450 bool
02451 lambda_transform_legal_p (lambda_trans_matrix trans,
02452 int nb_loops,
02453 varray_type dependence_relations)
02454 {
02455 unsigned int i;
02456 lambda_vector distres;
02457 struct data_dependence_relation *ddr;
02458
02459 #if defined ENABLE_CHECKING
02460 if (LTM_COLSIZE (trans) != nb_loops
02461 || LTM_ROWSIZE (trans) != nb_loops)
02462 abort ();
02463 #endif
02464
02465
02466
02467 ddr = (struct data_dependence_relation *)
02468 VARRAY_GENERIC_PTR (dependence_relations, 0);
02469 if (ddr == NULL)
02470 return true;
02471 if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
02472 return false;
02473
02474 distres = lambda_vector_new (nb_loops);
02475
02476
02477 for (i = 0; i < VARRAY_ACTIVE_SIZE (dependence_relations); i++)
02478 {
02479 ddr = (struct data_dependence_relation *)
02480 VARRAY_GENERIC_PTR (dependence_relations, i);
02481
02482
02483
02484
02485 if (DDR_ARE_DEPENDENT (ddr) == chrec_known
02486 || (DR_IS_READ (DDR_A (ddr)) && DR_IS_READ (DDR_B (ddr))))
02487 continue;
02488
02489
02490 if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
02491 return false;
02492
02493
02494
02495 if (DDR_DIST_VECT (ddr) == NULL)
02496 return false;
02497
02498
02499 lambda_matrix_vector_mult (LTM_MATRIX (trans), nb_loops, nb_loops,
02500 DDR_DIST_VECT (ddr), distres);
02501
02502 if (!lambda_vector_lexico_pos (distres, nb_loops))
02503 return false;
02504 }
02505 return true;
02506 }