GCC Middle and Back End API Reference
simplify_using_ranges Class Reference

#include <vr-values.h>

Collaboration diagram for simplify_using_ranges:

Data Structures

struct  switch_update
 

Public Member Functions

 simplify_using_ranges (range_query *query=NULL, int not_executable_flag=0)
 
 ~simplify_using_ranges ()
 
bool simplify (gimple_stmt_iterator *)
 
bool fold_cond (gcond *)
 

Private Member Functions

void legacy_fold_cond (gcond *, edge *)
 
tree legacy_fold_cond_overflow (gimple *stmt)
 
tree fold_cond_with_ops (tree_code, tree, tree, gimple *s)
 
bool simplify_casted_compare (tree_code &cond_code, tree &op0, tree &op1)
 
bool simplify_truth_ops_using_ranges (gimple_stmt_iterator *, gimple *)
 
bool simplify_div_or_mod_using_ranges (gimple_stmt_iterator *, gimple *)
 
bool simplify_abs_using_ranges (gimple_stmt_iterator *, gimple *)
 
bool simplify_bit_ops_using_ranges (gimple_stmt_iterator *, gimple *)
 
bool simplify_min_or_max_using_ranges (gimple_stmt_iterator *, gimple *)
 
bool simplify_cond_using_ranges_1 (gcond *)
 
bool simplify_compare_using_ranges_1 (tree_code &, tree &, tree &, gimple *)
 
bool simplify_compare_assign_using_ranges_1 (gimple_stmt_iterator *, gimple *)
 
bool simplify_switch_using_ranges (gswitch *)
 
bool simplify_float_conversion_using_ranges (gimple_stmt_iterator *, gimple *)
 
bool simplify_internal_call_using_ranges (gimple_stmt_iterator *, gimple *)
 
bool two_valued_val_range_p (tree, tree *, tree *, gimple *)
 
bool op_with_boolean_value_range_p (tree, gimple *)
 
void set_and_propagate_unexecutable (edge e)
 
void cleanup_edges_and_switches (void)
 

Private Attributes

vec< edgeto_remove_edges
 
vec< switch_updateto_update_switch_stmts
 
class range_queryquery
 
int m_not_executable_flag
 
vec< edgem_flag_set_edges
 

Detailed Description

Support routines for Value Range Propagation (VRP).
   Copyright (C) 2016-2024 Free Software Foundation, Inc.

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

Constructor & Destructor Documentation

◆ simplify_using_ranges()

simplify_using_ranges::simplify_using_ranges ( range_query * query = NULL,
int not_executable_flag = 0 )

◆ ~simplify_using_ranges()

simplify_using_ranges::~simplify_using_ranges ( )

Member Function Documentation

◆ cleanup_edges_and_switches()

◆ fold_cond()

bool simplify_using_ranges::fold_cond ( gcond * cond)

◆ fold_cond_with_ops()

tree simplify_using_ranges::fold_cond_with_ops ( tree_code code,
tree op0,
tree op1,
gimple * s )
private

◆ legacy_fold_cond()

void simplify_using_ranges::legacy_fold_cond ( gcond * stmt,
edge * taken_edge_p )
private
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.  Otherwise, set *TAKEN_EDGE_P to NULL.   

References dump_file, dump_flags, find_taken_edge(), FOR_EACH_SSA_TREE_OPERAND, gimple_bb(), i, legacy_fold_cond_overflow(), NULL, NULL_TREE, print_generic_expr(), print_generic_stmt(), print_gimple_stmt(), query, r, range_query::range_of_expr(), SSA_OP_USE, TDF_DETAILS, and TREE_TYPE.

Referenced by fold_cond().

◆ legacy_fold_cond_overflow()

◆ op_with_boolean_value_range_p()

bool simplify_using_ranges::op_with_boolean_value_range_p ( tree op,
gimple * s )
private
Return true if op is in a boolean [0, 1] value-range.   

References integer_onep(), integer_zerop(), query, range_query::range_of_expr(), range_true_and_false(), TREE_CODE, TREE_TYPE, and TYPE_PRECISION.

Referenced by simplify_truth_ops_using_ranges().

◆ set_and_propagate_unexecutable()

◆ simplify()

◆ simplify_abs_using_ranges()

bool simplify_using_ranges::simplify_abs_using_ranges ( gimple_stmt_iterator * gsi,
gimple * stmt )
private
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 build_zero_cst(), fold_cond_with_ops(), fold_stmt(), follow_single_use_edges(), gimple_assign_rhs1(), gimple_assign_set_rhs1(), gimple_assign_set_rhs_code(), integer_zerop(), TREE_TYPE, and update_stmt().

Referenced by simplify().

◆ simplify_bit_ops_using_ranges()

bool simplify_using_ranges::simplify_bit_ops_using_ranges ( gimple_stmt_iterator * gsi,
gimple * stmt )
private
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 wi::bit_and_not(), gcc_unreachable, gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs_with_ops(), gsi_stmt(), NULL_TREE, query, range_query::range_of_expr(), TREE_CODE, TREE_TYPE, vrange::undefined_p(), update_stmt(), and vr_set_zero_nonzero_bits().

Referenced by simplify().

◆ simplify_casted_compare()

