GCC Middle and Back End API Reference
tree-vrp.c File Reference

Data Structures

struct  value_range_d
struct  assert_locus_d
struct  switch_update
struct  case_info

Typedefs

typedef struct value_range_d value_range_t
typedef struct assert_locus_dassert_locus_t

Enumerations

enum  value_range_type { VR_UNDEFINED, VR_RANGE, VR_ANTI_RANGE, VR_VARYING }

Functions

static bool live_on_edge ()
static int compare_values (tree val1, tree val2)
static int compare_values_warnv (tree val1, tree val2, bool *)
static void vrp_meet (value_range_t *, value_range_t *)
static void vrp_intersect_ranges (value_range_t *, value_range_t *)
static tree vrp_evaluate_conditional_warnv_with_ops (enum tree_code, tree, tree, bool, bool *, bool *)
static tree vrp_val_max ()
static tree vrp_val_min ()
static bool vrp_val_is_max ()
static bool vrp_val_is_min ()
static bool needs_overflow_infinity ()
static bool supports_overflow_infinity ()
static tree make_overflow_infinity ()
static tree negative_overflow_infinity ()
static tree positive_overflow_infinity ()
static bool is_negative_overflow_infinity ()
static bool is_positive_overflow_infinity ()
static bool is_overflow_infinity ()
static bool stmt_overflow_infinity ()
static tree avoid_overflow_infinity ()
static bool nonnull_arg_p ()
static void set_value_range_to_undefined ()
static void set_value_range_to_varying ()
static void set_value_range (value_range_t *vr, enum value_range_type t, tree min, tree max, bitmap equiv)
static void set_and_canonicalize_value_range (value_range_t *vr, enum value_range_type t, tree min, tree max, bitmap equiv)
static void copy_value_range ()
static void set_value_range_to_value ()
static void set_value_range_to_nonnegative (value_range_t *vr, tree type, bool overflow_infinity)
static void set_value_range_to_nonnull ()
static void set_value_range_to_null ()
static void set_value_range_to_truthvalue ()
static void abs_extent_range ()
static value_range_tget_value_range ()
static bool vrp_operand_equal_p ()
static bool vrp_bitmap_equal_p ()
static bool update_value_range ()
static void add_equivalence ()
static bool range_is_nonnull ()
static bool range_is_null ()
static bool range_int_cst_p ()
static bool range_int_cst_singleton_p ()
static bool symbolic_range_p ()
static bool overflow_infinity_range_p ()
static bool usable_range_p ()
static bool gimple_assign_nonnegative_warnv_p ()
static bool gimple_call_nonnegative_warnv_p ()
static bool gimple_stmt_nonnegative_warnv_p ()
static bool gimple_assign_nonzero_warnv_p ()
static bool gimple_stmt_nonzero_warnv_p ()
static bool vrp_stmt_computes_nonzero ()
static bool valid_value_p ()
static int operand_less_p ()
static int compare_values_warnv ()
static int compare_values ()
static int value_inside_range ()
static bool value_ranges_intersect_p ()
static int range_includes_zero_p ()
static bool value_range_nonnegative_p ()
bool ssa_name_nonnegative_p ()
static tree value_range_constant_singleton ()
static tree op_with_constant_singleton_value_range ()
static bool op_with_boolean_value_range_p ()
static void extract_range_from_assert ()
static void extract_range_from_ssa_name ()
static tree vrp_int_const_binop ()
static bool zero_nonzero_bits_from_vr (value_range_t *vr, double_int *may_be_nonzero, double_int *must_be_nonzero)
static bool ranges_from_anti_range (value_range_t *ar, value_range_t *vr0, value_range_t *vr1)
static void extract_range_from_multiplicative_op_1 (value_range_t *vr, enum tree_code code, value_range_t *vr0, value_range_t *vr1)
static int quad_int_cmp (double_int l0, double_int h0, double_int l1, double_int h1, bool uns)
static void quad_int_pair_sort (double_int *l0, double_int *h0, double_int *l1, double_int *h1, bool uns)
static void extract_range_from_binary_expr_1 (value_range_t *vr, enum tree_code code, tree expr_type, value_range_t *vr0_, value_range_t *vr1_)
static void extract_range_from_binary_expr (value_range_t *vr, enum tree_code code, tree expr_type, tree op0, tree op1)
static void extract_range_from_unary_expr_1 (value_range_t *vr, enum tree_code code, tree type, value_range_t *vr0_, tree op0_type)
static void extract_range_from_unary_expr (value_range_t *vr, enum tree_code code, tree type, tree op0)
static void extract_range_from_cond_expr ()
static void extract_range_from_comparison (value_range_t *vr, enum tree_code code, tree type, tree op0, tree op1)
static void extract_range_basic ()
static void extract_range_from_assignment ()
static void adjust_range_with_scev (value_range_t *vr, struct loop *loop, gimple stmt, tree var)
static bool vrp_var_may_overflow ()
static tree compare_ranges (enum tree_code comp, value_range_t *vr0, value_range_t *vr1, bool *strict_overflow_p)
static tree compare_range_with_value (enum tree_code comp, value_range_t *vr, tree val, bool *strict_overflow_p)
void dump_value_range (FILE *, value_range_t *)
void debug_value_range (value_range_t *)
void dump_all_value_ranges (FILE *)
void debug_all_value_ranges (void)
void dump_vr_equiv (FILE *, bitmap)
void debug_vr_equiv (bitmap)
void dump_value_range ()
DEBUG_FUNCTION void debug_value_range ()
void dump_all_value_ranges ()
static gimple build_assert_expr_for ()
static bool fp_predicate ()
static bool infer_value_range ()
void dump_asserts_for (FILE *, tree)
void debug_asserts_for (tree)
void dump_all_asserts (FILE *)
void debug_all_asserts (void)
void dump_asserts_for ()
DEBUG_FUNCTION void debug_asserts_for ()
void dump_all_asserts ()
static void register_new_assert_for (tree name, tree expr, enum tree_code comp_code, tree val, basic_block bb, edge e, gimple_stmt_iterator si)
static bool extract_code_and_val_from_cond_with_ops (tree name, enum tree_code cond_code, tree cond_op0, tree cond_op1, bool invert, enum tree_code *code_p, tree *val_p)
static double_int masked_increment (double_int val, double_int mask, double_int sgnbit, unsigned int prec)
static bool register_edge_assert_for_2 (tree name, edge e, gimple_stmt_iterator bsi, enum tree_code cond_code, tree cond_op0, tree cond_op1, bool invert)
static bool register_edge_assert_for_1 (tree op, enum tree_code code, edge e, gimple_stmt_iterator bsi)
static bool register_edge_assert_for (tree name, edge e, gimple_stmt_iterator si, enum tree_code cond_code, tree cond_op0, tree cond_op1)
static bool find_conditional_asserts ()
static int compare_case_labels ()
static bool find_switch_asserts ()
static bool find_assert_locations_1 ()
static bool find_assert_locations ()
static bool process_assert_insertions_for ()
static void process_assert_insertions ()
static void insert_range_assertions ()
static void check_array_ref ()
static void search_for_addr_array ()
static tree check_array_bounds ()
static void check_all_array_refs ()
static void remove_range_assertions ()
static bool stmt_interesting_for_vrp ()
static void vrp_initialize ()
static tree vrp_valueize ()
static enum ssa_prop_result vrp_visit_assignment_or_call ()
static value_range_t get_vr_for_comparison ()
static tree compare_name_with_value (enum tree_code comp, tree var, tree val, bool *strict_overflow_p)
static tree compare_names (enum tree_code comp, tree n1, tree n2, bool *strict_overflow_p)
static tree vrp_evaluate_conditional_warnv_with_ops_using_ranges (enum tree_code code, tree op0, tree op1, bool *strict_overflow_p)
static tree vrp_evaluate_conditional ()
static enum ssa_prop_result vrp_visit_cond_stmt ()
static bool find_case_label_index ()
static bool find_case_label_range (gimple stmt, tree min, tree max, size_t *min_idx, size_t *max_idx)
static bool find_case_label_ranges (gimple stmt, value_range_t *vr, size_t *min_idx1, size_t *max_idx1, size_t *min_idx2, size_t *max_idx2)
static enum ssa_prop_result vrp_visit_switch_stmt ()
static enum ssa_prop_result vrp_visit_stmt ()
static void union_ranges (enum value_range_type *vr0type, tree *vr0min, tree *vr0max, enum value_range_type vr1type, tree vr1min, tree vr1max)
static void intersect_ranges (enum value_range_type *vr0type, tree *vr0min, tree *vr0max, enum value_range_type vr1type, tree vr1min, tree vr1max)
static void vrp_intersect_ranges_1 ()
static void vrp_intersect_ranges ()
static void vrp_meet_1 ()
static void vrp_meet ()
static enum ssa_prop_result vrp_visit_phi_node ()
static bool simplify_truth_ops_using_ranges ()
static bool simplify_div_or_mod_using_ranges ()
static bool simplify_abs_using_ranges ()
static bool simplify_bit_ops_using_ranges ()
static tree test_for_singularity (enum tree_code cond_code, tree op0, tree op1, value_range_t *vr)
static bool range_fits_type_p ()
static bool simplify_cond_using_ranges ()
static bool simplify_switch_using_ranges ()
static bool simplify_conversion_using_ranges ()
static bool simplify_float_conversion_using_ranges ()
static bool simplify_stmt_using_ranges ()
static bool fold_predicate_in ()
static bool vrp_fold_stmt ()
static tree simplify_stmt_for_jump_threading ()
static void identify_jump_threads ()
static void finalize_jump_threads ()
static void vrp_finalize ()
static unsigned int execute_vrp ()
static bool gate_vrp ()
gimple_opt_passmake_pass_vrp ()

