LCOV - code coverage report
Current view: top level - gcc - tree-chrec.h (source / functions) Coverage Total Hit
Test: gcc.info Lines: 83.6 % 67 56
Test Date: 2026-02-28 14:20:25 Functions: 85.7 % 7 6
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              : #ifndef GCC_TREE_CHREC_H
      22              : #define GCC_TREE_CHREC_H
      23              : 
      24              : /* The following trees are unique elements.  Thus the comparison of another
      25              :    element to these elements should be done on the pointer to these trees,
      26              :    and not on their value.
      27              : 
      28              :    extern tree chrec_not_analyzed_yet;
      29              :    extern tree chrec_dont_know;
      30              :    extern tree chrec_known;
      31              : 
      32              :    chrec_not_analyzed_yet is NULL_TREE and the others are defined
      33              :    in global_trees[].  */
      34              : 
      35              : /* After having added an automatically generated element, please
      36              :    include it in the following function.  */
      37              : 
      38              : inline bool
      39   1512006734 : automatically_generated_chrec_p (const_tree chrec)
      40              : {
      41   1512006734 :   return (chrec == chrec_dont_know
      42   1417038551 :           || chrec == chrec_known);
      43              : }
      44              : 
      45              : /* The tree nodes aka. CHRECs.  */
      46              : 
      47              : inline bool
      48    482111880 : tree_is_chrec (const_tree expr)
      49              : {
      50    482111880 :   if (TREE_CODE (expr) == POLYNOMIAL_CHREC
      51    953625882 :       || automatically_generated_chrec_p (expr))
      52            0 :     return true;
      53              :   else
      54              :     return false;
      55              : }
      56              : 
      57              : 
      58              : enum ev_direction {EV_DIR_GROWS, EV_DIR_DECREASES, EV_DIR_UNKNOWN};
      59              : enum ev_direction scev_direction (const_tree);
      60              : 
      61              : /* Chrec folding functions.  */
      62              : extern tree chrec_fold_plus (tree, tree, tree);
      63              : extern tree chrec_fold_minus (tree, tree, tree);
      64              : extern tree chrec_fold_multiply (tree, tree, tree);
      65              : extern tree chrec_convert (tree, tree, gimple *, bool = true, tree = NULL);
      66              : extern tree chrec_convert_rhs (tree, tree, gimple * = NULL);
      67              : extern tree chrec_convert_aggressive (tree, tree, bool *);
      68              : 
      69              : /* Operations.  */
      70              : extern tree chrec_apply (unsigned, tree, tree);
      71              : extern tree chrec_apply_map (tree, vec<tree> );
      72              : extern tree chrec_replace_initial_condition (tree, tree);
      73              : extern tree initial_condition (tree);
      74              : extern tree initial_condition_in_loop_num (tree, unsigned);
      75              : extern tree evolution_part_in_loop_num (tree, unsigned);
      76              : extern tree hide_evolution_in_other_loops_than_loop (tree, unsigned);
      77              : extern tree reset_evolution_in_loop (unsigned, tree, tree);
      78              : extern tree chrec_merge (tree, tree);
      79              : extern void for_each_scev_op (tree *, bool (*) (tree *, void *), void *);
      80              : extern bool convert_affine_scev (class loop *, tree, tree *, tree *, gimple *,
      81              :                                  bool, tree = NULL);
      82              : 
      83              : /* Observers.  */
      84              : extern bool eq_evolutions_p (const_tree, const_tree);
      85              : extern bool is_multivariate_chrec (const_tree);
      86              : extern bool chrec_contains_symbols (const_tree, class loop * = NULL);
      87              : extern bool chrec_contains_symbols_defined_in_loop (const_tree, unsigned);
      88              : extern bool chrec_contains_undetermined (const_tree);
      89              : extern bool tree_contains_chrecs (const_tree, int *);
      90              : extern bool evolution_function_is_affine_multivariate_p (const_tree, int);
      91              : extern bool evolution_function_is_univariate_p (const_tree, int = 0);
      92              : extern unsigned nb_vars_in_chrec (tree);
      93              : extern bool evolution_function_is_invariant_p (tree, int);
      94              : extern bool scev_is_linear_expression (tree);
      95              : extern bool evolution_function_right_is_integer_cst (const_tree);
      96              : 
      97              : /* Determines whether CHREC is equal to zero.  */
      98              : 
      99              : inline bool
     100     42005737 : chrec_zerop (const_tree chrec)
     101              : {
     102     42005737 :   if (chrec == NULL_TREE)
     103              :     return false;
     104              : 
     105     42005737 :   if (TREE_CODE (chrec) == INTEGER_CST)
     106     36174840 :     return integer_zerop (chrec);
     107              : 
     108              :   return false;
     109              : }
     110              : 
     111              : /* Determines whether CHREC is a loop invariant with respect to LOOP_NUM.
     112              :    Set the result in RES and return true when the property can be computed.  */
     113              : 
     114              : inline bool
     115     52736618 : no_evolution_in_loop_p (tree chrec, unsigned loop_num, bool *res)
     116              : {
     117     52736618 :   tree scev;
     118              : 
     119     52736618 :   if (chrec == chrec_not_analyzed_yet
     120     52736618 :       || chrec == chrec_dont_know
     121    102259910 :       || chrec_contains_symbols_defined_in_loop (chrec, loop_num))
     122      6844914 :     return false;
     123              : 
     124     45891704 :   STRIP_NOPS (chrec);
     125     45891704 :   scev = hide_evolution_in_other_loops_than_loop (chrec, loop_num);
     126     45891704 :   *res = !tree_contains_chrecs (scev, NULL);
     127     45891704 :   return true;
     128              : }
     129              : 
     130              : /* Build a polynomial chain of recurrence.  */
     131              : 
     132              : inline tree
     133     41920439 : build_polynomial_chrec (unsigned loop_num,
     134              :                         tree left,
     135              :                         tree right)
     136              : {
     137     41920439 :   bool val;
     138              : 
     139     41920439 :   if (left == chrec_dont_know
     140     41920368 :       || right == chrec_dont_know)
     141              :     return chrec_dont_know;
     142              : 
     143     41919779 :   if (!no_evolution_in_loop_p (left, loop_num, &val)
     144     41919779 :       || !val)
     145         1537 :     return chrec_dont_know;
     146              : 
     147              :   /* Types of left and right sides of a chrec should be compatible, but
     148              :      pointer CHRECs are special in that the evolution is of ptroff type.  */
     149     41918242 :   if (POINTER_TYPE_P (TREE_TYPE (left)))
     150      8619297 :     gcc_checking_assert (ptrofftype_p (TREE_TYPE (right)));
     151              :   else
     152              :     {
     153              :       /* Pointer types should occur only on the left hand side, i.e. in
     154              :          the base of the chrec, and not in the step.  */
     155     33298945 :       gcc_checking_assert (!POINTER_TYPE_P (TREE_TYPE (right))
     156              :                            && types_compatible_p (TREE_TYPE (left),
     157              :                                                   TREE_TYPE (right)));
     158              :     }
     159              : 
     160     41918242 :   if (chrec_zerop (right))
     161              :     return left;
     162              : 
     163     41918099 :   tree chrec = build2 (POLYNOMIAL_CHREC, TREE_TYPE (left), left, right);
     164     41918099 :   CHREC_VARIABLE (chrec) = loop_num;
     165     41918099 :   return chrec;
     166              : }
     167              : 
     168              : /* Determines whether the expression CHREC is a constant.  */
     169              : 
     170              : inline bool
     171     55697720 : evolution_function_is_constant_p (const_tree chrec)
     172              : {
     173     55697720 :   if (chrec == NULL_TREE)
     174              :     return false;
     175              : 
     176     55697720 :   return is_gimple_min_invariant (chrec);
     177              : }
     178              : 
     179              : /* Determine whether CHREC is an affine evolution function in LOOPNUM.  */
     180              : 
     181              : inline bool
     182      5134612 : evolution_function_is_affine_in_loop (const_tree chrec, int loopnum)
     183              : {
     184      5134612 :   if (chrec == NULL_TREE)
     185              :     return false;
     186              : 
     187      5134612 :   switch (TREE_CODE (chrec))
     188              :     {
     189      5131496 :     case POLYNOMIAL_CHREC:
     190      5131496 :       if (evolution_function_is_invariant_p (CHREC_LEFT (chrec), loopnum)
     191     10259430 :           && evolution_function_is_invariant_p (CHREC_RIGHT (chrec), loopnum))
     192              :         return true;
     193              :       else
     194         3562 :         return false;
     195              : 
     196              :     default:
     197              :       return false;
     198              :     }
     199              : }
     200              : 
     201              : /* Determine whether CHREC is an affine evolution function or not.  */
     202              : 
     203              : inline bool
     204     45646821 : evolution_function_is_affine_p (const_tree chrec)
     205              : {
     206     45646821 :   return chrec
     207     45646821 :     && TREE_CODE (chrec) == POLYNOMIAL_CHREC
     208     10954082 :     && evolution_function_is_invariant_p (CHREC_RIGHT (chrec),
     209     10954082 :                                           CHREC_VARIABLE (chrec))
     210     56555783 :     && (TREE_CODE (CHREC_RIGHT (chrec)) != POLYNOMIAL_CHREC
     211           60 :         || evolution_function_is_affine_p (CHREC_RIGHT (chrec)));
     212              : }
     213              : 
     214              : /* Determines whether EXPR does not contains chrec expressions.  */
     215              : 
     216              : inline bool
     217     36593104 : tree_does_not_contain_chrecs (const_tree expr)
     218              : {
     219     36593104 :   return !tree_contains_chrecs (expr, NULL);
     220              : }
     221              : 
     222              : /* Returns the type of the chrec.  */
     223              : 
     224              : inline tree
     225    210118261 : chrec_type (const_tree chrec)
     226              : {
     227    210118261 :   if (automatically_generated_chrec_p (chrec))
     228              :     return NULL_TREE;
     229              : 
     230    210118261 :   return TREE_TYPE (chrec);
     231              : }
     232              : 
     233              : inline tree
     234            0 : chrec_fold_op (enum tree_code code, tree type, tree op0, tree op1)
     235              : {
     236            0 :   switch (code)
     237              :     {
     238            0 :     case PLUS_EXPR:
     239            0 :       return chrec_fold_plus (type, op0, op1);
     240              : 
     241            0 :     case MINUS_EXPR:
     242            0 :       return chrec_fold_minus (type, op0, op1);
     243              : 
     244            0 :     case MULT_EXPR:
     245            0 :       return chrec_fold_multiply (type, op0, op1);
     246              : 
     247            0 :     default:
     248            0 :       gcc_unreachable ();
     249              :     }
     250              : 
     251              : }
     252              : 
     253              : #endif  /* GCC_TREE_CHREC_H  */
        

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.