GCC Middle and Back End API Reference
tree-scalar-evolution.c File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "hash-table.h"
Include dependency graph for tree-scalar-evolution.c:

Data Structures

struct  scev_info_str
struct  instantiate_cache_entry
struct  instantiate_cache_entry_hasher
struct  instantiate_cache_type
struct  chrec_stats

Typedefs

typedef enum t_bool t_bool

Enumerations

enum  t_bool { t_false, t_true, t_dont_know }

Functions

static tree analyze_scalar_evolution_1 (struct loop *, tree, tree)
static tree analyze_scalar_evolution_for_address_of (struct loop *loop, tree var)
static struct scev_info_strnew_scev_info_str ()
static hashval_t hash_scev_info ()
static int eq_scev_info ()
static void del_scev_info ()
static treefind_var_scev_info ()
bool chrec_contains_symbols_defined_in_loop ()
static bool loop_phi_node_p ()
tree compute_overall_effect_of_inner_loop ()
static void set_scalar_evolution ()
static tree get_scalar_evolution ()
static tree add_to_evolution_1 (unsigned loop_nb, tree chrec_before, tree to_add, gimple at_stmt)
static tree add_to_evolution (unsigned loop_nb, tree chrec_before, enum tree_code code, tree to_add, gimple at_stmt)
gimple get_loop_exit_condition ()
static t_bool follow_ssa_edge (struct loop *loop, gimple, gimple, tree *, int)
static t_bool follow_ssa_edge_binary (struct loop *loop, gimple at_stmt, tree type, tree rhs0, enum tree_code code, tree rhs1, gimple halting_phi, tree *evolution_of_loop, int limit)
static t_bool follow_ssa_edge_expr (struct loop *loop, gimple at_stmt, tree expr, gimple halting_phi, tree *evolution_of_loop, int limit)
static t_bool follow_ssa_edge_in_rhs (struct loop *loop, gimple stmt, gimple halting_phi, tree *evolution_of_loop, int limit)
static bool backedge_phi_arg_p ()
static t_bool follow_ssa_edge_in_condition_phi_branch (int i, struct loop *loop, gimple condition_phi, gimple halting_phi, tree *evolution_of_branch, tree init_cond, int limit)
static t_bool follow_ssa_edge_in_condition_phi (struct loop *loop, gimple condition_phi, gimple halting_phi, tree *evolution_of_loop, int limit)
static t_bool follow_ssa_edge_inner_loop_phi (struct loop *outer_loop, gimple loop_phi_node, gimple halting_phi, tree *evolution_of_loop, int limit)
static tree analyze_evolution_in_loop (gimple loop_phi_node, tree init_cond)
static tree analyze_initial_condition ()
static tree interpret_loop_phi ()
static tree interpret_condition_phi ()
static tree interpret_rhs_expr (struct loop *loop, gimple at_stmt, tree type, tree rhs1, enum tree_code code, tree rhs2)
static tree interpret_expr ()
static tree interpret_gimple_assign ()
static tree compute_scalar_evolution_in_loop (struct loop *wrto_loop, struct loop *def_loop, tree ev)
static tree analyze_scalar_evolution_1 ()
tree analyze_scalar_evolution ()
static tree analyze_scalar_evolution_for_address_of ()
static tree analyze_scalar_evolution_in_loop (struct loop *wrto_loop, struct loop *use_loop, tree version, bool *folded_casts)
static treeget_instantiated_value_entry ()
static tree loop_closed_phi_def ()
static tree instantiate_scev_r (basic_block, struct loop *, struct loop *, tree, bool, instantiate_cache_type &, int)
static tree instantiate_scev_name (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, bool fold_conversions, instantiate_cache_type &cache, int size_expr)
static tree instantiate_scev_poly (basic_block instantiate_below, struct loop *evolution_loop, struct loop *, tree chrec, bool fold_conversions, instantiate_cache_type &cache, int size_expr)
static tree instantiate_scev_binary (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, enum tree_code code, tree type, tree c0, tree c1, bool fold_conversions, instantiate_cache_type &cache, int size_expr)
static tree instantiate_array_ref (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, bool fold_conversions, instantiate_cache_type &cache, int size_expr)
static tree instantiate_scev_convert (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, tree type, tree op, bool fold_conversions, instantiate_cache_type &cache, int size_expr)
static tree instantiate_scev_not (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, enum tree_code code, tree type, tree op, bool fold_conversions, instantiate_cache_type &cache, int size_expr)
static tree instantiate_scev_3 (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, bool fold_conversions, instantiate_cache_type &cache, int size_expr)
static tree instantiate_scev_2 (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, bool fold_conversions, instantiate_cache_type &cache, int size_expr)
static tree instantiate_scev_1 (basic_block instantiate_below, struct loop *evolution_loop, struct loop *inner_loop, tree chrec, bool fold_conversions, instantiate_cache_type &cache, int size_expr)
tree instantiate_scev (basic_block instantiate_below, struct loop *evolution_loop, tree chrec)
tree resolve_mixers ()
tree number_of_latch_executions ()
tree number_of_exit_cond_executions ()
static void reset_chrecs_counters ()
static void dump_chrecs_stats ()
static void gather_chrec_stats ()
static int gather_stats_on_scev_database_1 ()
void gather_stats_on_scev_database ()
static void initialize_scalar_evolutions_analyzer ()
void scev_initialize ()
bool scev_initialized_p ()
void scev_reset_htab ()
void scev_reset ()
bool simple_iv (struct loop *wrto_loop, struct loop *use_loop, tree op, affine_iv *iv, bool allow_nonconstant_step)
void scev_finalize ()
bool expression_expensive_p ()
unsigned int scev_const_prop ()

Variables

static unsigned nb_set_scev = 0
static unsigned nb_get_scev = 0
tree chrec_not_analyzed_yet
tree chrec_dont_know
tree chrec_known
static htab_t scalar_evolution_info
static instantiate_cache_typectbl

Typedef Documentation