Variables

static sbitmaplive
static bitmap need_assert_for
static assert_locus_tasserts_for
static unsigned num_vr_values
static value_range_t ** vr_value
static bool values_propagated
static int * vr_phi_edge_counts
static vec< edgeto_remove_edges
static vec< switch_updateto_update_switch_stmts
static vec< treeequiv_stack

Typedef Documentation

typedef struct assert_locus_d* assert_locus_t
typedef struct value_range_d value_range_t

Enumeration Type Documentation

@verbatim Support routines for Value Range Propagation (VRP).

Copyright (C) 2005-2013 Free Software Foundation, Inc. Contributed by Diego Novillo dnovi.nosp@m.llo@.nosp@m.redha.nosp@m.t.co.nosp@m.m.

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

Type of value ranges.  See value_range_d for a description of these
   types.   
Enumerator:
VR_UNDEFINED 
VR_RANGE 
VR_ANTI_RANGE 
VR_VARYING 

Function Documentation

static void abs_extent_range ( )
static
If abs (min) < abs (max), set VR to [-max, max], if
   abs (min) >= abs (max), set VR to [-min, min].   

References compare_values(), set_and_canonicalize_value_range(), set_value_range_to_varying(), and VR_RANGE.

Referenced by extract_range_from_binary_expr_1().

static void add_equivalence ( )
static
Add VAR and VAR's equivalence set to EQUIV.  This is the central
   point where equivalence processing can be turned on/off.   

References bitmap_ior_into(), bitmap_set_bit(), and value_range_d::equiv.

Referenced by extract_range_from_assert(), and extract_range_from_ssa_name().

static tree avoid_overflow_infinity ( )
inlinestatic
If VAL is now an overflow infinity, return VAL.  Otherwise, return
   the same value with TREE_OVERFLOW clear.  This can be used to avoid
   confusing a regular value with an overflow value.   

References is_overflow_infinity(), vrp_val_is_max(), vrp_val_is_min(), vrp_val_max(), and vrp_val_min().

Referenced by extract_range_from_assert(), and set_value_range_to_value().

static gimple build_assert_expr_for ( )
static
Given a COND_EXPR COND of the form 'V OP W', and an SSA name V,
   create a new SSA name N and return the assertion assignment
   'V = ASSERT_EXPR <V, V OP W>'.   

References create_new_def_for().

Referenced by process_assert_insertions_for().

static tree check_array_bounds ( )
static
walk_tree() callback that checks if *TP is
   an ARRAY_REF inside an ADDR_EXPR (in which an array
   subscript one outside the valid range is allowed). Call
   check_array_ref for each ARRAY_REF found. The location is
   passed in DATA.   

References check_array_ref(), walk_stmt_info::info, and search_for_addr_array().

Referenced by check_all_array_refs().

static void check_array_ref ( )
static
Checks one ARRAY_REF in REF, located at LOCUS. Ignores flexible arrays
   and "struct" hacks. If VRP can determine that the
   array subscript is a constant, check if it is outside valid
   range. If the array subscript is a RANGE, warn if it is
   non-overlapping with valid range.
   IGNORE_OFF_BY_ONE is true if the ARRAY_REF is inside a ADDR_EXPR.   

References array_ref_low_bound(), array_ref_up_bound(), dump_file, dump_flags, dump_generic_expr(), get_base_address(), get_value_range(), int_const_binop(), value_range_d::max, value_range_d::min, tree_int_cst_equal(), tree_int_cst_lt(), value_range_d::type, VR_ANTI_RANGE, VR_RANGE, and warning_at().

Referenced by check_array_bounds(), and search_for_addr_array().

static int compare_case_labels ( )
static
Compare two case labels sorting first by the destination bb index
   and then by the case value.   

References case_info::bb, case_info::expr, basic_block_def::index, and tree_int_cst_compare().

Referenced by find_switch_asserts().

static tree compare_name_with_value ( enum tree_code  comp,
tree  var,
tree  val,
bool *  strict_overflow_p 
)
static
Compare all the value ranges for names equivalent to VAR with VAL
   using comparison code COMP.  Return the same value returned by
   compare_range_with_value, including the setting of
   *STRICT_OVERFLOW_P.   

References compare_range_with_value(), value_range_d::equiv, get_value_range(), and get_vr_for_comparison().

Referenced by vrp_evaluate_conditional_warnv_with_ops().

static tree compare_names ( enum tree_code  comp,
tree  n1,
tree  n2,
bool *  strict_overflow_p 
)
static
Given a comparison code COMP and names N1 and N2, compare all the
   ranges equivalent to N1 against all the ranges equivalent to N2
   to determine the value of N1 COMP N2.  Return the same value
   returned by compare_ranges.  Set *STRICT_OVERFLOW_P to indicate
   whether we relied on an overflow infinity in the comparison.   

References bitmap_clear_bit(), bitmap_intersect_p(), bitmap_obstack_initialize(), bitmap_set_bit(), compare_ranges(), value_range_d::equiv, get_value_range(), get_vr_for_comparison(), i1, and i2.

Referenced by vrp_evaluate_conditional_warnv_with_ops().

static tree compare_range_with_value ( enum tree_code  comp,
value_range_t vr,
tree  val,
bool *  strict_overflow_p 
)
static
Given a value range VR, a value VAL and a comparison code COMP, return
   BOOLEAN_TRUE_NODE if VR COMP VAL always returns true for all the
   values in VR.  Return BOOLEAN_FALSE_NODE if the comparison
   always returns false.  Return NULL_TREE if it is not always
   possible to determine the value of the comparison.  Also set
   *STRICT_OVERFLOW_P to indicate whether a range with an overflow
   infinity was used in the test.   

References compare_values_warnv(), value_range_d::max, value_range_d::min, overflow_infinity_range_p(), value_range_d::type, usable_range_p(), value_inside_range(), VR_ANTI_RANGE, VR_UNDEFINED, and VR_VARYING.

Referenced by compare_name_with_value(), simplify_abs_using_ranges(), simplify_div_or_mod_using_ranges(), and vrp_evaluate_conditional_warnv_with_ops_using_ranges().

static tree compare_ranges ( enum tree_code  comp,
value_range_t vr0,
value_range_t vr1,
bool *  strict_overflow_p 
)
static
Given two numeric value ranges VR0, VR1 and a comparison code COMP:

   - Return BOOLEAN_TRUE_NODE if VR0 COMP VR1 always returns true for
     all the values in the ranges.

   - Return BOOLEAN_FALSE_NODE if the comparison always returns false.

   - Return NULL_TREE if it is not always possible to determine the
     value of the comparison.

   Also set *STRICT_OVERFLOW_P to indicate whether a range with an
   overflow infinity was used in the test.   

References compare_values_warnv(), value_range_d::max, value_range_d::min, overflow_infinity_range_p(), value_range_d::type, usable_range_p(), VR_ANTI_RANGE, VR_RANGE, VR_UNDEFINED, and VR_VARYING.

Referenced by compare_names(), and vrp_evaluate_conditional_warnv_with_ops_using_ranges().

static int compare_values ( )
static
Compare values like compare_values_warnv, but treat comparisons of
   nonconstants which rely on undefined overflow as incomparable.   

References compare_values_warnv(), and is_gimple_min_invariant().

static int compare_values_warnv ( tree  val1,
tree  val2,
bool *   
)
static
static int compare_values_warnv ( )
static
Compare two values VAL1 and VAL2.  Return

        -2 if VAL1 and VAL2 cannot be compared at compile-time,
        -1 if VAL1 < VAL2,
         0 if VAL1 == VAL2,
        +1 if VAL1 > VAL2, and
        +2 if VAL1 != VAL2

   This is similar to tree_int_cst_compare but supports pointer values
   and values that cannot be compared at compile time.

   If STRICT_OVERFLOW_P is not NULL, then set *STRICT_OVERFLOW_P to
   true if the return value is only valid if we assume that signed
   overflow is undefined.   

References compare_values_warnv(), fold_binary_to_constant(), fold_unary_to_constant(), integer_onep(), is_gimple_min_invariant(), is_negative_overflow_infinity(), is_positive_overflow_infinity(), operand_equal_p(), operand_less_p(), tree_int_cst_compare(), and tree_int_cst_sgn().

DEBUG_FUNCTION void debug_all_asserts ( )
Dump all the registered assertions for all the names to stderr.   

References dump_all_asserts().

DEBUG_FUNCTION void debug_all_value_ranges ( )
Dump all value ranges to stderr.   

