GCC Middle and Back End API Reference
tree-chrec.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "tree.h"
#include "gimple-expr.h"
#include "tree-pretty-print.h"
#include "fold-const.h"
#include "cfgloop.h"
#include "tree-ssa-loop-ivopts.h"
#include "tree-ssa-loop-niter.h"
#include "tree-chrec.h"
#include "gimple.h"
#include "tree-ssa-loop.h"
#include "dumpfile.h"
#include "tree-scalar-evolution.h"
Include dependency graph for tree-chrec.cc:

Functions

static tree chrec_fold_plus_poly_poly (enum tree_code code, tree type, tree poly0, tree poly1)
 
static tree chrec_fold_multiply_poly_poly (tree type, tree poly0, tree poly1)
 
static tree chrec_fold_automatically_generated_operands (tree op0, tree op1)
 
static tree chrec_fold_plus_1 (enum tree_code code, tree type, tree op0, tree op1)
 
tree chrec_fold_plus (tree type, tree op0, tree op1)
 
tree chrec_fold_minus (tree type, tree op0, tree op1)
 
tree chrec_fold_multiply (tree type, tree op0, tree op1)
 
static tree tree_fold_binomial (tree type, tree n, unsigned int k)
 
static tree chrec_evaluate (unsigned var, tree chrec, tree n, unsigned int k)
 
tree chrec_apply (unsigned var, tree chrec, tree x)
 
tree chrec_apply_map (tree chrec, vec< tree > iv_map)
 
tree chrec_replace_initial_condition (tree chrec, tree init_cond)
 
tree initial_condition (tree chrec)
 
tree hide_evolution_in_other_loops_than_loop (tree chrec, unsigned loop_num)
 
static tree chrec_component_in_loop_num (tree chrec, unsigned loop_num, bool right)
 
tree evolution_part_in_loop_num (tree chrec, unsigned loop_num)
 
tree initial_condition_in_loop_num (tree chrec, unsigned loop_num)
 
tree reset_evolution_in_loop (unsigned loop_num, tree chrec, tree new_evol)
 
tree chrec_merge (tree chrec1, tree chrec2)
 
static bool is_multivariate_chrec_rec (const_tree chrec, unsigned int rec_var)
 
bool is_multivariate_chrec (const_tree chrec)
 
static bool chrec_contains_symbols (const_tree chrec, hash_set< const_tree > &visited, class loop *loop)
 
bool chrec_contains_symbols (const_tree chrec, class loop *loop)
 
static bool chrec_contains_symbols_defined_in_loop (const_tree chrec, unsigned loop_nb, hash_set< const_tree > &visited)
 
bool chrec_contains_symbols_defined_in_loop (const_tree chrec, unsigned loop_nb)
 
static bool chrec_contains_undetermined (const_tree chrec, hash_set< const_tree > &visited)
 
bool chrec_contains_undetermined (const_tree chrec)
 
static bool tree_contains_chrecs (const_tree expr, int *size, hash_set< const_tree > &visited)
 
bool tree_contains_chrecs (const_tree expr, int *size)
 
static bool evolution_function_is_invariant_rec_p (tree chrec, int loopnum)
 
bool evolution_function_is_invariant_p (tree chrec, int loopnum)
 
bool evolution_function_is_affine_multivariate_p (const_tree chrec, int loopnum)
 
bool evolution_function_is_univariate_p (const_tree chrec, int loopnum)
 
unsigned nb_vars_in_chrec (tree chrec)
 
bool convert_affine_scev (class loop *loop, tree type, tree *base, tree *step, gimple *at_stmt, bool use_overflow_semantics, tree from)
 
tree chrec_convert_rhs (tree type, tree chrec, gimple *at_stmt)
 
static tree chrec_convert_1 (tree type, tree chrec, gimple *at_stmt, bool use_overflow_semantics, tree from)
 
tree chrec_convert (tree type, tree chrec, gimple *at_stmt, bool use_overflow_semantics, tree from)
 