typedef enum t_bool t_bool
Depth first search algorithm.   

Enumeration Type Documentation

enum t_bool
Depth first search algorithm.   
Enumerator:
t_false 
t_true 
t_dont_know 

Function Documentation

static tree add_to_evolution ( unsigned  loop_nb,
tree  chrec_before,
enum tree_code  code,
tree  to_add,
gimple  at_stmt 
)
static
Add TO_ADD to the evolution part of CHREC_BEFORE in the dimension
   of LOOP_NB.

   Description (provided for completeness, for those who read code in
   a plane, and for my poor 62 bytes brain that would have forgotten
   all this in the next two or three months):

   The algorithm of translation of programs from the SSA representation
   into the chrecs syntax is based on a pattern matching.  After having
   reconstructed the overall tree expression for a loop, there are only
   two cases that can arise:

   1. a = loop-phi (init, a + expr)
   2. a = loop-phi (init, expr)

   where EXPR is either a scalar constant with respect to the analyzed
   loop (this is a degree 0 polynomial), or an expression containing
   other loop-phi definitions (these are higher degree polynomials).

   Examples:

   1.
   | init = ...
   | loop_1
   |   a = phi (init, a + 5)
   | endloop

   2.
   | inita = ...
   | initb = ...
   | loop_1
   |   a = phi (inita, 2 * b + 3)
   |   b = phi (initb, b + 1)
   | endloop

   For the first case, the semantics of the SSA representation is:

   | a (x) = init + \sum_{j = 0}^{x - 1} expr (j)

   that is, there is a loop index "x" that determines the scalar value
   of the variable during the loop execution.  During the first
   iteration, the value is that of the initial condition INIT, while
   during the subsequent iterations, it is the sum of the initial
   condition with the sum of all the values of EXPR from the initial
   iteration to the before last considered iteration.

   For the second case, the semantics of the SSA program is:

   | a (x) = init, if x = 0;
   |         expr (x - 1), otherwise.

   The second case corresponds to the PEELED_CHREC, whose syntax is
   close to the syntax of a loop-phi-node:

   | phi (init, expr)  vs.  (init, expr)_x

   The proof of the translation algorithm for the first case is a
   proof by structural induction based on the degree of EXPR.

   Degree 0:
   When EXPR is a constant with respect to the analyzed loop, or in
   other words when EXPR is a polynomial of degree 0, the evolution of
   the variable A in the loop is an affine function with an initial
   condition INIT, and a step EXPR.  In order to show this, we start
   from the semantics of the SSA representation:

   f (x) = init + \sum_{j = 0}^{x - 1} expr (j)

   and since "expr (j)" is a constant with respect to "j",

   f (x) = init + x * expr

   Finally, based on the semantics of the pure sum chrecs, by
   identification we get the corresponding chrecs syntax:

   f (x) = init * \binom{x}{0} + expr * \binom{x}{1}
   f (x) -> {init, +, expr}_x

   Higher degree:
   Suppose that EXPR is a polynomial of degree N with respect to the
   analyzed loop_x for which we have already determined that it is
   written under the chrecs syntax:

   | expr (x)  ->  {b_0, +, b_1, +, ..., +, b_{n-1}} (x)

   We start from the semantics of the SSA program:

   | f (x) = init + \sum_{j = 0}^{x - 1} expr (j)
   |
   | f (x) = init + \sum_{j = 0}^{x - 1}
   |                (b_0 * \binom{j}{0} + ... + b_{n-1} * \binom{j}{n-1})
   |
   | f (x) = init + \sum_{j = 0}^{x - 1}
   |                \sum_{k = 0}^{n - 1} (b_k * \binom{j}{k})
   |
   | f (x) = init + \sum_{k = 0}^{n - 1}
   |                (b_k * \sum_{j = 0}^{x - 1} \binom{j}{k})
   |
   | f (x) = init + \sum_{k = 0}^{n - 1}
   |                (b_k * \binom{x}{k + 1})
   |
   | f (x) = init + b_0 * \binom{x}{1} + ...
   |              + b_{n-1} * \binom{x}{n}
   |
   | f (x) = init * \binom{x}{0} + b_0 * \binom{x}{1} + ...
   |                             + b_{n-1} * \binom{x}{n}
   |

   And finally from the definition of the chrecs syntax, we identify:
   | f (x)  ->  {init, +, b_0, +, ..., +, b_{n-1}}_x

   This shows the mechanism that stands behind the add_to_evolution
   function.  An important point is that the use of symbolic
   parameters avoids the need of an analysis schedule.

   Example:

   | inita = ...
   | initb = ...
   | loop_1
   |   a = phi (inita, a + 2 + b)
   |   b = phi (initb, b + 1)
   | endloop

   When analyzing "a", the algorithm keeps "b" symbolically:

   | a  ->  {inita, +, 2 + b}_1

   Then, after instantiation, the analyzer ends on the evolution:

   | a  ->  {inita, +, 2 + initb, +, 1}_1

References add_to_evolution_1(), build_int_cst_type(), build_real(), chrec_dont_know, chrec_fold_multiply(), chrec_type(), dconstm1, dump_file, dump_flags, and print_generic_expr().

Referenced by follow_ssa_edge_binary().

static tree add_to_evolution_1 ( unsigned  loop_nb,
tree  chrec_before,
tree  to_add,
gimple  at_stmt 
)
static
Helper function for add_to_evolution.  Returns the evolution
   function for an assignment of the form "a = b + c", where "a" and
   "b" are on the strongly connected component.  CHREC_BEFORE is the
   information that we already have collected up to this point.
   TO_ADD is the evolution of "c".

   When CHREC_BEFORE has an evolution part in LOOP_NB, add to this
   evolution the expression TO_ADD, otherwise construct an evolution
   part for this loop.   

References build_int_cst(), build_polynomial_chrec(), build_real(), cfun, chrec_convert(), chrec_convert_rhs(), chrec_dont_know, chrec_fold_plus(), chrec_type(), dconst0, flow_loop_nested_p(), get_chrec_loop(), get_loop(), and type().

