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