References dump_all_value_ranges().

void debug_asserts_for ( tree  )
DEBUG_FUNCTION void debug_asserts_for ( )
Dump all the registered assertions for NAME to stderr.   

References dump_asserts_for().

void debug_value_range ( value_range_t )
DEBUG_FUNCTION void debug_value_range ( )
Dump value range VR to stderr.   

References dump_value_range().

void debug_vr_equiv ( bitmap  )
void dump_all_asserts ( FILE *  )
void dump_all_asserts ( )
Dump all the registered assertions for all the names to FILE.   

References dump_asserts_for().

void dump_all_value_ranges ( FILE *  )
void dump_all_value_ranges ( )
Dump value ranges of all SSA_NAMEs to FILE.   

References dump_value_range(), num_vr_values, and print_generic_expr().

void dump_asserts_for ( FILE *  ,
tree   
)
void dump_vr_equiv ( FILE *  ,
bitmap   
)
static unsigned int execute_vrp ( )
static
Main entry point to VRP (Value Range Propagation).  This pass is
   loosely based on J. R. C. Patterson, ``Accurate Static Branch
   Prediction by Value Range Propagation,'' in SIGPLAN Conference on
   Programming Language Design and Implementation, pp. 67-78, 1995.
   Also available at http://citeseer.ist.psu.edu/patterson95accurate.html

   This is essentially an SSA-CCP pass modified to deal with ranges
   instead of constants.

   While propagating ranges, we may find that two or more SSA name
   have equivalent, though distinct ranges.  For instance,

     1  x_9 = p_3->a;
     2  p_4 = ASSERT_EXPR <p_3, p_3 != 0>
     3  if (p_4 == q_2)
     4    p_5 = ASSERT_EXPR <p_4, p_4 == q_2>;
     5  endif
     6  if (q_2)

   In the code above, pointer p_5 has range [q_2, q_2], but from the
   code we can also determine that p_5 cannot be NULL and, if q_2 had
   a non-varying range, p_5's range should also be compatible with it.

   These equivalences are created by two expressions: ASSERT_EXPR and
   copy operations.  Since p_5 is an assertion on p_4, and p_4 was the
   result of another assertion, then we can use the fact that p_5 and
   p_4 are equivalent when evaluating p_5's range.

   Together with value ranges, we also propagate these equivalences
   between names so that we can take advantage of information from
   multiple ranges when doing final replacement.  Note that this
   equivalency relation is transitive but not symmetric.

   In the example above, p_5 is equivalent to p_4, q_2 and p_3, but we
   cannot assert that q_2 is equivalent to p_5 because q_2 may be used
   in contexts where that assertion does not hold (e.g., in line 6).

   TODO, the main difference between this pass and Patterson's is that
   we do not propagate edge probabilities.  We only compute whether
   edges can be taken or not.  That is, instead of having a spectrum
   of jump probabilities between 0 and 1, we only deal with 0, 1 and
   DON'T KNOW.  In the future, it may be worthwhile to propagate
   probabilities to aid branch prediction.   

References CDI_DOMINATORS, finalize_jump_threads(), free_dominance_info(), free_numbers_of_iterations_estimates(), gimple_switch_label(), gimple_switch_set_label(), gimple_switch_set_num_labels(), insert_range_assertions(), loop_optimizer_finalize(), loop_optimizer_init(), LOOPS_HAVE_RECORDED_EXITS, LOOPS_NEED_FIXUP, loops_state_set(), mark_dfs_back_edges(), remove_edge(), remove_range_assertions(), rewrite_into_loop_closed_ssa(), scev_finalize(), scev_initialize(), ssa_propagate(), switch_update::stmt, threadedge_finalize_values(), threadedge_initialize_values(), update_ssa(), switch_update::vec, vrp_finalize(), vrp_initialize(), vrp_visit_phi_node(), and vrp_visit_stmt().

static bool extract_code_and_val_from_cond_with_ops ( tree  name,
enum tree_code  cond_code,
tree  cond_op0,
tree  cond_op1,
bool  invert,
enum tree_code code_p,
tree val_p 
)
static
(COND_OP0 COND_CODE COND_OP1) is a predicate which uses NAME.
   Extract a suitable test code and value and store them into *CODE_P and
   *VAL_P so the predicate is normalized to NAME *CODE_P *VAL_P.

   If no extraction was possible, return FALSE, otherwise return TRUE.

   If INVERT is true, then we invert the result stored into *CODE_P.   

References compare_values(), invert_tree_comparison(), and swap_tree_comparison().

Referenced by register_edge_assert_for(), and register_edge_assert_for_2().

static void extract_range_from_binary_expr ( value_range_t vr,
enum tree_code  code,
tree  expr_type,
tree  op0,
tree  op1 
)
static
Extract range information from a binary expression OP0 CODE OP1 based on
   the ranges of each of its operands with resulting type EXPR_TYPE.
   The resulting range is stored in *VR.   

References extract_range_from_binary_expr_1(), get_value_range(), is_gimple_min_invariant(), set_value_range_to_value(), and set_value_range_to_varying().

Referenced by adjust_range_with_scev(), and extract_range_from_assignment().

static void extract_range_from_binary_expr_1 ( value_range_t vr,
enum tree_code  code,
tree  expr_type,
value_range_t vr0_,
value_range_t vr1_ 
)
static
Extract range information from a binary operation CODE based on
   the ranges of each of its operands, *VR0 and *VR1 with resulting
   type EXPR_TYPE.  The resulting range is stored in *VR.   

References abs_extent_range(), double_int::and_not(), build_int_cst(), function::can_throw_non_call_exceptions, cfun, double_int::cmp(), compare_tree_int(), compare_values(), double_int_to_tree(), double_int::ext(), extract_range_from_multiplicative_op_1(), fold_unary_to_constant(), int_const_binop(), is_gimple_min_invariant(), double_int::is_negative(), is_negative_overflow_infinity(), is_overflow_infinity(), is_positive_overflow_infinity(), double_int::is_zero(), double_int::llshift(), value_range_d::max, double_int::max(), double_int::max_value(), value_range_d::min, double_int::min(), double_int::min_value(), needs_overflow_infinity(), negative_overflow_infinity(), positive_overflow_infinity(), quad_int_pair_sort(), range_includes_zero_p(), range_int_cst_p(), range_int_cst_singleton_p(), range_is_nonnull(), range_is_null(), ranges_from_anti_range(), set_and_canonicalize_value_range(), set_value_range(), set_value_range_to_nonnull(), set_value_range_to_null(), set_value_range_to_undefined(), set_value_range_to_varying(), double_int::sext(), double_int::slt(), supports_overflow_infinity(), symbolic_range_p(), tree_int_cst_lt(), tree_int_cst_sgn(), tree_to_double_int(), value_range_d::type, type(), double_int::ult(), value_range_nonnegative_p(), VR_ANTI_RANGE, VR_RANGE, VR_UNDEFINED, VR_VARYING, vrp_int_const_binop(), vrp_meet(), vrp_val_is_max(), vrp_val_is_min(), vrp_val_max(), vrp_val_min(), double_int::wide_mul_with_sign(), zero_nonzero_bits_from_vr(), and double_int::zext().

Referenced by extract_range_from_binary_expr(), and extract_range_from_unary_expr_1().

static void extract_range_from_comparison ( value_range_t vr,
enum tree_code  code,
tree  type,
tree  op0,
tree  op1 
)
static
Extract range information from a comparison expression EXPR based
   on the range of its operand and the expression code.   

References value_range_d::equiv, is_gimple_min_invariant(), is_overflow_infinity(), set_value_range(), set_value_range_to_truthvalue(), set_value_range_to_value(), VR_RANGE, and vrp_evaluate_conditional_warnv_with_ops().

Referenced by extract_range_from_assignment().

static void extract_range_from_cond_expr ( )
static
Extract range information from a conditional expression STMT based on
   the ranges of each of its operands and the expression code.   

References copy_value_range(), get_value_range(), gimple_assign_rhs2(), gimple_assign_rhs3(), is_gimple_min_invariant(), set_value_range_to_value(), set_value_range_to_varying(), and vrp_meet().

Referenced by extract_range_from_assignment().

static void extract_range_from_multiplicative_op_1 ( value_range_t vr,
enum tree_code  code,
value_range_t vr0,
value_range_t vr1 
)
static
static void extract_range_from_ssa_name ( )
static
Extract range information from SSA name VAR and store it in VR.  If
   VAR has an interesting range, use it.  Otherwise, create the
   range [VAR, VAR] and return it.  This is useful in situations where
   we may have conditionals testing values of VARYING names.  For
   instance,

        x_3 = y_5;
        if (x_3 > y_5)
          ...

    Even if y_5 is deemed VARYING, we can determine that x_3 > y_5 is
    always false.   

References add_equivalence(), copy_value_range(), value_range_d::equiv, get_value_range(), set_value_range(), value_range_d::type, VR_RANGE, VR_UNDEFINED, and VR_VARYING.

Referenced by extract_range_from_assignment().