Referenced by add_to_evolution().

static tree analyze_evolution_in_loop ( gimple  loop_phi_node,
tree  init_cond 
)
static
static tree analyze_initial_condition ( )
static
Given a loop-phi-node, return the initial conditions of the
   variable on entry of the loop.  When the CCP has propagated
   constants into the loop-phi-node, the initial condition is
   instantiated, otherwise the initial condition is kept symbolic.
   This analyzer does not analyze the evolution outside the current
   loop, and leaves this task to the on-demand tree reconstructor.   

References chrec_dont_know, chrec_merge(), chrec_not_analyzed_yet, degenerate_phi_result(), dump_file, dump_flags, flow_bb_inside_loop_p(), gimple_phi_arg_edge(), gimple_phi_num_args(), is_gimple_min_invariant(), loop_containing_stmt(), print_generic_expr(), print_gimple_stmt(), and edge_def::src.

Referenced by interpret_loop_phi().

tree analyze_scalar_evolution ( )
Analyzes and returns the scalar evolution of the ssa_name VAR in
   LOOP.  LOOP is the loop in which the variable is used.

   Example of use: having a pointer VAR to a SSA_NAME node, STMT a
   pointer to the statement that uses this variable, in order to
   determine the evolution function of the variable, use the following
   calls:

   loop_p loop = loop_containing_stmt (stmt);
   tree chrec_with_symbols = analyze_scalar_evolution (loop, var);
   tree chrec_instantiated = instantiate_parameters (loop, chrec_with_symbols);

References analyze_scalar_evolution_1(), block_before_loop(), dump_file, dump_flags, get_scalar_evolution(), loop::num, and print_generic_expr().

Referenced by adjust_range_with_scev(), analyze_scalar_evolution_for_address_of(), analyze_scalar_evolution_in_loop(), dr_analyze_indices(), follow_ssa_edge_inner_loop_phi(), get_initial_def_for_induction(), graphite_can_represent_expr(), idx_infer_loop_bounds(), infer_loop_bounds_from_pointer_arith(), infer_loop_bounds_from_signedness(), instantiate_scev_name(), interpret_condition_phi(), interpret_loop_phi(), interpret_rhs_expr(), predicate_scalar_phi(), scalar_evolution_in_region(), scev_const_prop(), vect_analyze_scalar_cycles_1(), and vrp_var_may_overflow().

static tree analyze_scalar_evolution_1 ( struct loop ,
tree  ,
tree   
)
static
@verbatim Scalar evolution detector.

Copyright (C) 2003-2013 Free Software Foundation, Inc. Contributed by Sebastian Pop s.pop.nosp@m.@lap.nosp@m.oste..nosp@m.net

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/.

Referenced by analyze_scalar_evolution(), analyze_scalar_evolution_1(), and compute_scalar_evolution_in_loop().

static tree analyze_scalar_evolution_for_address_of ( struct loop loop,
tree  var 
)
static

Referenced by interpret_rhs_expr().

static tree analyze_scalar_evolution_for_address_of ( )
static
Analyzes and returns the scalar evolution of VAR address in LOOP.   

References analyze_scalar_evolution().

static tree analyze_scalar_evolution_in_loop ( struct loop wrto_loop,
struct loop use_loop,
tree  version,
bool *  folded_casts 
)
static
Analyze scalar evolution of use of VERSION in USE_LOOP with respect to
   WRTO_LOOP (which should be a superloop of USE_LOOP)

   FOLDED_CASTS is set to true if resolve_mixers used
   chrec_convert_aggressive (TODO -- not really, we are way too conservative
   at the moment in order to keep things simple).

   To illustrate the meaning of USE_LOOP and WRTO_LOOP, consider the following
   example:

   for (i = 0; i < 100; i++)                    -- loop 1
     {
       for (j = 0; j < 100; j++)                -- loop 2
         {
           k1 = i;
           k2 = j;

           use2 (k1, k2);

           for (t = 0; t < 100; t++)            -- loop 3
             use3 (k1, k2);

         }
       use1 (k1, k2);
     }

   Both k1 and k2 are invariants in loop3, thus
     analyze_scalar_evolution_in_loop (loop3, loop3, k1) = k1
     analyze_scalar_evolution_in_loop (loop3, loop3, k2) = k2

   As they are invariant, it does not matter whether we consider their
   usage in loop 3 or loop 2, hence
     analyze_scalar_evolution_in_loop (loop2, loop3, k1) =
       analyze_scalar_evolution_in_loop (loop2, loop2, k1) = i
     analyze_scalar_evolution_in_loop (loop2, loop3, k2) =
       analyze_scalar_evolution_in_loop (loop2, loop2, k2) = [0,+,1]_2

   Similarly for their evolutions with respect to loop 1.  The values of K2
   in the use in loop 2 vary independently on loop 1, thus we cannot express
   the evolution with respect to loop 1:
     analyze_scalar_evolution_in_loop (loop1, loop3, k1) =
       analyze_scalar_evolution_in_loop (loop1, loop2, k1) = [0,+,1]_1
     analyze_scalar_evolution_in_loop (loop1, loop3, k2) =
       analyze_scalar_evolution_in_loop (loop1, loop2, k2) = dont_know

   The value of k2 in the use in loop 1 is known, though:
     analyze_scalar_evolution_in_loop (loop1, loop1, k1) = [0,+,1]_1
     analyze_scalar_evolution_in_loop (loop1, loop1, k2) = 100

References analyze_scalar_evolution(), chrec_dont_know, loop_outer(), no_evolution_in_loop_p(), loop::num, and resolve_mixers().

Referenced by scev_const_prop(), and simple_iv().

static bool backedge_phi_arg_p ( )
static
Checks whether the I-th argument of a PHI comes from a backedge.   

References edge_def::flags, and gimple_phi_arg_edge().

Referenced by follow_ssa_edge_in_condition_phi_branch(), and interpret_condition_phi().