bool simplify_using_ranges::simplify_casted_compare ( tree_code & cond_code,
tree & op0,
tree & op1 )
private
Simplify OP0 code OP1 when OP1 is a constant and OP0 was a SSA_NAME
defined by a type conversion. Replacing OP0 with RHS of the type conversion.
Doing so makes the conversion dead which helps subsequent passes.   

References CASE_CONVERT, desired_pro_or_demotion_p(), fold_convert, gimple_assign_rhs1(), gimple_assign_rhs_code(), int_fits_type_p(), INTEGRAL_TYPE_P, is_gimple_assign(), POINTER_TYPE_P, query, range_fits_type_p(), range_query::range_of_expr(), SSA_NAME_DEF_STMT, SSA_NAME_OCCURS_IN_ABNORMAL_PHI, TREE_CODE, TREE_OPERAND, TREE_TYPE, TYPE_PRECISION, TYPE_SIGN, vrange::undefined_p(), and vrange::varying_p().

Referenced by simplify_compare_using_ranges_1().

◆ simplify_compare_assign_using_ranges_1()

bool simplify_using_ranges::simplify_compare_assign_using_ranges_1 ( gimple_stmt_iterator * gsi,
gimple * stmt )
private

◆ simplify_compare_using_ranges_1()

bool simplify_using_ranges::simplify_compare_using_ranges_1 ( tree_code & cond_code,
tree & op0,
tree & op1,
gimple * stmt )
private
Try to simplify OP0 COND_CODE OP1 using a relational operator to an
equality test if the range information indicates only one value can
satisfy the original conditional.    

References INTEGRAL_TYPE_P, invert_tree_comparison(), is_gimple_min_invariant(), query, range_query::range_of_expr(), irange::set_undefined(), simplify_casted_compare(), test_for_singularity(), TREE_CODE, TREE_TYPE, vrange::undefined_p(), and vrange::varying_p().

Referenced by simplify_compare_assign_using_ranges_1(), and simplify_cond_using_ranges_1().

◆ simplify_cond_using_ranges_1()

bool simplify_using_ranges::simplify_cond_using_ranges_1 ( gcond * stmt)
private
Simplify a conditional using a relational operator to an equality
test if the range information indicates only one value can satisfy
the original conditional.   

References dump_file, fold_cond(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_cond_set_code(), gimple_cond_set_lhs(), gimple_cond_set_rhs(), print_gimple_stmt(), simplify_compare_using_ranges_1(), and update_stmt().

Referenced by simplify().

◆ simplify_div_or_mod_using_ranges()

bool simplify_using_ranges::simplify_div_or_mod_using_ranges ( gimple_stmt_iterator * gsi,
gimple * stmt )
private
Simplify a division or modulo operator to a right shift or bitwise and
if the first operand is unsigned or is greater than zero and the second
operand is an exact power of two.  For TRUNC_MOD_EXPR op0 % op1 with
constant op1 (op1min = op1) or with op1 in [op1min, op1max] range,
optimize it into just op0 if op0's range is known to be a subset of
[-op1min + 1, op1min - 1] for signed and [0, op1min - 1] for unsigned
modulo.   

References build_int_cst(), build_zero_cst(), fold_cond_with_ops(), fold_convert, fold_stmt(), fold_unary, follow_single_use_edges(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs1(), gimple_assign_set_rhs2(), gimple_assign_set_rhs_code(), gimple_assign_set_rhs_from_tree(), int_const_binop(), integer_one_node, integer_onep(), integer_pow2p(), integer_type_node, irange::lower_bound(), NULL, NULL_TREE, query, range_query::range_of_expr(), irange::set_varying(), TREE_CODE, tree_int_cst_lt(), tree_int_cst_sgn(), tree_log2(), TREE_TYPE, irange::type(), TYPE_UNSIGNED, vrange::undefined_p(), update_stmt(), irange::upper_bound(), vrange::varying_p(), and wide_int_to_tree().

Referenced by simplify().

◆ simplify_float_conversion_using_ranges()

◆ simplify_internal_call_using_ranges()

◆ simplify_min_or_max_using_ranges()

bool simplify_using_ranges::simplify_min_or_max_using_ranges ( gimple_stmt_iterator * gsi,
gimple * stmt )
private
Simplify a min or max if the ranges of the two operands are
disjoint.   Return true if we do simplify.   

References fold_cond_with_ops(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs_from_tree(), and integer_zerop().

Referenced by simplify().

◆ simplify_switch_using_ranges()

◆ simplify_truth_ops_using_ranges()

◆ two_valued_val_range_p()

bool simplify_using_ranges::two_valued_val_range_p ( tree var,
tree * a,
tree * b,
gimple * s )
private
Return true if VAR is a two-valued variable.  Set a and b with the
two-values when it is true.  Return false otherwise.   

References a, b, irange::lower_bound(), irange::num_pairs(), query, range_query::range_of_expr(), TREE_TYPE, vrange::undefined_p(), irange::upper_bound(), vrange::varying_p(), and wide_int_to_tree().

Referenced by simplify().

Field Documentation

◆ m_flag_set_edges

vec<edge> simplify_using_ranges::m_flag_set_edges
private

◆ m_not_executable_flag

int simplify_using_ranges::m_not_executable_flag
private

◆ query

◆ to_remove_edges

vec<edge> simplify_using_ranges::to_remove_edges
private

◆ to_update_switch_stmts

vec<switch_update> simplify_using_ranges::to_update_switch_stmts
private

The documentation for this class was generated from the following files: