00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "config.h"
00028 #include "system.h"
00029 #include "coretypes.h"
00030 #include "tm.h"
00031 #include "ggc.h"
00032 #include "tree.h"
00033 #include "real.h"
00034 #include "diagnostic.h"
00035 #include "cfgloop.h"
00036 #include "tree-flow.h"
00037 #include "tree-chrec.h"
00038 #include "tree-pass.h"
00039 #include "params.h"
00040 #include "tree-scalar-evolution.h"
00041
00042
00043
00044
00045
00046
00047
00048 static inline bool
00049 is_not_constant_evolution (tree cst)
00050 {
00051 return (TREE_CODE (cst) == POLYNOMIAL_CHREC);
00052 }
00053
00054
00055
00056 static inline tree
00057 chrec_fold_poly_cst (enum tree_code code,
00058 tree type,
00059 tree poly,
00060 tree cst)
00061 {
00062 gcc_assert (poly);
00063 gcc_assert (cst);
00064 gcc_assert (TREE_CODE (poly) == POLYNOMIAL_CHREC);
00065 gcc_assert (!is_not_constant_evolution (cst));
00066 gcc_assert (type == chrec_type (poly));
00067
00068 switch (code)
00069 {
00070 case PLUS_EXPR:
00071 return build_polynomial_chrec
00072 (CHREC_VARIABLE (poly),
00073 chrec_fold_plus (type, CHREC_LEFT (poly), cst),
00074 CHREC_RIGHT (poly));
00075
00076 case MINUS_EXPR:
00077 return build_polynomial_chrec
00078 (CHREC_VARIABLE (poly),
00079 chrec_fold_minus (type, CHREC_LEFT (poly), cst),
00080 CHREC_RIGHT (poly));
00081
00082 case MULT_EXPR:
00083 return build_polynomial_chrec
00084 (CHREC_VARIABLE (poly),
00085 chrec_fold_multiply (type, CHREC_LEFT (poly), cst),
00086 chrec_fold_multiply (type, CHREC_RIGHT (poly), cst));
00087
00088 default:
00089 return chrec_dont_know;
00090 }
00091 }
00092
00093
00094
00095 static inline tree
00096 chrec_fold_plus_poly_poly (enum tree_code code,
00097 tree type,
00098 tree poly0,
00099 tree poly1)
00100 {
00101 tree left, right;
00102
00103 gcc_assert (poly0);
00104 gcc_assert (poly1);
00105 gcc_assert (TREE_CODE (poly0) == POLYNOMIAL_CHREC);
00106 gcc_assert (TREE_CODE (poly1) == POLYNOMIAL_CHREC);
00107 gcc_assert (chrec_type (poly0) == chrec_type (poly1));
00108 gcc_assert (type == chrec_type (poly0));
00109
00110
00111
00112
00113
00114 if (CHREC_VARIABLE (poly0) < CHREC_VARIABLE (poly1))
00115 {
00116 if (code == PLUS_EXPR)
00117 return build_polynomial_chrec
00118 (CHREC_VARIABLE (poly1),
00119 chrec_fold_plus (type, poly0, CHREC_LEFT (poly1)),
00120 CHREC_RIGHT (poly1));
00121 else
00122 return build_polynomial_chrec
00123 (CHREC_VARIABLE (poly1),
00124 chrec_fold_minus (type, poly0, CHREC_LEFT (poly1)),
00125 chrec_fold_multiply (type, CHREC_RIGHT (poly1),
00126 SCALAR_FLOAT_TYPE_P (type)
00127 ? build_real (type, dconstm1)
00128 : build_int_cst_type (type, -1)));
00129 }
00130
00131 if (CHREC_VARIABLE (poly0) > CHREC_VARIABLE (poly1))
00132 {
00133 if (code == PLUS_EXPR)
00134 return build_polynomial_chrec
00135 (CHREC_VARIABLE (poly0),
00136 chrec_fold_plus (type, CHREC_LEFT (poly0), poly1),
00137 CHREC_RIGHT (poly0));
00138 else
00139 return build_polynomial_chrec
00140 (CHREC_VARIABLE (poly0),
00141 chrec_fold_minus (type, CHREC_LEFT (poly0), poly1),
00142 CHREC_RIGHT (poly0));
00143 }
00144
00145 if (code == PLUS_EXPR)
00146 {
00147 left = chrec_fold_plus
00148 (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1));
00149 right = chrec_fold_plus
00150 (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1));
00151 }
00152 else
00153 {
00154 left = chrec_fold_minus
00155 (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1));
00156 right = chrec_fold_minus
00157 (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1));
00158 }
00159
00160 if (chrec_zerop (right))
00161 return left;
00162 else
00163 return build_polynomial_chrec
00164 (CHREC_VARIABLE (poly0), left, right);
00165 }
00166
00167
00168
00169
00170
00171 static inline tree
00172 chrec_fold_multiply_poly_poly (tree type,
00173 tree poly0,
00174 tree poly1)
00175 {
00176 tree t0, t1, t2;
00177 int var;
00178
00179 gcc_assert (poly0);
00180 gcc_assert (poly1);
00181 gcc_assert (TREE_CODE (poly0) == POLYNOMIAL_CHREC);
00182 gcc_assert (TREE_CODE (poly1) == POLYNOMIAL_CHREC);
00183 gcc_assert (chrec_type (poly0) == chrec_type (poly1));
00184 gcc_assert (type == chrec_type (poly0));
00185
00186
00187
00188
00189 if (CHREC_VARIABLE (poly0) < CHREC_VARIABLE (poly1))
00190
00191 return build_polynomial_chrec
00192 (CHREC_VARIABLE (poly1),
00193 chrec_fold_multiply (type, CHREC_LEFT (poly1), poly0),
00194 CHREC_RIGHT (poly1));
00195
00196 if (CHREC_VARIABLE (poly1) < CHREC_VARIABLE (poly0))
00197
00198 return build_polynomial_chrec
00199 (CHREC_VARIABLE (poly0),
00200 chrec_fold_multiply (type, CHREC_LEFT (poly0), poly1),
00201 CHREC_RIGHT (poly0));
00202
00203
00204
00205
00206
00207 t0 = chrec_fold_multiply (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1));
00208
00209
00210 t1 = chrec_fold_multiply (type, CHREC_LEFT (poly0), CHREC_RIGHT (poly1));
00211 t1 = chrec_fold_plus (type, t1, chrec_fold_multiply (type,
00212 CHREC_RIGHT (poly0),
00213 CHREC_LEFT (poly1)));
00214 t1 = chrec_fold_plus (type, t1, chrec_fold_multiply (type,
00215 CHREC_RIGHT (poly0),
00216 CHREC_RIGHT (poly1)));
00217
00218 t2 = chrec_fold_multiply (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1));
00219 t2 = chrec_fold_multiply (type, SCALAR_FLOAT_TYPE_P (type)
00220 ? build_real (type, dconst2)
00221 : build_int_cst (type, 2), t2);
00222
00223 var = CHREC_VARIABLE (poly0);
00224 return build_polynomial_chrec (var, t0,
00225 build_polynomial_chrec (var, t1, t2));
00226 }
00227
00228
00229
00230
00231 static inline tree
00232 chrec_fold_automatically_generated_operands (tree op0,
00233 tree op1)
00234 {
00235 if (op0 == chrec_dont_know
00236 || op1 == chrec_dont_know)
00237 return chrec_dont_know;
00238
00239 if (op0 == chrec_known
00240 || op1 == chrec_known)
00241 return chrec_known;
00242
00243 if (op0 == chrec_not_analyzed_yet
00244 || op1 == chrec_not_analyzed_yet)
00245 return chrec_not_analyzed_yet;
00246
00247
00248 return chrec_dont_know;
00249 }
00250
00251
00252
00253 static tree
00254 chrec_fold_plus_1 (enum tree_code code, tree type,
00255 tree op0, tree op1)
00256 {
00257 if (automatically_generated_chrec_p (op0)
00258 || automatically_generated_chrec_p (op1))
00259 return chrec_fold_automatically_generated_operands (op0, op1);
00260
00261 switch (TREE_CODE (op0))
00262 {
00263 case POLYNOMIAL_CHREC:
00264 switch (TREE_CODE (op1))
00265 {
00266 case POLYNOMIAL_CHREC:
00267 return chrec_fold_plus_poly_poly (code, type, op0, op1);
00268
00269 default:
00270 if (code == PLUS_EXPR)
00271 return build_polynomial_chrec
00272 (CHREC_VARIABLE (op0),
00273 chrec_fold_plus (type, CHREC_LEFT (op0), op1),
00274 CHREC_RIGHT (op0));
00275 else
00276 return build_polynomial_chrec
00277 (CHREC_VARIABLE (op0),
00278 chrec_fold_minus (type, CHREC_LEFT (op0), op1),
00279 CHREC_RIGHT (op0));
00280 }
00281
00282 default:
00283 switch (TREE_CODE (op1))
00284 {
00285 case POLYNOMIAL_CHREC:
00286 if (code == PLUS_EXPR)
00287 return build_polynomial_chrec
00288 (CHREC_VARIABLE (op1),
00289 chrec_fold_plus (type, op0, CHREC_LEFT (op1)),
00290 CHREC_RIGHT (op1));
00291 else
00292 return build_polynomial_chrec
00293 (CHREC_VARIABLE (op1),
00294 chrec_fold_minus (type, op0, CHREC_LEFT (op1)),
00295 chrec_fold_multiply (type, CHREC_RIGHT (op1),
00296 SCALAR_FLOAT_TYPE_P (type)
00297 ? build_real (type, dconstm1)
00298 : build_int_cst_type (type, -1)));
00299
00300 default:
00301 {
00302 int size = 0;
00303 if ((tree_contains_chrecs (op0, &size)
00304 || tree_contains_chrecs (op1, &size))
00305 && size < PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE))
00306 return build2 (code, type, op0, op1);
00307 else if (size < PARAM_VALUE (PARAM_SCEV_MAX_EXPR_SIZE))
00308 return fold_build2 (code, type,
00309 fold_convert (type, op0),
00310 fold_convert (type, op1));
00311 else
00312 return chrec_dont_know;
00313 }
00314 }
00315 }
00316 }
00317
00318
00319
00320 tree
00321 chrec_fold_plus (tree type,
00322 tree op0,
00323 tree op1)
00324 {
00325 if (automatically_generated_chrec_p (op0)
00326 || automatically_generated_chrec_p (op1))
00327 return chrec_fold_automatically_generated_operands (op0, op1);
00328
00329 if (integer_zerop (op0))
00330 return op1;
00331 if (integer_zerop (op1))
00332 return op0;
00333
00334 return chrec_fold_plus_1 (PLUS_EXPR, type, op0, op1);
00335 }
00336
00337
00338
00339 tree
00340 chrec_fold_minus (tree type,
00341 tree op0,
00342 tree op1)
00343 {
00344 if (automatically_generated_chrec_p (op0)
00345 || automatically_generated_chrec_p (op1))
00346 return chrec_fold_automatically_generated_operands (op0, op1);
00347
00348 if (integer_zerop (op1))
00349 return op0;
00350
00351 return chrec_fold_plus_1 (MINUS_EXPR, type, op0, op1);
00352 }
00353
00354
00355
00356 tree
00357 chrec_fold_multiply (tree type,
00358 tree op0,
00359 tree op1)
00360 {
00361 if (automatically_generated_chrec_p (op0)
00362 || automatically_generated_chrec_p (op1))
00363 return chrec_fold_automatically_generated_operands (op0, op1);
00364
00365 switch (TREE_CODE (op0))
00366 {
00367 case POLYNOMIAL_CHREC:
00368 switch (TREE_CODE (op1))
00369 {
00370 case POLYNOMIAL_CHREC:
00371 return chrec_fold_multiply_poly_poly (type, op0, op1);
00372
00373 default:
00374 if (integer_onep (op1))
00375 return op0;
00376 if (integer_zerop (op1))
00377 return build_int_cst (type, 0);
00378
00379 return build_polynomial_chrec
00380 (CHREC_VARIABLE (op0),
00381 chrec_fold_multiply (type, CHREC_LEFT (op0), op1),
00382 chrec_fold_multiply (type, CHREC_RIGHT (op0), op1));
00383 }
00384
00385 default:
00386 if (integer_onep (op0))
00387 return op1;
00388
00389 if (integer_zerop (op0))
00390 return build_int_cst (type, 0);
00391
00392 switch (TREE_CODE (op1))
00393 {
00394 case POLYNOMIAL_CHREC:
00395 return build_polynomial_chrec
00396 (CHREC_VARIABLE (op1),
00397 chrec_fold_multiply (type, CHREC_LEFT (op1), op0),
00398 chrec_fold_multiply (type, CHREC_RIGHT (op1), op0));
00399
00400 default:
00401 if (integer_onep (op1))
00402 return op0;
00403 if (integer_zerop (op1))
00404 return build_int_cst (type, 0);
00405 return fold_build2 (MULT_EXPR, type, op0, op1);
00406 }
00407 }
00408 }
00409
00410
00411
00412
00413
00414
00415
00416
00417 static tree
00418 tree_fold_binomial (tree type, tree n, unsigned int k)
00419 {
00420 unsigned HOST_WIDE_INT lidx, lnum, ldenom, lres, ldum;
00421 HOST_WIDE_INT hidx, hnum, hdenom, hres, hdum;
00422 unsigned int i;
00423 tree res;
00424
00425
00426 if (k == 0)
00427 return build_int_cst (type, 1);
00428 if (k == 1)
00429 return fold_convert (type, n);
00430
00431
00432 if (TREE_INT_CST_HIGH (n) == 0
00433 && TREE_INT_CST_LOW (n) < k)
00434 return NULL_TREE;
00435
00436
00437 lnum = TREE_INT_CST_LOW (n);
00438 hnum = TREE_INT_CST_HIGH (n);
00439
00440
00441 ldenom = 2;
00442 hdenom = 0;
00443
00444
00445 if (lnum == 0)
00446 {
00447 hidx = hnum - 1;
00448 lidx = ~ (unsigned HOST_WIDE_INT) 0;
00449 }
00450 else
00451 {
00452 hidx = hnum;
00453 lidx = lnum - 1;
00454 }
00455
00456
00457 if (mul_double (lnum, hnum, lidx, hidx, &lnum, &hnum))
00458 return NULL_TREE;
00459
00460 for (i = 3; i <= k; i++)
00461 {
00462
00463 if (lidx == 0)
00464 {
00465 hidx--;
00466 lidx = ~ (unsigned HOST_WIDE_INT) 0;
00467 }
00468 else
00469 lidx--;
00470
00471
00472 if (mul_double (lnum, hnum, lidx, hidx, &lnum, &hnum))
00473 return NULL_TREE;
00474
00475
00476 mul_double (ldenom, hdenom, i, 0, &ldenom, &hdenom);
00477 }
00478
00479
00480 div_and_round_double (EXACT_DIV_EXPR, 1, lnum, hnum, ldenom, hdenom,
00481 &lres, &hres, &ldum, &hdum);
00482
00483 res = build_int_cst_wide (type, lres, hres);
00484 return int_fits_type_p (res, type) ? res : NULL_TREE;
00485 }
00486
00487
00488
00489
00490 static tree
00491 chrec_evaluate (unsigned var, tree chrec, tree n, unsigned int k)
00492 {
00493 tree arg0, arg1, binomial_n_k;
00494 tree type = TREE_TYPE (chrec);
00495
00496 while (TREE_CODE (chrec) == POLYNOMIAL_CHREC
00497 && CHREC_VARIABLE (chrec) > var)
00498 chrec = CHREC_LEFT (chrec);
00499
00500 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
00501 && CHREC_VARIABLE (chrec) == var)
00502 {
00503 arg0 = chrec_evaluate (var, CHREC_RIGHT (chrec), n, k + 1);
00504 if (arg0 == chrec_dont_know)
00505 return chrec_dont_know;
00506 binomial_n_k = tree_fold_binomial (type, n, k);
00507 if (!binomial_n_k)
00508 return chrec_dont_know;
00509 arg1 = fold_build2 (MULT_EXPR, type,
00510 CHREC_LEFT (chrec), binomial_n_k);
00511 return chrec_fold_plus (type, arg0, arg1);
00512 }
00513
00514 binomial_n_k = tree_fold_binomial (type, n, k);
00515 if (!binomial_n_k)
00516 return chrec_dont_know;
00517
00518 return fold_build2 (MULT_EXPR, type, chrec, binomial_n_k);
00519 }
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532 tree
00533 chrec_apply (unsigned var,
00534 tree chrec,
00535 tree x)
00536 {
00537 tree type = chrec_type (chrec);
00538 tree res = chrec_dont_know;
00539
00540 if (automatically_generated_chrec_p (chrec)
00541 || automatically_generated_chrec_p (x)
00542
00543
00544
00545
00546 || chrec_contains_symbols_defined_in_loop (chrec, var))
00547 return chrec_dont_know;
00548
00549 if (dump_file && (dump_flags & TDF_DETAILS))
00550 fprintf (dump_file, "(chrec_apply \n");
00551
00552 if (TREE_CODE (x) == INTEGER_CST && SCALAR_FLOAT_TYPE_P (type))
00553 x = build_real_from_int_cst (type, x);
00554
00555 if (evolution_function_is_affine_p (chrec))
00556 {
00557
00558 x = chrec_convert (type, x, NULL_TREE);
00559 res = chrec_fold_multiply (type, CHREC_RIGHT (chrec), x);
00560 if (!integer_zerop (CHREC_LEFT (chrec)))
00561 res = chrec_fold_plus (type, CHREC_LEFT (chrec), res);
00562 }
00563
00564 else if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
00565 res = chrec;
00566
00567 else if (TREE_CODE (x) == INTEGER_CST
00568 && tree_int_cst_sgn (x) == 1)
00569
00570 res = chrec_evaluate (var, chrec, x, 0);
00571 else
00572 res = chrec_dont_know;
00573
00574 if (dump_file && (dump_flags & TDF_DETAILS))
00575 {
00576 fprintf (dump_file, " (varying_loop = %d\n", var);
00577 fprintf (dump_file, ")\n (chrec = ");
00578 print_generic_expr (dump_file, chrec, 0);
00579 fprintf (dump_file, ")\n (x = ");
00580 print_generic_expr (dump_file, x, 0);
00581 fprintf (dump_file, ")\n (res = ");
00582 print_generic_expr (dump_file, res, 0);
00583 fprintf (dump_file, "))\n");
00584 }
00585
00586 return res;
00587 }
00588
00589
00590
00591 tree
00592 chrec_replace_initial_condition (tree chrec,
00593 tree init_cond)
00594 {
00595 if (automatically_generated_chrec_p (chrec))
00596 return chrec;
00597
00598 gcc_assert (chrec_type (chrec) == chrec_type (init_cond));
00599
00600 switch (TREE_CODE (chrec))
00601 {
00602 case POLYNOMIAL_CHREC:
00603 return build_polynomial_chrec
00604 (CHREC_VARIABLE (chrec),
00605 chrec_replace_initial_condition (CHREC_LEFT (chrec), init_cond),
00606 CHREC_RIGHT (chrec));
00607
00608 default:
00609 return init_cond;
00610 }
00611 }
00612
00613
00614
00615 tree
00616 initial_condition (tree chrec)
00617 {
00618 if (automatically_generated_chrec_p (chrec))
00619 return chrec;
00620
00621 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
00622 return initial_condition (CHREC_LEFT (chrec));
00623 else
00624 return chrec;
00625 }
00626
00627
00628
00629
00630 tree
00631 hide_evolution_in_other_loops_than_loop (tree chrec,
00632 unsigned loop_num)
00633 {
00634 if (automatically_generated_chrec_p (chrec))
00635 return chrec;
00636
00637 switch (TREE_CODE (chrec))
00638 {
00639 case POLYNOMIAL_CHREC:
00640 if (CHREC_VARIABLE (chrec) == loop_num)
00641 return build_polynomial_chrec
00642 (loop_num,
00643 hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
00644 loop_num),
00645 CHREC_RIGHT (chrec));
00646
00647 else if (CHREC_VARIABLE (chrec) < loop_num)
00648
00649 return initial_condition (chrec);
00650
00651 else
00652 return hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
00653 loop_num);
00654
00655 default:
00656 return chrec;
00657 }
00658 }
00659
00660
00661
00662
00663 static tree
00664 chrec_component_in_loop_num (tree chrec,
00665 unsigned loop_num,
00666 bool right)
00667 {
00668 tree component;
00669
00670 if (automatically_generated_chrec_p (chrec))
00671 return chrec;
00672
00673 switch (TREE_CODE (chrec))
00674 {
00675 case POLYNOMIAL_CHREC:
00676 if (CHREC_VARIABLE (chrec) == loop_num)
00677 {
00678 if (right)
00679 component = CHREC_RIGHT (chrec);
00680 else
00681 component = CHREC_LEFT (chrec);
00682
00683 if (TREE_CODE (CHREC_LEFT (chrec)) != POLYNOMIAL_CHREC
00684 || CHREC_VARIABLE (CHREC_LEFT (chrec)) != CHREC_VARIABLE (chrec))
00685 return component;
00686
00687 else
00688 return build_polynomial_chrec
00689 (loop_num,
00690 chrec_component_in_loop_num (CHREC_LEFT (chrec),
00691 loop_num,
00692 right),
00693 component);
00694 }
00695
00696 else if (CHREC_VARIABLE (chrec) < loop_num)
00697
00698 return NULL_TREE;
00699
00700 else
00701 return chrec_component_in_loop_num (CHREC_LEFT (chrec),
00702 loop_num,
00703 right);
00704
00705 default:
00706 if (right)
00707 return NULL_TREE;
00708 else
00709 return chrec;
00710 }
00711 }
00712
00713
00714
00715
00716
00717 tree
00718 evolution_part_in_loop_num (tree chrec,
00719 unsigned loop_num)
00720 {
00721 return chrec_component_in_loop_num (chrec, loop_num, true);
00722 }
00723
00724
00725
00726
00727
00728 tree
00729 initial_condition_in_loop_num (tree chrec,
00730 unsigned loop_num)
00731 {
00732 return chrec_component_in_loop_num (chrec, loop_num, false);
00733 }
00734
00735
00736
00737
00738
00739
00740 tree
00741 reset_evolution_in_loop (unsigned loop_num,
00742 tree chrec,
00743 tree new_evol)
00744 {
00745 gcc_assert (chrec_type (chrec) == chrec_type (new_evol));
00746
00747 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
00748 && CHREC_VARIABLE (chrec) > loop_num)
00749 {
00750 tree left = reset_evolution_in_loop (loop_num, CHREC_LEFT (chrec),
00751 new_evol);
00752 tree right = reset_evolution_in_loop (loop_num, CHREC_RIGHT (chrec),
00753 new_evol);
00754 return build3 (POLYNOMIAL_CHREC, TREE_TYPE (left),
00755 build_int_cst (NULL_TREE, CHREC_VARIABLE (chrec)),
00756 left, right);
00757 }
00758
00759 while (TREE_CODE (chrec) == POLYNOMIAL_CHREC
00760 && CHREC_VARIABLE (chrec) == loop_num)
00761 chrec = CHREC_LEFT (chrec);
00762
00763 return build_polynomial_chrec (loop_num, chrec, new_evol);
00764 }
00765
00766
00767
00768
00769 tree
00770 chrec_merge (tree chrec1,
00771 tree chrec2)
00772 {
00773 if (chrec1 == chrec_dont_know
00774 || chrec2 == chrec_dont_know)
00775 return chrec_dont_know;
00776
00777 if (chrec1 == chrec_known
00778 || chrec2 == chrec_known)
00779 return chrec_known;
00780
00781 if (chrec1 == chrec_not_analyzed_yet)
00782 return chrec2;
00783 if (chrec2 == chrec_not_analyzed_yet)
00784 return chrec1;
00785
00786 if (eq_evolutions_p (chrec1, chrec2))
00787 return chrec1;
00788
00789 return chrec_dont_know;
00790 }
00791
00792
00793
00794
00795
00796
00797
00798 static bool
00799 is_multivariate_chrec_rec (tree chrec, unsigned int rec_var)
00800 {
00801 if (chrec == NULL_TREE)
00802 return false;
00803
00804 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
00805 {
00806 if (CHREC_VARIABLE (chrec) != rec_var)
00807 return true;
00808 else
00809 return (is_multivariate_chrec_rec (CHREC_LEFT (chrec), rec_var)
00810 || is_multivariate_chrec_rec (CHREC_RIGHT (chrec), rec_var));
00811 }
00812 else
00813 return false;
00814 }
00815
00816
00817
00818 bool
00819 is_multivariate_chrec (tree chrec)
00820 {
00821 if (chrec == NULL_TREE)
00822 return false;
00823
00824 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
00825 return (is_multivariate_chrec_rec (CHREC_LEFT (chrec),
00826 CHREC_VARIABLE (chrec))
00827 || is_multivariate_chrec_rec (CHREC_RIGHT (chrec),
00828 CHREC_VARIABLE (chrec)));
00829 else
00830 return false;
00831 }
00832
00833
00834
00835 bool
00836 chrec_contains_symbols (tree chrec)
00837 {
00838 if (chrec == NULL_TREE)
00839 return false;
00840
00841 if (TREE_CODE (chrec) == SSA_NAME
00842 || TREE_CODE (chrec) == VAR_DECL
00843 || TREE_CODE (chrec) == PARM_DECL
00844 || TREE_CODE (chrec) == FUNCTION_DECL
00845 || TREE_CODE (chrec) == LABEL_DECL
00846 || TREE_CODE (chrec) == RESULT_DECL
00847 || TREE_CODE (chrec) == FIELD_DECL)
00848 return true;
00849
00850 switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
00851 {
00852 case 3:
00853 if (chrec_contains_symbols (TREE_OPERAND (chrec, 2)))
00854 return true;
00855
00856 case 2:
00857 if (chrec_contains_symbols (TREE_OPERAND (chrec, 1)))
00858 return true;
00859
00860 case 1:
00861 if (chrec_contains_symbols (TREE_OPERAND (chrec, 0)))
00862 return true;
00863
00864 default:
00865 return false;
00866 }
00867 }
00868
00869
00870
00871 bool
00872 chrec_contains_undetermined (tree chrec)
00873 {
00874 if (chrec == chrec_dont_know
00875 || chrec == chrec_not_analyzed_yet
00876 || chrec == NULL_TREE)
00877 return true;
00878
00879 switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
00880 {
00881 case 3:
00882 if (chrec_contains_undetermined (TREE_OPERAND (chrec, 2)))
00883 return true;
00884
00885 case 2:
00886 if (chrec_contains_undetermined (TREE_OPERAND (chrec, 1)))
00887 return true;
00888
00889 case 1:
00890 if (chrec_contains_undetermined (TREE_OPERAND (chrec, 0)))
00891 return true;
00892
00893 default:
00894 return false;
00895 }
00896 }
00897
00898
00899
00900
00901
00902 bool
00903 tree_contains_chrecs (tree expr, int *size)
00904 {
00905 if (expr == NULL_TREE)
00906 return false;
00907
00908 if (size)
00909 (*size)++;
00910
00911 if (tree_is_chrec (expr))
00912 return true;
00913
00914 switch (TREE_CODE_LENGTH (TREE_CODE (expr)))
00915 {
00916 case 3:
00917 if (tree_contains_chrecs (TREE_OPERAND (expr, 2), size))
00918 return true;
00919
00920 case 2:
00921 if (tree_contains_chrecs (TREE_OPERAND (expr, 1), size))
00922 return true;
00923
00924 case 1:
00925 if (tree_contains_chrecs (TREE_OPERAND (expr, 0), size))
00926 return true;
00927
00928 default:
00929 return false;
00930 }
00931 }
00932
00933
00934
00935 static bool
00936 evolution_function_is_invariant_rec_p (tree chrec, int loopnum)
00937 {
00938 if (evolution_function_is_constant_p (chrec))
00939 return true;
00940
00941 if (TREE_CODE (chrec) == SSA_NAME
00942 && expr_invariant_in_loop_p (current_loops->parray[loopnum],
00943 chrec))
00944 return true;
00945
00946 if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
00947 {
00948 if (CHREC_VARIABLE (chrec) == (unsigned) loopnum
00949 || !evolution_function_is_invariant_rec_p (CHREC_RIGHT (chrec),
00950 loopnum)
00951 || !evolution_function_is_invariant_rec_p (CHREC_LEFT (chrec),
00952 loopnum))
00953 return false;
00954 return true;
00955 }
00956
00957 switch (TREE_CODE_LENGTH (TREE_CODE (chrec)))
00958 {
00959 case 2:
00960 if (!evolution_function_is_invariant_rec_p (TREE_OPERAND (chrec, 1),
00961 loopnum))
00962 return false;
00963
00964 case 1:
00965 if (!evolution_function_is_invariant_rec_p (TREE_OPERAND (chrec, 0),
00966 loopnum))
00967 return false;
00968 return true;
00969
00970 default:
00971 return false;
00972 }
00973
00974 return false;
00975 }
00976
00977
00978
00979 bool
00980 evolution_function_is_invariant_p (tree chrec, int loopnum)
00981 {
00982 if (evolution_function_is_constant_p (chrec))
00983 return true;
00984
00985 if (current_loops != NULL)
00986 return evolution_function_is_invariant_rec_p (chrec, loopnum);
00987
00988 return false;
00989 }
00990
00991
00992
00993
00994 bool
00995 evolution_function_is_affine_multivariate_p (tree chrec)
00996 {
00997 if (chrec == NULL_TREE)
00998 return false;
00999
01000 switch (TREE_CODE (chrec))
01001 {
01002 case POLYNOMIAL_CHREC:
01003 if (evolution_function_is_constant_p (CHREC_LEFT (chrec)))
01004 {
01005 if (evolution_function_is_constant_p (CHREC_RIGHT (chrec)))
01006 return true;
01007 else
01008 {
01009 if (TREE_CODE (CHREC_RIGHT (chrec)) == POLYNOMIAL_CHREC
01010 && CHREC_VARIABLE (CHREC_RIGHT (chrec))
01011 != CHREC_VARIABLE (chrec)
01012 && evolution_function_is_affine_multivariate_p
01013 (CHREC_RIGHT (chrec)))
01014 return true;
01015 else
01016 return false;
01017 }
01018 }
01019 else
01020 {
01021 if (evolution_function_is_constant_p (CHREC_RIGHT (chrec))
01022 && TREE_CODE (CHREC_LEFT (chrec)) == POLYNOMIAL_CHREC
01023 && CHREC_VARIABLE (CHREC_LEFT (chrec)) != CHREC_VARIABLE (chrec)
01024 && evolution_function_is_affine_multivariate_p
01025 (CHREC_LEFT (chrec)))
01026 return true;
01027 else
01028 return false;
01029 }
01030
01031 default:
01032 return false;
01033 }
01034 }
01035
01036
01037
01038
01039 bool
01040 evolution_function_is_univariate_p (tree chrec)
01041 {
01042 if (chrec == NULL_TREE)
01043 return true;
01044
01045 switch (TREE_CODE (chrec))
01046 {
01047 case POLYNOMIAL_CHREC:
01048 switch (TREE_CODE (CHREC_LEFT (chrec)))
01049 {
01050 case POLYNOMIAL_CHREC:
01051 if (CHREC_VARIABLE (chrec) != CHREC_VARIABLE (CHREC_LEFT (chrec)))
01052 return false;
01053 if (!evolution_function_is_univariate_p (CHREC_LEFT (chrec)))
01054 return false;
01055 break;
01056
01057 default:
01058 break;
01059 }
01060
01061 switch (TREE_CODE (CHREC_RIGHT (chrec)))
01062 {
01063 case POLYNOMIAL_CHREC:
01064 if (CHREC_VARIABLE (chrec) != CHREC_VARIABLE (CHREC_RIGHT (chrec)))
01065 return false;
01066 if (!evolution_function_is_univariate_p (CHREC_RIGHT (chrec)))
01067 return false;
01068 break;
01069
01070 default:
01071 break;
01072 }
01073
01074 default:
01075 return true;
01076 }
01077 }
01078
01079
01080
01081
01082 unsigned
01083 nb_vars_in_chrec (tree chrec)
01084 {
01085 if (chrec == NULL_TREE)
01086 return 0;
01087
01088 switch (TREE_CODE (chrec))
01089 {
01090 case POLYNOMIAL_CHREC:
01091 return 1 + nb_vars_in_chrec
01092 (initial_condition_in_loop_num (chrec, CHREC_VARIABLE (chrec)));
01093
01094 default:
01095 return 0;
01096 }
01097 }
01098
01099
01100
01101
01102 static bool
01103 avoid_arithmetics_in_type_p (tree type)
01104 {
01105
01106
01107
01108 if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != NULL_TREE)
01109 return true;
01110
01111 return false;
01112 }
01113
01114 static tree chrec_convert_1 (tree, tree, tree, bool);
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124 bool
01125 convert_affine_scev (struct loop *loop, tree type,
01126 tree *base, tree *step, tree at_stmt,
01127 bool use_overflow_semantics)
01128 {
01129 tree ct = TREE_TYPE (*step);
01130 bool enforce_overflow_semantics;
01131 bool must_check_src_overflow, must_check_rslt_overflow;
01132 tree new_base, new_step;
01133
01134
01135 if (avoid_arithmetics_in_type_p (type))
01136 return false;
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153 must_check_src_overflow = TYPE_PRECISION (ct) < TYPE_PRECISION (type);
01154
01155 enforce_overflow_semantics = (use_overflow_semantics
01156 && nowrap_type_p (type));
01157 if (enforce_overflow_semantics)
01158 {
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168
01169 if (must_check_src_overflow)
01170 {
01171 if (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (ct))
01172 must_check_rslt_overflow = true;
01173 else
01174 must_check_rslt_overflow = false;
01175 }
01176 else if (TYPE_UNSIGNED (ct) == TYPE_UNSIGNED (type)
01177 && TYPE_PRECISION (ct) == TYPE_PRECISION (type))
01178 {
01179 must_check_rslt_overflow = false;
01180 must_check_src_overflow = true;
01181 }
01182 else
01183 must_check_rslt_overflow = true;
01184 }
01185 else
01186 must_check_rslt_overflow = false;
01187
01188 if (must_check_src_overflow
01189 && scev_probably_wraps_p (*base, *step, at_stmt, loop,
01190 use_overflow_semantics))
01191 return false;
01192
01193 new_base = chrec_convert_1 (type, *base, at_stmt,
01194 use_overflow_semantics);
01195
01196