bool chrec_contains_symbols_defined_in_loop ( )
Return true when CHREC contains symbolic names defined in
   LOOP_NB.   

References cfun, chrec_contains_symbols_defined_in_loop(), flow_loop_nested_p(), get_loop(), is_gimple_min_invariant(), and loop_containing_stmt().

tree compute_overall_effect_of_inner_loop ( )
Compute the scalar evolution for EVOLUTION_FN after crossing LOOP.
   In general, in the case of multivariate evolutions we want to get
   the evolution in different loops.  LOOP specifies the level for
   which to get the evolution.

   Example:

   | for (j = 0; j < 100; j++)
   |   {
   |     for (k = 0; k < 100; k++)
   |       {
   |         i = k + j;   - Here the value of i is a function of j, k.
   |       }
   |      ... = i         - Here the value of i is a function of j.
   |   }
   | ... = i              - Here the value of i is a scalar.

   Example:

   | i_0 = ...
   | loop_1 10 times
   |   i_1 = phi (i_0, i_2)
   |   i_2 = i_1 + 2
   | endloop

   This loop has the same effect as:
   LOOP_1 has the same effect as:

   | i_1 = i_0 + 20

   The overall effect of the loop, "i_0 + 20" in the previous example,
   is obtained by passing in the parameters: LOOP = 1,
   EVOLUTION_FN = {i_0, +, 2}_1.

References chrec_apply(), chrec_contains_symbols_defined_in_loop(), chrec_dont_know, flow_loop_nested_p(), get_chrec_loop(), instantiate_parameters(), no_evolution_in_loop_p(), loop::num, and number_of_latch_executions().

Referenced by compute_scalar_evolution_in_loop(), follow_ssa_edge_inner_loop_phi(), instantiate_scev_name(), interpret_loop_phi(), rewrite_close_phi_out_of_ssa(), scalar_evolution_in_region(), and scev_const_prop().

static tree compute_scalar_evolution_in_loop ( struct loop wrto_loop,
struct loop def_loop,
tree  ev 
)
static
This section contains all the entry points:
   - number_of_iterations_in_loop,
   - analyze_scalar_evolution,
   - instantiate_parameters.
Compute and return the evolution function in WRTO_LOOP, the nearest
   common ancestor of DEF_LOOP and USE_LOOP.   

References analyze_scalar_evolution_1(), chrec_not_analyzed_yet, compute_overall_effect_of_inner_loop(), loop_depth(), no_evolution_in_loop_p(), loop::num, and superloop_at_depth().

Referenced by analyze_scalar_evolution_1().

static void del_scev_info ( )
static
Deletes database element E.   

References ggc_free().

Referenced by scev_initialize().

static int eq_scev_info ( )
inlinestatic
Compares database elements E1 and E2.   

References scev_info_str::instantiated_below, and scev_info_str::var.

Referenced by scev_initialize().

bool expression_expensive_p ( )
Returns true if the expression EXPR is considered to be too expensive
   for scev_const_prop.   

References integer_pow2p(), is_gimple_val(), tcc_binary, tcc_comparison, and tcc_unary.

Referenced by may_eliminate_iv(), and scev_const_prop().

static tree* find_var_scev_info ( )
static
Get the scalar evolution of VAR for INSTANTIATED_BELOW basic block.
   A first query on VAR returns chrec_not_analyzed_yet.   

References scev_info_str::chrec, scev_info_str::instantiated_below, new_scev_info_str(), scalar_evolution_info, and scev_info_str::var.

Referenced by get_scalar_evolution(), and set_scalar_evolution().

static t_bool follow_ssa_edge ( struct loop loop,
gimple  def,
gimple  halting_phi,
tree evolution_of_loop,
int  limit 
)
static
static t_bool follow_ssa_edge_binary ( struct loop loop,
gimple  at_stmt,
tree  type,
tree  rhs0,
enum tree_code  code,
tree  rhs1,
gimple  halting_phi,
tree evolution_of_loop,
int  limit 
)
static
Follow the ssa edge into the binary expression RHS0 CODE RHS1.
   Return true if the strongly connected component has been found.   

References add_to_evolution(), chrec_convert(), chrec_dont_know, follow_ssa_edge(), loop::num, t_dont_know, t_false, and t_true.

Referenced by follow_ssa_edge_expr(), and follow_ssa_edge_in_rhs().

static t_bool follow_ssa_edge_expr ( struct loop loop,
gimple  at_stmt,
tree  expr,
gimple  halting_phi,
tree evolution_of_loop,
int  limit 
)
static
Follow the ssa edge into the expression EXPR.
   Return true if the strongly connected component has been found.   

References chrec_convert(), follow_ssa_edge(), follow_ssa_edge_binary(), and t_false.

Referenced by follow_ssa_edge_in_rhs(), and follow_ssa_edge_inner_loop_phi().

static t_bool follow_ssa_edge_in_condition_phi ( struct loop loop,
gimple  condition_phi,
gimple  halting_phi,
tree evolution_of_loop,
int  limit 
)
static
This function merges the branches of a condition-phi-node in a
   loop.   

References chrec_dont_know, chrec_merge(), follow_ssa_edge_in_condition_phi_branch(), gimple_phi_num_args(), t_dont_know, t_false, and t_true.

Referenced by follow_ssa_edge().

static t_bool follow_ssa_edge_in_condition_phi_branch ( int  i,
struct loop loop,
gimple  condition_phi,
gimple  halting_phi,
tree evolution_of_branch,
tree  init_cond,
int  limit 
)
inlinestatic
Helper function for one branch of the condition-phi-node.  Return
   true if the strongly connected component has been found following
   this path.   

References backedge_phi_arg_p(), chrec_dont_know, follow_ssa_edge(), and t_false.

Referenced by follow_ssa_edge_in_condition_phi().

static t_bool follow_ssa_edge_in_rhs ( struct loop loop,
gimple  stmt,
gimple  halting_phi,
tree evolution_of_loop,
int  limit 
)
static
Follow the ssa edge into the right hand side of an assignment STMT.
   Return true if the strongly connected component has been found.   

