GCC Middle and Back End API Reference
|
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_str * | new_scev_info_str () |
static hashval_t | hash_scev_info () |
static int | eq_scev_info () |
static void | del_scev_info () |
static tree * | find_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 tree * | get_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_type * | ctbl |
enum t_bool |
|
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 |
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().
Given a LOOP_PHI_NODE, this function determines the evolution function from LOOP_PHI_NODE to LOOP_PHI_NODE in the loop.
References chrec_dont_know, chrec_merge(), chrec_not_analyzed_yet, dump_file, dump_flags, flow_bb_inside_loop_p(), follow_ssa_edge(), gimple_phi_arg_edge(), gimple_phi_num_args(), loop_containing_stmt(), no_evolution_in_loop_p(), loop::num, operand_equal_p(), print_generic_expr(), print_gimple_stmt(), edge_def::src, t_false, and t_true.
Referenced by interpret_loop_phi().
|
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().
@verbatim Scalar evolution detector.
Copyright (C) 2003-2013 Free Software Foundation, Inc. Contributed by Sebastian Pop s.pop @lap oste. 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 |
Helper recursive function.
References analyze_scalar_evolution_1(), block_before_loop(), chrec_dont_know, chrec_not_analyzed_yet, compute_scalar_evolution_in_loop(), find_common_loop(), flow_bb_inside_loop_p(), gimple_bb(), interpret_condition_phi(), interpret_expr(), interpret_gimple_assign(), interpret_loop_phi(), basic_block_def::loop_father, loop_phi_node_p(), and set_scalar_evolution().
Referenced by interpret_rhs_expr().
|
static |
Analyzes and returns the scalar evolution of VAR address in LOOP.
References analyze_scalar_evolution().
|
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 |
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 |
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 |
|
static |
Dump the contents of a CHREC_STATS structure.
References chrec_stats::nb_affine, chrec_stats::nb_affine_multivar, chrec_stats::nb_chrec_dont_know, chrec_stats::nb_chrecs, nb_get_scev, chrec_stats::nb_higher_poly, nb_set_scev, chrec_stats::nb_undetermined, and scalar_evolution_info.
Referenced by gather_stats_on_scev_database().
|
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 |
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 |
Follow an SSA edge from a loop-phi-node to itself, constructing a path that is analyzed on the return walk.
References flow_loop_nested_p(), follow_ssa_edge_in_condition_phi(), follow_ssa_edge_in_rhs(), follow_ssa_edge_inner_loop_phi(), gimple_nop_p(), loop_containing_stmt(), loop_phi_node_p(), t_dont_know, t_false, and t_true.
Referenced by analyze_evolution_in_loop(), follow_ssa_edge_binary(), follow_ssa_edge_expr(), and follow_ssa_edge_in_condition_phi_branch().
|
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 |
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 |
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().
|
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 |
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 |
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().
|
static |
Gather statistics about CHREC.
References chrec_contains_undetermined(), dump_file, dump_flags, evolution_function_is_affine_multivariate_p(), evolution_function_is_affine_p(), chrec_stats::nb_affine, chrec_stats::nb_affine_multivar, chrec_stats::nb_chrecs, chrec_stats::nb_higher_poly, chrec_stats::nb_undetermined, and print_generic_expr().
Referenced by gather_stats_on_scev_database_1().
void gather_stats_on_scev_database | ( | void | ) |
Classify the chrecs of the whole database.
References dump_chrecs_stats(), dump_file, gather_stats_on_scev_database_1(), reset_chrecs_counters(), and scalar_evolution_info.
Referenced by analyze_all_data_dependences().
|
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().
|
static |
Returns from CACHE a pointer to the cached chrec for NAME.
References cache, instantiate_cache_entry::chrec, chrec_not_analyzed_yet, hash_table< Descriptor, Allocator >::create(), instantiate_cache_type::entries, hash_table< Descriptor, Allocator >::find_slot_with_hash(), instantiate_cache_type::htab, hash_table< Descriptor, Allocator >::is_created(), and instantiate_cache_entry::name.
Referenced by instantiate_scev_name().
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 |
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().
|
inlinestatic |
Computes a hash function for database element ELT.
References scev_info_str::var.
Referenced by scev_initialize().
|
static |
Initializer.
References chrec_dont_know, chrec_known, and chrec_not_analyzed_yet.
Referenced by scev_initialize().
|
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
Interpret the expression EXPR.
References automatically_generated_chrec_p(), chrec_dont_know, extract_ops_from_tree(), get_gimple_rhs_class(), GIMPLE_TERNARY_RHS, and interpret_rhs_expr().
Referenced by analyze_scalar_evolution_1().
|
static |
Interpret the rhs of the assignment STMT.
References gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), and interpret_rhs_expr().
Referenced by analyze_scalar_evolution_1().
|
static |
Analyze the scalar evolution for LOOP_PHI_NODE.
References analyze_evolution_in_loop(), analyze_initial_condition(), analyze_scalar_evolution(), chrec_dont_know, compute_overall_effect_of_inner_loop(), loop_containing_stmt(), loop_depth(), operand_equal_p(), and superloop_at_depth().
Referenced by analyze_scalar_evolution_1().
|
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 |
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 |
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().
|
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().
|
inlinestatic |
Reset the counters.
References chrec_stats::nb_affine, chrec_stats::nb_affine_multivar, chrec_stats::nb_chrec_dont_know, chrec_stats::nb_chrecs, chrec_stats::nb_higher_poly, and chrec_stats::nb_undetermined.
Referenced by gather_stats_on_scev_database().
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().
unsigned int scev_const_prop | ( | void | ) |
Replace ssa names for that scev can prove they are constant by the appropriate constants. Also perform final value replacement in loops, in case the replacement expressions are cheap. We only consider SSA names defined by phi nodes; rest is left to the ordinary constant propagation pass.
References analyze_scalar_evolution(), analyze_scalar_evolution_in_loop(), bitmap_set_bit(), cfun, chrec_contains_symbols_defined_in_loop(), chrec_dont_know, compute_overall_effect_of_inner_loop(), contains_abnormal_ssa_name_p(), edge_def::dest, dump_file, dump_flags, expression_expensive_p(), force_gimple_operand_gsi(), gsi_after_labels(), gsi_end_p(), gsi_for_stmt(), gsi_insert_before(), gsi_next(), GSI_SAME_STMT, gsi_start_phis(), gsi_stmt(), is_gimple_min_invariant(), LI_FROM_INNERMOST, loop_depth(), basic_block_def::loop_father, may_propagate_copy(), loop::num, number_of_latch_executions(), number_of_loops(), print_gimple_stmt(), remove_phi_node(), replace_uses_by(), resolve_mixers(), scev_reset(), single_exit(), single_pred_p(), split_loop_exit_edge(), superloop_at_depth(), tree_does_not_contain_chrecs(), type(), unshare_expr(), and virtual_operand_p().
void scev_finalize | ( | void | ) |
Finalize the scalar evolution analysis.
References scalar_evolution_info.
Referenced by analyze_function(), do_pre(), estimate_function_body_sizes(), execute_vrp(), find_obviously_necessary_stmts(), tree_complete_unroll_inner(), tree_estimate_probability_driver(), tree_ssa_cs_elim(), and tree_ssa_loop_done().
void scev_initialize | ( | void | ) |
Initialize the analysis of scalar evolutions for LOOPS.
References del_scev_info(), eq_scev_info(), hash_scev_info(), initialize_scalar_evolutions_analyzer(), loop::nb_iterations, and scalar_evolution_info.
Referenced by analyze_function(), do_pre(), estimate_function_body_sizes(), execute_vrp(), find_obviously_necessary_stmts(), tree_complete_unroll_inner(), tree_estimate_probability_driver(), tree_ssa_cs_elim(), and tree_ssa_loop_init().
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 | ( | void | ) |
Cleans up the information cached by the scalar evolutions analysis in the hash table and in the loop->nb_iterations.
References loop::nb_iterations, and scev_reset_htab().
Referenced by canonicalize_induction_variables(), gen_parallel_loop(), gimple_duplicate_loop_to_header_edge(), gloog(), graphite_finalize(), graphite_initialize(), repair_loop_structures(), scev_const_prop(), tree_predictive_commoning(), tree_predictive_commoning_loop(), tree_ssa_dce_loop(), tree_ssa_iv_optimize_loop(), tree_ssa_loop_bounds(), tree_ssa_prefetch_arrays(), tree_unroll_loops_completely(), vect_do_peeling_for_alignment(), and vect_do_peeling_for_loop_bound().
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 |
Associate CHREC to SCALAR.
References dump_file, dump_flags, find_var_scev_info(), basic_block_def::index, nb_set_scev, and print_generic_expr().
Referenced by analyze_scalar_evolution_1().
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().
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_known |
When the analyzer has detected that a property will never happen, then it qualifies it with chrec_known.
Referenced by analyze_all_data_dependences(), build_classic_dist_vector_1(), chrec_fold_automatically_generated_operands(), chrec_merge(), classify_partition(), compute_affine_dependence(), cond_if_else_store_replacement(), determine_loop_nest_reuse(), dump_data_dependence_relation(), init_omega_for_ddr_1(), initialize_data_dependence_relation(), initialize_scalar_evolutions_analyzer(), instantiate_scev_r(), lambda_transform_legal_p(), split_data_refs_to_components(), subscript_dependence_tester_1(), vect_analyze_data_ref_dependence(), vect_find_same_alignment_drs(), 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().
|
static |
|
static |
Referenced by dump_chrecs_stats(), and get_scalar_evolution().
|
static |
Counters for the scev database.
Referenced by dump_chrecs_stats(), and set_scalar_evolution().
|
static |