LCOV - code coverage report
Current view: top level - gcc - tree-chrec.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 87.7 % 808 709
Test Date: 2026-07-11 15:47:05 Functions: 91.1 % 45 41
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Chains of recurrences.
       2              :    Copyright (C) 2003-2026 Free Software Foundation, Inc.
       3              :    Contributed by Sebastian Pop <pop@cri.ensmp.fr>
       4              : 
       5              : This file is part of GCC.
       6              : 
       7              : GCC is free software; you can redistribute it and/or modify it under
       8              : the terms of the GNU General Public License as published by the Free
       9              : Software Foundation; either version 3, or (at your option) any later
      10              : version.
      11              : 
      12              : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      13              : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      14              : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      15              : for more details.
      16              : 
      17              : You should have received a copy of the GNU General Public License
      18              : along with GCC; see the file COPYING3.  If not see
      19              : <http://www.gnu.org/licenses/>.  */
      20              : 
      21              : /* This file implements operations on chains of recurrences.  Chains
      22              :    of recurrences are used for modeling evolution functions of scalar
      23              :    variables.
      24              : */
      25              : 
      26              : #include "config.h"
      27              : #include "system.h"
      28              : #include "coretypes.h"
      29              : #include "backend.h"
      30              : #include "tree.h"
      31              : #include "gimple-expr.h"
      32              : #include "tree-pretty-print.h"
      33              : #include "fold-const.h"
      34              : #include "cfgloop.h"
      35              : #include "tree-ssa-loop-ivopts.h"
      36              : #include "tree-ssa-loop-niter.h"
      37              : #include "tree-chrec.h"
      38              : #include "gimple.h"
      39              : #include "tree-ssa-loop.h"
      40              : #include "dumpfile.h"
      41              : #include "tree-scalar-evolution.h"
      42              : 
      43              : /* Extended folder for chrecs.  */
      44              : 
      45              : /* Fold the addition of two polynomial functions.  */
      46              : 
      47              : static inline tree
      48        87925 : chrec_fold_plus_poly_poly (enum tree_code code,
      49              :                            tree type,
      50              :                            tree poly0,
      51              :                            tree poly1)
      52              : {
      53        87925 :   tree left, right;
      54        87925 :   class loop *loop0 = get_chrec_loop (poly0);
      55        87925 :   class loop *loop1 = get_chrec_loop (poly1);
      56              : 
      57        87925 :   gcc_assert (poly0);
      58        87925 :   gcc_assert (poly1);
      59        87925 :   gcc_assert (TREE_CODE (poly0) == POLYNOMIAL_CHREC);
      60        87925 :   gcc_assert (TREE_CODE (poly1) == POLYNOMIAL_CHREC);
      61        87925 :   if (POINTER_TYPE_P (chrec_type (poly0)))
      62          866 :     gcc_checking_assert (ptrofftype_p (chrec_type (poly1))
      63              :                          && useless_type_conversion_p (type, chrec_type (poly0)));
      64              :   else
      65        87059 :     gcc_checking_assert (useless_type_conversion_p (type, chrec_type (poly0))
      66              :                          && useless_type_conversion_p (type, chrec_type (poly1)));
      67              : 
      68              :   /*
      69              :     {a, +, b}_1 + {c, +, d}_2  ->  {{a, +, b}_1 + c, +, d}_2,
      70              :     {a, +, b}_2 + {c, +, d}_1  ->  {{c, +, d}_1 + a, +, b}_2,
      71              :     {a, +, b}_x + {c, +, d}_x  ->  {a+c, +, b+d}_x.  */
      72        87925 :   if (flow_loop_nested_p (loop0, loop1))
      73              :     {
      74          296 :       if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
      75          232 :         return build_polynomial_chrec
      76          232 :           (CHREC_VARIABLE (poly1),
      77          232 :            chrec_fold_plus (type, poly0, CHREC_LEFT (poly1)),
      78          464 :            CHREC_RIGHT (poly1));
      79              :       else
      80           64 :         return build_polynomial_chrec
      81          128 :           (CHREC_VARIABLE (poly1),
      82           64 :            chrec_fold_minus (type, poly0, CHREC_LEFT (poly1)),
      83           64 :            chrec_fold_multiply (type, CHREC_RIGHT (poly1),
      84           64 :                                 SCALAR_FLOAT_TYPE_P (type)
      85            0 :                                 ? build_real (type, dconstm1)
      86          128 :                                 : build_int_cst_type (type, -1)));
      87              :     }
      88              : 
      89        87629 :   if (flow_loop_nested_p (loop1, loop0))
      90              :     {
      91          602 :       if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
      92          556 :         return build_polynomial_chrec
      93          556 :           (CHREC_VARIABLE (poly0),
      94          556 :            chrec_fold_plus (type, CHREC_LEFT (poly0), poly1),
      95         1112 :            CHREC_RIGHT (poly0));
      96              :       else
      97           46 :         return build_polynomial_chrec
      98           46 :           (CHREC_VARIABLE (poly0),
      99           46 :            chrec_fold_minus (type, CHREC_LEFT (poly0), poly1),
     100           92 :            CHREC_RIGHT (poly0));
     101              :     }
     102              : 
     103              :   /* This function should never be called for chrecs of loops that
     104              :      do not belong to the same loop nest.  */
     105        87027 :   if (loop0 != loop1)
     106              :     {
     107              :       /* It still can happen if we are not in loop-closed SSA form.  */
     108           38 :       gcc_assert (! loops_state_satisfies_p (LOOP_CLOSED_SSA));
     109           38 :       return chrec_dont_know;
     110              :     }
     111              : 
     112        86989 :   if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
     113              :     {
     114        31390 :       tree rtype = code == POINTER_PLUS_EXPR ? chrec_type (poly1) : type;
     115        31390 :       left = chrec_fold_plus
     116        31390 :         (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1));
     117        31390 :       right = chrec_fold_plus
     118        31390 :         (rtype, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1));
     119              :     }
     120              :   else
     121              :     {
     122        55599 :       left = chrec_fold_minus
     123        55599 :         (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1));
     124        55599 :       right = chrec_fold_minus
     125        55599 :         (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1));
     126              :     }
     127              : 
     128        86989 :   if (chrec_zerop (right))
     129              :     return left;
     130              :   /* When we have an evolution in a non-wrapping type and in the process of
     131              :      accumulating CHREC_RIGHT there was overflow this indicates in the
     132              :      association that happened in accumulating the CHRECs clearly involved UB.
     133              :      Avoid this.  When accumulating two CHRECs we basically turn
     134              :      (a + INCR1) + INCR2 into a + (INCR1 + INCR2) which is not always valid.
     135              :      Note this check only catches few invalid cases.  */
     136        32397 :   else if ((INTEGRAL_TYPE_P (type) && ! TYPE_OVERFLOW_WRAPS (type))
     137        20913 :            && TREE_CODE (right) == INTEGER_CST
     138        35289 :            && TREE_OVERFLOW (right))
     139            5 :     return chrec_dont_know;
     140              :   else
     141        32512 :     return build_polynomial_chrec
     142        32512 :       (CHREC_VARIABLE (poly0), left, right);
     143              : }
     144              : 
     145              : 
     146              : 
     147              : /* Fold the multiplication of two polynomial functions.  */
     148              : 
     149              : static inline tree
     150        40457 : chrec_fold_multiply_poly_poly (tree type,
     151              :                                tree poly0,
     152              :                                tree poly1)
     153              : {
     154        40457 :   tree t0, t1, t2;
     155        40457 :   int var;
     156        40457 :   class loop *loop0 = get_chrec_loop (poly0);
     157        40457 :   class loop *loop1 = get_chrec_loop (poly1);
     158              : 
     159        40457 :   gcc_assert (poly0);
     160        40457 :   gcc_assert (poly1);
     161        40457 :   gcc_assert (TREE_CODE (poly0) == POLYNOMIAL_CHREC);
     162        40457 :   gcc_assert (TREE_CODE (poly1) == POLYNOMIAL_CHREC);
     163        40457 :   gcc_checking_assert (useless_type_conversion_p (type, chrec_type (poly0))
     164              :                        && useless_type_conversion_p (type, chrec_type (poly1)));
     165              : 
     166              :   /* {a, +, b}_1 * {c, +, d}_2  ->  {c*{a, +, b}_1, +, d}_2,
     167              :      {a, +, b}_2 * {c, +, d}_1  ->  {a*{c, +, d}_1, +, b}_2,
     168              :      {a, +, b}_x * {c, +, d}_x  ->  {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x.  */
     169        40457 :   if (flow_loop_nested_p (loop0, loop1))
     170              :     /* poly0 is a constant wrt. poly1.  */
     171            0 :     return build_polynomial_chrec
     172            0 :       (CHREC_VARIABLE (poly1),
     173            0 :        chrec_fold_multiply (type, CHREC_LEFT (poly1), poly0),
     174            0 :        CHREC_RIGHT (poly1));
     175              : 
     176        40457 :   if (flow_loop_nested_p (loop1, loop0))
     177              :     /* poly1 is a constant wrt. poly0.  */
     178            0 :     return build_polynomial_chrec
     179            0 :       (CHREC_VARIABLE (poly0),
     180            0 :        chrec_fold_multiply (type, CHREC_LEFT (poly0), poly1),
     181            0 :        CHREC_RIGHT (poly0));
     182              : 
     183        40457 :   if (loop0 != loop1)
     184              :     {
     185              :       /* It still can happen if we are not in loop-closed SSA form.  */
     186            0 :       gcc_assert (! loops_state_satisfies_p (LOOP_CLOSED_SSA));
     187            0 :       return chrec_dont_know;
     188              :     }
     189              : 
     190              :   /* poly0 and poly1 are two polynomials in the same variable,
     191              :      {a, +, b}_x * {c, +, d}_x  ->  {a*c, +, a*d + b*c + b*d, +, 2*b*d}_x.  */
     192              : 
     193              :   /* "a*c".  */
     194        40457 :   t0 = chrec_fold_multiply (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1));
     195              : 
     196              :   /* "a*d + b*c".  */
     197        40457 :   t1 = chrec_fold_multiply (type, CHREC_LEFT (poly0), CHREC_RIGHT (poly1));
     198       121371 :   t1 = chrec_fold_plus (type, t1, chrec_fold_multiply (type,
     199        40457 :                                                        CHREC_RIGHT (poly0),
     200        40457 :                                                        CHREC_LEFT (poly1)));
     201              :   /* "b*d".  */
     202        40457 :   t2 = chrec_fold_multiply (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1));
     203              :   /* "a*d + b*c + b*d".  */
     204        40457 :   t1 = chrec_fold_plus (type, t1, t2);
     205              :   /* "2*b*d".  */
     206        80914 :   t2 = chrec_fold_multiply (type, SCALAR_FLOAT_TYPE_P (type)
     207           33 :                             ? build_real (type, dconst2)
     208        40424 :                             : build_int_cst (type, 2), t2);
     209              : 
     210        40457 :   var = CHREC_VARIABLE (poly0);
     211        40457 :   return build_polynomial_chrec (var, t0,
     212        40457 :                                  build_polynomial_chrec (var, t1, t2));
     213              : }
     214              : 
     215              : /* When the operands are automatically_generated_chrec_p, the fold has
     216              :    to respect the semantics of the operands.  */
     217              : 
     218              : static inline tree
     219      5968497 : chrec_fold_automatically_generated_operands (tree op0,
     220              :                                              tree op1)
     221              : {
     222      5968497 :   if (op0 == chrec_dont_know
     223       957210 :       || op1 == chrec_dont_know)
     224              :     return chrec_dont_know;
     225              : 
     226            0 :   if (op0 == chrec_known
     227            0 :       || op1 == chrec_known)
     228              :     return chrec_known;
     229              : 
     230            0 :   if (op0 == chrec_not_analyzed_yet
     231            0 :       || op1 == chrec_not_analyzed_yet)
     232            0 :     return chrec_not_analyzed_yet;
     233              : 
     234              :   /* The default case produces a safe result.  */
     235              :   return chrec_dont_know;
     236              : }
     237              : 
     238              : /* Fold the addition of two chrecs.  */
     239              : 
     240              : static tree
     241     30891882 : chrec_fold_plus_1 (enum tree_code code, tree type,
     242              :                    tree op0, tree op1)
     243              : {
     244     61783764 :   if (automatically_generated_chrec_p (op0)
     245     30891882 :       || automatically_generated_chrec_p (op1))
     246            0 :     return chrec_fold_automatically_generated_operands (op0, op1);
     247              : 
     248     30891882 :   switch (TREE_CODE (op0))
     249              :     {
     250      9818551 :     case POLYNOMIAL_CHREC:
     251      9818551 :       gcc_checking_assert
     252              :         (!chrec_contains_symbols_defined_in_loop (op0, CHREC_VARIABLE (op0)));
     253      9818551 :       switch (TREE_CODE (op1))
     254              :         {
     255        87925 :         case POLYNOMIAL_CHREC:
     256        87925 :           gcc_checking_assert
     257              :             (!chrec_contains_symbols_defined_in_loop (op1,
     258              :                                                       CHREC_VARIABLE (op1)));
     259        87925 :           return chrec_fold_plus_poly_poly (code, type, op0, op1);
     260              : 
     261       224593 :         CASE_CONVERT:
     262       224593 :           if (tree_contains_chrecs (op1, NULL))
     263              :             {
     264              :               /* We can strip sign-conversions to signed by performing the
     265              :                  operation in unsigned.  */
     266          703 :               tree optype = TREE_TYPE (TREE_OPERAND (op1, 0));
     267          703 :               if (INTEGRAL_TYPE_P (type)
     268          703 :                   && INTEGRAL_TYPE_P (optype)
     269          678 :                   && tree_nop_conversion_p (type, optype)
     270          897 :                   && TYPE_UNSIGNED (optype))
     271              :                 {
     272           91 :                   tree tem = chrec_convert (optype, op0, NULL);
     273           91 :                   if (TREE_CODE (tem) == POLYNOMIAL_CHREC)
     274           12 :                     return chrec_convert (type,
     275              :                                           chrec_fold_plus_1 (code, optype,
     276              :                                                              tem,
     277           12 :                                                              TREE_OPERAND
     278              :                                                                (op1, 0)),
     279           12 :                                           NULL);
     280              :                 }
     281          691 :               return chrec_dont_know;
     282              :             }
     283              :           /* FALLTHRU */
     284              : 
     285      9729923 :         default:
     286      9729923 :           if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
     287      8942302 :             return build_polynomial_chrec
     288      8942302 :               (CHREC_VARIABLE (op0),
     289      8942302 :                chrec_fold_plus (type, CHREC_LEFT (op0), op1),
     290     17884604 :                CHREC_RIGHT (op0));
     291              :           else
     292       787621 :             return build_polynomial_chrec
     293       787621 :               (CHREC_VARIABLE (op0),
     294       787621 :                chrec_fold_minus (type, CHREC_LEFT (op0), op1),
     295      1575242 :                CHREC_RIGHT (op0));
     296              :         }
     297              : 
     298      3029956 :     CASE_CONVERT:
     299      3029956 :       if (tree_contains_chrecs (op0, NULL))
     300              :         {
     301              :           /* We can strip sign-conversions to signed by performing the
     302              :              operation in unsigned.  */
     303        40586 :           tree optype = TREE_TYPE (TREE_OPERAND (op0, 0));
     304        40586 :           if (INTEGRAL_TYPE_P (type)
     305        39189 :               && INTEGRAL_TYPE_P (optype)
     306        35152 :               && tree_nop_conversion_p (type, optype)
     307        65638 :               && TYPE_UNSIGNED (optype))
     308        50036 :             return chrec_convert (type,
     309              :                                   chrec_fold_plus_1 (code, optype,
     310        25018 :                                                      TREE_OPERAND (op0, 0),
     311              :                                                      chrec_convert (optype,
     312              :                                                                     op1, NULL)),
     313        25018 :                                   NULL);
     314        15568 :           return chrec_dont_know;
     315              :         }
     316              :       /* FALLTHRU */
     317              : 
     318     21032745 :     default:
     319     21032745 :       gcc_checking_assert (!tree_contains_chrecs (op0, NULL));
     320     21032745 :       switch (TREE_CODE (op1))
     321              :         {
     322      3095280 :         case POLYNOMIAL_CHREC:
     323      3095280 :           gcc_checking_assert
     324              :             (!chrec_contains_symbols_defined_in_loop (op1,
     325              :                                                       CHREC_VARIABLE (op1)));
     326      3095280 :           if (code == PLUS_EXPR || code == POINTER_PLUS_EXPR)
     327      3020931 :             return build_polynomial_chrec
     328      3020931 :               (CHREC_VARIABLE (op1),
     329      3020931 :                chrec_fold_plus (type, op0, CHREC_LEFT (op1)),
     330      6041862 :                CHREC_RIGHT (op1));
     331              :           else
     332        74349 :             return build_polynomial_chrec
     333       148698 :               (CHREC_VARIABLE (op1),
     334        74349 :                chrec_fold_minus (type, op0, CHREC_LEFT (op1)),
     335        74349 :                chrec_fold_multiply (type, CHREC_RIGHT (op1),
     336        74349 :                                     SCALAR_FLOAT_TYPE_P (type)
     337            4 :                                     ? build_real (type, dconstm1)
     338       148694 :                                     : build_int_cst_type (type, -1)));
     339              : 
     340      2381798 :         CASE_CONVERT:
     341      2381798 :           if (tree_contains_chrecs (op1, NULL))
     342              :             {
     343              :               /* We can strip sign-conversions to signed by performing the
     344              :                  operation in unsigned.  */
     345        57867 :               tree optype = TREE_TYPE (TREE_OPERAND (op1, 0));
     346        57867 :               if (INTEGRAL_TYPE_P (type)
     347        20746 :                   && INTEGRAL_TYPE_P (optype)
     348        20746 :                   && tree_nop_conversion_p (type, optype)
     349        74460 :                   && TYPE_UNSIGNED (optype))
     350        16593 :                 return chrec_convert (type,
     351              :                                       chrec_fold_plus_1 (code, optype,
     352              :                                                          chrec_convert (optype,
     353              :                                                                         op0,
     354              :                                                                         NULL),
     355        16593 :                                                          TREE_OPERAND (op1, 0)),
     356        16593 :                                       NULL);
     357        41274 :               return chrec_dont_know;
     358              :             }
     359              :           /* FALLTHRU */
     360              : 
     361     17879598 :         default:
     362     17879598 :           {
     363     17879598 :             int size = 0;
     364     17879598 :             if ((tree_contains_chrecs (op0, &size)
     365     17879598 :                  || tree_contains_chrecs (op1, &size))
     366     17879598 :                 && size < param_scev_max_expr_size)
     367            0 :               return build2 (code, type, op0, op1);
     368     17879598 :             else if (size < param_scev_max_expr_size)
     369              :               {
     370     17879496 :                 if (code == POINTER_PLUS_EXPR)
     371      3420480 :                   return fold_build_pointer_plus (fold_convert (type, op0),
     372              :                                                   op1);
     373              :                 else
     374     14459016 :                   return fold_build2 (code, type,
     375              :                                       fold_convert (type, op0),
     376              :                                       fold_convert (type, op1));
     377              :               }
     378              :             else
     379          102 :               return chrec_dont_know;
     380              :           }
     381              :         }
     382              :     }
     383              : }
     384              : 
     385              : /* Fold the addition of two chrecs.  */
     386              : 
     387              : tree
     388     37151574 : chrec_fold_plus (tree type,
     389              :                  tree op0,
     390              :                  tree op1)
     391              : {
     392     37151574 :   enum tree_code code;
     393     71336372 :   if (automatically_generated_chrec_p (op0)
     394     37151574 :       || automatically_generated_chrec_p (op1))
     395      3624740 :     return chrec_fold_automatically_generated_operands (op0, op1);
     396              : 
     397     33526834 :   if (integer_zerop (op0))
     398      4091172 :     return chrec_convert (type, op1, NULL);
     399     29435662 :   if (integer_zerop (op1))
     400      1871567 :     return chrec_convert (type, op0, NULL);
     401              : 
     402     27564095 :   if (POINTER_TYPE_P (type))
     403              :     code = POINTER_PLUS_EXPR;
     404              :   else
     405     21221161 :     code = PLUS_EXPR;
     406              : 
     407     27564095 :   return chrec_fold_plus_1 (code, type, op0, op1);
     408              : }
     409              : 
     410              : /* Fold the subtraction of two chrecs.  */
     411              : 
     412              : tree
     413      4117955 : chrec_fold_minus (tree type,
     414              :                   tree op0,
     415              :                   tree op1)
     416              : {
     417      7642372 :   if (automatically_generated_chrec_p (op0)
     418      4117955 :       || automatically_generated_chrec_p (op1))
     419       735173 :     return chrec_fold_automatically_generated_operands (op0, op1);
     420              : 
     421      3382782 :   if (integer_zerop (op1))
     422              :     return op0;
     423              : 
     424      3286164 :   return chrec_fold_plus_1 (MINUS_EXPR, type, op0, op1);
     425              : }
     426              : 
     427              : /* Fold the multiplication of two chrecs.  */
     428              : 
     429              : tree
     430     21908577 : chrec_fold_multiply (tree type,
     431              :                      tree op0,
     432              :                      tree op1)
     433              : {
     434     21909031 :   if (automatically_generated_chrec_p (op0)
     435     20458058 :       || automatically_generated_chrec_p (op1))
     436      1608584 :     return chrec_fold_automatically_generated_operands (op0, op1);
     437              : 
     438     20300447 :   if (TREE_CODE (op0) != POLYNOMIAL_CHREC
     439     16276650 :       && TREE_CODE (op1) == POLYNOMIAL_CHREC)
     440              :     std::swap (op0, op1);
     441              : 
     442     20300447 :   switch (TREE_CODE (op0))
     443              :     {
     444      4217198 :     case POLYNOMIAL_CHREC:
     445      4217198 :       gcc_checking_assert
     446              :         (!chrec_contains_symbols_defined_in_loop (op0, CHREC_VARIABLE (op0)));
     447      4217198 :       switch (TREE_CODE (op1))
     448              :         {
     449        40457 :         case POLYNOMIAL_CHREC:
     450        40457 :           gcc_checking_assert
     451              :             (!chrec_contains_symbols_defined_in_loop (op1,
     452              :                                                       CHREC_VARIABLE (op1)));
     453        40457 :           return chrec_fold_multiply_poly_poly (type, op0, op1);
     454              : 
     455        58402 :         CASE_CONVERT:
     456        58402 :           if (tree_contains_chrecs (op1, NULL))
     457              :             {
     458              :               /* We can strip sign-conversions to signed by performing the
     459              :                  operation in unsigned.  */
     460          225 :               tree optype = TREE_TYPE (TREE_OPERAND (op1, 0));
     461          225 :               if (INTEGRAL_TYPE_P (type)
     462          225 :                   && INTEGRAL_TYPE_P (optype)
     463          225 :                   && tree_nop_conversion_p (type, optype)
     464          247 :                   && TYPE_UNSIGNED (optype))
     465              :                 {
     466           22 :                   tree tem = chrec_convert (optype, op0, NULL);
     467           22 :                   if (TREE_CODE (tem) == POLYNOMIAL_CHREC)
     468           22 :                     return chrec_convert (type,
     469              :                                           chrec_fold_multiply (optype, tem,
     470           22 :                                                                TREE_OPERAND
     471              :                                                                  (op1, 0)),
     472           22 :                                           NULL);
     473              :                 }
     474          203 :               return chrec_dont_know;
     475              :             }
     476              :           /* FALLTHRU */
     477              : 
     478      4176516 :         default:
     479      4176516 :           if (integer_onep (op1))
     480              :             return op0;
     481      4176065 :           if (integer_zerop (op1))
     482          410 :             return build_int_cst (type, 0);
     483              : 
     484              :           /* When overflow is undefined and CHREC_LEFT/RIGHT do not have the
     485              :              same sign or CHREC_LEFT is zero then folding the multiply into
     486              :              the addition does not have the same behavior on overflow.
     487              :              Using unsigned arithmetic in that case causes too many performance
     488              :              regressions, but catch the constant case where the multiplication
     489              :              of the step overflows.  */
     490      4175655 :           if (INTEGRAL_TYPE_P (type)
     491      4175462 :               && TYPE_OVERFLOW_UNDEFINED (type)
     492      1064668 :               && !integer_zerop (CHREC_LEFT (op0))
     493       605335 :               && TREE_CODE (op1) == INTEGER_CST
     494      4604435 :               && TREE_CODE (CHREC_RIGHT (op0)) == INTEGER_CST)
     495              :             {
     496       336388 :               wi::overflow_type ovf = wi::OVF_NONE;
     497       336388 :               wide_int res
     498       336388 :                 = wi::mul (wi::to_wide (CHREC_RIGHT (op0)),
     499       672776 :                            wi::to_wide (op1), TYPE_SIGN (type), &ovf);
     500       336388 :               if (ovf != wi::OVF_NONE)
     501              :                 {
     502           36 :                   tree utype = unsigned_type_for (type);
     503           36 :                   tree uop1 = chrec_convert_rhs (utype, op1);
     504           36 :                   tree uleft0 = chrec_convert_rhs (utype, CHREC_LEFT (op0));
     505           36 :                   tree uright0 = chrec_convert_rhs (utype, CHREC_RIGHT (op0));
     506           36 :                   tree left = chrec_fold_multiply (utype, uleft0, uop1);
     507           36 :                   tree right = chrec_fold_multiply (utype, uright0, uop1);
     508           36 :                   tree tem = build_polynomial_chrec (CHREC_VARIABLE (op0),
     509              :                                                      left, right);
     510           36 :                   return chrec_convert_rhs (type, tem);
     511              :                 }
     512       336388 :             }
     513      4175619 :           tree left = chrec_fold_multiply (type, CHREC_LEFT (op0), op1);
     514      4175619 :           tree right = chrec_fold_multiply (type, CHREC_RIGHT (op0), op1);
     515      4175619 :           return build_polynomial_chrec (CHREC_VARIABLE (op0), left, right);
     516              :         }
     517              : 
     518      4805537 :     CASE_CONVERT:
     519      4805537 :       if (tree_contains_chrecs (op0, NULL))
     520              :         {
     521              :           /* We can strip sign-conversions to signed by performing the
     522              :              operation in unsigned.  */
     523        53755 :           tree optype = TREE_TYPE (TREE_OPERAND (op0, 0));
     524        53755 :           if (INTEGRAL_TYPE_P (type)
     525        53755 :               && INTEGRAL_TYPE_P (optype)
     526        53755 :               && tree_nop_conversion_p (type, optype)
     527        65515 :               && TYPE_UNSIGNED (optype))
     528        23470 :             return chrec_convert (type,
     529              :                                   chrec_fold_multiply (optype,
     530        11735 :                                                        TREE_OPERAND (op0, 0),
     531              :                                                        chrec_convert (optype,
     532              :                                                                       op1,
     533              :                                                                       NULL)),
     534        11735 :                                   NULL);
     535        42020 :           return chrec_dont_know;
     536              :         }
     537              :       /* FALLTHRU */
     538              : 
     539     16029494 :     default:
     540     16029494 :       gcc_checking_assert (!tree_contains_chrecs (op0, NULL));
     541     16029494 :       if (integer_onep (op0))
     542              :         return op1;
     543              : 
     544     11017308 :       if (integer_zerop (op0))
     545      2327917 :         return build_int_cst (type, 0);
     546              : 
     547      8689391 :       switch (TREE_CODE (op1))
     548              :         {
     549            0 :         case POLYNOMIAL_CHREC:
     550            0 :           gcc_unreachable ();
     551              : 
     552      1084329 :         CASE_CONVERT:
     553      1084329 :           if (tree_contains_chrecs (op1, NULL))
     554              :             return chrec_fold_multiply (type, op1, op0);
     555              :           /* FALLTHRU */
     556              : 
     557      8688937 :         default:
     558      8688937 :           if (integer_onep (op1))
     559              :             return op0;
     560      8624472 :           if (integer_zerop (op1))
     561         1500 :             return build_int_cst (type, 0);
     562      8622972 :           return fold_build2 (MULT_EXPR, type, op0, op1);
     563              :         }
     564              :     }
     565              : }
     566              : 
     567              : 
     568              : 
     569              : /* Operations.  */
     570              : 
     571              : /* Evaluate the binomial coefficient.  Return NULL_TREE if the intermediate
     572              :    calculation overflows, otherwise return C(n,k) with type TYPE.  */
     573              : 
     574              : static tree
     575        11826 : tree_fold_binomial (tree type, tree n, unsigned int k)
     576              : {
     577        11826 :   wi::overflow_type overflow;
     578        11826 :   unsigned int i;
     579              : 
     580              :   /* Handle the most frequent cases.  */
     581        11826 :   if (k == 0)
     582         3917 :     return build_int_cst (type, 1);
     583         7909 :   if (k == 1)
     584         3917 :     return fold_convert (type, n);
     585              : 
     586         3992 :   widest_int num = wi::to_widest (n);
     587              : 
     588              :   /* Check that k <= n.  */
     589         3992 :   if (wi::ltu_p (num, k))
     590              :     return NULL_TREE;
     591              : 
     592              :   /* Denominator = 2.  */
     593         3933 :   widest_int denom = 2;
     594              : 
     595              :   /* Index = Numerator-1.  */
     596         3933 :   widest_int idx = num - 1;
     597              : 
     598              :   /* Numerator = Numerator*Index = n*(n-1).  */
     599         3933 :   num = wi::smul (num, idx, &overflow);
     600         3933 :   if (overflow)
     601              :     return NULL_TREE;
     602              : 
     603         3939 :   for (i = 3; i <= k; i++)
     604              :     {
     605              :       /* Index--.  */
     606            6 :       --idx;
     607              : 
     608              :       /* Numerator *= Index.  */
     609            6 :       num = wi::smul (num, idx, &overflow);
     610            6 :       if (overflow)
     611              :         return NULL_TREE;
     612              : 
     613              :       /* Denominator *= i.  */
     614            6 :       denom *= i;
     615              :     }
     616              : 
     617              :   /* Result = Numerator / Denominator.  */
     618         3933 :   num = wi::udiv_trunc (num, denom);
     619         3933 :   if (! wi::fits_to_tree_p (num, type))
     620              :     return NULL_TREE;
     621         3923 :   return wide_int_to_tree (type, num);
     622         7925 : }
     623              : 
     624              : /* Helper function.  Use the Newton's interpolating formula for
     625              :    evaluating the value of the evolution function.
     626              :    The result may be in an unsigned type of CHREC.  */
     627              : 
     628              : static tree
     629        11973 : chrec_evaluate (unsigned var, tree chrec, tree n, unsigned int k)
     630              : {
     631        11973 :   tree arg0, arg1, binomial_n_k;
     632        11973 :   tree type = TREE_TYPE (chrec);
     633        11973 :   class loop *var_loop = get_loop (cfun, var);
     634              : 
     635        11973 :   while (TREE_CODE (chrec) == POLYNOMIAL_CHREC
     636        11973 :          && flow_loop_nested_p (var_loop, get_chrec_loop (chrec)))
     637            0 :     chrec = CHREC_LEFT (chrec);
     638              : 
     639              :   /* The formula associates the expression and thus we have to make
     640              :      sure to not introduce undefined overflow.  */
     641        11973 :   tree ctype = type;
     642        11973 :   if (INTEGRAL_TYPE_P (type)
     643        11973 :       && ! TYPE_OVERFLOW_WRAPS (type))
     644        11655 :     ctype = unsigned_type_for (type);
     645              : 
     646        11973 :   if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
     647        11973 :       && CHREC_VARIABLE (chrec) == var)
     648              :     {
     649         7987 :       arg1 = chrec_evaluate (var, CHREC_RIGHT (chrec), n, k + 1);
     650         7987 :       if (arg1 == chrec_dont_know)
     651              :         return chrec_dont_know;
     652         7840 :       binomial_n_k = tree_fold_binomial (ctype, n, k);
     653         7840 :       if (!binomial_n_k)
     654            0 :         return chrec_dont_know;
     655         7840 :       tree l = chrec_convert (ctype, CHREC_LEFT (chrec), NULL);
     656         7840 :       arg0 = fold_build2 (MULT_EXPR, ctype, l, binomial_n_k);
     657         7840 :       return chrec_fold_plus (ctype, arg0, arg1);
     658              :     }
     659              : 
     660         3986 :   binomial_n_k = tree_fold_binomial (ctype, n, k);
     661         3986 :   if (!binomial_n_k)
     662           69 :     return chrec_dont_know;
     663              : 
     664         3917 :   return fold_build2 (MULT_EXPR, ctype,
     665              :                       chrec_convert (ctype, chrec, NULL), binomial_n_k);
     666              : }
     667              : 
     668              : /* Evaluates "CHREC (X)" when the varying variable is VAR.
     669              :    Example:  Given the following parameters,
     670              : 
     671              :    var = 1
     672              :    chrec = {3, +, 4}_1
     673              :    x = 10
     674              : 
     675              :    The result is given by the Newton's interpolating formula:
     676              :    3 * \binom{10}{0} + 4 * \binom{10}{1}.
     677              : */
     678              : 
     679              : tree
     680       866901 : chrec_apply (unsigned var,
     681              :              tree chrec,
     682              :              tree x)
     683              : {
     684       866901 :   tree type = chrec_type (chrec);
     685       866901 :   tree res = chrec_dont_know;
     686              : 
     687      1733802 :   if (automatically_generated_chrec_p (chrec)
     688       966864 :       || automatically_generated_chrec_p (x)
     689              : 
     690              :       /* When the symbols are defined in an outer loop, it is possible
     691              :          to symbolically compute the apply, since the symbols are
     692              :          constants with respect to the varying loop.  */
     693       866901 :       || chrec_contains_symbols_defined_in_loop (chrec, var))
     694        99963 :     return chrec_dont_know;
     695              : 
     696       766938 :   if (dump_file && (dump_flags & TDF_SCEV))
     697            0 :     fprintf (dump_file, "(chrec_apply \n");
     698              : 
     699       766938 :   if (TREE_CODE (x) == INTEGER_CST && SCALAR_FLOAT_TYPE_P (type))
     700          115 :     x = build_real_from_int_cst (type, x);
     701              : 
     702       766938 :   switch (TREE_CODE (chrec))
     703              :     {
     704       765535 :     case POLYNOMIAL_CHREC:
     705       765535 :       if (evolution_function_is_affine_p (chrec))
     706              :         {
     707       760274 :           tree chrecr = CHREC_RIGHT (chrec);
     708       760274 :           tree chrecl = CHREC_LEFT (chrec);
     709       760274 :           if (CHREC_VARIABLE (chrec) != var)
     710          526 :             res = build_polynomial_chrec (CHREC_VARIABLE (chrec),
     711              :                                           chrec_apply (var, chrecl, x),
     712              :                                           chrec_apply (var, chrecr, x));
     713              : 
     714              :           /* "{a, +, a}" (x-1) -> "a*x".  */
     715       759748 :           else if (operand_equal_p (chrecl, chrecr)
     716       136019 :                    && TREE_CODE (x) == PLUS_EXPR
     717         6934 :                    && integer_all_onesp (TREE_OPERAND (x, 1))
     718         6677 :                    && !POINTER_TYPE_P (type)
     719       766414 :                    && TYPE_PRECISION (TREE_TYPE (x))
     720         6666 :                       >= TYPE_PRECISION (type))
     721              :             {
     722              :               /* We know the number of iterations can't be negative.  */
     723         4828 :               res = build_int_cst (TREE_TYPE (x), 1);
     724         4828 :               res = chrec_fold_plus (TREE_TYPE (x), x, res);
     725         4828 :               res = chrec_convert_rhs (type, res, NULL);
     726         4828 :               res = chrec_fold_multiply (type, chrecr, res);
     727              :             }
     728              :           /* "{a, +, b} (x)"  ->  "a + b*x".  */
     729              :           else
     730              :             {
     731              :               /* The overall increment might not fit in a signed type so
     732              :                  use an unsigned computation to get at the final value
     733              :                  and avoid undefined signed overflow.  */
     734       754920 :               tree utype = TREE_TYPE (chrecr);
     735       754920 :               if (INTEGRAL_TYPE_P (utype) && !TYPE_OVERFLOW_WRAPS (utype))
     736       672525 :                 utype = unsigned_type_for (TREE_TYPE (chrecr));
     737       754920 :               res = chrec_convert_rhs (utype, x, NULL);
     738       754920 :               res = chrec_fold_multiply (utype,
     739              :                                          chrec_convert (utype, chrecr, NULL),
     740              :                                          res);
     741              :               /* When the resulting increment fits the original type
     742              :                  do the increment in it.  */
     743       754920 :               if (TREE_CODE (res) == INTEGER_CST
     744       754920 :                   && int_fits_type_p (res, TREE_TYPE (chrecr)))
     745              :                 {
     746       398491 :                   res = chrec_convert (TREE_TYPE (chrecr), res, NULL);
     747       398491 :                   res = chrec_fold_plus (type, chrecl, res);
     748              :                 }
     749              :               else
     750              :                 {
     751       356429 :                   res = chrec_fold_plus (utype,
     752              :                                          chrec_convert (utype, chrecl, NULL),
     753              :                                          res);
     754       356429 :                   res = chrec_convert (type, res, NULL);
     755              :                 }
     756              :             }
     757              :         }
     758         5261 :       else if (TREE_CODE (x) == INTEGER_CST
     759         5261 :                && tree_int_cst_sgn (x) == 1)
     760              :         /* testsuite/.../ssa-chrec-38.c.  */
     761         3986 :         res = chrec_convert (type, chrec_evaluate (var, chrec, x, 0), NULL);
     762              :       else
     763         1275 :         res = chrec_dont_know;
     764              :       break;
     765              : 
     766          246 :     CASE_CONVERT:
     767          246 :       res = chrec_convert (TREE_TYPE (chrec),
     768          246 :                            chrec_apply (var, TREE_OPERAND (chrec, 0), x),
     769              :                            NULL);
     770          246 :       break;
     771              : 
     772              :     default:
     773              :       res = chrec;
     774              :       break;
     775              :     }
     776              : 
     777       766938 :   if (dump_file && (dump_flags & TDF_SCEV))
     778              :     {
     779            0 :       fprintf (dump_file, "  (varying_loop = %d", var);
     780            0 :       fprintf (dump_file, ")\n  (chrec = ");
     781            0 :       print_generic_expr (dump_file, chrec);
     782            0 :       fprintf (dump_file, ")\n  (x = ");
     783            0 :       print_generic_expr (dump_file, x);
     784            0 :       fprintf (dump_file, ")\n  (res = ");
     785            0 :       print_generic_expr (dump_file, res);
     786            0 :       fprintf (dump_file, "))\n");
     787              :     }
     788              : 
     789              :   return res;
     790              : }
     791              : 
     792              : /* For a given CHREC and an induction variable map IV_MAP that maps
     793              :    (loop->num, expr) for every loop number of the current_loops an
     794              :    expression, calls chrec_apply when the expression is not NULL.  */
     795              : 
     796              : tree
     797          888 : chrec_apply_map (tree chrec, vec<tree> iv_map)
     798              : {
     799          888 :   int i;
     800          888 :   tree expr;
     801              : 
     802         9821 :   FOR_EACH_VEC_ELT (iv_map, i, expr)
     803         8933 :     if (expr)
     804         1591 :       chrec = chrec_apply (i, chrec, expr);
     805              : 
     806          888 :   return chrec;
     807              : }
     808              : 
     809              : /* Replaces the initial condition in CHREC with INIT_COND.  */
     810              : 
     811              : tree
     812      2350169 : chrec_replace_initial_condition (tree chrec,
     813              :                                  tree init_cond)
     814              : {
     815      2350169 :   if (automatically_generated_chrec_p (chrec))
     816              :     return chrec;
     817              : 
     818      2350169 :   gcc_assert (chrec_type (chrec) == chrec_type (init_cond));
     819              : 
     820      2350169 :   switch (TREE_CODE (chrec))
     821              :     {
     822      1185426 :     case POLYNOMIAL_CHREC:
     823      1185426 :       return build_polynomial_chrec
     824      1185426 :         (CHREC_VARIABLE (chrec),
     825      1185426 :          chrec_replace_initial_condition (CHREC_LEFT (chrec), init_cond),
     826      2370852 :          CHREC_RIGHT (chrec));
     827              : 
     828              :     default:
     829              :       return init_cond;
     830              :     }
     831              : }
     832              : 
     833              : /* Returns the initial condition of a given CHREC.  */
     834              : 
     835              : tree
     836     11318392 : initial_condition (tree chrec)
     837              : {
     838     18575528 :   if (automatically_generated_chrec_p (chrec))
     839              :     return chrec;
     840              : 
     841     17327688 :   if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
     842      7257136 :     return initial_condition (CHREC_LEFT (chrec));
     843              :   else
     844              :     return chrec;
     845              : }
     846              : 
     847              : /* Returns a univariate function that represents the evolution in
     848              :    LOOP_NUM.  Mask the evolution of any other loop.  */
     849              : 
     850              : tree
     851     48602562 : hide_evolution_in_other_loops_than_loop (tree chrec,
     852              :                                          unsigned loop_num)
     853              : {
     854     48605189 :   class loop *loop = get_loop (cfun, loop_num), *chloop;
     855     48605189 :   if (automatically_generated_chrec_p (chrec))
     856              :     return chrec;
     857              : 
     858     48605189 :   switch (TREE_CODE (chrec))
     859              :     {
     860      2491734 :     case POLYNOMIAL_CHREC:
     861      2491734 :       chloop = get_chrec_loop (chrec);
     862              : 
     863      2491734 :       if (chloop == loop)
     864      2022551 :         return build_polynomial_chrec
     865      2022551 :           (loop_num,
     866      2022551 :            hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
     867              :                                                     loop_num),
     868      4045102 :            CHREC_RIGHT (chrec));
     869              : 
     870       469183 :       else if (flow_loop_nested_p (chloop, loop))
     871              :         /* There is no evolution in this loop.  */
     872       466556 :         return initial_condition (chrec);
     873              : 
     874         2627 :       else if (flow_loop_nested_p (loop, chloop))
     875         2627 :         return hide_evolution_in_other_loops_than_loop (CHREC_LEFT (chrec),
     876         2627 :                                                         loop_num);
     877              : 
     878              :       else
     879            0 :         return chrec_dont_know;
     880              : 
     881              :     default:
     882              :       return chrec;
     883              :     }
     884              : }
     885              : 
     886              : /* Returns the evolution part of CHREC in LOOP_NUM when RIGHT is
     887              :    true, otherwise returns the initial condition in LOOP_NUM.  */
     888              : 
     889              : static tree
     890     40735834 : chrec_component_in_loop_num (tree chrec,
     891              :                              unsigned loop_num,
     892              :                              bool right)
     893              : {
     894     40735834 :   tree component;
     895     40735834 :   class loop *loop = get_loop (cfun, loop_num), *chloop;
     896              : 
     897     40735834 :   if (automatically_generated_chrec_p (chrec))
     898              :     return chrec;
     899              : 
     900     39487994 :   switch (TREE_CODE (chrec))
     901              :     {
     902     33780211 :     case POLYNOMIAL_CHREC:
     903     33780211 :       chloop = get_chrec_loop (chrec);
     904              : 
     905     33780211 :       if (chloop == loop)
     906              :         {
     907     32449621 :           if (right)
     908     16561830 :             component = CHREC_RIGHT (chrec);
     909              :           else
     910     15887791 :             component = CHREC_LEFT (chrec);
     911              : 
     912     32449621 :           if (TREE_CODE (CHREC_LEFT (chrec)) != POLYNOMIAL_CHREC
     913     32449621 :               || CHREC_VARIABLE (CHREC_LEFT (chrec)) != CHREC_VARIABLE (chrec))
     914              :             return component;
     915              : 
     916              :           else
     917            0 :             return build_polynomial_chrec
     918            0 :               (loop_num,
     919            0 :                chrec_component_in_loop_num (CHREC_LEFT (chrec),
     920              :                                             loop_num,
     921              :                                             right),
     922            0 :                component);
     923              :         }
     924              : 
     925      1330590 :       else if (flow_loop_nested_p (chloop, loop))
     926              :         /* There is no evolution part in this loop.  */
     927              :         return NULL_TREE;
     928              : 
     929              :       else
     930              :         {
     931      1330590 :           gcc_assert (flow_loop_nested_p (loop, chloop));
     932      1330590 :           return chrec_component_in_loop_num (CHREC_LEFT (chrec),
     933              :                                               loop_num,
     934      1330590 :                                               right);
     935              :         }
     936              : 
     937      5707783 :      default:
     938      5707783 :       if (right)
     939              :         return NULL_TREE;
     940              :       else
     941              :         return chrec;
     942              :     }
     943              : }
     944              : 
     945              : /* Returns the evolution part in LOOP_NUM.  Example: the call
     946              :    evolution_part_in_loop_num ({{0, +, 1}_1, +, 2}_1, 1) returns
     947              :    {1, +, 2}_1  */
     948              : 
     949              : tree
     950     22674196 : evolution_part_in_loop_num (tree chrec,
     951              :                             unsigned loop_num)
     952              : {
     953     22674196 :   return chrec_component_in_loop_num (chrec, loop_num, true);
     954              : }
     955              : 
     956              : /* Returns the initial condition in LOOP_NUM.  Example: the call
     957              :    initial_condition_in_loop_num ({{0, +, 1}_1, +, 2}_2, 2) returns
     958              :    {0, +, 1}_1  */
     959              : 
     960              : tree
     961     16731048 : initial_condition_in_loop_num (tree chrec,
     962              :                                unsigned loop_num)
     963              : {
     964     16731048 :   return chrec_component_in_loop_num (chrec, loop_num, false);
     965              : }
     966              : 
     967              : /* Set or reset the evolution of CHREC to NEW_EVOL in loop LOOP_NUM.
     968              :    This function is essentially used for setting the evolution to
     969              :    chrec_dont_know, for example after having determined that it is
     970              :    impossible to say how many times a loop will execute.  */
     971              : 
     972              : tree
     973            0 : reset_evolution_in_loop (unsigned loop_num,
     974              :                          tree chrec,
     975              :                          tree new_evol)
     976              : {
     977            0 :   class loop *loop = get_loop (cfun, loop_num);
     978              : 
     979            0 :   if (POINTER_TYPE_P (chrec_type (chrec)))
     980            0 :     gcc_assert (ptrofftype_p (chrec_type (new_evol)));
     981              :   else
     982            0 :     gcc_assert (chrec_type (chrec) == chrec_type (new_evol));
     983              : 
     984            0 :   if (TREE_CODE (chrec) == POLYNOMIAL_CHREC
     985            0 :       && flow_loop_nested_p (loop, get_chrec_loop (chrec)))
     986              :     {
     987            0 :       tree left = reset_evolution_in_loop (loop_num, CHREC_LEFT (chrec),
     988              :                                            new_evol);
     989            0 :       tree right = reset_evolution_in_loop (loop_num, CHREC_RIGHT (chrec),
     990              :                                             new_evol);
     991            0 :       return build_polynomial_chrec (CHREC_VARIABLE (chrec), left, right);
     992              :     }
     993              : 
     994            0 :   while (TREE_CODE (chrec) == POLYNOMIAL_CHREC
     995            0 :          && CHREC_VARIABLE (chrec) == loop_num)
     996            0 :     chrec = CHREC_LEFT (chrec);
     997              : 
     998            0 :   return build_polynomial_chrec (loop_num, chrec, new_evol);
     999              : }
    1000              : 
    1001              : /* Merges two evolution functions that were found by following two
    1002              :    alternate paths of a conditional expression.  */
    1003              : 
    1004              : tree
    1005     16321535 : chrec_merge (tree chrec1,
    1006              :              tree chrec2)
    1007              : {
    1008     16321535 :   if (chrec1 == chrec_dont_know
    1009     16321535 :       || chrec2 == chrec_dont_know)
    1010              :     return chrec_dont_know;
    1011              : 
    1012     13688533 :   if (chrec1 == chrec_known
    1013     13688533 :       || chrec2 == chrec_known)
    1014              :     return chrec_known;
    1015              : 
    1016     13688533 :   if (chrec1 == chrec_not_analyzed_yet)
    1017              :     return chrec2;
    1018      2874994 :   if (chrec2 == chrec_not_analyzed_yet)
    1019              :     return chrec1;
    1020              : 
    1021      2874994 :   if (eq_evolutions_p (chrec1, chrec2))
    1022              :     return chrec1;
    1023              : 
    1024      2325072 :   return chrec_dont_know;
    1025              : }
    1026              : 
    1027              : 
    1028              : 
    1029              : /* Observers.  */
    1030              : 
    1031              : /* Helper function for is_multivariate_chrec.  */
    1032              : 
    1033              : static bool
    1034            0 : is_multivariate_chrec_rec (const_tree chrec, unsigned int rec_var)
    1035              : {
    1036            0 :   if (chrec == NULL_TREE)
    1037              :     return false;
    1038              : 
    1039            0 :   if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
    1040              :     {
    1041            0 :       if (CHREC_VARIABLE (chrec) != rec_var)
    1042              :         return true;
    1043              :       else
    1044            0 :         return (is_multivariate_chrec_rec (CHREC_LEFT (chrec), rec_var)
    1045            0 :                 || is_multivariate_chrec_rec (CHREC_RIGHT (chrec), rec_var));
    1046              :     }
    1047              :   else
    1048              :     return false;
    1049              : }
    1050              : 
    1051              : /* Determine whether the given chrec is multivariate or not.  */
    1052              : 
    1053              : bool
    1054            0 : is_multivariate_chrec (const_tree chrec)
    1055              : {
    1056            0 :   if (chrec == NULL_TREE)
    1057              :     return false;
    1058              : 
    1059            0 :   if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
    1060            0 :     return (is_multivariate_chrec_rec (CHREC_LEFT (chrec),
    1061            0 :                                        CHREC_VARIABLE (chrec))
    1062            0 :             || is_multivariate_chrec_rec (CHREC_RIGHT (chrec),
    1063            0 :                                           CHREC_VARIABLE (chrec)));
    1064              :   else
    1065              :     return false;
    1066              : }
    1067              : 
    1068              : /* Determines whether the chrec contains symbolic names or not.  If LOOP isn't
    1069              :    NULL, we also consider chrec wrto outer loops of LOOP as symbol.  */
    1070              : 
    1071              : static bool
    1072     37717553 : chrec_contains_symbols (const_tree chrec, hash_set<const_tree> &visited,
    1073              :                         class loop *loop)
    1074              : {
    1075     37717553 :   int i, n;
    1076              : 
    1077     37717553 :   if (chrec == NULL_TREE)
    1078              :     return false;
    1079              : 
    1080     37717553 :   if (TREE_CODE (chrec) == SSA_NAME
    1081              :       || VAR_P (chrec)
    1082              :       || TREE_CODE (chrec) == POLY_INT_CST
    1083              :       || TREE_CODE (chrec) == PARM_DECL
    1084              :       || TREE_CODE (chrec) == FUNCTION_DECL
    1085              :       || TREE_CODE (chrec) == LABEL_DECL
    1086              :       || TREE_CODE (chrec) == RESULT_DECL
    1087              :       || TREE_CODE (chrec) == FIELD_DECL)
    1088              :     return true;
    1089              : 
    1090     31853832 :   if (loop != NULL
    1091          600 :       && TREE_CODE (chrec) == POLYNOMIAL_CHREC
    1092     31854034 :       && flow_loop_nested_p (get_chrec_loop (chrec), loop))
    1093              :     return true;
    1094              : 
    1095     31853832 :   if (visited.add (chrec))
    1096              :     return false;
    1097              : 
    1098     31209026 :   n = TREE_OPERAND_LENGTH (chrec);
    1099     80347946 :   for (i = 0; i < n; i++)
    1100     21910884 :     if (chrec_contains_symbols (TREE_OPERAND (chrec, i), visited, loop))
    1101              :       return true;
    1102              :   return false;
    1103              : }
    1104              : 
    1105              : /* Return true if CHREC contains any symbols.  If LOOP is not NULL, check if
    1106              :    CHREC contains any chrec which is invariant wrto the loop (nest), in other
    1107              :    words, chrec defined by outer loops of loop, so from LOOP's point of view,
    1108              :    the chrec is considered as a SYMBOL.  */
    1109              : 
    1110              : bool
    1111     15806669 : chrec_contains_symbols (const_tree chrec, class loop* loop)
    1112              : {
    1113     15806669 :   hash_set<const_tree> visited;
    1114     15806669 :   return chrec_contains_symbols (chrec, visited, loop);
    1115     15806669 : }
    1116              : 
    1117              : /* Return true when CHREC contains symbolic names defined in
    1118              :    LOOP_NB.  */
    1119              : 
    1120              : static bool
    1121    342186471 : chrec_contains_symbols_defined_in_loop (const_tree chrec, unsigned loop_nb,
    1122              :                                         hash_set<const_tree> &visited)
    1123              : {
    1124    342186471 :   int i, n;
    1125              : 
    1126    342186471 :   if (chrec == NULL_TREE)
    1127              :     return false;
    1128              : 
    1129    342039287 :   if (is_gimple_min_invariant (chrec))
    1130              :     return false;
    1131              : 
    1132    202232433 :   if (TREE_CODE (chrec) == SSA_NAME)
    1133              :     {
    1134     72727732 :       gimple *def;
    1135     72727732 :       loop_p def_loop, loop;
    1136              : 
    1137     72727732 :       if (SSA_NAME_IS_DEFAULT_DEF (chrec))
    1138              :         return false;
    1139              : 
    1140     68333467 :       def = SSA_NAME_DEF_STMT (chrec);
    1141     68333467 :       def_loop = loop_containing_stmt (def);
    1142     68333467 :       loop = get_loop (cfun, loop_nb);
    1143              : 
    1144     68333467 :       if (def_loop == NULL)
    1145              :         return false;
    1146              : 
    1147     68333467 :       if (loop == def_loop || flow_loop_nested_p (loop, def_loop))
    1148      4336154 :         return true;
    1149              : 
    1150              :       return false;
    1151              :     }
    1152              : 
    1153    129504701 :   if (visited.add (chrec))
    1154              :     return false;
    1155              : 
    1156    129463451 :   n = TREE_OPERAND_LENGTH (chrec);
    1157    473668300 :   for (i = 0; i < n; i++)
    1158    216004692 :     if (chrec_contains_symbols_defined_in_loop (TREE_OPERAND (chrec, i),
    1159              :                                                 loop_nb, visited))
    1160              :       return true;
    1161              :   return false;
    1162              : }
    1163              : 
    1164              : /* Return true when CHREC contains symbolic names defined in
    1165              :    LOOP_NB.  */
    1166              : 
    1167              : bool
    1168    126181779 : chrec_contains_symbols_defined_in_loop (const_tree chrec, unsigned loop_nb)
    1169              : {
    1170    126181779 :   hash_set<const_tree> visited;
    1171    126181779 :   return chrec_contains_symbols_defined_in_loop (chrec, loop_nb, visited);
    1172    126181779 : }
    1173              : 
    1174              : /* Determines whether the chrec contains undetermined coefficients.  */
    1175              : 
    1176              : static bool
    1177    227127937 : chrec_contains_undetermined (const_tree chrec, hash_set<const_tree> &visited)
    1178              : {
    1179    227127937 :   int i, n;
    1180              : 
    1181    227127937 :   if (chrec == chrec_dont_know)
    1182              :     return true;
    1183              : 
    1184    203805958 :   if (chrec == NULL_TREE)
    1185              :     return false;
    1186              : 
    1187    203427902 :   if (visited.add (chrec))
    1188              :     return false;
    1189              : 
    1190    190042635 :   n = TREE_OPERAND_LENGTH (chrec);
    1191    505963866 :   for (i = 0; i < n; i++)
    1192    125879791 :     if (chrec_contains_undetermined (TREE_OPERAND (chrec, i), visited))
    1193              :       return true;
    1194              :   return false;
    1195              : }
    1196              : 
    1197              : bool
    1198    101248146 : chrec_contains_undetermined (const_tree chrec)
    1199              : {
    1200    101248146 :   hash_set<const_tree> visited;
    1201    101248146 :   return chrec_contains_undetermined (chrec, visited);
    1202    101248146 : }
    1203              : 
    1204              : /* Determines whether the tree EXPR contains chrecs, and increment
    1205              :    SIZE if it is not a NULL pointer by an estimation of the depth of
    1206              :    the tree.  */
    1207              : 
    1208              : static bool
    1209    445878174 : tree_contains_chrecs (const_tree expr, int *size, hash_set<const_tree> &visited)
    1210              : {
    1211    445878174 :   int i, n;
    1212              : 
    1213    445878174 :   if (expr == NULL_TREE)
    1214              :     return false;
    1215              : 
    1216    444726963 :   if (size)
    1217     78357694 :     (*size)++;
    1218              : 
    1219    445095373 :   if (tree_is_chrec (expr))
    1220              :     return true;
    1221              : 
    1222    421545344 :   if (visited.add (expr))
    1223              :     return false;
    1224              : 
    1225    419116336 :   n = TREE_OPERAND_LENGTH (expr);
    1226   1054514947 :   for (i = 0; i < n; i++)
    1227    216572803 :     if (tree_contains_chrecs (TREE_OPERAND (expr, i), size, visited))
    1228              :       return true;
    1229              :   return false;
    1230              : }
    1231              : 
    1232              : bool
    1233    229305371 : tree_contains_chrecs (const_tree expr, int *size)
    1234              : {
    1235    229305371 :   hash_set<const_tree> visited;
    1236    229305371 :   return tree_contains_chrecs (expr, size, visited);
    1237    229305371 : }
    1238              : 
    1239              : 
    1240              : /* Recursive helper function.  */
    1241              : 
    1242              : static bool
    1243     45026045 : evolution_function_is_invariant_rec_p (tree chrec, int loopnum)
    1244              : {
    1245     90052090 :   if (evolution_function_is_constant_p (chrec))
    1246              :     return true;
    1247              : 
    1248      9840804 :   if (TREE_CODE (chrec) == SSA_NAME
    1249      9840804 :       && (loopnum == 0
    1250      2070843 :           || expr_invariant_in_loop_p (get_loop (cfun, loopnum), chrec)))
    1251      2047969 :     return true;
    1252              : 
    1253      7792835 :   if (TREE_CODE (chrec) == POLYNOMIAL_CHREC)
    1254              :     {
    1255      6129032 :       if (CHREC_VARIABLE (chrec) == (unsigned) loopnum
    1256       134642 :           || flow_loop_nested_p (get_loop (cfun, loopnum),
    1257       134642 :                                  get_chrec_loop (chrec))
    1258         3246 :           || !evolution_function_is_invariant_rec_p (CHREC_RIGHT (chrec),
    1259              :                                                      loopnum)
    1260      6132278 :           || !evolution_function_is_invariant_rec_p (CHREC_LEFT (chrec),
    1261              :                                                      loopnum))
    1262      6125786 :         return false;
    1263              :       return true;
    1264              :     }
    1265              : 
    1266      1663803 :   switch (TREE_OPERAND_LENGTH (chrec))
    1267              :     {
    1268       932361 :     case 2:
    1269       932361 :       if (!evolution_function_is_invariant_rec_p (TREE_OPERAND (chrec, 1),
    1270              :                                                   loopnum))
    1271              :         return false;
    1272              :       /* FALLTHRU */
    1273              : 
    1274      1598244 :     case 1:
    1275      1598244 :       if (!evolution_function_is_invariant_rec_p (TREE_OPERAND (chrec, 0),
    1276              :                                                   loopnum))
    1277              :         return false;
    1278              :       return true;
    1279              : 
    1280              :     default:
    1281              :       return false;
    1282              :     }
    1283              : }
    1284              : 
    1285              : /* Return true if CHREC is invariant in loop LOOPNUM, false otherwise. */
    1286              : 
    1287              : bool
    1288     30001086 : evolution_function_is_invariant_p (tree chrec, int loopnum)
    1289              : {
    1290     30001086 :   return evolution_function_is_invariant_rec_p (chrec, loopnum);
    1291              : }
    1292              : 
    1293              : /* Determine whether the given tree is an affine multivariate
    1294              :    evolution.  */
    1295              : 
    1296              : bool
    1297      6795473 : evolution_function_is_affine_multivariate_p (const_tree chrec, int loopnum)
    1298              : {
    1299      6795473 :   if (chrec == NULL_TREE)
    1300              :     return false;
    1301              : 
    1302      6795473 :   switch (TREE_CODE (chrec))
    1303              :     {
    1304      6243931 :     case POLYNOMIAL_CHREC:
    1305      6243931 :       if (evolution_function_is_invariant_rec_p (CHREC_LEFT (chrec), loopnum))
    1306              :         {
    1307      6142865 :           if (evolution_function_is_invariant_rec_p (CHREC_RIGHT (chrec), loopnum))
    1308              :             return true;
    1309              :           else
    1310              :             {
    1311          203 :               if (TREE_CODE (CHREC_RIGHT (chrec)) == POLYNOMIAL_CHREC
    1312          203 :                   && CHREC_VARIABLE (CHREC_RIGHT (chrec))
    1313          203 :                      != CHREC_VARIABLE (chrec)
    1314          203 :                   && evolution_function_is_affine_multivariate_p
    1315            0 :                   (CHREC_RIGHT (chrec), loopnum))
    1316              :                 return true;
    1317              :               else
    1318          203 :                 return false;
    1319              :             }
    1320              :         }
    1321              :       else
    1322              :         {
    1323       101066 :           if (evolution_function_is_invariant_rec_p (CHREC_RIGHT (chrec), loopnum)
    1324       101066 :               && TREE_CODE (CHREC_LEFT (chrec)) == POLYNOMIAL_CHREC
    1325       101021 :               && CHREC_VARIABLE (CHREC_LEFT (chrec)) != CHREC_VARIABLE (chrec)
    1326       202087 :               && evolution_function_is_affine_multivariate_p
    1327       101021 :               (CHREC_LEFT (chrec), loopnum))
    1328              :             return true;
    1329              :           else
    1330           45 :             return false;
    1331              :         }
    1332              : 
    1333              :     default:
    1334              :       return false;
    1335              :     }
    1336              : }
    1337              : 
    1338              : /* Determine whether the given tree is a function in zero or one
    1339              :    variables with respect to loop specified by LOOPNUM.  Note only positive
    1340              :    LOOPNUM stands for a real loop.  */
    1341              : 
    1342              : bool
    1343      3459374 : evolution_function_is_univariate_p (const_tree chrec, int loopnum)
    1344              : {
    1345      3459374 :   if (chrec == NULL_TREE)
    1346              :     return true;
    1347              : 
    1348      3459374 :   tree sub_chrec;
    1349      3459374 :   switch (TREE_CODE (chrec))
    1350              :     {
    1351      3459371 :     case POLYNOMIAL_CHREC:
    1352      3459371 :       switch (TREE_CODE (CHREC_LEFT (chrec)))
    1353              :         {
    1354        31417 :         case POLYNOMIAL_CHREC:
    1355        31417 :           sub_chrec = CHREC_LEFT (chrec);
    1356        31417 :           if (CHREC_VARIABLE (chrec) != CHREC_VARIABLE (sub_chrec)
    1357        31417 :               && (loopnum <= 0
    1358         5053 :                   || CHREC_VARIABLE (sub_chrec) == (unsigned) loopnum
    1359           18 :                   || flow_loop_nested_p (get_loop (cfun, loopnum),
    1360           18 :                                          get_chrec_loop (sub_chrec))))
    1361        31405 :             return false;
    1362           12 :           if (!evolution_function_is_univariate_p (sub_chrec, loopnum))
    1363              :             return false;
    1364              :           break;
    1365              : 
    1366      3427954 :         default:
    1367      3427954 :           if (tree_contains_chrecs (CHREC_LEFT (chrec), NULL))
    1368              :             return false;
    1369              :           break;
    1370              :         }
    1371              : 
    1372      3427966 :       switch (TREE_CODE (CHREC_RIGHT (chrec)))
    1373              :         {
    1374            0 :         case POLYNOMIAL_CHREC:
    1375            0 :           sub_chrec = CHREC_RIGHT (chrec);
    1376            0 :           if (CHREC_VARIABLE (chrec) != CHREC_VARIABLE (sub_chrec)
    1377            0 :               && (loopnum <= 0
    1378            0 :                   || CHREC_VARIABLE (sub_chrec) == (unsigned) loopnum
    1379            0 :                   || flow_loop_nested_p (get_loop (cfun, loopnum),
    1380            0 :                                          get_chrec_loop (sub_chrec))))
    1381            0 :             return false;
    1382            0 :           if (!evolution_function_is_univariate_p (sub_chrec, loopnum))
    1383              :             return false;
    1384              :           break;
    1385              : 
    1386      3427966 :         default:
    1387      3427966 :           if (tree_contains_chrecs (CHREC_RIGHT (chrec), NULL))
    1388              :             return false;
    1389              :           break;
    1390              :         }
    1391              :       return true;
    1392              : 
    1393              :     default:
    1394              :       return true;
    1395              :     }
    1396              : }
    1397              : 
    1398              : /* Returns the number of variables of CHREC.  Example: the call
    1399              :    nb_vars_in_chrec ({{0, +, 1}_5, +, 2}_6) returns 2.  */
    1400              : 
    1401              : unsigned
    1402      3370130 : nb_vars_in_chrec (tree chrec)
    1403              : {
    1404      6740260 :   if (chrec == NULL_TREE)
    1405              :     return 0;
    1406              : 
    1407      6740260 :   switch (TREE_CODE (chrec))
    1408              :     {
    1409      3370130 :     case POLYNOMIAL_CHREC:
    1410      3370130 :       return 1 + nb_vars_in_chrec
    1411      3370130 :         (initial_condition_in_loop_num (chrec, CHREC_VARIABLE (chrec)));
    1412              : 
    1413              :     default:
    1414              :       return 0;
    1415              :     }
    1416              : }
    1417              : 
    1418              : /* Converts BASE and STEP of affine scev to TYPE.  LOOP is the loop whose iv
    1419              :    the scev corresponds to.  AT_STMT is the statement at that the scev is
    1420              :    evaluated.  USE_OVERFLOW_SEMANTICS is true if this function should assume
    1421              :    that the rules for overflow of the given language apply (e.g., that signed
    1422              :    arithmetics in C does not overflow) -- i.e., to use them to avoid
    1423              :    unnecessary tests, but also to enforce that the result follows them.
    1424              :    FROM is the source variable converted if it's not NULL.  Returns true if
    1425              :    the conversion succeeded, false otherwise.  */
    1426              : 
    1427              : bool
    1428      7544502 : convert_affine_scev (class loop *loop, tree type,
    1429              :                      tree *base, tree *step, gimple *at_stmt,
    1430              :                      bool use_overflow_semantics, tree from)
    1431              : {
    1432      7544502 :   tree ct = TREE_TYPE (*step);
    1433      7544502 :   bool enforce_overflow_semantics;
    1434      7544502 :   bool must_check_src_overflow, must_check_rslt_overflow;
    1435      7544502 :   tree new_base, new_step;
    1436      7544502 :   tree step_type = POINTER_TYPE_P (type) ? sizetype : type;
    1437              : 
    1438              :   /* In general,
    1439              :      (TYPE) (BASE + STEP * i) = (TYPE) BASE + (TYPE -- sign extend) STEP * i,
    1440              :      but we must check some assumptions.
    1441              : 
    1442              :      1) If [BASE, +, STEP] wraps, the equation is not valid when precision
    1443              :         of CT is smaller than the precision of TYPE.  For example, when we
    1444              :         cast unsigned char [254, +, 1] to unsigned, the values on left side
    1445              :         are 254, 255, 0, 1, ..., but those on the right side are
    1446              :         254, 255, 256, 257, ...
    1447              :      2) In case that we must also preserve the fact that signed ivs do not
    1448              :         overflow, we must additionally check that the new iv does not wrap.
    1449              :         For example, unsigned char [125, +, 1] casted to signed char could
    1450              :         become a wrapping variable with values 125, 126, 127, -128, -127, ...,
    1451              :         which would confuse optimizers that assume that this does not
    1452              :         happen.  */
    1453      7544502 :   must_check_src_overflow = TYPE_PRECISION (ct) < TYPE_PRECISION (type);
    1454              : 
    1455     17183524 :   enforce_overflow_semantics = (use_overflow_semantics
    1456      7544502 :                                 && nowrap_type_p (type));
    1457      2517653 :   if (enforce_overflow_semantics)
    1458              :     {
    1459              :       /* We can avoid checking whether the result overflows in the following
    1460              :          cases:
    1461              : 
    1462              :          -- must_check_src_overflow is true, and the range of TYPE is superset
    1463              :             of the range of CT -- i.e., in all cases except if CT signed and
    1464              :             TYPE unsigned.
    1465              :          -- both CT and TYPE have the same precision and signedness, and we
    1466              :             verify instead that the source does not overflow (this may be
    1467              :             easier than verifying it for the result, as we may use the
    1468              :             information about the semantics of overflow in CT).  */
    1469      2517653 :       if (must_check_src_overflow)
    1470              :         {
    1471       442131 :           if (TYPE_UNSIGNED (type) && !TYPE_UNSIGNED (ct))
    1472              :             must_check_rslt_overflow = true;
    1473              :           else
    1474              :             must_check_rslt_overflow = false;
    1475              :         }
    1476      2075522 :       else if (TYPE_UNSIGNED (ct) == TYPE_UNSIGNED (type)
    1477      2075522 :                && TYPE_PRECISION (ct) == TYPE_PRECISION (type))
    1478              :         {
    1479              :           must_check_rslt_overflow = false;
    1480              :           must_check_src_overflow = true;
    1481              :         }
    1482              :       else
    1483              :         must_check_rslt_overflow = true;
    1484              :     }
    1485              :   else
    1486              :     must_check_rslt_overflow = false;
    1487              : 
    1488      7121369 :   if (must_check_src_overflow
    1489      7544502 :       && scev_probably_wraps_p (from, *base, *step, at_stmt, loop,
    1490              :                                 use_overflow_semantics))
    1491              :     return false;
    1492              : 
    1493      6724794 :   new_base = chrec_convert (type, *base, at_stmt, use_overflow_semantics);
    1494              :   /* The step must be sign extended, regardless of the signedness
    1495              :      of CT and TYPE.  This only needs to be handled specially when
    1496              :      CT is unsigned -- to avoid e.g. unsigned char [100, +, 255]
    1497              :      (with values 100, 99, 98, ...) from becoming signed or unsigned
    1498              :      [100, +, 255] with values 100, 355, ...; the sign-extension is
    1499              :      performed by default when CT is signed.  */
    1500      6724794 :   new_step = *step;
    1501      6724794 :   if (TYPE_PRECISION (step_type) > TYPE_PRECISION (ct) && TYPE_UNSIGNED (ct))
    1502              :     {
    1503       135737 :       tree signed_ct = signed_type_for (ct);
    1504       135737 :       new_step = chrec_convert (signed_ct, new_step, at_stmt,
    1505              :                                 use_overflow_semantics);
    1506              :     }
    1507      6724794 :   new_step = chrec_convert (step_type, new_step, at_stmt,
    1508              :                             use_overflow_semantics);
    1509              : 
    1510     13445595 :   if (automatically_generated_chrec_p (new_base)
    1511      2037709 :       || automatically_generated_chrec_p (new_step))
    1512              :     return false;
    1513              : 
    1514      6720541 :   if (must_check_rslt_overflow
    1515              :       /* Note that in this case we cannot use the fact that signed variables
    1516              :          do not overflow, as this is what we are verifying for the new iv.  */
    1517      6720541 :       && scev_probably_wraps_p (NULL_TREE, new_base, new_step,
    1518              :                                 at_stmt, loop, false))
    1519              :     return false;
    1520              : 
    1521      5506793 :   *base = new_base;
    1522      5506793 :   *step = new_step;
    1523      5506793 :   return true;
    1524              : }
    1525              : 
    1526              : 
    1527              : /* Convert CHREC for the right hand side of a CHREC.
    1528              :    The increment for a pointer type is always sizetype.  */
    1529              : 
    1530              : tree
    1531     31918572 : chrec_convert_rhs (tree type, tree chrec, gimple *at_stmt)
    1532              : {
    1533     31918572 :   if (POINTER_TYPE_P (type))
    1534      5915618 :     type = sizetype;
    1535              : 
    1536     31918572 :   return chrec_convert (type, chrec, at_stmt);
    1537              : }
    1538              : 
    1539              : /* Convert CHREC to TYPE.  When the analyzer knows the context in
    1540              :    which the CHREC is built, it sets AT_STMT to the statement that
    1541              :    contains the definition of the analyzed variable, otherwise the
    1542              :    conversion is less accurate: the information is used for
    1543              :    determining a more accurate estimation of the number of iterations.
    1544              :    By default AT_STMT could be safely set to NULL_TREE.
    1545              : 
    1546              :    USE_OVERFLOW_SEMANTICS is true if this function should assume that
    1547              :    the rules for overflow of the given language apply (e.g., that signed
    1548              :    arithmetics in C does not overflow) -- i.e., to use them to avoid
    1549              :    unnecessary tests, but also to enforce that the result follows them.
    1550              : 
    1551              :    FROM is the source variable converted if it's not NULL.  */
    1552              : 
    1553              : static tree
    1554    159635561 : chrec_convert_1 (tree type, tree chrec, gimple *at_stmt,
    1555              :                  bool use_overflow_semantics, tree from)
    1556              : {
    1557    159635561 :   tree ct, res;
    1558    159635561 :   tree base, step;
    1559    159635561 :   class loop *loop;
    1560              : 
    1561    275401580 :   if (automatically_generated_chrec_p (chrec))
    1562              :     return chrec;
    1563              : 
    1564    158300385 :   ct = chrec_type (chrec);
    1565    158300385 :   if (useless_type_conversion_p (type, ct))
    1566              :     return chrec;
    1567              : 
    1568     42534366 :   if (!evolution_function_is_affine_p (chrec))
    1569     36384089 :     goto keep_cast;
    1570              : 
    1571      6150277 :   loop = get_chrec_loop (chrec);
    1572      6150277 :   base = CHREC_LEFT (chrec);
    1573      6150277 :   step = CHREC_RIGHT (chrec);
    1574              : 
    1575      6150277 :   if (convert_affine_scev (loop, type, &base, &step, at_stmt,
    1576              :                            use_overflow_semantics, from))
    1577      4626371 :     return build_polynomial_chrec (loop->num, base, step);
    1578              : 
    1579              :   /* If we cannot propagate the cast inside the chrec, just keep the cast.  */
    1580      1523906 : keep_cast:
    1581              :   /* Fold will not canonicalize (long)(i - 1) to (long)i - 1 because that
    1582              :      may be more expensive.  We do want to perform this optimization here
    1583              :      though for canonicalization reasons.  */
    1584     37907995 :   if (use_overflow_semantics
    1585     37250985 :       && (TREE_CODE (chrec) == PLUS_EXPR
    1586     37250985 :           || TREE_CODE (chrec) == MINUS_EXPR)
    1587      3536323 :       && TREE_CODE (type) == INTEGER_TYPE
    1588      3416399 :       && TREE_CODE (ct) == INTEGER_TYPE
    1589      3416353 :       && TYPE_PRECISION (type) > TYPE_PRECISION (ct)
    1590     38070717 :       && TYPE_OVERFLOW_UNDEFINED (ct))
    1591        60135 :     res = fold_build2 (TREE_CODE (chrec), type,
    1592              :                        fold_convert (type, TREE_OPERAND (chrec, 0)),
    1593              :                        fold_convert (type, TREE_OPERAND (chrec, 1)));
    1594              :   /* Similar perform the trick that (signed char)((int)x + 2) can be
    1595              :      narrowed to (signed char)((unsigned char)x + 2).  */
    1596     37847860 :   else if (use_overflow_semantics
    1597     37190850 :            && TREE_CODE (chrec) == POLYNOMIAL_CHREC
    1598      1554074 :            && TREE_CODE (ct) == INTEGER_TYPE
    1599      1542005 :            && TREE_CODE (type) == INTEGER_TYPE
    1600      1379232 :            && TYPE_OVERFLOW_UNDEFINED (type)
    1601     38986107 :            && TYPE_PRECISION (type) < TYPE_PRECISION (ct))
    1602              :     {
    1603        28917 :       tree utype = unsigned_type_for (type);
    1604        86751 :       res = build_polynomial_chrec (CHREC_VARIABLE (chrec),
    1605        28917 :                                     fold_convert (utype,
    1606              :                                                   CHREC_LEFT (chrec)),
    1607        28917 :                                     fold_convert (utype,
    1608              :                                                   CHREC_RIGHT (chrec)));
    1609        28917 :       res = chrec_convert_1 (type, res, at_stmt, use_overflow_semantics, from);
    1610              :     }
    1611              :   /* Similar perform the trick that (unsigned T)(base + step) can be
    1612              :      folded to ((unsigned T)x + (unsigned T)step).  */
    1613     37818943 :   else if (use_overflow_semantics
    1614     37161933 :            && TREE_CODE (chrec) == POLYNOMIAL_CHREC
    1615      1525157 :            && INTEGRAL_TYPE_P (ct)
    1616      1513168 :            && INTEGRAL_TYPE_P (type)
    1617      1350395 :            && TYPE_OVERFLOW_UNDEFINED (type)
    1618              :            /* Must be unsigned so we don't introduce any UB.  */
    1619      1109410 :            && TYPE_UNSIGNED (type)
    1620              :            /* The outer type must at least as wide than the inner type so we
    1621              :                  don't truncate when we fold and must the inner CHREC must be
    1622              :                  non-wrapping so we don't change the behavior when folding to
    1623              :                  a wider type.  */
    1624            0 :           && TYPE_PRECISION (type) >= TYPE_PRECISION (ct)
    1625     37818943 :           && (!TYPE_UNSIGNED (ct)
    1626            0 :               || TYPE_PRECISION (type) == TYPE_PRECISION (ct)
    1627            0 :               || nonwrapping_chrec_p (chrec)))
    1628              :     {
    1629            0 :       res = build_polynomial_chrec (CHREC_VARIABLE (chrec),
    1630            0 :                                     fold_convert (type,
    1631              :                                                   CHREC_LEFT (chrec)),
    1632            0 :                                     fold_convert (type,
    1633              :                                                   CHREC_RIGHT (chrec)));
    1634            0 :       res = chrec_convert_1 (type, res, at_stmt, use_overflow_semantics, from);
    1635              :     }
    1636              :   else
    1637     37818943 :     res = fold_convert (type, chrec);
    1638              : 
    1639              :   /* Don't propagate overflows.  */
    1640     37907995 :   if (CONSTANT_CLASS_P (res))
    1641     12072753 :     TREE_OVERFLOW (res) = 0;
    1642              : 
    1643              :   /* But reject constants that don't fit in their type after conversion.
    1644              :      This can happen if TYPE_MIN_VALUE or TYPE_MAX_VALUE are not the
    1645              :      natural values associated with TYPE_PRECISION and TYPE_UNSIGNED,
    1646              :      and can cause problems later when computing niters of loops.  Note
    1647              :      that we don't do the check before converting because we don't want
    1648              :      to reject conversions of negative chrecs to unsigned types.  */
    1649     37907995 :   if (TREE_CODE (res) == INTEGER_CST
    1650     12072752 :       && TREE_CODE (type) == INTEGER_TYPE
    1651     12054700 :       && !int_fits_type_p (res, type))
    1652         4573 :     res = chrec_dont_know;
    1653              : 
    1654              :   return res;
    1655              : }
    1656              : 
    1657              : /* Convert CHREC to TYPE.  When the analyzer knows the context in
    1658              :    which the CHREC is built, it sets AT_STMT to the statement that
    1659              :    contains the definition of the analyzed variable, otherwise the
    1660              :    conversion is less accurate: the information is used for
    1661              :    determining a more accurate estimation of the number of iterations.
    1662              :    By default AT_STMT could be safely set to NULL_TREE.
    1663              : 
    1664              :    The following rule is always true: TREE_TYPE (chrec) ==
    1665              :    TREE_TYPE (CHREC_LEFT (chrec)) == TREE_TYPE (CHREC_RIGHT (chrec)).
    1666              :    An example of what could happen when adding two chrecs and the type
    1667              :    of the CHREC_RIGHT is different than CHREC_LEFT is:
    1668              : 
    1669              :    {(uint) 0, +, (uchar) 10} +
    1670              :    {(uint) 0, +, (uchar) 250}
    1671              : 
    1672              :    that would produce a wrong result if CHREC_RIGHT is not (uint):
    1673              : 
    1674              :    {(uint) 0, +, (uchar) 4}
    1675              : 
    1676              :    instead of
    1677              : 
    1678              :    {(uint) 0, +, (uint) 260}
    1679              : 
    1680              :    USE_OVERFLOW_SEMANTICS is true if this function should assume that
    1681              :    the rules for overflow of the given language apply (e.g., that signed
    1682              :    arithmetics in C does not overflow) -- i.e., to use them to avoid
    1683              :    unnecessary tests, but also to enforce that the result follows them.
    1684              : 
    1685              :    FROM is the source variable converted if it's not NULL.  */
    1686              : 
    1687              : tree
    1688    159606644 : chrec_convert (tree type, tree chrec, gimple *at_stmt,
    1689              :                bool use_overflow_semantics, tree from)
    1690              : {
    1691    159606644 :   return chrec_convert_1 (type, chrec, at_stmt, use_overflow_semantics, from);
    1692              : }
    1693              : 
    1694              : /* Convert CHREC to TYPE, without regard to signed overflows.  Returns the new
    1695              :    chrec if something else than what chrec_convert would do happens, NULL_TREE
    1696              :    otherwise.  This function set TRUE to variable pointed by FOLD_CONVERSIONS
    1697              :    if the result chrec may overflow.  */
    1698              : 
    1699              : tree
    1700      9105914 : chrec_convert_aggressive (tree type, tree chrec, bool *fold_conversions)
    1701              : {
    1702      9105914 :   tree inner_type, left, right, lc, rc, rtype;
    1703              : 
    1704      9105914 :   gcc_assert (fold_conversions != NULL);
    1705              : 
    1706     17698392 :   if (automatically_generated_chrec_p (chrec)
    1707      9105914 :       || TREE_CODE (chrec) != POLYNOMIAL_CHREC)
    1708              :     return NULL_TREE;
    1709              : 
    1710       669685 :   inner_type = TREE_TYPE (chrec);
    1711       669685 :   if (TYPE_PRECISION (type) > TYPE_PRECISION (inner_type))
    1712              :     return NULL_TREE;
    1713              : 
    1714       589110 :   if (useless_type_conversion_p (type, inner_type))
    1715              :     return NULL_TREE;
    1716              : 
    1717       513436 :   if (!*fold_conversions && evolution_function_is_affine_p (chrec))
    1718              :     {
    1719       512626 :       tree base, step;
    1720       512626 :       class loop *loop;
    1721              : 
    1722       512626 :       loop = get_chrec_loop (chrec);
    1723       512626 :       base = CHREC_LEFT (chrec);
    1724       512626 :       step = CHREC_RIGHT (chrec);
    1725       512626 :       if (convert_affine_scev (loop, type, &base, &step, NULL, true))
    1726         2136 :         return build_polynomial_chrec (loop->num, base, step);
    1727              :     }
    1728       511300 :   rtype = POINTER_TYPE_P (type) ? sizetype : type;
    1729              : 
    1730       511300 :   left = CHREC_LEFT (chrec);
    1731       511300 :   right = CHREC_RIGHT (chrec);
    1732       511300 :   lc = chrec_convert_aggressive (type, left, fold_conversions);
    1733       511300 :   if (!lc)
    1734       511300 :     lc = chrec_convert (type, left, NULL);
    1735       511300 :   rc = chrec_convert_aggressive (rtype, right, fold_conversions);
    1736       511300 :   if (!rc)
    1737       510616 :     rc = chrec_convert (rtype, right, NULL);
    1738              : 
    1739       511300 :   *fold_conversions = true;
    1740              : 
    1741       511300 :   return build_polynomial_chrec (CHREC_VARIABLE (chrec), lc, rc);
    1742              : }
    1743              : 
    1744              : /* Returns true when CHREC0 == CHREC1.  */
    1745              : 
    1746              : bool
    1747     13452528 : eq_evolutions_p (const_tree chrec0, const_tree chrec1)
    1748              : {
    1749     13485326 :   if (chrec0 == NULL_TREE
    1750     13485326 :       || chrec1 == NULL_TREE
    1751     13485326 :       || TREE_CODE (chrec0) != TREE_CODE (chrec1))
    1752              :     return false;
    1753              : 
    1754     12573249 :   if (operand_equal_p (chrec0, chrec1, 0))
    1755              :     return true;
    1756              : 
    1757      9383333 :   if (! types_compatible_p (TREE_TYPE (chrec0), TREE_TYPE (chrec1)))
    1758              :     return false;
    1759              : 
    1760      9382114 :   switch (TREE_CODE (chrec0))
    1761              :     {
    1762      3881912 :     case POLYNOMIAL_CHREC:
    1763      3881912 :       return (CHREC_VARIABLE (chrec0) == CHREC_VARIABLE (chrec1)
    1764      3881575 :               && eq_evolutions_p (CHREC_LEFT (chrec0), CHREC_LEFT (chrec1))
    1765      4214531 :               && eq_evolutions_p (CHREC_RIGHT (chrec0), CHREC_RIGHT (chrec1)));
    1766              : 
    1767        54916 :     case PLUS_EXPR:
    1768        54916 :     case MULT_EXPR:
    1769        54916 :     case MINUS_EXPR:
    1770        54916 :     case POINTER_PLUS_EXPR:
    1771        54916 :       return eq_evolutions_p (TREE_OPERAND (chrec0, 0),
    1772        54916 :                               TREE_OPERAND (chrec1, 0))
    1773        95857 :           && eq_evolutions_p (TREE_OPERAND (chrec0, 1),
    1774        40941 :                               TREE_OPERAND (chrec1, 1));
    1775              : 
    1776        32798 :     CASE_CONVERT:
    1777        32798 :       return eq_evolutions_p (TREE_OPERAND (chrec0, 0),
    1778        65596 :                               TREE_OPERAND (chrec1, 0));
    1779              : 
    1780              :     default:
    1781              :       return false;
    1782              :     }
    1783              : }
    1784              : 
    1785              : /* Returns EV_GROWS if CHREC grows (assuming that it does not overflow),
    1786              :    EV_DECREASES if it decreases, and EV_UNKNOWN if we cannot determine
    1787              :    which of these cases happens.  */
    1788              : 
    1789              : enum ev_direction
    1790      2536431 : scev_direction (const_tree chrec)
    1791              : {
    1792      2536431 :   const_tree step;
    1793              : 
    1794      2536431 :   if (!evolution_function_is_affine_p (chrec))
    1795              :     return EV_DIR_UNKNOWN;
    1796              : 
    1797      2532511 :   step = CHREC_RIGHT (chrec);
    1798      2532511 :   if (TREE_CODE (step) != INTEGER_CST)
    1799              :     return EV_DIR_UNKNOWN;
    1800              : 
    1801      2444978 :   if (tree_int_cst_sign_bit (step))
    1802              :     return EV_DIR_DECREASES;
    1803              :   else
    1804      2179618 :     return EV_DIR_GROWS;
    1805              : }
    1806              : 
    1807              : /* Iterates over all the components of SCEV, and calls CBCK.  */
    1808              : 
    1809              : void
    1810            0 : for_each_scev_op (tree *scev, bool (*cbck) (tree *, void *), void *data)
    1811              : {
    1812            0 :   switch (TREE_CODE_LENGTH (TREE_CODE (*scev)))
    1813              :     {
    1814            0 :     case 3:
    1815            0 :       for_each_scev_op (&TREE_OPERAND (*scev, 2), cbck, data);
    1816              :       /* FALLTHRU */
    1817              : 
    1818            0 :     case 2:
    1819            0 :       for_each_scev_op (&TREE_OPERAND (*scev, 1), cbck, data);
    1820              :       /* FALLTHRU */
    1821              : 
    1822            0 :     case 1:
    1823            0 :       for_each_scev_op (&TREE_OPERAND (*scev, 0), cbck, data);
    1824              :       /* FALLTHRU */
    1825              : 
    1826            0 :     default:
    1827            0 :       cbck (scev, data);
    1828            0 :       break;
    1829              :     }
    1830            0 : }
    1831              : 
    1832              : /* Returns true when the operation can be part of a linear
    1833              :    expression.  */
    1834              : 
    1835              : static inline bool
    1836        34023 : operator_is_linear (tree scev)
    1837              : {
    1838        34023 :   switch (TREE_CODE (scev))
    1839              :     {
    1840              :     case INTEGER_CST:
    1841              :     case POLYNOMIAL_CHREC:
    1842              :     case PLUS_EXPR:
    1843              :     case POINTER_PLUS_EXPR:
    1844              :     case MULT_EXPR:
    1845              :     case MINUS_EXPR:
    1846              :     case NEGATE_EXPR:
    1847              :     case SSA_NAME:
    1848              :     case NON_LVALUE_EXPR:
    1849              :     case BIT_NOT_EXPR:
    1850              :     CASE_CONVERT:
    1851              :       return true;
    1852              : 
    1853            8 :     default:
    1854            8 :       return false;
    1855              :     }
    1856              : }
    1857              : 
    1858              : /* Return true when SCEV is a linear expression.  Linear expressions
    1859              :    can contain additions, substractions and multiplications.
    1860              :    Multiplications are restricted to constant scaling: "cst * x".  */
    1861              : 
    1862              : bool
    1863        77887 : scev_is_linear_expression (tree scev)
    1864              : {
    1865       160326 :   if (evolution_function_is_constant_p (scev))
    1866              :     return true;
    1867              : 
    1868        34023 :   if (scev == NULL
    1869        34023 :       || !operator_is_linear (scev))
    1870              :     return false;
    1871              : 
    1872        34015 :   if (TREE_CODE (scev) == MULT_EXPR)
    1873          601 :     return !(tree_contains_chrecs (TREE_OPERAND (scev, 0), NULL)
    1874            0 :              && tree_contains_chrecs (TREE_OPERAND (scev, 1), NULL));
    1875              : 
    1876        33414 :   if (TREE_CODE (scev) == POLYNOMIAL_CHREC
    1877        33414 :       && !evolution_function_is_affine_multivariate_p (scev, CHREC_VARIABLE (scev)))
    1878              :     return false;
    1879              : 
    1880        33214 :   switch (TREE_CODE_LENGTH (TREE_CODE (scev)))
    1881              :     {
    1882            0 :     case 3:
    1883            0 :       return scev_is_linear_expression (TREE_OPERAND (scev, 0))
    1884            0 :         && scev_is_linear_expression (TREE_OPERAND (scev, 1))
    1885            0 :         && scev_is_linear_expression (TREE_OPERAND (scev, 2));
    1886              : 
    1887        24464 :     case 2:
    1888        24464 :       return scev_is_linear_expression (TREE_OPERAND (scev, 0))
    1889        24464 :         && scev_is_linear_expression (TREE_OPERAND (scev, 1));
    1890              : 
    1891         2276 :     case 1:
    1892         2276 :       return scev_is_linear_expression (TREE_OPERAND (scev, 0));
    1893              : 
    1894              :     case 0:
    1895              :       return true;
    1896              : 
    1897              :     default:
    1898              :       return false;
    1899              :     }
    1900              : }
    1901              : 
    1902              : /* Determines whether the expression CHREC contains only integer consts
    1903              :    in the right parts.  */
    1904              : 
    1905              : bool
    1906         4315 : evolution_function_right_is_integer_cst (const_tree chrec)
    1907              : {
    1908         4315 :   if (chrec == NULL_TREE)
    1909              :     return false;
    1910              : 
    1911         4315 :   switch (TREE_CODE (chrec))
    1912              :     {
    1913              :     case INTEGER_CST:
    1914              :       return true;
    1915              : 
    1916         4315 :     case POLYNOMIAL_CHREC:
    1917         4315 :       return TREE_CODE (CHREC_RIGHT (chrec)) == INTEGER_CST
    1918         4315 :         && (TREE_CODE (CHREC_LEFT (chrec)) != POLYNOMIAL_CHREC
    1919          470 :             || evolution_function_right_is_integer_cst (CHREC_LEFT (chrec)));
    1920              : 
    1921            0 :     CASE_CONVERT:
    1922            0 :       return evolution_function_right_is_integer_cst (TREE_OPERAND (chrec, 0));
    1923              : 
    1924              :     default:
    1925              :       return false;
    1926              :     }
    1927              : }
        

Generated by: LCOV version 2.4-beta

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.