References chrec_convert(), follow_ssa_edge_binary(), follow_ssa_edge_expr(), get_gimple_rhs_class(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_expr_type(), GIMPLE_SINGLE_RHS, and t_false.

Referenced by follow_ssa_edge().

static t_bool follow_ssa_edge_inner_loop_phi ( struct loop outer_loop,
gimple  loop_phi_node,
gimple  halting_phi,
tree evolution_of_loop,
int  limit 
)
static
Follow an SSA edge in an inner loop.  It computes the overall
   effect of the loop, and following the symbolic initial conditions,
   it follows the edges in the parent loop.  The inner loop is
   considered as a single statement.   

References analyze_scalar_evolution(), chrec_dont_know, compute_overall_effect_of_inner_loop(), flow_bb_inside_loop_p(), follow_ssa_edge_expr(), gimple_phi_arg_edge(), gimple_phi_num_args(), loop_containing_stmt(), edge_def::src, t_false, and t_true.

Referenced by follow_ssa_edge().

void gather_stats_on_scev_database ( void  )
static int gather_stats_on_scev_database_1 ( )
static
Callback for htab_traverse, gathers information on chrecs in the
   hashtable.   

References scev_info_str::chrec, and gather_chrec_stats().

Referenced by gather_stats_on_scev_database().

gimple get_loop_exit_condition ( )
This section selects the loops that will be good candidates for the
   scalar evolution analysis.  For the moment, greedily select all the
   loop nests we could analyze.   
For a loop with a single exit edge, return the COND_EXPR that
   guards the exit edge.  If the expression is too difficult to
   analyze, then give up.   

References dump_file, dump_flags, last_stmt(), print_gimple_stmt(), single_exit(), and edge_def::src.

Referenced by find_loop_location(), slpeel_can_duplicate_loop_p(), slpeel_make_loop_iterate_ntimes(), and vect_get_loop_niters().

static tree get_scalar_evolution ( )
static
Retrieve the chrec associated to SCALAR instantiated below
   INSTANTIATED_BELOW block.   

References chrec_not_analyzed_yet, dump_file, dump_flags, find_var_scev_info(), nb_get_scev, and print_generic_expr().

Referenced by analyze_scalar_evolution().

static hashval_t hash_scev_info ( )
inlinestatic
Computes a hash function for database element ELT.   

References scev_info_str::var.

Referenced by scev_initialize().

static void initialize_scalar_evolutions_analyzer ( )
static
Initializer.   

References chrec_dont_know, chrec_known, and chrec_not_analyzed_yet.

Referenced by scev_initialize().

static tree instantiate_array_ref ( basic_block  instantiate_below,
struct loop evolution_loop,
struct loop inner_loop,
tree  chrec,
bool  fold_conversions,
instantiate_cache_type cache,
int  size_expr 
)
static
Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
   and EVOLUTION_LOOP, that were left under a symbolic form.

   "CHREC" is an array reference to be instantiated.

   CACHE is the cache of already instantiated values.

   FOLD_CONVERSIONS should be set to true when the conversions that
   may wrap in signed/pointer type are folded, as long as the value of
   the chrec is preserved.

   SIZE_EXPR is used for computing the size of the expression to be
   instantiated, and to stop if it exceeds some limit.   

References chrec_dont_know, instantiate_scev_r(), and unshare_expr().

Referenced by instantiate_scev_r().

tree instantiate_scev ( basic_block  instantiate_below,
struct loop evolution_loop,
tree  chrec 
)
Analyze all the parameters of the chrec that were left under a
   symbolic form.  INSTANTIATE_BELOW is the basic block that stops the
   recursive instantiation of parameters: a parameter is a variable
   that is defined in a basic block that dominates INSTANTIATE_BELOW or
   a function parameter.   

References cache, dump_file, dump_flags, basic_block_def::index, instantiate_scev_r(), loop::num, and print_generic_expr().

Referenced by dr_analyze_indices(), graphite_can_represent_expr(), instantiate_parameters(), and scalar_evolution_in_region().

static tree instantiate_scev_1 ( basic_block  instantiate_below,
struct loop evolution_loop,
struct loop inner_loop,
tree  chrec,
bool  fold_conversions,
instantiate_cache_type cache,
int  size_expr 
)
static
Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
   and EVOLUTION_LOOP, that were left under a symbolic form.

   CHREC is an expression with 2 operands to be instantiated.

   CACHE is the cache of already instantiated values.

   FOLD_CONVERSIONS should be set to true when the conversions that
   may wrap in signed/pointer type are folded, as long as the value of
   the chrec is preserved.

   SIZE_EXPR is used for computing the size of the expression to be
   instantiated, and to stop if it exceeds some limit.   

References chrec_dont_know, and instantiate_scev_r().

Referenced by instantiate_scev_r().

static tree instantiate_scev_2 ( basic_block  instantiate_below,
struct loop evolution_loop,
struct loop inner_loop,
tree  chrec,
bool  fold_conversions,
instantiate_cache_type cache,
int  size_expr 
)
static
Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
   and EVOLUTION_LOOP, that were left under a symbolic form.

   CHREC is an expression with 2 operands to be instantiated.

   CACHE is the cache of already instantiated values.

   FOLD_CONVERSIONS should be set to true when the conversions that
   may wrap in signed/pointer type are folded, as long as the value of
   the chrec is preserved.

   SIZE_EXPR is used for computing the size of the expression to be
   instantiated, and to stop if it exceeds some limit.   

References chrec_dont_know, and instantiate_scev_r().

Referenced by instantiate_scev_r().

static tree instantiate_scev_3 ( basic_block  instantiate_below,
struct loop evolution_loop,
struct loop inner_loop,
tree  chrec,
bool  fold_conversions,
instantiate_cache_type cache,
int  size_expr 
)
static
Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
   and EVOLUTION_LOOP, that were left under a symbolic form.

   CHREC is an expression with 3 operands to be instantiated.

   CACHE is the cache of already instantiated values.

   FOLD_CONVERSIONS should be set to true when the conversions that
   may wrap in signed/pointer type are folded, as long as the value of
   the chrec is preserved.

   SIZE_EXPR is used for computing the size of the expression to be
   instantiated, and to stop if it exceeds some limit.   

References chrec_dont_know, and instantiate_scev_r().

Referenced by instantiate_scev_r().

static tree instantiate_scev_binary ( basic_block  instantiate_below,
struct loop evolution_loop,
struct loop inner_loop,
tree  chrec,
enum tree_code  code,
tree  type,
tree  c0,
tree  c1,
bool  fold_conversions,
instantiate_cache_type cache,
int  size_expr 
)
static
Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
   and EVOLUTION_LOOP, that were left under a symbolic form.

   "C0 CODE C1" is a binary expression of type TYPE to be instantiated.

   CACHE is the cache of already instantiated values.

   FOLD_CONVERSIONS should be set to true when the conversions that
   may wrap in signed/pointer type are folded, as long as the value of
   the chrec is preserved.

   SIZE_EXPR is used for computing the size of the expression to be
   instantiated, and to stop if it exceeds some limit.   

References chrec_convert(), chrec_convert_rhs(), chrec_dont_know, chrec_fold_minus(), chrec_fold_multiply(), chrec_fold_plus(), and instantiate_scev_r().

Referenced by instantiate_scev_r().

static tree instantiate_scev_convert ( basic_block  instantiate_below,
struct loop evolution_loop,
struct loop inner_loop,
tree  chrec,
tree  type,
tree  op,
bool  fold_conversions,
instantiate_cache_type cache,
int  size_expr 
)
static
Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
   and EVOLUTION_LOOP, that were left under a symbolic form.

   "CHREC" that stands for a convert expression "(TYPE) OP" is to be
   instantiated.

   CACHE is the cache of already instantiated values.

   FOLD_CONVERSIONS should be set to true when the conversions that
   may wrap in signed/pointer type are folded, as long as the value of
   the chrec is preserved.

   SIZE_EXPR is used for computing the size of the expression to be
   instantiated, and to stop if it exceeds some limit.   

References chrec_convert(), chrec_convert_aggressive(), chrec_dont_know, and instantiate_scev_r().

Referenced by instantiate_scev_r().

static tree instantiate_scev_name ( basic_block  instantiate_below,
struct loop evolution_loop,
struct loop inner_loop,
tree  chrec,
bool  fold_conversions,
instantiate_cache_type cache,
int  size_expr 
)
static
Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
   and EVOLUTION_LOOP, that were left under a symbolic form.

   CHREC is an SSA_NAME to be instantiated.

   CACHE is the cache of already instantiated values.

   FOLD_CONVERSIONS should be set to true when the conversions that
   may wrap in signed/pointer type are folded, as long as the value of
   the chrec is preserved.

   SIZE_EXPR is used for computing the size of the expression to be
   instantiated, and to stop if it exceeds some limit.   

References analyze_scalar_evolution(), CDI_DOMINATORS, chrec_dont_know, chrec_not_analyzed_yet, compute_overall_effect_of_inner_loop(), dominated_by_p(), find_common_loop(), flow_loop_nested_p(), get_instantiated_value_entry(), gimple_bb(), instantiate_scev_r(), loop_closed_phi_def(), loop_containing_stmt(), loop_depth(), basic_block_def::loop_father, and si.

Referenced by instantiate_scev_r().

static tree instantiate_scev_not ( basic_block  instantiate_below,
struct loop evolution_loop,
struct loop inner_loop,
tree  chrec,
enum tree_code  code,
tree  type,
tree  op,
bool  fold_conversions,
instantiate_cache_type cache,
int  size_expr 
)
static
Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
   and EVOLUTION_LOOP, that were left under a symbolic form.

   CHREC is a BIT_NOT_EXPR or a NEGATE_EXPR expression to be instantiated.
   Handle ~X as -1 - X.
   Handle -X as -1 * X.

   CACHE is the cache of already instantiated values.

   FOLD_CONVERSIONS should be set to true when the conversions that
   may wrap in signed/pointer type are folded, as long as the value of
   the chrec is preserved.

   SIZE_EXPR is used for computing the size of the expression to be
   instantiated, and to stop if it exceeds some limit.   

References chrec_convert(), chrec_dont_know, chrec_fold_minus(), chrec_fold_multiply(), and instantiate_scev_r().

Referenced by instantiate_scev_r().

static tree instantiate_scev_poly ( basic_block  instantiate_below,
struct loop evolution_loop,
struct loop ,
tree  chrec,
bool  fold_conversions,
instantiate_cache_type cache,
int  size_expr 
)
static
Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
   and EVOLUTION_LOOP, that were left under a symbolic form.

   CHREC is a polynomial chain of recurrence to be instantiated.

   CACHE is the cache of already instantiated values.

   FOLD_CONVERSIONS should be set to true when the conversions that
   may wrap in signed/pointer type are folded, as long as the value of
   the chrec is preserved.

   SIZE_EXPR is used for computing the size of the expression to be
   instantiated, and to stop if it exceeds some limit.   

References build_polynomial_chrec(), chrec_convert_rhs(), chrec_dont_know, chrec_type(), get_chrec_loop(), and instantiate_scev_r().

Referenced by instantiate_scev_r().

static tree instantiate_scev_r ( basic_block  instantiate_below,
struct loop evolution_loop,
struct loop inner_loop,
tree  chrec,
bool  fold_conversions,
instantiate_cache_type cache,
int  size_expr 
)
static
Analyze all the parameters of the chrec, between INSTANTIATE_BELOW
   and EVOLUTION_LOOP, that were left under a symbolic form.

   CHREC is the scalar evolution to instantiate.

   CACHE is the cache of already instantiated values.

   FOLD_CONVERSIONS should be set to true when the conversions that
   may wrap in signed/pointer type are folded, as long as the value of
   the chrec is preserved.

   SIZE_EXPR is used for computing the size of the expression to be
   instantiated, and to stop if it exceeds some limit.   

References automatically_generated_chrec_p(), chrec_dont_know, chrec_known, chrec_type(), instantiate_array_ref(), instantiate_scev_1(), instantiate_scev_2(), instantiate_scev_3(), instantiate_scev_binary(), instantiate_scev_convert(), instantiate_scev_name(), instantiate_scev_not(), instantiate_scev_poly(), and is_gimple_min_invariant().

Referenced by instantiate_array_ref(), instantiate_scev(), instantiate_scev_1(), instantiate_scev_2(), instantiate_scev_3(), instantiate_scev_binary(), instantiate_scev_convert(), instantiate_scev_name(), instantiate_scev_not(), instantiate_scev_poly(), and resolve_mixers().

static tree interpret_condition_phi ( )
static
This function merges the branches of a condition-phi-node,
   contained in the outermost loop, and whose arguments are already
   analyzed.   

References analyze_scalar_evolution(), backedge_phi_arg_p(), chrec_dont_know, chrec_merge(), chrec_not_analyzed_yet, and gimple_phi_num_args().

Referenced by analyze_scalar_evolution_1().

static tree interpret_expr ( )
static
static tree interpret_gimple_assign ( )
static
static tree interpret_rhs_expr ( struct loop loop,
gimple  at_stmt,
tree  type,
tree  rhs1,
enum tree_code  code,
tree  rhs2 
)
static
Interpret the operation RHS1 OP RHS2.  If we didn't
   analyze this node before, follow the definitions until ending
   either on an analyzed GIMPLE_ASSIGN, or on a loop-phi-node.  On the
   return path, this function propagates evolutions (ala constant copy
   propagation).  OPND1 is not a GIMPLE expression because we could
   analyze the effect of an inner loop: see interpret_loop_phi.   

References analyze_scalar_evolution(), analyze_scalar_evolution_for_address_of(), chrec_convert(), chrec_dont_know, chrec_fold_minus(), chrec_fold_multiply(), chrec_fold_plus(), get_gimple_rhs_class(), get_inner_reference(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), GIMPLE_SINGLE_RHS, handled_component_p(), HOST_WIDE_INT, is_gimple_assign(), is_gimple_min_invariant(), offset, tcc_binary, and unsigned_type_for().

Referenced by interpret_expr(), and interpret_gimple_assign().

static tree loop_closed_phi_def ( )
static
Return the closed_loop_phi node for VAR.  If there is none, return
   NULL_TREE.   

References edge_def::dest, gsi_end_p(), gsi_next(), gsi_start_phis(), gsi_stmt(), loop_containing_stmt(), and single_exit().

Referenced by instantiate_scev_name().

static bool loop_phi_node_p ( )
static
Return true when PHI is a loop-phi-node.   

References gimple_bb(), loop::header, and loop_containing_stmt().

Referenced by analyze_scalar_evolution_1(), and follow_ssa_edge().

static struct scev_info_str* new_scev_info_str ( )
staticread
Constructs a new SCEV_INFO_STR structure for VAR and INSTANTIATED_BELOW.   

References scev_info_str::chrec, chrec_not_analyzed_yet, scev_info_str::instantiated_below, and scev_info_str::var.

Referenced by find_var_scev_info().

tree number_of_exit_cond_executions ( )
Returns the number of executions of the exit condition of LOOP,
   i.e., the number by one higher than number_of_latch_executions.
   Note that unlike number_of_latch_executions, this number does
   not necessarily fit in the unsigned variant of the type of
   the control variable -- if the number of iterations is a constant,
   we return chrec_dont_know if adding one to number_of_latch_executions
   overflows; however, in case the number of iterations is symbolic
   expression, the caller is responsible for dealing with this
   the possible overflow.   

References build_int_cst(), chrec_contains_undetermined(), chrec_dont_know, chrec_fold_plus(), chrec_type(), and number_of_latch_executions().

Referenced by classify_partition(), generate_memcpy_builtin(), generate_memset_builtin(), and vect_get_loop_niters().

tree number_of_latch_executions ( )
Entry point for the analysis of the number of iterations pass.
   This function tries to safely approximate the number of iterations
   the loop will run.  When this property is not decidable at compile
   time, the result is chrec_dont_know.  Otherwise the result is a
   scalar or a symbolic parameter.  When the number of iterations may
   be equal to zero and the property cannot be determined at compile
   time, the result is a COND_EXPR that represents in a symbolic form
   the conditions under which the number of iterations is not zero.

   Example of analysis: suppose that the loop has an exit condition:

   "if (b > 49) goto end_loop;"

   and that in a previous analysis we have determined that the
   variable 'b' has an evolution function:

   "EF = {23, +, 5}_2".

   When we evaluate the function at the point 5, i.e. the value of the
   variable 'b' after 5 iterations in the loop, we have EF (5) = 48,
   and EF (6) = 53.  In this case the value of 'b' on exit is '53' and
   the loop body has been executed 6 times.   

References build_int_cst(), chrec_dont_know, dump_file, dump_flags, integer_nonzerop(), integer_zerop(), tree_niter_desc::may_be_zero, loop::nb_iterations, tree_niter_desc::niter, number_of_iterations_exit(), print_generic_expr(), and single_exit().

Referenced by build_loop_iteration_domains(), canonicalize_loop_induction_variables(), chrec_is_positive(), compute_overall_effect_of_inner_loop(), estimate_numbers_of_iterations_loop(), find_scop_parameters(), generate_memcpy_builtin(), generate_memset_builtin(), graphite_can_represent_loop(), number_of_exit_cond_executions(), and scev_const_prop().

tree resolve_mixers ( )
Similar to instantiate_parameters, but does not introduce the
   evolutions in outer loops for LOOP invariants in CHREC, and does not
   care about causing overflows, as long as they do not affect value
   of an expression.   

References block_before_loop(), cache, and instantiate_scev_r().

Referenced by analyze_scalar_evolution_in_loop(), and scev_const_prop().

bool scev_initialized_p ( void  )
Return true if SCEV is initialized.   

References scalar_evolution_info.

Referenced by estimated_loop_iterations(), fini_copy_prop(), and max_loop_iterations().

void scev_reset_htab ( void  )
Cleans up the information cached by the scalar evolutions analysis
   in the hash table.   

References scalar_evolution_info.

Referenced by rewrite_commutative_reductions_out_of_ssa(), rewrite_cross_bb_scalar_deps_out_of_ssa(), and scev_reset().

static void set_scalar_evolution ( )
static
bool simple_iv ( struct loop wrto_loop,
struct loop use_loop,
tree  op,
affine_iv iv,
bool  allow_nonconstant_step 
)
Checks whether use of OP in USE_LOOP behaves as a simple affine iv with
   respect to WRTO_LOOP and returns its base and step in IV if possible
   (see analyze_scalar_evolution_in_loop for more details on USE_LOOP
   and WRTO_LOOP).  If ALLOW_NONCONSTANT_STEP is true, we want step to be
   invariant in LOOP.  Otherwise we require it to be an integer constant.

   IV->no_overflow is set to true if we are sure the iv cannot overflow (e.g.
   because it is computed in signed arithmetics).  Consequently, adding an
   induction variable

   for (i = IV->base; ; i += IV->step)

   is only safe if IV->no_overflow is false, or TYPE_OVERFLOW_UNDEFINED is
   false for the type of the induction variable, or you can prove that i does
   not wrap by some other argument.  Otherwise, this might introduce undefined
   behavior, and

   for (i = iv->base; ; i = (type) ((unsigned type) i + (unsigned type) iv->step))

   must be used instead.   

References analyze_scalar_evolution_in_loop(), affine_iv::base, build_int_cst(), chrec_contains_symbols_defined_in_loop(), chrec_contains_undetermined(), affine_iv::no_overflow, loop::num, affine_iv::step, tree_contains_chrecs(), tree_does_not_contain_chrecs(), and type().

Referenced by constant_after_peeling(), determine_biv_step(), dr_analyze_innermost(), estimate_function_body_sizes(), find_givs_in_stmt_scev(), gather_scalar_reductions(), idx_analyze_ref(), inhibit_phi_insertion(), is_comparison_with_loop_invariant_p(), number_of_iterations_exit(), ref_at_iteration(), rewrite_phi_with_iv(), try_create_reduction_list(), and vect_analyze_data_refs().


Variable Documentation

tree chrec_dont_know
Reserved to the cases where the analyzer has detected an
   undecidable property at compile time.   

Referenced by add_other_self_distances(), add_to_evolution(), add_to_evolution_1(), analyze_evolution_in_loop(), analyze_initial_condition(), analyze_miv_subscript(), analyze_overlapping_iterations(), analyze_scalar_evolution_1(), analyze_scalar_evolution_in_loop(), analyze_siv_subscript(), analyze_siv_subscript_cst_affine(), analyze_subscript_affine_affine(), analyze_ziv_subscript(), build_polynomial_chrec(), chrec_apply(), chrec_contains_undetermined(), chrec_convert_1(), chrec_evaluate(), chrec_fold_automatically_generated_operands(), chrec_fold_multiply(), chrec_fold_plus_1(), chrec_fold_poly_cst(), chrec_merge(), classify_partition(), compute_affine_dependence(), compute_data_dependences_for_bb(), compute_data_dependences_for_loop(), compute_overall_effect_of_inner_loop(), compute_overlap_steps_for_affine_1_2(), compute_overlap_steps_for_affine_univar(), compute_subscript_distance(), cond_if_else_store_replacement(), determine_loop_nest_reuse(), dump_data_dependence_relation(), extract_affine(), find_data_references_in_bb(), find_data_references_in_loop(), find_loop_niter(), find_loop_niter_by_eval(), follow_ssa_edge_binary(), follow_ssa_edge_in_condition_phi(), follow_ssa_edge_in_condition_phi_branch(), follow_ssa_edge_inner_loop_phi(), initialize_data_dependence_relation(), initialize_scalar_evolutions_analyzer(), instantiate_array_ref(), instantiate_scev_1(), instantiate_scev_2(), instantiate_scev_3(), instantiate_scev_binary(), instantiate_scev_convert(), instantiate_scev_name(), instantiate_scev_not(), instantiate_scev_poly(), instantiate_scev_r(), interpret_condition_phi(), interpret_expr(), interpret_loop_phi(), interpret_rhs_expr(), known_dependences_p(), lambda_transform_legal_p(), loop_niter_by_eval(), max_stmt_executions_tree(), no_evolution_in_loop_p(), number_of_exit_cond_executions(), number_of_latch_executions(), scan_tree_for_params(), scev_const_prop(), subscript_dependence_tester_1(), vect_analyze_data_ref_dependence(), vect_find_same_alignment_drs(), vect_get_loop_niters(), and vect_slp_analyze_data_ref_dependence().

tree chrec_not_analyzed_yet
The following trees are unique elements.  Thus the comparison of
   another element to these elements should be done on the pointer to
   these trees, and not on their value.   
The SSA_NAMEs that are not yet analyzed are qualified with NULL_TREE.   

Referenced by analyze_evolution_in_loop(), analyze_initial_condition(), analyze_scalar_evolution_1(), chrec_fold_automatically_generated_operands(), chrec_merge(), compute_scalar_evolution_in_loop(), get_instantiated_value_entry(), get_scalar_evolution(), initialize_scalar_evolutions_analyzer(), instantiate_scev_name(), interpret_condition_phi(), new_scev_info_str(), and no_evolution_in_loop_p().

instantiate_cache_type* ctbl
static
unsigned nb_get_scev = 0
static
unsigned nb_set_scev = 0
static
Counters for the scev database.   

Referenced by dump_chrecs_stats(), and set_scalar_evolution().