tree chrec_convert_aggressive (tree type, tree chrec, bool *fold_conversions)
 
bool eq_evolutions_p (const_tree chrec0, const_tree chrec1)
 
enum ev_direction scev_direction (const_tree chrec)
 
void for_each_scev_op (tree *scev, bool(*cbck)(tree *, void *), void *data)
 
static bool operator_is_linear (tree scev)
 
bool scev_is_linear_expression (tree scev)
 
bool evolution_function_right_is_integer_cst (const_tree chrec)
 

Function Documentation

◆ chrec_apply()

◆ chrec_apply_map()

tree chrec_apply_map ( tree chrec,
vec< tree > iv_map )
For a given CHREC and an induction variable map IV_MAP that maps
(loop->num, expr) for every loop number of the current_loops an
expression, calls chrec_apply when the expression is not NULL.   

References chrec_apply(), expr, FOR_EACH_VEC_ELT, ggc_alloc(), and i.

◆ chrec_component_in_loop_num()

static tree chrec_component_in_loop_num ( tree chrec,
unsigned loop_num,
bool right )
static

◆ chrec_contains_symbols() [1/2]

bool chrec_contains_symbols ( const_tree chrec,
class loop * loop )
Return true if CHREC contains any symbols.  If LOOP is not NULL, check if
CHREC contains any chrec which is invariant wrto the loop (nest), in other
words, chrec defined by outer loops of loop, so from LOOP's point of view,
the chrec is considered as a SYMBOL.   

References chrec_contains_symbols(), and visited.

◆ chrec_contains_symbols() [2/2]

static bool chrec_contains_symbols ( const_tree chrec,
hash_set< const_tree > & visited,
class loop * loop )
static

◆ chrec_contains_symbols_defined_in_loop() [1/2]

bool chrec_contains_symbols_defined_in_loop ( const_tree chrec,
unsigned loop_nb )
Return true when CHREC contains symbolic names defined in
LOOP_NB.   

References chrec_contains_symbols_defined_in_loop(), ggc_alloc(), and visited.

Referenced by no_evolution_in_loop_p().

◆ chrec_contains_symbols_defined_in_loop() [2/2]

◆ chrec_contains_undetermined() [1/2]

bool chrec_contains_undetermined ( const_tree chrec)

◆ chrec_contains_undetermined() [2/2]

◆ chrec_convert()

tree chrec_convert ( tree type,
tree chrec,
gimple * at_stmt,
bool use_overflow_semantics,
tree from )
Convert CHREC to TYPE.  When the analyzer knows the context in
which the CHREC is built, it sets AT_STMT to the statement that
contains the definition of the analyzed variable, otherwise the
conversion is less accurate: the information is used for
determining a more accurate estimation of the number of iterations.
By default AT_STMT could be safely set to NULL_TREE.

The following rule is always true: TREE_TYPE (chrec) ==
TREE_TYPE (CHREC_LEFT (chrec)) == TREE_TYPE (CHREC_RIGHT (chrec)).
An example of what could happen when adding two chrecs and the type
of the CHREC_RIGHT is different than CHREC_LEFT is:

{(uint) 0, +, (uchar) 10} +
{(uint) 0, +, (uchar) 250}

that would produce a wrong result if CHREC_RIGHT is not (uint):

{(uint) 0, +, (uchar) 4}

instead of

{(uint) 0, +, (uint) 260}

USE_OVERFLOW_SEMANTICS is true if this function should assume that
the rules for overflow of the given language apply (e.g., that signed
arithmetics in C does not overflow) -- i.e., to use them to avoid
unnecessary tests, but also to enforce that the result follows them.

FROM is the source variable converted if it's not NULL.   

References chrec_convert_1(), and ggc_alloc().