static void extract_range_from_unary_expr ( value_range_t vr,
enum tree_code  code,
tree  type,
tree  op0 
)
static
Extract range information from a unary expression CODE OP0 based on
   the range of its operand with resulting type TYPE.
   The resulting range is stored in *VR.   

References extract_range_from_unary_expr_1(), get_value_range(), is_gimple_min_invariant(), set_value_range_to_value(), and set_value_range_to_varying().

Referenced by extract_range_from_assignment().

static void finalize_jump_threads ( )
static
We identified all the jump threading opportunities earlier, but could
   not transform the CFG at that time.  This routine transforms the
   CFG and arranges for the dominator tree to be rebuilt if necessary.

   Note the SSA graph update will occur during the normal TODO
   processing by the pass manager.   

References thread_through_all_blocks().

Referenced by execute_vrp().

static bool find_assert_locations ( )
static
Do an RPO walk over the function computing SSA name liveness
   on-the-fly and deciding on assert expressions to insert.
   Returns true if there are assert expressions to be inserted.   

References case_info::bb, bitmap_clear(), bitmap_empty_p(), bitmap_ior(), edge_def::dest, find_assert_locations_1(), edge_def::flags, basic_block_def::index, pre_and_rev_post_order_compute(), basic_block_def::preds, sbitmap_alloc(), sbitmap_free(), edge_def::src, and basic_block_def::succs.

Referenced by insert_range_assertions().

static bool find_assert_locations_1 ( )
static
Traverse all the statements in block BB looking for statements that
   may generate useful assertions for the SSA names in their operand.
   If a statement produces a useful assertion A for name N_i, then the
   list of assertions already generated for N_i is scanned to
   determine if A is actually needed.

   If N_i already had the assertion A at a location dominating the
   current location, then nothing needs to be done.  Otherwise, the
   new location for A is recorded instead.

   1- For every statement S in BB, all the variables used by S are
      added to bitmap FOUND_IN_SUBGRAPH.

   2- If statement S uses an operand N in a way that exposes a known
      value range for N, then if N was not already generated by an
      ASSERT_EXPR, create a new assert location for N.  For instance,
      if N is a pointer and the statement dereferences it, we can
      assume that N is not NULL.

   3- COND_EXPRs are a special case of #2.  We can derive range
      information from the predicate but need to insert different
      ASSERT_EXPRs for each of the sub-graphs rooted at the
      conditional block.  If the last statement of BB is a conditional
      expression of the form 'X op Y', then

      a) Remove X and Y from the set FOUND_IN_SUBGRAPH.

      b) If the conditional is the only entry point to the sub-graph
         corresponding to the THEN_CLAUSE, recurse into it.  On
         return, if X and/or Y are marked in FOUND_IN_SUBGRAPH, then
         an ASSERT_EXPR is added for the corresponding variable.

      c) Repeat step (b) on the ELSE_CLAUSE.

      d) Mark X and Y in FOUND_IN_SUBGRAPH.

      For instance,

            if (a == 9)
              b = a;
            else
              b = c + 1;

      In this case, an assertion on the THEN clause is useful to
      determine that 'a' is always 9 on that edge.  However, an assertion
      on the ELSE clause would be unnecessary.

   4- If BB does not end in a conditional expression, then we recurse
      into BB's dominator children.

   At the end of the recursive traversal, every SSA name will have a
   list of locations where ASSERT_EXPRs should be added.  When a new
   location for name N is found, it is registered by calling
   register_new_assert_for.  That function keeps track of all the
   registered assertions to prevent adding unnecessary assertions.
   For instance, if a pointer P_4 is dereferenced more than once in a
   dominator tree, only the location dominating all the dereference of
   P_4 will receive an ASSERT_EXPR.

   If this function returns true, then it means that there are names
   for which we need to generate ASSERT_EXPRs.  Those assertions are
   inserted by process_assert_insertions.   

