tree-chrec.c

Go to the documentation of this file.
00001 /* Chains of recurrences.
00002    Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
00003    Contributed by Sebastian Pop <pop@cri.ensmp.fr>
00004 
00005 This file is part of GCC.
00006 
00007 GCC is free software; you can redistribute it and/or modify it under
00008 the terms of the GNU General Public License as published by the Free
00009 Software Foundation; either version 2, or (at your option) any later
00010 version.
00011 
00012 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
00013 WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with GCC; see the file COPYING.  If not, write to the Free
00019 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
00020 02110-1301, USA.  */
00021 
00022 /* This file implements operations on chains of recurrences.  Chains
00023    of recurrences are used for modeling evolution functions of scalar
00024    variables.
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 /* Extended folder for chrecs.  */
00045 
00046 /* Determines whether CST is not a constant evolution.  */
00047 
00048 static inline bool
00049 is_not_constant_evolution (tree cst)
00050 {
00051   return (TREE_CODE (cst) == POLYNOMIAL_CHREC);
00052 }
00053 
00054 /* Fold CODE for a polynomial function and a constant.  */
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 /* Fold the addition of two polynomial functions.  */
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     {a, +, b}_1 + {c, +, d}_2  ->  {{a, +, b}_1 + c, +, d}_2,
00112     {a, +, b}_2 + {c, +, d}_1  ->  {{c, +, d}_1 + a, +, b}_2,
00113     {a, +, b}_x + {c, +, d}_x  ->  {a+c, +, b+d}_x.  */
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 /* Fold the multiplication of two polynomial functions.  */
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   /* {a, +, b}_1 * {c, +, d}_2  ->  {c*{a, +, b}_1, +, d}_2,
00187      {a, +, b}_2 * {c, +, d}_1  ->  {a*{c, +, d}_1, +, b}_2,
00188      {a, +, b}_x * {c, +, d}_x  ->  {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x.  */
00189   if (CHREC_VARIABLE (poly0) < CHREC_VARIABLE (poly1))
00190     /* poly0 is a constant wrt. poly1.  */
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     /* poly1 is a constant wrt. poly0.  */
00198     return build_polynomial_chrec 
00199       (CHREC_VARIABLE (poly0), 
00200        chrec_fold_multiply (type, CHREC_LEFT (poly0), poly1),
00201        CHREC_RIGHT (poly0));
00202   
00203   /* poly0 and poly1 are two polynomials in the same variable,
00204      {a, +, b}_x * {c, +, d}_x  ->  {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x.  */
00205       
00206   /* "a*c".  */
00207   t0 = chrec_fold_multiply (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1));
00208 
00209   /* "a*d + b*c + b*d".  */
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   /* "2*b*d".  */
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 /* When the operands are automatically_generated_chrec_p, the fold has
00229    to respect the semantics of the operands.  */
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   /* The default case produces a safe result.  */
00248   return chrec_dont_know;
00249 }
00250 
00251 /* Fold the addition of two chrecs.  */
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 /* Fold the addition of two chrecs.  */
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 /* Fold the subtraction of two chrecs.  */
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 /* Fold the multiplication of two chrecs.  */
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 /* Operations.  */
00413 
00414 /* Evaluate the binomial coefficient.  Return NULL_TREE if the intermediate
00415    calculation overflows, otherwise return C(n,k) with type TYPE.  */
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   /* Handle the most frequent cases.  */
00426   if (k == 0)
00427     return build_int_cst (type, 1);
00428   if (k == 1)
00429     return fold_convert (type, n);
00430 
00431   /* Check that k <= n.  */
00432   if (TREE_INT_CST_HIGH (n) == 0
00433       && TREE_INT_CST_LOW (n) < k)
00434     return NULL_TREE;
00435 
00436   /* Numerator = n.  */
00437   lnum = TREE_INT_CST_LOW (n);
00438   hnum = TREE_INT_CST_HIGH (n);
00439 
00440   /* Denominator = 2.  */
00441   ldenom = 2;
00442   hdenom = 0;
00443 
00444   /* Index = Numerator-1.  */
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   /* Numerator = Numerator*Index = n*(n-1).  */
00457   if (mul_double (lnum, hnum, lidx, hidx, &lnum, &hnum))
00458     return NULL_TREE;
00459 
00460   for (i = 3; i <= k; i++)
00461     {
00462       /* Index--.  */
00463       if (lidx == 0)
00464         {
00465           hidx--;
00466           lidx = ~ (unsigned HOST_WIDE_INT) 0;
00467         }
00468       else
00469         lidx--;
00470 
00471       /* Numerator *= Index.  */
00472       if (mul_double (lnum, hnum, lidx, hidx, &lnum, &hnum))
00473         return NULL_TREE;
00474 
00475       /* Denominator *= i.  */
00476       mul_double (ldenom, hdenom, i, 0, &ldenom, &hdenom);
00477     }
00478 
00479   /* Result = Numerator / Denominator.  */
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 /* Helper function.  Use the Newton's interpolating formula for
00488    evaluating the value of the evolution function.  */
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 /* Evaluates "CHREC (X)" when the varying variable is VAR.  
00522    Example:  Given the following parameters, 
00523    
00524    var = 1
00525    chrec = {3, +, 4}_1
00526    x = 10
00527    
00528    The result is given by the Newton's interpolating formula: 
00529    3 * \binom{10}{0} + 4 * \binom{10}{1}.
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       /* When the symbols are defined in an outer loop, it is possible
00544          to symbolically compute the apply, since the symbols are
00545          constants with respect to the varying loop.  */
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       /* "{a, +, b} (x)"  ->  "a + b*x".  */
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     /* testsuite/.../ssa-chrec-38.c.  */
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 /* Replaces the initial condition in CHREC with INIT_COND.  */
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 /* Returns the initial condition of a given CHREC.  */
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 /* Returns a univariate function that represents the evolution in
00628    LOOP_NUM.  Mask the evolution of any other loop.  */
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         /* There is no evolution in this loop.  */
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 /* Returns the evolution part of CHREC in LOOP_NUM when RIGHT is
00661    true, otherwise returns the initial condition in LOOP_NUM.  */
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         /* There is no evolution part in this loop.  */
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 /* Returns the evolution part in LOOP_NUM.  Example: the call
00714    evolution_part_in_loop_num ({{0, +, 1}_1, +, 2}_1, 1) returns 
00715    {1, +, 2}_1  */
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 /* Returns the initial condition in LOOP_NUM.  Example: the call
00725    initial_condition_in_loop_num ({{0, +, 1}_1, +, 2}_2, 2) returns 
00726    {0, +, 1}_1  */
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 /* Set or reset the evolution of CHREC to NEW_EVOL in loop LOOP_NUM.
00736    This function is essentially used for setting the evolution to
00737    chrec_dont_know, for example after having determined that it is
00738    impossible to say how many times a loop will execute.  */
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 /* Merges two evolution functions that were found by following two
00767    alternate paths of a conditional expression.  */
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 /* Observers.  */
00795 
00796 /* Helper function for is_multivariate_chrec.  */
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 /* Determine whether the given chrec is multivariate or not.  */
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 /* Determines whether the chrec contains symbolic names or not.  */
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 /* Determines whether the chrec contains undetermined coefficients.  */
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 /* Determines whether the tree EXPR contains chrecs, and increment
00899    SIZE if it is not a NULL pointer by an estimation of the depth of
00900    the tree.  */
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 /* Recursive helper function.  */
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 /* Return true if CHREC is invariant in loop LOOPNUM, false otherwise. */
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 /* Determine whether the given tree is an affine multivariate
00992    evolution.  */
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 /* Determine whether the given tree is a function in zero or one 
01037    variables.  */
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 /* Returns the number of variables of CHREC.  Example: the call
01080    nb_vars_in_chrec ({{0, +, 1}_5, +, 2}_6) returns 2.  */
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 /* Returns true if TYPE is a type in that we cannot directly perform
01100    arithmetics, even though it is a scalar type.  */
01101 
01102 static bool
01103 avoid_arithmetics_in_type_p (tree type)
01104 {
01105   /* Ada frontend uses subtypes -- an arithmetic cannot be directly performed
01106      in the subtype, but a base type must be used, and the result then can
01107      be casted to the subtype.  */
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 /* Converts BASE and STEP of affine scev to TYPE.  LOOP is the loop whose iv
01117    the scev corresponds to.  AT_STMT is the statement at that the scev is
01118    evaluated.  USE_OVERFLOW_SEMANTICS is true if this function should assume that
01119    the rules for overflow of the given language apply (e.g., that signed
01120    arithmetics in C does not overflow) -- i.e., to use them to avoid unnecessary
01121    tests, but also to enforce that the result follows them.  Returns true if the
01122    conversion succeeded, false otherwise.  */
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   /* If we cannot perform arithmetic in TYPE, avoid creating an scev.  */
01135   if (avoid_arithmetics_in_type_p (type))
01136     return false;
01137 
01138   /* In general,
01139      (TYPE) (BASE + STEP * i) = (TYPE) BASE + (TYPE -- sign extend) STEP * i,
01140      but we must check some assumptions.
01141      
01142      1) If [BASE, +, STEP] wraps, the equation is not valid when precision
01143         of CT is smaller than the precision of TYPE.  For example, when we
01144         cast unsigned char [254, +, 1] to unsigned, the values on left side
01145         are 254, 255, 0, 1, ..., but those on the right side are
01146         254, 255, 256, 257, ...
01147      2) In case that we must also preserve the fact that signed ivs do not
01148         overflow, we must additionally check that the new iv does not wrap.
01149         For example, unsigned char [125, +, 1] casted to signed char could
01150         become a wrapping variable with values 125, 126, 127, -128, -127, ...,
01151         which would confuse optimizers that assume that this does not
01152         happen.  */
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       /* We can avoid checking whether the result overflows in the following
01160          cases:
01161 
01162          -- must_check_src_overflow is true, and the range of TYPE is superset
01163             of the range of CT -- i.e., in all cases except if CT signed and
01164             TYPE unsigned.
01165          -- both CT and TYPE have the same precision and signedness, and we
01166             verify instead that the source does not overflow (this may be
01167             easier than verifying it for the result, as we may use the
01168             information about the semantics of overflow in CT).  */
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   /* The step must be sign extended, regardless of the signedness
01196      of