Referenced by scev_dfs::add_to_evolution_1(), analyze_miv_subscript(), analyze_siv_subscript_cst_affine(), analyze_ziv_subscript(), can_use_analyze_subscript_affine_affine(), chrec_apply(), chrec_convert_aggressive(), chrec_convert_rhs(), chrec_evaluate(), chrec_fold_multiply(), chrec_fold_plus(), chrec_fold_plus_1(), convert_affine_scev(), scev_dfs::follow_ssa_edge_binary(), scev_dfs::follow_ssa_edge_expr(), initialize_matrix_A(), instantiate_scev_binary(), instantiate_scev_convert(), instantiate_scev_not(), and interpret_rhs_expr().

◆ chrec_convert_1()

static tree chrec_convert_1 ( tree type,
tree chrec,
gimple * at_stmt,
bool use_overflow_semantics,
tree from )
static
Convert CHREC to TYPE.  When the analyzer knows the context in
which the CHREC is built, it sets AT_STMT to the statement that
contains the definition of the analyzed variable, otherwise the
conversion is less accurate: the information is used for
determining a more accurate estimation of the number of iterations.
By default AT_STMT could be safely set to NULL_TREE.

USE_OVERFLOW_SEMANTICS is true if this function should assume that
the rules for overflow of the given language apply (e.g., that signed
arithmetics in C does not overflow) -- i.e., to use them to avoid
unnecessary tests, but also to enforce that the result follows them.

FROM is the source variable converted if it's not NULL.   

References automatically_generated_chrec_p(), build_polynomial_chrec(), chrec_convert_1(), chrec_dont_know, CHREC_LEFT, CHREC_RIGHT, chrec_type(), CHREC_VARIABLE, CONSTANT_CLASS_P, convert_affine_scev(), evolution_function_is_affine_p(), fold_build2, fold_convert, get_chrec_loop(), ggc_alloc(), int_fits_type_p(), loop::num, TREE_CODE, TREE_OPERAND, TREE_OVERFLOW, TYPE_OVERFLOW_UNDEFINED, TYPE_PRECISION, unsigned_type_for(), and useless_type_conversion_p().

Referenced by chrec_convert(), and chrec_convert_1().

◆ chrec_convert_aggressive()

tree chrec_convert_aggressive ( tree type,
tree chrec,
bool * fold_conversions )
Convert CHREC to TYPE, without regard to signed overflows.  Returns the new
chrec if something else than what chrec_convert would do happens, NULL_TREE
otherwise.  This function set TRUE to variable pointed by FOLD_CONVERSIONS
if the result chrec may overflow.   

References automatically_generated_chrec_p(), build_polynomial_chrec(), chrec_convert(), chrec_convert_aggressive(), CHREC_LEFT, CHREC_RIGHT, CHREC_VARIABLE, convert_affine_scev(), evolution_function_is_affine_p(), gcc_assert, get_chrec_loop(), ggc_alloc(), NULL, NULL_TREE, loop::num, POINTER_TYPE_P, sizetype, TREE_CODE, TREE_TYPE, type(), TYPE_PRECISION, and useless_type_conversion_p().

Referenced by chrec_convert_aggressive(), and instantiate_scev_convert().

◆ chrec_convert_rhs()

tree chrec_convert_rhs ( tree type,
tree chrec,
gimple * at_stmt )
Convert CHREC for the right hand side of a CHREC.
The increment for a pointer type is always sizetype.   

References chrec_convert(), ggc_alloc(), POINTER_TYPE_P, and sizetype.

Referenced by scev_dfs::add_to_evolution_1(), chrec_apply(), chrec_fold_multiply(), instantiate_scev_binary(), and instantiate_scev_poly().

◆ chrec_evaluate()

static tree chrec_evaluate ( unsigned var,
tree chrec,
tree n,
unsigned int k )
static
Helper function.  Use the Newton's interpolating formula for
evaluating the value of the evolution function.
The result may be in an unsigned type of CHREC.   

