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