References bitmap_bit_p(), bitmap_clear_bit(), bitmap_set_bit(), find_conditional_asserts(), find_switch_asserts(), fp_predicate(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_phi_result(), gsi_end_p(), gsi_last_bb(), gsi_next(), gsi_prev(), gsi_start_phis(), gsi_stmt(), has_single_use(), infer_value_range(), integer_zerop(), is_gimple_assign(), is_gimple_debug(), last, last_stmt(), register_new_assert_for(), si, and virtual_operand_p().

Referenced by find_assert_locations().

static bool find_case_label_index ( )
static
Searches the case label vector VEC for the index *IDX of the CASE_LABEL
   that includes the value VAL.  The search is restricted to the range
   [START_IDX, n - 1] where n is the size of VEC.

   If there is a CASE_LABEL for VAL, its index is placed in IDX and true is
   returned.

   If there is no CASE_LABEL for VAL and there is one that is larger than VAL,
   it is placed in IDX and false is returned.

   If VAL is larger than any CASE_LABEL, n is placed on IDX and false is
   returned.  

References gimple_switch_label(), gimple_switch_num_labels(), and tree_int_cst_compare().

Referenced by find_case_label_range(), and simplify_switch_using_ranges().

static bool find_case_label_range ( gimple  stmt,
tree  min,
tree  max,
size_t *  min_idx,
size_t *  max_idx 
)
static
Searches the case label vector VEC for the range of CASE_LABELs that is used
   for values between MIN and MAX. The first index is placed in MIN_IDX. The
   last index is placed in MAX_IDX. If the range of CASE_LABELs is empty
   then MAX_IDX < MIN_IDX.
   Returns true if the default label is not needed.  

References find_case_label_index(), gimple_switch_label(), int_const_binop(), and integer_onep().

Referenced by find_case_label_ranges().

static bool find_case_label_ranges ( gimple  stmt,
value_range_t vr,
size_t *  min_idx1,
size_t *  max_idx1,
size_t *  min_idx2,
size_t *  max_idx2 
)
static
Searches the case label vector VEC for the ranges of CASE_LABELs that are
   used in range VR.  The indices are placed in MIN_IDX1, MAX_IDX, MIN_IDX2 and
   MAX_IDX2.  If the ranges of CASE_LABELs are empty then MAX_IDX1 < MIN_IDX1.
   Returns true if the default label is not needed.   

References find_case_label_range(), gimple_switch_label(), gimple_switch_num_labels(), value_range_d::max, value_range_d::min, tree_int_cst_compare(), value_range_d::type, VR_ANTI_RANGE, and VR_RANGE.

Referenced by simplify_switch_using_ranges(), and vrp_visit_switch_stmt().

static bool find_conditional_asserts ( )
static
Determine whether the outgoing edges of BB should receive an
   ASSERT_EXPR for each of the operands of BB's LAST statement.
   The last statement of BB must be a COND_EXPR.

   If any of the sub-graphs rooted at BB have an interesting use of
   the predicate operands, an assert location node is added to the
   list of assertions for the corresponding operands.   

References edge_def::dest, gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gsi_for_stmt(), register_edge_assert_for(), and basic_block_def::succs.

Referenced by find_assert_locations_1().

static bool find_switch_asserts ( )
static
Determine whether the outgoing edges of BB should receive an
   ASSERT_EXPR for each of the operands of BB's LAST statement.
   The last statement of BB must be a SWITCH_EXPR.

   If any of the sub-graphs rooted at BB have an interesting use of
   the predicate operands, an assert location node is added to the
   list of assertions for the corresponding operands.   

References case_info::bb, compare_case_labels(), case_info::expr, find_edge(), gimple_switch_index(), gimple_switch_label(), gimple_switch_num_labels(), gsi_for_stmt(), and register_edge_assert_for().

Referenced by find_assert_locations_1().

static bool fold_predicate_in ( )
static
If the statement pointed by SI has a predicate whose value can be
   computed using the value range information computed by VRP, compute
   its value and return true.  Otherwise, return false.   

References dump_file, gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs_from_tree(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_make_false(), gimple_cond_make_true(), gimple_cond_rhs(), gimple_expr_type(), gsi_stmt(), integer_onep(), integer_zerop(), is_gimple_assign(), print_generic_expr(), print_gimple_expr(), tcc_comparison, and vrp_evaluate_conditional().

Referenced by vrp_fold_stmt().

static bool fp_predicate ( )
inlinestatic
Return false if EXPR is a predicate expression involving floating
   point values.   

References gimple_cond_lhs().

Referenced by find_assert_locations_1().

static bool gate_vrp ( )
static
static value_range_t get_vr_for_comparison ( )
inlinestatic
Helper that gets the value range of the SSA_NAME with version I
   or a symbolic range containing the SSA_NAME only if the value range
   is varying or undefined.   

References get_value_range(), value_range_d::max, value_range_d::min, value_range_d::type, VR_RANGE, VR_UNDEFINED, and VR_VARYING.

Referenced by compare_name_with_value(), and compare_names().

static bool gimple_assign_nonnegative_warnv_p ( )
static
Return true if the result of assignment STMT is know to be non-negative.
   If the return value is based on the assumption that signed overflow is
   undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
   *STRICT_OVERFLOW_P. 

References get_gimple_rhs_class(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), GIMPLE_BINARY_RHS, gimple_expr_type(), GIMPLE_INVALID_RHS, GIMPLE_SINGLE_RHS, GIMPLE_TERNARY_RHS, GIMPLE_UNARY_RHS, tree_binary_nonnegative_warnv_p(), tree_single_nonnegative_warnv_p(), and tree_unary_nonnegative_warnv_p().

Referenced by gimple_stmt_nonnegative_warnv_p().

static bool gimple_assign_nonzero_warnv_p ( )
static
Return true if the result of assignment STMT is know to be non-zero.
   If the return value is based on the assumption that signed overflow is
   undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
   *STRICT_OVERFLOW_P. 

References get_gimple_rhs_class(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), GIMPLE_BINARY_RHS, gimple_expr_type(), GIMPLE_INVALID_RHS, GIMPLE_SINGLE_RHS, GIMPLE_TERNARY_RHS, GIMPLE_UNARY_RHS, tree_binary_nonzero_warnv_p(), tree_single_nonzero_warnv_p(), and tree_unary_nonzero_warnv_p().

Referenced by gimple_stmt_nonzero_warnv_p().

static bool gimple_call_nonnegative_warnv_p ( )
static
Return true if return value of call STMT is know to be non-negative.
   If the return value is based on the assumption that signed overflow is
   undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
   *STRICT_OVERFLOW_P. 

References gimple_call_arg(), gimple_call_fndecl(), gimple_call_num_args(), gimple_expr_type(), and tree_call_nonnegative_warnv_p().

Referenced by gimple_stmt_nonnegative_warnv_p().

static bool gimple_stmt_nonnegative_warnv_p ( )
static
Return true if STMT is know to to compute a non-negative value.
   If the return value is based on the assumption that signed overflow is
   undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
   *STRICT_OVERFLOW_P. 

References gimple_assign_nonnegative_warnv_p(), and gimple_call_nonnegative_warnv_p().

Referenced by extract_range_basic().

static bool gimple_stmt_nonzero_warnv_p ( )
static
Return true if STMT is know to to compute a non-zero value.
   If the return value is based on the assumption that signed overflow is
   undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't change
   *STRICT_OVERFLOW_P. 

References gimple_alloca_call_p(), and gimple_assign_nonzero_warnv_p().

Referenced by vrp_stmt_computes_nonzero().

static void identify_jump_threads ( )
static
Blocks which have more than one predecessor and more than
   one successor present jump threading opportunities, i.e.,
   when the block is reached from a specific predecessor, we
   may be able to determine which of the outgoing edges will
   be traversed.  When this optimization applies, we are able
   to avoid conditionals at runtime and we may expose secondary
   optimization opportunities.

   This routine is effectively a driver for the generic jump
   threading code.  It basically just presents the generic code
   with edges that may be suitable for jump threading.

   Unlike DOM, we do not iterate VRP if jump threading was successful.
   While iterating may expose new opportunities for VRP, it is expected
   those opportunities would be very limited and the compile time cost
   to expose those opportunities would be significant.

   As jump threading opportunities are discovered, they are registered
   for later realization.   

References calculate_dominance_info(), CDI_DOMINATORS, edge_def::flags, gimple_build_cond(), gimple_cond_lhs(), gimple_cond_rhs(), gsi_last_bb(), gsi_stmt(), is_gimple_min_invariant(), last, mark_dfs_back_edges(), potentially_threadable_block(), basic_block_def::preds, simplify_stmt_for_jump_threading(), and thread_across_edge().

Referenced by vrp_finalize().

static bool infer_value_range ( )
static
If the range of values taken by OP can be inferred after STMT executes,
   return the comparison code (COMP_CODE_P) and value (VAL_P) that
   describes the inferred range.  Return true if a range could be
   inferred.   

References build_int_cst(), count_uses_and_derefs(), num_stores, stmt_could_throw_p(), and stmt_ends_bb_p().

Referenced by find_assert_locations_1().

static void insert_range_assertions ( )
static
Traverse the flowgraph looking for conditional jumps to insert range
   expressions.  These range expressions are meant to provide information
   to optimizations that need to reason in terms of value ranges.  They
   will not be expanded into RTL.  For instance, given:

   x = ...
   y = ...
   if (x < y)
     y = x - 2;
   else
     x = y + 3;

   this pass will transform the code into:

   x = ...
   y = ...
   if (x < y)
    {
      x = ASSERT_EXPR <x, x < y>
      y = x - 2
    }
   else
    {
      y = ASSERT_EXPR <y, x <= y>
      x = y + 3
    }

   The idea is that once copy and constant propagation have run, other
   optimizations will be able to determine what ranges of values can 'x'
   take in different paths of the code, simply by checking the reaching
   definition of 'x'.   

References calculate_dominance_info(), CDI_DOMINATORS, current_function_decl, dump_file, dump_flags, dump_function_to_file(), find_assert_locations(), free(), process_assert_insertions(), and update_ssa().

Referenced by execute_vrp().

static void intersect_ranges ( enum value_range_type vr0type,
tree vr0min,
tree vr0max,
enum value_range_type  vr1type,
tree  vr1min,
tree  vr1max 
)
static
Intersect the two value-ranges { *VR0TYPE, *VR0MIN, *VR0MAX } and
   { VR1TYPE, VR0MIN, VR0MAX } and store the result
   in { *VR0TYPE, *VR0MIN, *VR0MAX }.  This may not be the smallest
   possible such range.  The resulting range is not canonicalized.   

References int_const_binop(), integer_onep(), operand_equal_p(), operand_less_p(), VR_ANTI_RANGE, VR_RANGE, VR_UNDEFINED, vrp_val_is_max(), and vrp_val_is_min().

Referenced by vrp_intersect_ranges_1().

static bool is_negative_overflow_infinity ( )
inlinestatic
static bool is_positive_overflow_infinity ( )
inlinestatic
static bool live_on_edge ( )
static
Return true if the SSA name NAME is live on the edge E.   

References bitmap_bit_p(), edge_def::dest, and basic_block_def::index.

Referenced by register_edge_assert_for_2(), and thread_prologue_and_epilogue_insns().

static tree make_overflow_infinity ( )
inlinestatic
VAL is the maximum or minimum value of a type.  Return a
   corresponding overflow infinity.   

References copy_node().

Referenced by negative_overflow_infinity(), and positive_overflow_infinity().

gimple_opt_pass* make_pass_vrp ( )
static double_int masked_increment ( double_int  val,
double_int  mask,
double_int  sgnbit,
unsigned int  prec 
)
static
Find out smallest RES where RES > VAL && (RES & MASK) == RES, if any
   (otherwise return VAL).  VAL and MASK must be zero-extended for
   precision PREC.  If SGNBIT is non-zero, first xor VAL with SGNBIT
   (to transform signed values into unsigned) and at the end xor
   SGNBIT back.   

Referenced by register_edge_assert_for_2().

static bool needs_overflow_infinity ( )
inlinestatic
Return whether TYPE should use an overflow infinity distinct from
   TYPE_{MIN,MAX}_VALUE.  We use an overflow infinity value to
   represent a signed overflow during VRP computations.  An infinity
   is distinct from a half-range, which will go from some number to
   TYPE_{MIN,MAX}_VALUE.   

Referenced by extract_range_from_binary_expr_1(), extract_range_from_unary_expr_1(), is_negative_overflow_infinity(), is_overflow_infinity(), is_positive_overflow_infinity(), set_and_canonicalize_value_range(), set_value_range(), supports_overflow_infinity(), vrp_int_const_binop(), and vrp_visit_phi_node().

static tree negative_overflow_infinity ( )
inlinestatic
static bool nonnull_arg_p ( )
static
Return true if ARG is marked with the nonnull attribute in the
   current function signature.   

References cfun, compare_tree_int(), current_function_decl, HOST_WIDE_INT, lookup_attribute(), and function::static_chain_decl.

Referenced by get_value_range().

static bool op_with_boolean_value_range_p ( )
static
Return true if op is in a boolean [0, 1] value-range.   

References get_value_range(), integer_onep(), integer_zerop(), value_range_d::max, value_range_d::min, value_range_d::type, and VR_RANGE.

Referenced by simplify_truth_ops_using_ranges().

static tree op_with_constant_singleton_value_range ( )
static
If OP has a value range with a single constant value return that,
   otherwise return NULL_TREE.  This returns OP itself if OP is a
   constant.   

References get_value_range(), is_gimple_min_invariant(), and value_range_constant_singleton().

Referenced by adjust_range_with_scev(), and vrp_finalize().

static bool overflow_infinity_range_p ( )
inlinestatic
Return true if value range VR uses an overflow infinity.   

References is_overflow_infinity(), value_range_d::max, value_range_d::min, value_range_d::type, and VR_RANGE.

Referenced by compare_range_with_value(), compare_ranges(), and extract_range_from_unary_expr_1().

static tree positive_overflow_infinity ( )
inlinestatic
static void process_assert_insertions ( )
static
Process all the insertions registered for every name N_i registered
   in NEED_ASSERT_FOR.  The list of assertions to be inserted are
   found in ASSERTS_FOR[i].   

References cfun, dump_all_asserts(), dump_file, dump_flags, free(), gsi_commit_edge_inserts(), assert_locus_d::next, process_assert_insertions_for(), and statistics_counter_event().

Referenced by insert_range_assertions().

static bool process_assert_insertions_for ( )
static
static int quad_int_cmp ( double_int  l0,
double_int  h0,
double_int  l1,
double_int  h1,
bool  uns 
)
static
Some quadruple precision helpers.   

References double_int::cmp(), and double_int::ucmp().

Referenced by quad_int_pair_sort().

static void quad_int_pair_sort ( double_int l0,
double_int h0,
double_int l1,
double_int h1,
bool  uns 
)
static
static bool range_fits_type_p ( )
static
Return whether the value range *VR fits in an integer type specified
   by PRECISION and UNSIGNED_P.   

References double_int::ext(), value_range_d::max, value_range_d::min, tree_to_double_int(), value_range_d::type, and VR_RANGE.

Referenced by simplify_cond_using_ranges(), and simplify_float_conversion_using_ranges().

static int range_includes_zero_p ( )
inlinestatic
Return 1 if [MIN, MAX] includes the value zero, 0 if it does not
   include the value zero, -2 if we cannot tell.   

References build_int_cst(), and value_inside_range().

Referenced by extract_range_from_binary_expr_1(), extract_range_from_unary_expr_1(), and vrp_meet_1().

static bool range_int_cst_p ( )
inlinestatic
Return true if max and min of VR are INTEGER_CST.  It's not necessary
   a singleton.   

References value_range_d::max, value_range_d::min, value_range_d::type, and VR_RANGE.

Referenced by extract_range_from_binary_expr_1(), range_int_cst_singleton_p(), simplify_cond_using_ranges(), and zero_nonzero_bits_from_vr().

static bool range_int_cst_singleton_p ( )
inlinestatic
static bool range_is_nonnull ( )
inlinestatic
static bool range_is_null ( )
inlinestatic
static bool ranges_from_anti_range ( value_range_t ar,
value_range_t vr0,
value_range_t vr1 
)
static
Create two value-ranges in *VR0 and *VR1 from the anti-range *AR
   so that *VR0 U *VR1 == *AR.  Returns true if that is possible,
   false otherwise.  If *AR can be represented with a single range
   *VR1 will be VR_UNDEFINED.   

References double_int_to_tree(), value_range_d::max, value_range_d::min, tree_to_double_int(), value_range_d::type, VR_ANTI_RANGE, VR_RANGE, VR_UNDEFINED, vrp_val_is_max(), vrp_val_is_min(), vrp_val_max(), and vrp_val_min().

Referenced by extract_range_from_binary_expr_1(), and extract_range_from_unary_expr_1().

static bool register_edge_assert_for ( tree  name,
edge  e,
gimple_stmt_iterator  si,
enum tree_code  cond_code,
tree  cond_op0,
tree  cond_op1 
)
static
Try to register an edge assertion for SSA name NAME on edge E for
   the condition COND contributing to the conditional jump pointed to by SI.
   Return true if an assertion for NAME could be registered.   

References extract_code_and_val_from_cond_with_ops(), edge_def::flags, gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), integer_onep(), integer_zerop(), is_gimple_assign(), register_edge_assert_for_1(), and register_edge_assert_for_2().

Referenced by find_conditional_asserts(), and find_switch_asserts().

static bool register_edge_assert_for_1 ( tree  op,
enum tree_code  code,
edge  e,
gimple_stmt_iterator  bsi 
)
static
OP is an operand of a truth value expression which is known to have
   a particular value.  Register any asserts for OP and for any
   operands in OP's defining statement.

   If CODE is EQ_EXPR, then we want to register OP is zero (false),
   if CODE is NE_EXPR, then we want to register OP is nonzero (true).    

References build_int_cst(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), has_single_use(), invert_tree_comparison(), register_edge_assert_for_2(), register_new_assert_for(), and tcc_comparison.

Referenced by register_edge_assert_for().

static void register_new_assert_for ( tree  name,
tree  expr,
enum tree_code  comp_code,
tree  val,
basic_block  bb,
edge  e,
gimple_stmt_iterator  si 
)
static
If NAME doesn't have an ASSERT_EXPR registered for asserting
   'EXPR COMP_CODE VAL' at a location that dominates block BB or
   E->DEST, then register this location as a possible insertion point
   for ASSERT_EXPR <NAME, EXPR COMP_CODE VAL>.

   BB, E and SI provide the exact insertion point for the new
   ASSERT_EXPR.  If BB is NULL, then the ASSERT_EXPR is to be inserted
   on edge E.  Otherwise, if E is NULL, the ASSERT_EXPR is inserted on
   BB.  If SI points to a COND_EXPR or a SWITCH_EXPR statement, then E
   must not be NULL.   

References assert_locus_d::bb, bitmap_set_bit(), build_int_cst_wide(), CDI_DOMINATORS, assert_locus_d::comp_code, edge_def::dest, dominated_by_p(), assert_locus_d::e, assert_locus_d::expr, gsi_stmt(), assert_locus_d::next, operand_equal_p(), si, assert_locus_d::si, and assert_locus_d::val.

Referenced by find_assert_locations_1(), register_edge_assert_for_1(), and register_edge_assert_for_2().

static void remove_range_assertions ( )
static
Convert range assertion expressions into the implied copies and
   copy propagate away the copies.  Doing the trivial copy propagation
   here avoids the need to run the full copy propagation pass after
   VRP.

   FIXME, this will eventually lead to copy propagation removing the
   names that had useful range information attached to them.  For
   instance, if we had the assertion N_i = ASSERT_EXPR <N_j, N_j > 3>,
   then N_i will have the range [3, +INF].

   However, by converting the assertion into the implied copy
   operation N_i = N_j, we will then copy-propagate N_j into the uses
   of N_i and lose the range information.  We may want to hold on to
   ASSERT_EXPRs a little while longer as the ranges could be used in
   things like jump threading.

   The problem with keeping ASSERT_EXPRs around is that passes after
   VRP need to handle them appropriately.

   Another approach would be to make the range information a first
   class property of the SSA_NAME so that it can be queried from
   any pass.  This is made somewhat more complex by the need for
   multiple ranges to be associated with one SSA_NAME.   

References fold(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gsi_end_p(), gsi_next(), gsi_remove(), gsi_start_bb(), gsi_stmt(), is_gimple_assign(), release_defs(), and si.

Referenced by execute_vrp().

static void search_for_addr_array ( )
static
static void set_and_canonicalize_value_range ( value_range_t vr,
enum value_range_type  t,
tree  min,
tree  max,
bitmap  equiv 
)
static
Set value range VR to the canonical form of {T, MIN, MAX, EQUIV}.
   This means adjusting T, MIN and MAX representing the case of a
   wrapping range with MAX < MIN covering [MIN, type_max] U [type_min, MAX]
   as anti-rage ~[MAX+1, MIN-1].  Likewise for wrapping anti-ranges.
   In corner cases where MAX+1 or MIN-1 wraps this will fall back
   to varying.
   This routine exists to ease canonicalization in the case where we
   extract ranges from var + CST op limit.   

References build_int_cst(), int_const_binop(), integer_zerop(), is_overflow_infinity(), needs_overflow_infinity(), set_value_range(), set_value_range_to_undefined(), set_value_range_to_varying(), tree_int_cst_lt(), VR_ANTI_RANGE, VR_RANGE, VR_UNDEFINED, VR_VARYING, vrp_val_is_max(), vrp_val_is_min(), vrp_val_max(), and vrp_val_min().

Referenced by abs_extent_range(), extract_range_from_assert(), extract_range_from_binary_expr_1(), extract_range_from_unary_expr_1(), vrp_intersect_ranges_1(), and vrp_meet_1().

static void set_value_range_to_nonnegative ( value_range_t vr,
tree  type,
bool  overflow_infinity 
)
inlinestatic
Set value range VR to a non-negative range of type TYPE.
   OVERFLOW_INFINITY indicates whether to use an overflow infinity
   rather than TYPE_MAX_VALUE; this should be true if we determine
   that the range is nonnegative based on the assumption that signed
   overflow does not occur.   

References build_int_cst(), value_range_d::equiv, positive_overflow_infinity(), set_value_range(), set_value_range_to_varying(), supports_overflow_infinity(), and VR_RANGE.

Referenced by extract_range_basic().

static void set_value_range_to_nonnull ( )
inlinestatic
static void set_value_range_to_null ( )
inlinestatic
static void set_value_range_to_truthvalue ( )
inlinestatic
Set value range VR to a range of a truthvalue of type TYPE.   

References build_int_cst(), value_range_d::equiv, set_value_range(), set_value_range_to_varying(), and VR_RANGE.

Referenced by extract_range_from_comparison().

static void set_value_range_to_value ( )
inlinestatic
Set value range VR to a single value.  This function is only called
   with values we get from statements, and exists to clear the
   TREE_OVERFLOW flag so that we don't think we have an overflow
   infinity when we shouldn't.   

References avoid_overflow_infinity(), is_gimple_min_invariant(), set_value_range(), and VR_RANGE.

Referenced by adjust_range_with_scev(), extract_range_from_assignment(), extract_range_from_binary_expr(), extract_range_from_comparison(), extract_range_from_cond_expr(), extract_range_from_unary_expr(), extract_range_from_unary_expr_1(), set_value_range_to_null(), and simplify_bit_ops_using_ranges().

static bool simplify_abs_using_ranges ( )
static
If the operand to an ABS_EXPR is >= 0, then eliminate the
   ABS_EXPR.  If the operand is <= 0, then simplify the
   ABS_EXPR into a NEGATE_EXPR.   

References compare_range_with_value(), get_value_range(), gimple_assign_rhs1(), gimple_assign_set_rhs1(), gimple_assign_set_rhs_code(), gimple_has_location(), gimple_location(), input_location, integer_onep(), integer_zerop(), update_stmt(), WARN_STRICT_OVERFLOW_MISC, and warning_at().

Referenced by simplify_stmt_using_ranges().

static bool simplify_bit_ops_using_ranges ( )
static
Optimize away redundant BIT_AND_EXPR and BIT_IOR_EXPR.
   If all the bits that are being cleared by & are already
   known to be zero from VR, or all the bits that are being
   set by | are already known to be one from VR, the bit
   operation is redundant.   

References double_int::and_not(), get_value_range(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs_with_ops(), gsi_stmt(), is_gimple_min_invariant(), double_int::is_zero(), set_value_range_to_value(), update_stmt(), and zero_nonzero_bits_from_vr().

Referenced by simplify_stmt_using_ranges().

static bool simplify_div_or_mod_using_ranges ( )
static
static tree simplify_stmt_for_jump_threading ( )
static
A trivial wrapper so that we can present the generic jump threading
   code with a simple API for simplifying statements.  STMT is the
   statement we want to simplify, WITHIN_STMT provides the location
   for any overflow warnings.   

References extract_range_from_assignment(), gimple_assign_lhs(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), value_range_d::min, range_int_cst_singleton_p(), and vrp_evaluate_conditional().

Referenced by identify_jump_threads().

bool ssa_name_nonnegative_p ( )
Return true if T, an SSA_NAME, is known to be nonnegative.  Return
   false otherwise or if no value range information is available.   

References get_value_range(), and value_range_nonnegative_p().

static bool stmt_interesting_for_vrp ( )
static
static bool stmt_overflow_infinity ( )
inlinestatic
Return whether STMT has a constant rhs that is_overflow_infinity.  

References get_gimple_rhs_class(), gimple_assign_rhs1(), gimple_assign_rhs_code(), GIMPLE_SINGLE_RHS, is_gimple_assign(), and is_overflow_infinity().

Referenced by extract_range_basic().

static bool supports_overflow_infinity ( )
inlinestatic
Return whether TYPE can support our overflow infinity
   representation: we use the TREE_OVERFLOW flag, which only exists
   for constants.  If TYPE doesn't support this, we don't optimize
   cases which would require signed overflow--we drop them to
   VARYING.   

References needs_overflow_infinity(), vrp_val_max(), and vrp_val_min().

Referenced by extract_range_from_binary_expr_1(), extract_range_from_unary_expr_1(), negative_overflow_infinity(), positive_overflow_infinity(), set_value_range_to_nonnegative(), vrp_int_const_binop(), and vrp_visit_phi_node().

static bool symbolic_range_p ( )
inlinestatic
static tree test_for_singularity ( enum tree_code  cond_code,
tree  op0,
tree  op1,
value_range_t vr 
)
static
We are comparing trees OP0 and OP1 using COND_CODE.  OP0 has
   a known value range VR.

   If there is one and only one value which will satisfy the
   conditional, then return that value.  Else return NULL.   

References build_int_cst(), compare_values(), is_gimple_min_invariant(), is_overflow_infinity(), value_range_d::max, value_range_d::min, and operand_equal_p().

Referenced by simplify_cond_using_ranges().

static void union_ranges ( enum value_range_type vr0type,
tree vr0min,
tree vr0max,
enum value_range_type  vr1type,
tree  vr1min,
tree  vr1max 
)
static
Union the two value-ranges { *VR0TYPE, *VR0MIN, *VR0MAX } and
   { VR1TYPE, VR0MIN, VR0MAX } and store the result
   in { *VR0TYPE, *VR0MIN, *VR0MAX }.  This may not be the smallest
   possible such range.  The resulting range is not canonicalized.   

References int_const_binop(), operand_equal_p(), operand_less_p(), VR_ANTI_RANGE, VR_RANGE, VR_VARYING, vrp_val_is_max(), and vrp_val_is_min().

Referenced by vrp_meet_1().

static bool update_value_range ( )
inlinestatic
Update the value range and equivalence set for variable VAR to
   NEW_VR.  Return true if NEW_VR is different from VAR's previous
   value.

   NOTE: This function assumes that NEW_VR is a temporary value range
   object created for the sole purpose of updating VAR's range.  The
   storage used by the equivalence set from NEW_VR will be freed by
   this function.  Do not call update_value_range when NEW_VR
   is the range object associated with another SSA name.   

References value_range_d::equiv, get_value_range(), value_range_d::max, value_range_d::min, set_value_range(), set_value_range_to_varying(), value_range_d::type, VR_UNDEFINED, VR_VARYING, vrp_bitmap_equal_p(), and vrp_operand_equal_p().

Referenced by vrp_visit_assignment_or_call(), and vrp_visit_phi_node().

static bool usable_range_p ( )
static
Return false if we can not make a valid comparison based on VR;
   this will be the case if it uses an overflow infinity and overflow
   is not undefined (i.e., -fno-strict-overflow is in effect).
   Otherwise return true, and set *STRICT_OVERFLOW_P to true if VR
   uses an overflow infinity.   

References is_overflow_infinity(), value_range_d::max, value_range_d::min, value_range_d::type, and VR_RANGE.

Referenced by compare_range_with_value(), and compare_ranges().

static bool valid_value_p ( )
static
Returns true if EXPR is a valid value (as expected by compare_values) --
   a gimple invariant, or SSA_NAME +- CST.   

References is_gimple_min_invariant().

Referenced by adjust_range_with_scev(), and vrp_var_may_overflow().

static int value_inside_range ( )
inlinestatic
Return 1 if VAL is inside value range MIN <= VAL <= MAX,
          0 if VAL is not inside [MIN, MAX],
         -2 if we cannot tell either way.

   Benchmark compile/20001226-1.c compilation time after changing this
   function.   

References operand_less_p().

Referenced by compare_range_with_value(), and range_includes_zero_p().

static tree value_range_constant_singleton ( )
static
If *VR has a value rante that is a single constant value return that,
   otherwise return NULL_TREE.   

References is_gimple_min_invariant(), value_range_d::max, value_range_d::min, operand_equal_p(), value_range_d::type, and VR_RANGE.

Referenced by op_with_constant_singleton_value_range().

static bool value_range_nonnegative_p ( )
inlinestatic
Return true if *VR is know to only contain nonnegative values.   

References compare_values(), value_range_d::min, value_range_d::type, and VR_RANGE.

Referenced by extract_range_from_binary_expr_1(), extract_range_from_unary_expr_1(), and ssa_name_nonnegative_p().

static bool value_ranges_intersect_p ( )
inlinestatic
Return true if value ranges VR0 and VR1 have a non-empty
   intersection.

   Benchmark compile/20001226-1.c compilation time after changing this
   function.

References value_range_d::max, value_range_d::min, and operand_less_p().

static bool vrp_bitmap_equal_p ( )
inlinestatic
Return true, if the bitmaps B1 and B2 are equal.   

References bitmap_empty_p(), and bitmap_equal_p().

Referenced by update_value_range().

static tree vrp_evaluate_conditional ( )
static
Given (CODE OP0 OP1) within STMT, try to simplify it based on value range
   information.  Return NULL if the conditional can not be evaluated.
   The ranges of all the names equivalent with the operands in COND
   will be used when trying to compute the value.  If the result is
   based on undefined signed overflow, issue a warning if
   appropriate.   

References get_value_range(), gimple_has_location(), gimple_location(), input_location, integer_zerop(), is_gimple_min_invariant(), value_range_d::max, value_range_d::min, tcc_comparison, value_range_d::type, VR_VARYING, vrp_evaluate_conditional_warnv_with_ops(), vrp_val_is_max(), vrp_val_is_min(), WARN_STRICT_OVERFLOW_COMPARISON, WARN_STRICT_OVERFLOW_CONDITIONAL, and warning_at().

Referenced by fold_predicate_in(), and simplify_stmt_for_jump_threading().

static tree vrp_evaluate_conditional_warnv_with_ops ( enum tree_code  code,
tree  op0,
tree  op1,
bool  use_equiv_p,
bool *  strict_overflow_p,
bool *  only_ranges 
)
static
static tree vrp_evaluate_conditional_warnv_with_ops_using_ranges ( enum tree_code  code,
tree  op0,
tree  op1,
bool *  strict_overflow_p 
)
static
Helper function for vrp_evaluate_conditional_warnv.   

References compare_range_with_value(), compare_ranges(), get_value_range(), and swap_tree_comparison().

Referenced by vrp_evaluate_conditional_warnv_with_ops().

static void vrp_finalize ( )
static
static bool vrp_fold_stmt ( )
static
Callback for substitute_and_fold folding the stmt at *SI.   

References fold_predicate_in(), and simplify_stmt_using_ranges().

Referenced by vrp_finalize().

static tree vrp_int_const_binop ( )
static
Wrapper around int_const_binop.  If the operation overflows and we
   are not using wrapping arithmetic, then adjust the result to be
   -INF or +INF depending on CODE, VAL1 and VAL2.  This can return
   NULL_TREE if we need to use an overflow infinity representation but
   the type does not support it.   

References compare_values(), copy_node(), int_const_binop(), integer_zerop(), is_negative_overflow_infinity(), is_overflow_infinity(), is_positive_overflow_infinity(), needs_overflow_infinity(), negative_overflow_infinity(), positive_overflow_infinity(), supports_overflow_infinity(), and tree_int_cst_sgn().

Referenced by extract_range_from_binary_expr_1(), and extract_range_from_multiplicative_op_1().

static void vrp_intersect_ranges ( value_range_t ,
value_range_t  
)
static
static void vrp_intersect_ranges ( )
static
static void vrp_intersect_ranges_1 ( )
static
Intersect the two value-ranges *VR0 and *VR1 and store the result
   in *VR0.  This may not be the smallest possible such range.   

References bitmap_copy(), bitmap_ior_into(), copy_value_range(), value_range_d::equiv, intersect_ranges(), value_range_d::max, value_range_d::min, set_and_canonicalize_value_range(), set_value_range_to_undefined(), value_range_d::type, VR_UNDEFINED, and VR_VARYING.

Referenced by vrp_intersect_ranges().

static void vrp_meet ( )
static
static void vrp_meet_1 ( )
static
Meet operation for value ranges.  Given two value ranges VR0 and
   VR1, store in VR0 a range that contains both VR0 and VR1.  This
   may not be the smallest possible such range.   

References bitmap_and_into(), bitmap_clear(), value_range_d::equiv, value_range_d::max, value_range_d::min, range_includes_zero_p(), set_and_canonicalize_value_range(), set_value_range(), set_value_range_to_nonnull(), set_value_range_to_varying(), value_range_d::type, union_ranges(), VR_ANTI_RANGE, VR_RANGE, VR_UNDEFINED, and VR_VARYING.

Referenced by vrp_meet().

static bool vrp_operand_equal_p ( )
inlinestatic
Return true, if VAL1 and VAL2 are equal values for VRP purposes.   

References is_overflow_infinity(), and operand_equal_p().

Referenced by update_value_range().

static bool vrp_stmt_computes_nonzero ( )
static
Like tree_expr_nonzero_warnv_p, but this function uses value ranges
   obtained so far.   

References get_base_address(), get_value_range(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_stmt_nonzero_warnv_p(), is_gimple_assign(), and range_is_nonnull().

Referenced by extract_range_basic().

static bool vrp_val_is_max ( )
inlinestatic
Return whether VAL is equal to the maximum value of its type.  This
   will be true for a positive overflow infinity.  We can't do a
   simple equality comparison with TYPE_MAX_VALUE because C typedefs
   and Ada subtypes can produce types whose TYPE_MAX_VALUE is not ==
   to the integer constant with the same value in the type.   

References operand_equal_p(), and vrp_val_max().

Referenced by avoid_overflow_infinity(), dump_value_range(), extract_range_from_assert(), extract_range_from_binary_expr_1(), extract_range_from_multiplicative_op_1(), intersect_ranges(), is_overflow_infinity(), is_positive_overflow_infinity(), ranges_from_anti_range(), set_and_canonicalize_value_range(), set_value_range(), union_ranges(), vrp_evaluate_conditional(), and vrp_visit_phi_node().

static tree vrp_valueize ( )
inlinestatic
Return the singleton value-range for NAME or NAME.   

References get_value_range(), value_range_d::max, value_range_d::min, operand_equal_p(), value_range_d::type, and VR_RANGE.

Referenced by vrp_visit_assignment_or_call().

static bool vrp_var_may_overflow ( )
static
Return true if VAR may overflow at STMT.  This checks any available
   loop information to see if we can determine that VAR does not
   overflow.   

References analyze_scalar_evolution(), dump_file, dump_flags, evolution_part_in_loop_num(), get_chrec_loop(), initial_condition_in_loop_num(), instantiate_parameters(), is_gimple_min_invariant(), loop_containing_stmt(), loop_outer(), loop::num, print_generic_expr(), scev_probably_wraps_p(), and valid_value_p().

Referenced by vrp_visit_phi_node().

static enum ssa_prop_result vrp_visit_cond_stmt ( )
static
Visit conditional statement STMT.  If we can determine which edge
   will be taken out of STMT's basic block, record it in
   *TAKEN_EDGE_P and return SSA_PROP_INTERESTING.  Otherwise, return
   SSA_PROP_VARYING.   

References dump_file, dump_flags, dump_value_range(), find_taken_edge(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), print_generic_expr(), print_generic_stmt(), print_gimple_stmt(), SSA_PROP_INTERESTING, SSA_PROP_VARYING, and vrp_evaluate_conditional_warnv_with_ops().

Referenced by vrp_visit_stmt().

static enum ssa_prop_result vrp_visit_stmt ( )
static
Evaluate statement STMT.  If the statement produces a useful range,
   return SSA_PROP_INTERESTING and record the SSA name with the
   interesting range into *OUTPUT_P.

   If STMT is a conditional branch and we can determine its truth
   value, the taken edge is recorded in *TAKEN_EDGE_P.

   If STMT produces a varying value, return SSA_PROP_VARYING.   

References dump_file, dump_flags, get_value_range(), gimple_call_fndecl(), gimple_vuse(), is_gimple_assign(), is_gimple_call(), print_gimple_stmt(), set_value_range_to_varying(), SSA_PROP_VARYING, stmt_ends_bb_p(), stmt_interesting_for_vrp(), vrp_visit_assignment_or_call(), vrp_visit_cond_stmt(), and vrp_visit_switch_stmt().

Referenced by execute_vrp().

static enum ssa_prop_result vrp_visit_switch_stmt ( )
static
Visit switch statement STMT.  If we can determine which edge
   will be taken out of STMT's basic block, record it in
   *TAKEN_EDGE_P and return SSA_PROP_INTERESTING.  Otherwise, return
   SSA_PROP_VARYING.   

References dump_file, dump_flags, dump_value_range(), find_case_label_ranges(), find_edge(), get_value_range(), gimple_switch_default_label(), gimple_switch_index(), gimple_switch_label(), print_generic_expr(), print_generic_stmt(), SSA_PROP_INTERESTING, SSA_PROP_VARYING, symbolic_range_p(), value_range_d::type, VR_ANTI_RANGE, and VR_RANGE.

Referenced by vrp_visit_stmt().

static bool zero_nonzero_bits_from_vr ( value_range_t vr,
double_int may_be_nonzero,
double_int must_be_nonzero 
)
static
For range VR compute two double_int bitmasks.  In *MAY_BE_NONZERO
   bitmask if some bit is unset, it means for all numbers in the range
   the bit is 0, otherwise it might be 0 or 1.  In *MUST_BE_NONZERO
   bitmask if some bit is set, it means for all numbers in the range
   the bit is 1, otherwise it might be 0 or 1.   

References floor_log2(), double_int::high, HOST_WIDE_INT, double_int::low, value_range_d::max, value_range_d::min, range_int_cst_p(), range_int_cst_singleton_p(), tree_int_cst_sgn(), and tree_to_double_int().

Referenced by extract_range_from_binary_expr_1(), and simplify_bit_ops_using_ranges().


Variable Documentation

assert_locus_t* asserts_for
static
Array of locations lists where to insert assertions.  ASSERTS_FOR[I]
   holds a list of ASSERT_LOCUS_T nodes that describe where
   ASSERT_EXPRs for SSA name N_I should be inserted.   
vec<tree> equiv_stack
static
Stack of dest,src equivalency pairs that need to be restored after
   each attempt to thread a block's incoming edge to an outgoing edge.

   A NULL entry is used to mark the end of pairs which need to be
   restored.   
bitmap need_assert_for
static
If bit I is present, it means that SSA name N_i has a list of
   assertions that should be inserted in the IL.   
unsigned num_vr_values
static
Value range array.  After propagation, VR_VALUE[I] holds the range
   of values that SSA name N_I may take.   

Referenced by dump_all_value_ranges(), get_value_range(), vrp_finalize(), and vrp_initialize().

vec<edge> to_remove_edges
static
vec<switch_update> to_update_switch_stmts
static
bool values_propagated
static
int* vr_phi_edge_counts
static
For a PHI node which sets SSA name N_I, VR_COUNTS[I] holds the
   number of executable edges we saw the last time we visited the
   node.   

Referenced by vrp_finalize(), vrp_initialize(), and vrp_visit_phi_node().

value_range_t** vr_value
static