References cfun, chrec_convert(), chrec_dont_know, chrec_evaluate(), chrec_fold_plus(), CHREC_LEFT, CHREC_RIGHT, CHREC_VARIABLE, flow_loop_nested_p(), fold_build2, get_chrec_loop(), get_loop(), ggc_alloc(), INTEGRAL_TYPE_P, NULL, TREE_CODE, tree_fold_binomial(), TREE_TYPE, type(), TYPE_OVERFLOW_WRAPS, and unsigned_type_for().

Referenced by chrec_apply(), and chrec_evaluate().

◆ chrec_fold_automatically_generated_operands()

static tree chrec_fold_automatically_generated_operands ( tree op0,
tree op1 )
inlinestatic
When the operands are automatically_generated_chrec_p, the fold has
to respect the semantics of the operands.   

References chrec_dont_know, chrec_known, and chrec_not_analyzed_yet.

Referenced by chrec_fold_minus(), chrec_fold_multiply(), chrec_fold_plus(), and chrec_fold_plus_1().

◆ chrec_fold_minus()

◆ chrec_fold_multiply()

◆ chrec_fold_multiply_poly_poly()

◆ chrec_fold_plus()

◆ chrec_fold_plus_1()

◆ chrec_fold_plus_poly_poly()

static tree chrec_fold_plus_poly_poly ( enum tree_code code,
tree type,
tree poly0,
tree poly1 )
inlinestatic
Chains of recurrences.
   Copyright (C) 2003-2024 Free Software Foundation, Inc.
   Contributed by Sebastian Pop <pop@cri.ensmp.fr>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.   
This file implements operations on chains of recurrences.  Chains
  of recurrences are used for modeling evolution functions of scalar
  variables.
Extended folder for chrecs.   
Fold the addition of two polynomial functions.   

References build_int_cst_type(), build_polynomial_chrec(), build_real(), chrec_dont_know, chrec_fold_minus(), chrec_fold_multiply(), chrec_fold_plus(), CHREC_LEFT, CHREC_RIGHT, chrec_type(), CHREC_VARIABLE, chrec_zerop(), dconstm1, flow_loop_nested_p(), gcc_assert, gcc_checking_assert, get_chrec_loop(), ggc_alloc(), LOOP_CLOSED_SSA, loops_state_satisfies_p(), POINTER_TYPE_P, ptrofftype_p(), SCALAR_FLOAT_TYPE_P, TREE_CODE, type(), and useless_type_conversion_p().

Referenced by chrec_fold_plus_1().

◆ chrec_merge()

tree chrec_merge ( tree chrec1,
tree chrec2 )
Merges two evolution functions that were found by following two
alternate paths of a conditional expression.   

References chrec_dont_know, chrec_known, chrec_not_analyzed_yet, eq_evolutions_p(), and ggc_alloc().

Referenced by analyze_evolution_in_loop(), analyze_initial_condition(), scev_dfs::follow_ssa_edge_in_condition_phi(), and interpret_condition_phi().

◆ chrec_replace_initial_condition()

tree chrec_replace_initial_condition ( tree chrec,
tree init_cond )

◆ convert_affine_scev()

bool convert_affine_scev ( class loop * loop,
tree type,
tree * base,
tree * step,
gimple * at_stmt,
bool use_overflow_semantics,
tree from )
Converts BASE and STEP of affine scev to TYPE.  LOOP is the loop whose iv
the scev corresponds to.  AT_STMT is the statement at that the scev is
evaluated.  USE_OVERFLOW_SEMANTICS is true if this function should assume
that the rules for overflow of the given language apply (e.g., that signed
arithmetics in C does not overflow) -- i.e., to use them to avoid
unnecessary tests, but also to enforce that the result follows them.
FROM is the source variable converted if it's not NULL.  Returns true if
the conversion succeeded, false otherwise.   

References automatically_generated_chrec_p(), build_nonstandard_integer_type(), chrec_convert(), ggc_alloc(), nowrap_type_p(), NULL_TREE, POINTER_TYPE_P, scev_probably_wraps_p(), sizetype, TREE_TYPE, type(), TYPE_PRECISION, and TYPE_UNSIGNED.

