|
| static gphi * | single_non_singleton_phi_for_edges (gimple_seq seq, edge e0, edge e1) |
| static void | replace_phi_edge_with_variable (basic_block cond_block, edge e, gphi *phi, tree new_tree, bitmap dce_ssa_names=nullptr) |
| static bool | is_factor_profitable (gimple *def_stmt, basic_block merge, tree *operands, unsigned opcount) |
| static bool | factor_out_conditional_operation (edge e0, edge e1, basic_block merge, gphi *phi, gimple *cond_stmt, bool early_p) |
| static bool | phiopt_early_allow (gimple_seq &seq, gimple_match_op &op) |
| static tree | gimple_simplify_phiopt (bool early_p, tree type, gimple *comp_stmt, tree arg0, tree arg1, gimple_seq *seq) |
| static bool | one_feeding_comparison_into_p (basic_block bb, gimple *phi, gassign *&assign) |
| static bool | empty_bb_or_one_feeding_into_p (basic_block bb, gimple *phi, gimple *&stmt) |
| static void | move_stmt (gimple *stmt, gimple_stmt_iterator *gsi, auto_bitmap &inserted_exprs) |
| static bool | contains_hot_cold_predict (basic_block bb) |
| static bool | match_simplify_replacement (basic_block cond_bb, basic_block middle_bb, basic_block middle_bb_alt, edge e0, edge e1, gphi *phi, tree arg0, tree arg1, bool early_p, bool threeway_p) |
| static bool | comparison_combine (basic_block cond_bb, basic_block middle_bb, basic_block middle_bb_alt, edge e0, edge e1, gphi *phi, tree arg0, tree arg1, bool threeway_p) |
| static bool | jump_function_from_stmt (tree *arg, gimple *stmt) |
| static bool | rhs_is_fed_for_value_replacement (const_tree arg0, const_tree arg1, enum tree_code *code, const_tree rhs, enum tree_code bit_expression_code) |
| static bool | operand_equal_for_value_replacement (const_tree arg0, const_tree arg1, enum tree_code *code, gimple *cond) |
| static bool | neutral_element_p (tree_code code, tree arg, bool right) |
| static bool | absorbing_element_p (tree_code code, tree arg, bool right, tree rval) |
| static int | value_replacement (basic_block cond_bb, basic_block middle_bb, edge e0, edge e1, gphi *phi, tree arg0, tree arg1) |
| static bool | spaceship_replacement (basic_block cond_bb, basic_block middle_bb, edge e0, edge e1, gphi *phi, tree arg0, tree arg1) |
| static bool | cond_removal_in_builtin_zero_pattern (basic_block cond_bb, basic_block middle_bb, edge e1, edge e2, gphi *phi, tree arg0, tree arg1) |
| static hash_set< tree > * | get_non_trapping (void) |
| static bool | cond_store_replacement (basic_block middle_bb, basic_block join_bb, edge e0, edge e1, gimple *assign, hash_set< tree > *nontrap) |
| static bool | cond_if_else_store_replacement_1 (basic_block then_bb, basic_block else_bb, basic_block join_bb, gimple *then_assign, gimple *else_assign, gphi *vphi) |
| static gimple * | trailing_store_in_bb (basic_block bb, tree vdef, gphi *vphi, bool onlyonestore) |
| static tree | copy_mem_with_alias_set_zero (tree mem) |
| static bool | cond_store_replacement_limited (basic_block middle_bb, basic_block join_bb, basic_block cond_bb, edge e0, edge e1, bool caninsert_edge) |
| static gimple * | cselim_candidate (basic_block middle_bb, basic_block join_bb, edge e0) |
| static bool | cond_if_else_store_replacement_limited (basic_block then_bb, basic_block else_bb, basic_block join_bb) |
| static bool | cond_if_else_store_replacement (basic_block then_bb, basic_block else_bb, basic_block join_bb) |
| static bool | factor_out_conditional_load (edge e0, edge e1, basic_block merge, gphi *phi, bool early_p, bool before_vect) |
| static bool | factor_out_all (edge e1, edge e2, basic_block merge, gcond *cond_stmt, bool diamond_p, bool early_p) |
| static bool | local_mem_dependence (gimple *stmt, basic_block bb) |
| static void | hoist_adjacent_loads (basic_block bb0, basic_block bb1, basic_block bb2, basic_block bb3) |
| static bool | gate_hoist_loads (void) |
| template<class func_type> |
| static void | execute_over_cond_phis (func_type func) |
| gimple_opt_pass * | make_pass_phiopt (gcc::context *ctxt) |
| gimple_opt_pass * | make_pass_cselim (gcc::context *ctxt) |
The function comparison_combine tries to handle cases like:
if (a CMP0 b)
d = a CMP1 b;
PHI<d, [0,1]>
This has to be seperately as `a CMP1 b` might be trapping and
match_simplify_replacement does not handle trapping statements.
Returns true if a replacement happens.
References as_a(), boolean_type_node, combine_comparisons(), EDGE_SUCC, empty_block_p(), extract_true_false_edges_from_block(), FLOAT_TYPE_P, gcc_assert, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_code(), gimple_build(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), GSI_CONTINUE_LINKING, gsi_insert_seq_before(), gsi_last_bb(), HONOR_NANS(), integer_onep(), integer_zerop(), invert_tree_comparison(), last_nondebug_stmt(), one_feeding_comparison_into_p(), operand_equal_p(), replace_phi_edge_with_variable(), ssa_name_maybe_undef_p(), TREE_CODE, TREE_TYPE, and types_compatible_p().
Conditional store replacement. We already know
that the recognized pattern looks like so:
split:
if (cond) goto THEN_BB; else goto ELSE_BB (edge E1)
THEN_BB:
...
X = Y;
...
goto JOIN_BB;
ELSE_BB:
...
X = Z;
...
fallthrough (edge E0)
JOIN_BB:
some more
We check that it is safe to sink the store to JOIN_BB by verifying that
there are no read-after-write or write-after-write dependencies in
THEN_BB and ELSE_BB.
References chrec_dont_know, chrec_known, compute_all_dependences(), cond_if_else_store_replacement_1(), cond_if_else_store_replacement_limited(), DDR_A, DDR_ARE_DEPENDENT, DDR_B, DR_IS_READ, DR_IS_WRITE, DR_STMT, find_data_references_in_bb(), FOR_EACH_VEC_ELT_REVERSE, free_data_refs(), free_dependence_relations(), get_virtual_phi(), gimple_get_lhs(), gimple_set_visited(), gimple_uid(), gimple_visited_p(), i, NULL, NULL_TREE, operand_equal_p(), renumber_gimple_stmt_uids_in_blocks(), and vNULL.
Optimize x ? __builtin_fun (x) : C, where C is __builtin_fun (0).
Convert
<bb 2>
if (b_4(D) != 0)
goto <bb 3>
else
goto <bb 4>
<bb 3>
_2 = (unsigned long) b_4(D);
_9 = __builtin_popcountl (_2);
OR
_9 = __builtin_popcountl (b_4(D));
<bb 4>
c_12 = PHI <0(2), _9(3)>
Into
<bb 2>
_2 = (unsigned long) b_4(D);
_9 = __builtin_popcountl (_2);
OR
_9 = __builtin_popcountl (b_4(D));
<bb 4>
c_12 = PHI <_9(2)>
Similarly for __builtin_clz or __builtin_ctz if
C?Z_DEFINED_VALUE_AT_ZERO is 2, optab is present and
instead of 0 above it uses the value from that macro.
References BITINT_TYPE_P, build_int_cst(), CLZ_DEFINED_VALUE_AT_ZERO, CONVERT_EXPR_CODE_P, CTZ_DEFINED_VALUE_AT_ZERO, direct_internal_fn_supported_p(), dyn_cast(), EDGE_SUCC, extract_true_false_edges_from_block(), gcc_assert, gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_build_call_internal(), gimple_call_arg(), gimple_call_combined_fn(), gimple_call_internal_p(), gimple_call_num_args(), gimple_call_set_lhs(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_get_lhs(), gsi_end_p(), gsi_for_stmt(), gsi_insert_before(), gsi_last_bb(), gsi_move_before(), gsi_next_nondebug(), gsi_remove(), GSI_SAME_STMT, gsi_start_nondebug_after_labels_bb(), gsi_stmt(), integer_type_node, integer_zerop(), INTEGRAL_TYPE_P, is_gimple_call(), long_integer_type_node, long_long_integer_type_node, NULL, NULL_TREE, OPTIMIZE_FOR_BOTH, replace_phi_edge_with_variable(), reset_flow_sensitive_info(), SCALAR_INT_TYPE_MODE, wi::to_wide(), TREE_CODE, tree_fits_shwi_p(), tree_to_shwi(), TREE_TYPE, and TYPE_PRECISION.
Do the main work of conditional store replacement. We already know
that the recognized pattern looks like so:
split:
if (cond) goto MIDDLE_BB; else goto JOIN_BB (edge E1)
MIDDLE_BB:
something
fallthrough (edge E0)
JOIN_BB:
some more
ASSIGN is a store in MIDDLE_BB which is the candidate for cselim. We check
that MIDDLE_BB contains only one store (i.e., ASSIGN), that that store
doesn't trap (not via NOTRAP, but via checking if an access to the same
memory location dominates us, or the store is to a local addressable object)
and that the store has a "simple" RHS.
References add_phi_arg(), build2(), build_fold_addr_expr, build_zero_cst(), cfun, hash_set< KeyId, Lazy, Traits >::contains(), create_phi_node(), DECL_P, dump_file, dump_flags, fold_convert, FOR_EACH_IMM_USE_STMT, FOR_EACH_SSA_TREE_OPERAND, get_base_address(), get_virtual_phi(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_single_p(), gimple_bb(), gimple_build_assign(), gimple_has_volatile_ops(), gimple_location(), gimple_phi_arg_def(), gimple_phi_result(), gimple_phi_set_result(), gimple_set_location(), gimple_set_vdef(), gimple_set_vuse(), gimple_vop(), gimple_vuse(), gsi_after_labels(), gsi_for_stmt(), gsi_insert_before(), gsi_insert_on_edge(), GSI_NEW_STMT, gsi_remove(), handled_component_p(), is_gimple_reg_type(), make_ssa_name(), make_temp_ssa_name(), NULL, print_gimple_stmt(), ptr_type_node, ref_can_have_store_data_races(), REFERENCE_CLASS_P, release_defs(), SSA_NAME_DEF_STMT, SSA_OP_USE, statistics_counter_event(), suppress_warning(), TDF_DETAILS, TDF_MEMSYMS, TDF_VOPS, TREE_CODE, tree_could_trap_p(), TREE_OPERAND, TREE_READONLY, TREE_TYPE, unlink_stmt_vdef(), unshare_expr(), and update_stmt().
Do the main work of a limited conditional store replacement.
This recognized pattern like so:
COND_BB:
store = a_1;
// no loads
if (cond) goto MIDDLE_BB; else goto JOIN_BB (edge E1)
MIDDLE_BB:
something // no loads
store = a_2;
something // no loads
fallthrough (edge E0)
JOIN_BB:
some more
This is a limited form of the full cond_store_replacement
to be allowed from use from phiopt and can be done
without calculating the non-trapping cases.
References add_phi_arg(), auto_var_p(), cfun, copy_mem_with_alias_set_zero(), create_phi_node(), DECL_P, dump_file, dump_flags, EDGE_COUNT, FOR_EACH_IMM_USE_STMT, gcc_assert, get_base_address(), get_virtual_phi(), gimple_assign_lhs(), gimple_assign_load_p(), gimple_assign_rhs1(), gimple_assign_single_p(), gimple_bb(), gimple_build_assign(), gimple_has_volatile_ops(), gimple_location(), gimple_phi_arg_def(), gimple_phi_arg_def_from_edge(), gimple_phi_result(), gimple_phi_set_result(), gimple_set_location(), gimple_set_vdef(), gimple_set_vuse(), gimple_vop(), gimple_vuse(), gsi_after_labels(), gsi_for_stmt(), gsi_insert_before(), gsi_insert_on_edge(), gsi_remove(), GSI_SAME_STMT, is_gimple_reg_type(), lhs_could_trap_p(), make_ssa_name(), make_temp_ssa_name(), NULL, operand_equal_p(), basic_block_def::preds, print_gimple_stmt(), ref_can_have_store_data_races(), REFERENCE_CLASS_P, release_defs(), single_pred_p(), SSA_NAME_DEF_STMT, statistics_counter_event(), suppress_warning(), TDF_DETAILS, TDF_MEMSYMS, TDF_VOPS, trailing_store_in_bb(), TREE_ADDRESSABLE, TREE_CODE, TREE_TYPE, unlink_stmt_vdef(), unshare_expr(), and update_stmt().
Referenced by factor_out_all().
If PHI at MERGE is a "load PHI", PHI <*P, *Q> whose two arguments are
single-use, non-volatile scalar MEM_REF loads reading the same memory state
(same VUSE), factor the load out: introduce P' = PHI <P, Q> and a single
load *P' replacing the PHI. No speculative load is introduced (the load uses
whichever pointer the taken edge selected).
E0/E1 are the middle bbs to MERGE edges.
EARLY_P is set when the first phiopt is run.
BEFORE_VECT is true if this is before vectorization, where some extra checks
are needed for profitability.
Returns true if a load was factored out.
References add_phi_arg(), alias_ptr_types_compatible_p(), bb_loop_depth(), build2(), build_zero_cst(), cfun, create_phi_node(), dump_file, dump_flags, fold_convert, get_virtual_phi(), gimple_assign_load_p(), gimple_assign_rhs1(), gimple_bb(), gimple_build(), gimple_build_assign(), gimple_has_volatile_ops(), gimple_location(), gimple_phi_arg_def(), gimple_phi_arg_location(), gimple_phi_num_args(), gimple_phi_result(), gimple_set_vuse(), gimple_vuse(), gsi_after_labels(), gsi_for_stmt(), gsi_insert_before(), gsi_remove(), GSI_SAME_STMT, has_single_use(), is_factor_profitable(), make_ssa_name(), MR_DEPENDENCE_BASE, MR_DEPENDENCE_CLIQUE, operand_equal_p(), print_generic_expr(), ptr_type_node, release_defs(), remove_phi_node(), sizetype, SSA_NAME_DEF_STMT, statistics_counter_event(), TDF_DETAILS, TREE_CODE, TREE_OPERAND, TREE_TYPE, TYPE_ALIGN, types_compatible_p(), UNKNOWN_LOCATION, and virtual_operand_p().
Referenced by factor_out_all().
PR66726: Factor operations out of COND_EXPR. If the arguments of the PHI
stmt are Unary operator, factor out the operation and perform the operation
to the result of PHI stmt. COND_STMT is the controlling predicate.
Return true if the operation was factored out; false otherwise.
References add_phi_arg(), annotate_all_with_location(), cfun, gimple_match_op::code, create_phi_node(), drop_tree_overflow(), dump_file, dump_flags, dyn_cast(), find_different_opnum(), fold_convert, gcc_assert, gimple_assign_cast_p(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs_code(), gimple_bb(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_extract_op(), gimple_has_location(), gimple_location(), gimple_phi_arg_def(), gimple_phi_arg_location(), gimple_phi_num_args(), gimple_phi_result(), gsi_after_labels(), GSI_CONTINUE_LINKING, gsi_end_p(), gsi_for_stmt(), gsi_insert_seq_before(), gsi_prev_nondebug(), gsi_remove(), gsi_stmt(), has_single_use(), int_divide_or_mod_p(), int_fits_type_p(), INTEGRAL_TYPE_P, is_factor_profitable(), make_ssa_name(), maybe_push_res_to_seq(), NULL, NULL_TREE, gimple_match_op::num_ops, operand_equal_for_phi_arg_p(), gimple_match_op::operands_occurs_in_abnormal_phi(), gimple_match_op::ops, phi_nodes(), poly_int_tree_p(), print_generic_expr(), release_defs(), release_ssa_name(), remove_phi_node(), single_non_singleton_phi_for_edges(), SSA_NAME_DEF_STMT, statistics_counter_event(), TDF_DETAILS, TREE_CODE, TREE_OVERFLOW, TREE_TYPE, TYPE_PRECISION, TYPE_UNSIGNED, types_compatible_p(), UNKNOWN_LOCATION, and virtual_operand_p().
Referenced by factor_out_all().
gimple_simplify_phiopt is like gimple_simplify but designed for PHIOPT.
Return NULL if nothing can be simplified or the resulting simplified value
with parts pushed if EARLY_P was true. Also rejects non allowed tree code
if EARLY_P is set.
Takes the comparison from COMP_STMT and two args, ARG0 and ARG1 and tries
to simplify CMP ? ARG0 : ARG1.
Also try to simplify (!CMP) ? ARG1 : ARG0 if the non-inverse failed.
References annotate_all_with_location(), boolean_type_node, build2_loc(), cmp1(), dump_file, dump_flags, follow_all_ssa_edges(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_location(), gimple_seq_add_seq_without_update(), gimple_seq_discard(), HONOR_NANS(), invert_tree_comparison(), maybe_push_res_to_seq(), NULL, phiopt_early_allow(), print_generic_expr(), print_gimple_seq(), gimple_match_op::resimplify(), TDF_FOLDING, TDF_MEMSYMS, TDF_VOPS, gimple_match_cond::UNCOND, and UNKNOWN_LOCATION.
Referenced by match_simplify_replacement().
Given a "diamond" control-flow pattern where BB0 tests a condition,
BB1 and BB2 are "then" and "else" blocks dependent on this test,
and BB3 rejoins control flow following BB1 and BB2, look for
opportunities to hoist loads as follows. If BB3 contains a PHI of
two loads, one each occurring in BB1 and BB2, and the loads are
provably of adjacent fields in the same structure, then move both
loads into BB0. Of course this can only be done if there are no
dependencies preventing such motion.
One of the hoisted loads will always be speculative, so the
transformation is currently conservative:
- The fields must be strictly adjacent.
- The two fields must occupy a single memory block that is
guaranteed to not cross a page boundary.
The last is difficult to prove, as such memory blocks should be
aligned on the minimum of the stack alignment boundary and the
alignment guaranteed by heap allocation interfaces. Thus we rely
on a parameter for the alignment value.
Provided a good value is used for the last case, the first
restriction could possibly be relaxed.
References bit_position(), cfun, DECL_ALIGN, DECL_CHAIN, DECL_SIZE, dump_file, dump_flags, gimple_assign_rhs1(), gimple_assign_single_p(), gimple_bb(), gimple_has_volatile_ops(), gimple_phi_arg_def(), gimple_phi_num_args(), gimple_phi_result(), gsi_end_p(), gsi_for_stmt(), gsi_move_to_bb_end(), gsi_next(), gsi_start_phis(), basic_block_def::index, local_mem_dependence(), operand_equal_p(), optab_handler(), gphi_iterator::phi(), print_gimple_stmt(), SSA_NAME_DEF_STMT, SSA_NAME_IS_DEFAULT_DEF, statistics_counter_event(), TDF_DETAILS, TDF_MEMSYMS, TDF_VOPS, TREE_CODE, tree_fits_uhwi_p(), TREE_OPERAND, tree_to_uhwi(), TREE_TYPE, TYPE_MODE, and virtual_operand_p().
The function match_simplify_replacement does the main work of doing the
replacement using match and simplify. Return true if the replacement is done.
Otherwise return false.
BB is the basic block where the replacement is going to be done on. ARG0
is argument 0 from PHI. Likewise for ARG1.
References bitmap_set_bit, boolean_type_node, cfun, cmp1(), contains_hot_cold_predict(), dump_file, dump_flags, EDGE_SUCC, empty_bb_or_one_feeding_into_p(), extract_true_false_edges_from_block(), gcc_assert, gimple_assign_lhs(), gimple_assign_rhs_code(), gimple_build(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_phi_result(), gimple_seq_first_stmt(), gimple_seq_singleton_p(), gimple_simplify_phiopt(), GSI_CONTINUE_LINKING, gsi_insert_seq_before(), gsi_last_bb(), HONOR_NANS(), HONOR_SIGNED_ZEROS(), is_gimple_assign(), last_nondebug_stmt(), mark_lhs_in_seq_for_dce(), move_stmt(), NULL, operand_equal_for_phi_arg_p(), replace_phi_edge_with_variable(), SSA_NAME_IS_DEFAULT_DEF, ssa_name_maybe_undef_p(), SSA_NAME_VERSION, statistics_counter_event(), tcc_comparison, TDF_FOLDING, TREE_CODE, TREE_CODE_CLASS, and TREE_TYPE.
Replace PHI node element whose edge is E in block BB with variable NEW.
Remove the edge from COND_BLOCK which does not lead to BB (COND_BLOCK
is known to have two edges, one of which must reach BB).
References profile_probability::always(), loop::any_likely_upper_bound, loop::any_upper_bound, as_a(), cfun, copy_phi_arg_into_existing_phi(), dbg_cnt(), delete_basic_block(), dump_file, dump_flags, duplicate_ssa_name_range_info(), EDGE_COUNT, EDGE_SUCC, empty_block_p(), find_edge(), free_numbers_of_iterations_estimates(), gcc_assert, gcc_unreachable, gimple_bb(), gimple_cond_make_false(), gimple_cond_make_true(), gimple_phi_result(), gsi_last_bb(), gsi_remove(), basic_block_def::index, INTEGRAL_TYPE_P, loop_exits_from_bb_p(), basic_block_def::loop_father, NULL, PHI_ARG_DEF_PTR, redirect_edge_and_branch(), SET_USE, simple_dce_from_worklist(), single_pred_p(), single_succ_p(), SSA_NAME_DEF_STMT, SSA_NAME_RANGE_INFO, statistics_counter_event(), TDF_DETAILS, TREE_CODE, and TREE_TYPE.
Referenced by comparison_combine(), cond_removal_in_builtin_zero_pattern(), match_simplify_replacement(), and value_replacement().
Optimization of PHI nodes by converting them into straightline code.
Copyright (C) 2004-2026 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/>.
Return the singleton PHI in the SEQ of PHIs for edges E0 and E1.
References as_a(), gimple_phi_arg_def(), gimple_phi_result(), gsi_end_p(), gsi_next(), gsi_start(), gsi_stmt(), i, NULL, operand_equal_for_phi_arg_p(), and virtual_operand_p().
Referenced by factor_out_conditional_operation(), and value_replacement().
Attempt to optimize (x <=> y) cmp 0 and similar comparisons.
For strong ordering <=> try to match something like:
<bb 2> : // cond3_bb (== cond2_bb)
if (x_4(D) != y_5(D))
goto <bb 3>; [INV]
else
goto <bb 6>; [INV]
<bb 3> : // cond_bb
if (x_4(D) < y_5(D))
goto <bb 6>; [INV]
else
goto <bb 4>; [INV]
<bb 4> : // middle_bb
<bb 6> : // phi_bb
# iftmp.0_2 = PHI <1(4), 0(2), -1(3)>
_1 = iftmp.0_2 == 0;
and for partial ordering <=> something like:
<bb 2> : // cond3_bb
if (a_3(D) == b_5(D))
goto <bb 6>; [50.00%]
else
goto <bb 3>; [50.00%]
<bb 3> [local count: 536870913]: // cond2_bb
if (a_3(D) < b_5(D))
goto <bb 6>; [50.00%]
else
goto <bb 4>; [50.00%]
<bb 4> [local count: 268435456]: // cond_bb
if (a_3(D) > b_5(D))
goto <bb 6>; [50.00%]
else
goto <bb 5>; [50.00%]
<bb 5> [local count: 134217728]: // middle_bb
<bb 6> [local count: 1073741824]: // phi_bb
# SR.27_4 = PHI <0(2), -1(3), 1(4), -128(5)>
_2 = SR.27_4 > 0;
References absu_hwi(), as_a(), boolean_false_node, boolean_type_node, build2(), build3(), build_debug_expr_decl(), build_int_cst(), build_one_cst(), build_zero_cst(), cfun, cmp1(), COMPARISON_CLASS_P, cond_only_block_p(), EDGE_COUNT, EDGE_SUCC, empty_block_p(), fold_build1, fold_convert, FOR_EACH_IMM_USE_FAST, g, gcc_assert, gcc_checking_assert, gcc_unreachable, gimple_assign_cast_p(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_class(), gimple_assign_rhs_code(), gimple_assign_set_rhs1(), gimple_assign_set_rhs2(), gimple_assign_set_rhs_code(), gimple_assign_set_rhs_with_ops(), gimple_bb(), GIMPLE_BINARY_RHS, gimple_build_assign(), gimple_build_debug_bind(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_cond_set_code(), gimple_cond_set_lhs(), gimple_cond_set_rhs(), gimple_phi_arg_def(), gimple_phi_result(), gsi_after_labels(), gsi_for_stmt(), gsi_insert_before(), gsi_last_bb(), gsi_remove(), GSI_SAME_STMT, HONOR_NANS(), IN_RANGE, integer_minus_onep(), integer_onep(), integer_zerop(), INTEGRAL_TYPE_P, invert_tree_comparison(), is_gimple_assign(), is_gimple_debug(), make_ssa_name(), MAY_HAVE_DEBUG_BIND_STMTS, wi::ne_p(), NULL_TREE, operand_equal_p(), basic_block_def::preds, release_ssa_name(), remove_phi_node(), replace_uses_by(), safe_dyn_cast(), single_imm_use(), single_pred(), single_pred_p(), SSA_NAME_DEF_STMT, SSA_NAME_OCCURS_IN_ABNORMAL_PHI, statistics_counter_event(), basic_block_def::succs, swap_tree_comparison(), wi::to_wide(), wi::to_widest(), TREE_CODE, tree_fits_shwi_p(), tree_int_cst_lt(), TREE_OPERAND, tree_to_shwi(), TREE_TYPE, TYPE_PRECISION, TYPE_UNSIGNED, update_stmt(), USE_STMT, and useless_type_conversion_p().
The function value_replacement does the main work of doing the value
replacement. Return non-zero if the replacement is done. Otherwise return
0. If we remove the middle basic block, return 2.
BB is the basic block where the replacement is going to be done on. ARG0
is argument 0 from the PHI. Likewise for ARG1.
References absorbing_element_p(), as_a(), bb_seq(), boolean_type_node, build2(), build3(), build_debug_expr_decl(), CASE_CONVERT, cfun, CONVERT_EXPR_CODE_P, dump_file, dump_flags, EDGE_COUNT, EDGE_PRED, eni_time_weights, estimate_num_insns(), estimate_num_insns_seq(), profile_probability::even(), extract_true_false_edges_from_block(), fold_convert, FOR_EACH_IMM_USE_ON_STMT, FOR_EACH_IMM_USE_STMT, g, gcc_assert, get_global_range_query(), gimple_assign_lhs(), gimple_assign_rhs1(), gimple_assign_rhs2(), gimple_assign_rhs_class(), gimple_assign_rhs_code(), gimple_bb(), GIMPLE_BINARY_RHS, gimple_build_debug_bind(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_phi_result(), gimple_seq_empty_p(), gsi_after_labels(), gsi_end_p(), gsi_for_stmt(), gsi_insert_before(), gsi_last_bb(), gsi_last_nondebug_bb(), gsi_move_before(), gsi_next_nondebug(), gsi_prev_nondebug(), GSI_SAME_STMT, gsi_start_nondebug_after_labels_bb(), gsi_stmt(), HONOR_SIGNED_ZEROS(), i, basic_block_def::index, int_const_binop(), INTEGRAL_TYPE_P, is_gimple_assign(), is_gimple_debug(), jump_function_from_stmt(), MAY_HAVE_DEBUG_BIND_STMTS, neutral_element_p(), NULL, NULL_TREE, operand_equal_for_phi_arg_p(), operand_equal_for_value_replacement(), optimize_bb_for_speed_p(), phi_nodes(), POINTER_TYPE_P, print_generic_expr(), PROFILE_ABSENT, profile_status_for_fn, r, replace_exp(), replace_phi_edge_with_variable(), reset_debug_uses(), reset_flow_sensitive_info(), sc, SET_PHI_ARG_DEF, set_range_info(), single_imm_use(), single_non_singleton_phi_for_edges(), single_pred_p(), single_succ_edge(), ssa_name_maybe_undef_p(), SSA_NAME_RANGE_INFO, statistics_counter_event(), tcc_comparison, TDF_DETAILS, TREE_CODE, TREE_CODE_CLASS, tree_int_cst_equal(), tree_int_cst_le(), tree_int_cst_lt(), TREE_OVERFLOW, TREE_TYPE, update_stmt(), and virtual_operand_p().