GCC Middle and Back End API Reference
|
#include <vr-values.h>
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 Attributes | |
vec< edge > | to_remove_edges |
vec< switch_update > | to_update_switch_stmts |
class range_query * | query |
int | m_not_executable_flag |
vec< edge > | m_flag_set_edges |
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/>.
simplify_using_ranges::simplify_using_ranges | ( | range_query * | query = NULL, |
int | not_executable_flag = 0 ) |
References m_flag_set_edges, m_not_executable_flag, to_remove_edges, to_update_switch_stmts, and vNULL.
simplify_using_ranges::~simplify_using_ranges | ( | ) |
References cleanup_edges_and_switches(), and m_flag_set_edges.
|
private |
References CASE_HIGH, CASE_LOW, CDI_DOMINATORS, FOR_EACH_VEC_ELT, free_dominance_info(), gimple_switch_label(), gimple_switch_set_label(), gimple_switch_set_num_labels(), i, LOOPS_NEED_FIXUP, loops_state_set(), m_flag_set_edges, m_not_executable_flag, NULL_TREE, remove_edge(), simplify_using_ranges::switch_update::stmt, to_remove_edges, to_update_switch_stmts, TREE_VEC_ELT, TREE_VEC_LENGTH, and simplify_using_ranges::switch_update::vec.
Referenced by ~simplify_using_ranges().
If COND can be folded entirely as TRUE or FALSE, rewrite the conditional as such, and return TRUE.
References dump_file, dump_flags, EDGE_SUCC, gcc_unreachable, gimple_bb(), gimple_cond_lhs(), gimple_cond_make_false(), gimple_cond_make_true(), gimple_cond_rhs(), legacy_fold_cond(), print_gimple_expr(), query, r, range_query::range_of_stmt(), set_and_propagate_unexecutable(), TDF_DETAILS, TREE_CODE, and update_stmt().
Referenced by simplify_cond_using_ranges_1().
|
private |
Helper function for vrp_evaluate_conditional_warnv & other optimizers.
References boolean_false_node, boolean_true_node, boolean_type_node, range_op_handler::fold_range(), NULL, NULL_TREE, query, range_false(), range_query::range_of_expr(), range_true(), and TREE_TYPE.
Referenced by legacy_fold_cond_overflow(), simplify_abs_using_ranges(), simplify_div_or_mod_using_ranges(), and simplify_min_or_max_using_ranges().
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().
Helper function for legacy_fold_cond.
References boolean_false_node, boolean_true_node, fold_cond_with_ops(), gcc_unreachable, gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), integer_zerop(), INTEGRAL_TYPE_P, irange::intersect(), wi::max_value(), NULL_TREE, overflow_comparison_p(), POINTER_TYPE_P, query, range_query::range_of_expr(), irange::set(), irange::set_varying(), wi::to_wide(), TREE_TYPE, TYPE_MIN_VALUE, TYPE_PRECISION, vrange::undefined_p(), UNSIGNED, VR_ANTI_RANGE, and wide_int_to_tree().
Referenced by legacy_fold_cond().
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().
|
private |
References FOR_EACH_EDGE, m_flag_set_edges, m_not_executable_flag, basic_block_def::preds, set_and_propagate_unexecutable(), and basic_block_def::succs.
Referenced by fold_cond(), set_and_propagate_unexecutable(), and simplify_switch_using_ranges().
bool simplify_using_ranges::simplify | ( | gimple_stmt_iterator * | gsi | ) |
Simplify STMT using ranges if possible.
References as_a(), boolean_type_node, CASE_CONVERT, fold_stmt(), follow_single_use_edges(), gcc_checking_assert, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs_from_tree(), gimple_assign_set_rhs_with_ops(), gimple_build(), gimple_call_internal_p(), GSI_SAME_STMT, gsi_stmt(), int_const_binop(), INTEGRAL_TYPE_P, irange::intersect(), is_gimple_assign(), is_gimple_call(), wi::minus_one(), NULL_TREE, query, range_query::range_of_expr(), SIGNED, simplify_abs_using_ranges(), simplify_bit_ops_using_ranges(), simplify_compare_assign_using_ranges_1(), simplify_cond_using_ranges_1(), simplify_conversion_using_ranges(), simplify_div_or_mod_using_ranges(), simplify_float_conversion_using_ranges(), simplify_internal_call_using_ranges(), simplify_min_or_max_using_ranges(), simplify_switch_using_ranges(), single_imm_use(), tcc_binary, tcc_comparison, TREE_CODE, TREE_CODE_CLASS, TREE_TYPE, two_valued_val_range_p(), TYPE_PRECISION, TYPE_SIGN, vrange::undefined_p(), UNKNOWN_LOCATION, update_stmt(), VR_ANTI_RANGE, and wi::zero().
Referenced by fvrp_folder::fold_stmt(), and rvrp_folder::fold_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().
|
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().
|
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().
|
private |
Like simplify_cond_using_ranges_1 but for assignments rather than GIMPLE_COND.
References dump_file, gcc_assert, gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs1(), gimple_assign_set_rhs2(), gimple_assign_set_rhs_code(), INTEGRAL_TYPE_P, print_gimple_stmt(), simplify_compare_using_ranges_1(), simplify_truth_ops_using_ranges(), tcc_comparison, TREE_CODE_CLASS, TREE_TYPE, and update_stmt().
Referenced by simplify().
|
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 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().
|
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().
|
private |
Simplify a conversion from integral SSA name to float in STMT.
References build_nonstandard_integer_type(), can_float_p(), fold_stmt(), follow_single_use_edges(), GET_MODE_PRECISION(), GET_MODE_WIDER_MODE(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_set_rhs1(), gimple_build_assign(), gsi_insert_before(), GSI_SAME_STMT, make_ssa_name(), NARROWEST_INT_MODE, query, range_fits_type_p(), range_query::range_of_expr(), SCALAR_FLOAT_TYPE_MODE, SCALAR_INT_TYPE_MODE, SIGNED, TREE_CODE, TREE_TYPE, TYPE_MODE, TYPE_PRECISION, TYPE_UNSIGNED, vrange::undefined_p(), and vrange::varying_p().
Referenced by simplify().
|
private |
Simplify an internal fn call using ranges if possible.
References build_int_cst(), check_for_binary_op_overflow(), fold_convert, g, gimple_assign_lhs(), gimple_build_assign(), gimple_call_arg(), gimple_call_internal_fn(), gimple_call_lhs(), gimple_location(), gimple_set_location(), gsi_insert_before(), gsi_replace(), GSI_SAME_STMT, make_ssa_name(), NULL_TREE, query, TREE_CODE, TREE_TYPE, type(), unsigned_type_for(), useless_type_conversion_p(), and VECTOR_TYPE_P.
Referenced by simplify().
|
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 a switch statement using the value range of the switch argument.
References build_one_cst(), CASE_HIGH, CASE_LABEL, CASE_LOW, cfun, dump_file, dump_flags, find_case_label_index(), find_case_label_range(), find_case_label_ranges(), find_edge(), fold_convert, FOR_EACH_EDGE, get_legacy_range(), gimple_bb(), gimple_switch_default_label(), gimple_switch_index(), gimple_switch_label(), gimple_switch_num_labels(), i, int_const_binop(), label_to_block(), make_tree_vec(), NULL, NULL_TREE, query, range_query::range_of_expr(), set_and_propagate_unexecutable(), simplify_using_ranges::switch_update::stmt, TDF_DETAILS, to_remove_edges, to_update_switch_stmts, TREE_CODE, tree_int_cst_compare(), tree_int_cst_equal(), TREE_TYPE, TREE_VEC_ELT, vrange::undefined_p(), vrange::varying_p(), simplify_using_ranges::switch_update::vec, VR_ANTI_RANGE, and VR_RANGE.
Referenced by simplify().
|
private |
Simplify boolean operations if the source is known to be already a boolean.
References build_int_cst(), fold_stmt(), follow_single_use_edges(), gcc_assert, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_assign_set_rhs_with_ops(), gimple_build_assign(), gsi_insert_before(), GSI_SAME_STMT, gsi_stmt(), int_const_binop(), integer_zerop(), INTEGRAL_TYPE_P, make_ssa_name(), wi::one(), op_with_boolean_value_range_p(), set_range_info(), TREE_CODE, TREE_TYPE, TYPE_PRECISION, TYPE_UNSIGNED, update_stmt(), useless_type_conversion_p(), and wi::zero().
Referenced by simplify_compare_assign_using_ranges_1().
|
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().
|
private |
Referenced by cleanup_edges_and_switches(), set_and_propagate_unexecutable(), and simplify_using_ranges().
|
private |
Referenced by fold_cond(), fold_cond_with_ops(), legacy_fold_cond(), legacy_fold_cond_overflow(), op_with_boolean_value_range_p(), simplify(), simplify_bit_ops_using_ranges(), simplify_casted_compare(), simplify_compare_using_ranges_1(), simplify_div_or_mod_using_ranges(), simplify_float_conversion_using_ranges(), simplify_internal_call_using_ranges(), simplify_switch_using_ranges(), and two_valued_val_range_p().
Referenced by cleanup_edges_and_switches(), simplify_switch_using_ranges(), and simplify_using_ranges().
|
private |
Referenced by cleanup_edges_and_switches(), simplify_switch_using_ranges(), and simplify_using_ranges().