Referenced by chrec_convert_1(), chrec_convert_aggressive(), and idx_find_step().

◆ eq_evolutions_p()

◆ evolution_function_is_affine_multivariate_p()

◆ evolution_function_is_invariant_p()

bool evolution_function_is_invariant_p ( tree chrec,
int loopnum )

◆ evolution_function_is_invariant_rec_p()

◆ evolution_function_is_univariate_p()

bool evolution_function_is_univariate_p ( const_tree chrec,
int loopnum )
Determine whether the given tree is a function in zero or one
variables with respect to loop specified by LOOPNUM.  Note only positive
LOOPNUM stands for a real loop.   

References cfun, CHREC_LEFT, CHREC_RIGHT, CHREC_VARIABLE, evolution_function_is_univariate_p(), flow_loop_nested_p(), get_chrec_loop(), get_loop(), ggc_alloc(), NULL, NULL_TREE, TREE_CODE, and tree_contains_chrecs().

Referenced by add_other_self_distances(), evolution_function_is_univariate_p(), and siv_subscript_p().

◆ evolution_function_right_is_integer_cst()

bool evolution_function_right_is_integer_cst ( const_tree chrec)
Determines whether the expression CHREC contains only interger consts
in the right parts.   

References CASE_CONVERT, CHREC_LEFT, CHREC_RIGHT, evolution_function_right_is_integer_cst(), ggc_alloc(), NULL_TREE, TREE_CODE, and TREE_OPERAND.

Referenced by evolution_function_right_is_integer_cst().

◆ evolution_part_in_loop_num()

tree evolution_part_in_loop_num ( tree chrec,
unsigned loop_num )
Returns the evolution part in LOOP_NUM.  Example: the call
evolution_part_in_loop_num ({{0, +, 1}_1, +, 2}_1, 1) returns
{1, +, 2}_1   

References chrec_component_in_loop_num().

Referenced by get_scev_info(), idx_infer_loop_bounds(), idx_within_array_bound(), infer_loop_bounds_from_pointer_arith(), infer_loop_bounds_from_signedness(), vect_analyze_scalar_cycles_1(), and vect_is_simple_iv_evolution().

◆ for_each_scev_op()

void for_each_scev_op ( tree * scev,
bool(*)(tree *, void *) cbck,
void * data )
Iterates over all the components of SCEV, and calls CBCK.   

References for_each_scev_op(), ggc_alloc(), TREE_CODE, TREE_CODE_LENGTH, and TREE_OPERAND.

Referenced by for_each_scev_op().

◆ hide_evolution_in_other_loops_than_loop()

tree hide_evolution_in_other_loops_than_loop ( tree chrec,
unsigned loop_num )

◆ initial_condition()

◆ initial_condition_in_loop_num()

tree initial_condition_in_loop_num ( tree chrec,
unsigned loop_num )
Returns the initial condition in LOOP_NUM.  Example: the call
initial_condition_in_loop_num ({{0, +, 1}_1, +, 2}_2, 2) returns
{0, +, 1}_1   

References chrec_component_in_loop_num().

Referenced by get_scev_info(), idx_infer_loop_bounds(), infer_loop_bounds_from_pointer_arith(), infer_loop_bounds_from_signedness(), nb_vars_in_chrec(), vect_analyze_scalar_cycles_1(), and vect_is_simple_iv_evolution().

◆ is_multivariate_chrec()

bool is_multivariate_chrec ( const_tree chrec)
Determine whether the given chrec is multivariate or not.   

References CHREC_LEFT, CHREC_RIGHT, CHREC_VARIABLE, ggc_alloc(), is_multivariate_chrec_rec(), NULL_TREE, and TREE_CODE.

◆ is_multivariate_chrec_rec()

static bool is_multivariate_chrec_rec ( const_tree chrec,
unsigned int rec_var )
static
Observers.   
Helper function for is_multivariate_chrec.   

References CHREC_LEFT, CHREC_RIGHT, CHREC_VARIABLE, ggc_alloc(), is_multivariate_chrec_rec(), NULL_TREE, and TREE_CODE.

Referenced by is_multivariate_chrec(), and is_multivariate_chrec_rec().

◆ nb_vars_in_chrec()

unsigned nb_vars_in_chrec ( tree chrec)
Returns the number of variables of CHREC.  Example: the call
nb_vars_in_chrec ({{0, +, 1}_5, +, 2}_6) returns 2.   

References CHREC_VARIABLE, ggc_alloc(), initial_condition_in_loop_num(), nb_vars_in_chrec(), NULL_TREE, and TREE_CODE.

Referenced by analyze_subscript_affine_affine(), and nb_vars_in_chrec().

◆ operator_is_linear()

static bool operator_is_linear ( tree scev)
inlinestatic
Returns true when the operation can be part of a linear
expression.   

References CASE_CONVERT, ggc_alloc(), and TREE_CODE.

Referenced by scev_is_linear_expression().

◆ reset_evolution_in_loop()

tree reset_evolution_in_loop ( unsigned loop_num,
tree chrec,
tree new_evol )
Set or reset the evolution of CHREC to NEW_EVOL in loop LOOP_NUM.
This function is essentially used for setting the evolution to
chrec_dont_know, for example after having determined that it is
impossible to say how many times a loop will execute.   

References build_polynomial_chrec(), cfun, CHREC_LEFT, CHREC_RIGHT, chrec_type(), CHREC_VARIABLE, flow_loop_nested_p(), gcc_assert, get_chrec_loop(), get_loop(), ggc_alloc(), POINTER_TYPE_P, ptrofftype_p(), reset_evolution_in_loop(), and TREE_CODE.

Referenced by reset_evolution_in_loop().

◆ scev_direction()

enum ev_direction scev_direction ( const_tree chrec)
Returns EV_GROWS if CHREC grows (assuming that it does not overflow),
EV_DECREASES if it decreases, and EV_UNKNOWN if we cannot determine
which of these cases happens.   

References CHREC_RIGHT, EV_DIR_DECREASES, EV_DIR_GROWS, EV_DIR_UNKNOWN, evolution_function_is_affine_p(), ggc_alloc(), TREE_CODE, and tree_int_cst_sign_bit().

Referenced by compute_access_range(), and get_scev_info().

◆ scev_is_linear_expression()

bool scev_is_linear_expression ( tree scev)
Return true when SCEV is a linear expression.  Linear expressions
can contain additions, substractions and multiplications.
Multiplications are restricted to constant scaling: "cst * x".   

References CHREC_VARIABLE, evolution_function_is_affine_multivariate_p(), evolution_function_is_constant_p(), ggc_alloc(), NULL, operator_is_linear(), scev_is_linear_expression(), TREE_CODE, TREE_CODE_LENGTH, tree_contains_chrecs(), and TREE_OPERAND.

Referenced by scev_analyzable_p(), and scev_is_linear_expression().

◆ tree_contains_chrecs() [1/2]

bool tree_contains_chrecs ( const_tree expr,
int * size )

◆ tree_contains_chrecs() [2/2]

◆ tree_fold_binomial()

static tree tree_fold_binomial ( tree type,
tree n,
unsigned int k )
static
Operations.   
Evaluate the binomial coefficient.  Return NULL_TREE if the intermediate
calculation overflows, otherwise return C(n,k) with type TYPE.   

References build_int_cst(), wi::fits_to_tree_p(), fold_convert, ggc_alloc(), i, wi::ltu_p(), NULL_TREE, loop::num, wi::smul(), wi::to_widest(), wi::udiv_trunc(), and wide_int_to_tree().

Referenced by chrec_evaluate().