|
GCC Middle and Back End API Reference
|
#include "config.h"#include "system.h"#include "coretypes.h"#include "backend.h"#include "target.h"#include "rtl.h"#include "tree.h"#include "cfghooks.h"#include "df.h"#include "memmodel.h"#include "tm_p.h"#include "expmed.h"#include "optabs.h"#include "regs.h"#include "emit-rtl.h"#include "recog.h"#include "cfgrtl.h"#include "cfganal.h"#include "cfgcleanup.h"#include "explow.h"#include "expr.h"#include "output.h"#include "cfgloop.h"#include "tree-pass.h"#include "dbgcnt.h"#include "shrink-wrap.h"#include "rtl-iter.h"#include "ifcvt.h"
Data Structures | |
| struct | noce_parallel_cost_node |
| struct | noce_cc_reg_set |
Macros | |
| #define | MAX_CONDITIONAL_EXECUTE |
| #define | NULL_BLOCK ((basic_block) NULL) |
Enumerations | |
| enum | ifcvt_phase { IFCVT_BEFORE_COMBINE , IFCVT_AFTER_COMBINE , IFCVT_AFTER_RELOAD } |
Variables | |
| static ifcvt_phase | ifcvt_pass_phase |
| static bool | have_cbranchcc4 |
| static int | num_possible_if_blocks |
| static int | num_updated_if_blocks |
| static int | num_true_changes |
| static bool | ifcvt_changed_p |
| #define MAX_CONDITIONAL_EXECUTE |
If-conversion support. Copyright (C) 2000-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/>.
The number of instructions this pass may make run unconditionally in place of a branch. The conditional-execution path uses it as the number of insns it may predicate. The branchless paths use it as the number of insns they may speculate. The default charges the cost of an unpredictable branch, plus one. Some targets override it.
Referenced by cond_exec_find_if_block(), cond_exec_process_if_block(), cond_move_process_if_block(), and noce_process_if_block().
| #define NULL_BLOCK ((basic_block) NULL) |
Referenced by block_fallthru(), cond_exec_find_if_block(), cond_exec_process_if_block(), and noce_find_if_block().
| enum ifcvt_phase |
|
static |
Compute average of two given costs weighted by relative probabilities of respective basic blocks in an IF-THEN-ELSE. E is the IF-THEN edge. With P as the probability to take the IF-THEN branch, return P * THEN_COST + (1 - P) * ELSE_COST. Evaluate this as ELSE_COST + P * (THEN_COST - ELSE_COST) when THEN_COST >= ELSE_COST, and THEN_COST + (1 - P) * (ELSE_COST - THEN_COST) otherwise. Both forms pass a nonnegative value to profile_probability::apply and make its rounding independent of the CFG arm order.
References average_cost().
Referenced by average_cost(), and noce_original_region_cost().
|
static |
Return true iff basic block TEST_BB is suitable for conversion to a series of conditional moves. Unless REQUIRE_MULTIPLE is false, also check that we have more than one set (other routines can handle a single set better than we would). A diamond arm may have a single set. Require no more than PARAM_MAX_RTL_IF_CONVERSION_INSNS sets. While going through the insns, store the sum of their potential costs in COST. On success, if LIVE_OUT_DESTS is nonnull, record the distinct pseudo destinations that are live out of TEST_BB. If HAS_NON_SIMPLE_SRC is nonnull, set it when an instruction source is neither a constant nor a register operand. On success, if INSN_COUNT is nonnull, store the number of active sets in it.
References active_insn_p(), bb_ok_for_noce_convert_multiple_sets(), bitmap_bit_p, bitmap_clear(), bitmap_set_bit, can_conditionally_move_p(), contains_mem_rtx_p(), df_get_live_out(), FOR_BB_INSNS, GET_MODE, HARD_REGISTER_P, insn_cost(), noce_can_force_operand(), noce_operand_ok(), noce_simple_cmove_operand_p(), NULL, NULL_RTX, optimize_bb_for_speed_p(), REG_P, REGNO, SET_DEST, SET_SRC, and single_set().
Referenced by bb_ok_for_noce_convert_multiple_sets(), and noce_process_if_block().
|
static |
Return true iff basic block TEST_BB is valid for noce if-conversion. The condition used in this if-conversion is in COND. In practice, check that TEST_BB ends with a single set x := a and all previous computations in TEST_BB don't produce any values that are live after TEST_BB. In other words, all the insns in TEST_BB are there only to compute a value for x. Add the rtx cost of the insns in TEST_BB to COST. Record whether TEST_BB is a single simple set instruction in SIMPLE_P.
References active_insn_p(), BB_END, bb_valid_for_noce_process_p(), bitmap_intersect_p(), bitmap_set_bit, cc_in_cond(), contains_mem_rtx_p(), df_get_live_out(), first_active_insn(), FOR_BB_INSNS, gcc_assert, insn_valid_noce_process_p(), JUMP_P, last_active_insn(), noce_operand_ok(), NULL_RTX, onlyjump_p(), optimize_bb_for_speed_p(), pattern_cost(), PREV_INSN(), reg_obstack, reg_overlap_mentioned_p(), REG_P, reg_set_between_p(), REGNO, SET_DEST, SET_SRC, single_set(), SUBREG_P, and SUBREG_REG.
Referenced by bb_valid_for_noce_process_p(), and noce_process_if_block().
|
static |
Return true iff the registers that the insns in BB_A set do not get used in BB_B. If TO_RENAME is non-NULL then it is a location that will be renamed later by the caller and so conflicts on it should be ignored in this function.
References active_insn_p(), bbs_ok_for_cmove_arith(), bitmap_bit_p, bitmap_set_bit, DF_REF_REG, DF_REF_REGNO, FOR_BB_INSNS, FOR_EACH_INSN_DEF, FOR_EACH_INSN_USE, gcc_assert, MEM_P, paradoxical_subreg_p(), reg_obstack, REG_P, rtx_equal_p(), SET_DEST, and single_set().
Referenced by bbs_ok_for_cmove_arith(), and noce_try_cmove_arith().
|
static |
Return the basic block reached by falling through the basic block BB.
References block_fallthru(), find_fallthru_edge(), NULL_BLOCK, and basic_block_def::succs.
Referenced by block_fallthru(), cond_exec_process_if_block(), and merge_if_block().
|
static |
Subroutine of find_cond_trap: if BB contains only a trap insn, return it.
References BB_END, block_has_only_trap(), cfun, const_true_rtx, EDGE_COUNT, EXIT_BLOCK_PTR_FOR_FN, first_active_insn(), GET_CODE, NULL, PATTERN(), basic_block_def::succs, and TRAP_CONDITION.
Referenced by block_has_only_trap(), and find_cond_trap().
|
static |
CUR_BB has two edges, one falling through to the next block and one jumping to TARGET_BB, so it can be part of an && test or an || test. Return the number of non-note, non-jump, non-USE/CLOBBER insns in it, or -1 if CUR_BB is not of that form.
References BB_END, BB_HEAD, block_jumps_and_fallthru(), CALL_P, DEBUG_INSN_P, EDGE_COMPLEX, EDGE_COUNT, end(), FOR_EACH_EDGE, GET_CODE, INSN_P, JUMP_P, NEXT_INSN(), PATTERN(), and basic_block_def::succs.
Referenced by block_jumps_and_fallthru(), and cond_exec_find_if_block().
Return the CC reg if it is used in COND.
References cc_in_cond(), GET_MODE, GET_MODE_CLASS, have_cbranchcc4, NULL_RTX, and XEXP.
Referenced by bb_valid_for_noce_process_p(), cc_in_cond(), check_cond_move_block(), and end_ifcvt_sequence().
|
static |
Determine whether the total insn_cost on non-jump insns in basic block BB is less than MAX_COST. This function returns false if the cost of any instruction could not be estimated. The cost of the non-jump insns in BB is scaled by REG_BR_PROB_BASE as those insns are being speculated. MAX_COST is scaled with SCALE plus a small fudge factor.
References asm_noperands(), BB_END, BB_HEAD, CALL_P, cfun, cheap_bb_rtx_cost_p(), IFCVT_BEFORE_COMBINE, ifcvt_pass_phase, profile_probability::initialized_p(), insn_cost(), NEXT_INSN(), NONJUMP_INSN_P, optimize_bb_for_speed_p(), optimize_function_for_speed_p(), PATTERN(), REG_BR_PROB_BASE, SET_DEST, single_set(), and profile_probability::to_reg_br_prob_base().
Referenced by cheap_bb_rtx_cost_p(), find_if_case_1(), and find_if_case_2().
|
static |
Check whether a block is suitable for conditional move conversion. Every insn must be a simple set of a register to a constant or a register. For each assignment, store the value in the pointer map VALS, keyed by register pointer, then store the register pointer in REGS. COND is the condition we will test.
References BB_END, cc_in_cond(), check_cond_move_block(), CONSTANT_P, FOR_BB_INSNS, hash_map< KeyId, Value, Traits >::get(), GET_CODE, GET_MODE, HARD_REGISTER_P, JUMP_P, may_trap_p(), modified_between_p(), NEXT_INSN(), noce_simple_cmove_operand_p(), NONDEBUG_INSN_P, onlyjump_p(), hash_map< KeyId, Value, Traits >::put(), reg_overlap_mentioned_p(), REG_P, SET_DEST, set_of(), SET_SRC, side_effects_p(), single_set(), SUBREG_REG, and targetm.
Referenced by check_cond_move_block(), and cond_move_process_if_block().
|
static |
Determine if a given basic block heads a simple IF-THEN or IF-THEN-ELSE block. If so, we'll try to convert the insns to not require the branch. Return TRUE if we were successful at converting the block.
References ce_if_block::and_and_p, BB_END, BB_HEAD, block_jumps_and_fallthru(), cancel_changes(), cfun, cond_exec_find_if_block(), cond_exec_process_if_block(), dump_file, EDGE_COMPLEX, EDGE_COUNT, ce_if_block::else_bb, epilogue_completed, EXIT_BLOCK_PTR_FOR_FN, FOR_EACH_EDGE, fputc(), gcc_assert, basic_block_def::index, INSN_UID(), ce_if_block::join_bb, JUMP_P, ce_if_block::last_test_bb, MAX_CONDITIONAL_EXECUTE, basic_block_def::next_bb, NOTE_P, NULL, NULL_BLOCK, ce_if_block::num_and_and_blocks, ce_if_block::num_multiple_test_blocks, ce_if_block::num_multiple_test_insns, ce_if_block::num_or_or_blocks, num_possible_if_blocks, ce_if_block::pass, basic_block_def::preds, PREV_INSN(), reload_completed, simplejump_p(), single_pred(), single_pred_edge(), single_pred_p(), single_succ(), single_succ_edge(), single_succ_p(), basic_block_def::succs, tablejump_p(), targetm, ce_if_block::test_bb, and ce_if_block::then_bb.
Referenced by cond_exec_find_if_block(), and find_if_header().
Return the condition for a jump. Do not do any special processing.
References any_condjump_p(), cond_exec_get_condition(), GET_CODE, GET_MODE, JUMP_LABEL, label_ref_label(), NULL_RTX, pc_set(), reversed_comparison_code(), SET_SRC, and XEXP.
Referenced by cond_exec_get_condition(), cond_exec_process_if_block(), dead_or_predicable(), and noce_convert_multiple_sets_1().
|
static |
Given a simple IF-THEN or IF-THEN-ELSE block described by CE_INFO, attempt to convert it to conditional execution. DO_MULTIPLE_P allows CE_INFO's recorded chain of && or || test blocks to be converted as well. Return TRUE if we were successful at converting the block.
References ce_if_block::and_and_p, apply_change_group(), BB_END, BB_HEAD, block_fallthru(), cancel_changes(), cond_exec_get_condition(), cond_exec_process_if_block(), cond_exec_process_insns(), count_bb_insns(), DEBUG_INSN_P, delete_insn_chain(), dump_file, ce_if_block::else_bb, end(), find_active_insn_after(), find_active_insn_before(), find_reg_note(), first_active_insn(), flow_find_cross_jump(), flow_find_head_matching_sequence(), profile_probability::from_reg_br_prob_note(), get_last_bb_insn(), GET_MODE, ifcvt_changed_p, INSN_P, profile_probability::invert(), LABEL_P, last_active_insn(), ce_if_block::last_test_bb, MAX_CONDITIONAL_EXECUTE, merge_if_block(), MIN, modified_in_p(), NEXT_INSN(), NOTE_P, NULL, NULL_BLOCK, NULL_RTX, ce_if_block::num_and_and_blocks, ce_if_block::num_else_insns, ce_if_block::num_multiple_test_blocks, ce_if_block::num_or_or_blocks, ce_if_block::num_then_insns, onlyjump_p(), reversed_comparison_code(), ce_if_block::test_bb, ce_if_block::then_bb, profile_probability::uninitialized(), XEXP, and XINT.
Referenced by cond_exec_find_if_block(), and cond_exec_process_if_block().
|
static |
Go through the insns from START to END, converting them to conditional execution format if possible. CE_INFO describes the if-block being converted and is only read by the target IFCVT_MODIFY_INSN macro. TEST is the conditional-execution test to predicate them on and PROB_VAL the probability that it holds. MOD_OK allows one insn that modifies TEST, in which case it must be the last one. Return TRUE if all of the non-note insns were processed.
References CALL_P, COND_EXEC_CODE, cond_exec_process_insns(), COND_EXEC_TEST, copy_rtx(), DEBUG_INSN_P, end(), gcc_assert, GET_CODE, GET_MODE, profile_probability::initialized_p(), modified_in_p(), NEXT_INSN(), NONJUMP_INSN_P, NOTE_KIND, NOTE_P, PATTERN(), REG_NOTES, reload_completed, RTX_FRAME_RELATED_P, SET_INSN_DELETED, profile_probability::to_reg_br_prob_note(), and validate_change().
Referenced by cond_exec_process_if_block(), cond_exec_process_insns(), and dead_or_predicable().
|
static |
Given a basic block BB suitable for conditional move conversion, a condition COND, and pointer maps THEN_VALS and ELSE_VALS containing the register values depending on COND, emit the insns in the block as conditional moves. If ELSE_BLOCK is true, THEN_BB was already processed. The caller has started a sequence for the conversion. Return true if successful, false if something goes wrong.
References noce_if_info::cond_inverted, cond_move_convert_if_block(), FOR_BB_INSNS, gcc_assert, hash_map< KeyId, Value, Traits >::get(), GET_CODE, JUMP_P, noce_emit_cmove(), noce_emit_move_insn(), NONDEBUG_INSN_P, NULL_RTX, REG_P, SET_DEST, single_set(), and XEXP.
Referenced by cond_move_convert_if_block(), and cond_move_process_if_block().
|
static |
Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert it using only conditional moves. Return TRUE if we were successful at converting the block.
References check_cond_move_block(), noce_if_info::cond, cond_move_convert_if_block(), cond_move_process_if_block(), CONSTANT_P, noce_if_info::else_bb, emit_insn_before_setloc(), end_ifcvt_sequence(), end_sequence(), first_active_insn(), gcc_assert, gcc_checking_assert, hash_map< KeyId, Value, Traits >::get(), INSN_LOCATION(), noce_if_info::jump, MAX_CONDITIONAL_EXECUTE, noce_finish_if_conversion(), rtx_equal_p(), start_sequence(), targetm, and noce_if_info::then_bb.
Referenced by cond_move_process_if_block(), and noce_find_if_block().
Return true if X contains a conditional code mode rtx.
References contains_ccmode_rtx_p(), FOR_EACH_SUBRTX, GET_MODE, and GET_MODE_CLASS.
Referenced by contains_ccmode_rtx_p(), and insn_valid_noce_process_p().
|
static |
Count the number of non-jump active insns in BB.
References active_insn_p(), BB_END, BB_HEAD, count_bb_insns(), JUMP_P, and NEXT_INSN().
Referenced by cond_exec_process_if_block(), and count_bb_insns().
|
static |
Used by the code above to perform the actual rtl transformations. Return TRUE if successful. TEST_BB is the block containing the conditional branch. MERGE_BB is the block containing the code to manipulate. OTHER_BB is the other successor of TEST_BB, the one the code is being moved past. DEST_EDGE is an edge representing a jump to the join block; after the conversion, TEST_BB should be branching to its destination. REVERSEP is true if the sense of the branch should be reversed.
References any_condjump_p(), as_a(), BB_END, BB_HEAD, bitmap_and_into(), bitmap_bit_p, bitmap_empty_p(), bitmap_intersect_p(), bitmap_set_bit, block_label(), BRANCH_EDGE, can_move_insns_across(), cancel_changes(), cfun, cond_exec_get_condition(), cond_exec_process_insns(), confirm_change_group(), dead_or_predicable(), DEBUG_INSN_P, delete_insn(), df_get_live_in(), df_get_live_out(), DF_REF_REGNO, df_simulate_find_defs(), df_simulate_uses(), end(), ENTRY_BLOCK_PTR_FOR_FN, epilogue_completed, EXECUTE_IF_SET_IN_BITMAP, EXIT_BLOCK_PTR_FOR_FN, FALLTHRU_EDGE, find_reg_note(), FOR_BB_INSNS, FOR_BB_INSNS_REVERSE, FOR_EACH_INSN_DEF, profile_probability::from_reg_br_prob_note(), GET_MODE, i, INCOMING_REGNO, INSN_P, profile_probability::invert(), invert_jump_1(), JUMP_LABEL, JUMP_P, LABEL_P, max_reg_num(), max_regno, NEXT_INSN(), noce_get_condition(), NONDEBUG_INSN_P, NOTE_P, NULL, NULL_RTX, num_validated_changes(), onlyjump_p(), PREV_INSN(), redirect_edge_succ(), redirect_jump_1(), redirect_jump_2(), reg_obstack, remove_edge(), remove_note(), remove_reg_equal_equiv_notes_for_regno(), reorder_insns(), ret_rtx, reversed_comparison_code(), RTX_FRAME_RELATED_P, SHRINK_WRAPPING_ENABLED, simulate_backwards_to_point(), single_succ(), single_succ_p(), tablejump_p(), targetm, profile_probability::uninitialized(), update_br_prob_note(), verify_changes(), XEXP, and XINT.
Referenced by dead_or_predicable(), find_if_case_1(), and find_if_case_2().
| bool default_noce_conversion_profitable_p | ( | rtx_insn * | seq, |
| noce_if_info * | if_info ) |
Return true if SEQ is a good candidate as a replacement for the if-convertible sequence described in IF_INFO. This is the default implementation that targets can override through a target hook.
References default_noce_conversion_profitable_p(), noce_if_info::max_seq_cost, noce_parallel_seq_cost(), and noce_if_info::speed_p.
Referenced by default_builtin_tm_load_store(), and default_noce_conversion_profitable_p().
|
static |
Return sequence of instructions generated by if conversion. This function calls end_sequence() to end the current stream, ensures that the instructions are unshared, recognizable non-jump insns. On failure, this function returns a NULL_RTX.
References noce_if_info::a, noce_if_info::b, cc_in_cond(), noce_if_info::cond, end_ifcvt_sequence(), end_sequence(), get_insns(), JUMP_P, NEXT_INSN(), noce_clobbers_live_cc_p(), NULL, recog_memoized(), set_of(), set_used_flags(), noce_if_info::test_bb, unshare_all_rtl_in_chain(), and noce_if_info::x.
Referenced by cond_move_process_if_block(), end_ifcvt_sequence(), noce_try_abs(), noce_try_addcc(), noce_try_bitop(), noce_try_cmove(), noce_try_cmove_arith(), noce_try_cond_arith(), noce_try_ifelse_collapse(), noce_try_inverse_constants(), noce_try_minmax(), noce_try_move(), noce_try_shifted_store_flag(), noce_try_sign_bit_splat(), noce_try_sign_mask(), noce_try_store_flag(), noce_try_store_flag_constants(), noce_try_store_flag_logical(), and noce_try_store_flag_mask().
|
static |
Return the active insn after INSN inside basic block CURR_BB.
References BB_END, CALL_P, find_active_insn_after(), JUMP_P, NEXT_INSN(), NONJUMP_INSN_P, NULL, and NULL_RTX.
Referenced by cond_exec_process_if_block(), and find_active_insn_after().
|
static |
Return the active insn before INSN inside basic block CURR_BB.
References BB_HEAD, CALL_P, find_active_insn_before(), JUMP_P, NONJUMP_INSN_P, NULL, NULL_RTX, and PREV_INSN().
Referenced by cond_exec_process_if_block(), and find_active_insn_before().
|
static |
Convert a branch over a trap, or a branch to a trap, into a conditional trap.
References BB_END, block_has_only_trap(), can_merge_blocks_p(), copy_rtx(), current_ir_type(), delete_basic_block(), delete_insn(), df_set_bb_dirty(), dump_file, EDGE_COUNT, emit_barrier_after(), emit_insn_before_setloc(), emit_jump_insn_after(), find_cond_trap(), gen_cond_trap(), GET_CODE, GET_MODE, basic_block_def::index, INSN_LOCATION(), IR_RTL_CFGLAYOUT, JUMP_LABEL, LABEL_NUSES, merge_blocks(), NEXT_INSN(), noce_get_condition(), NULL, num_true_changes, num_updated_if_blocks, onlyjump_p(), PATTERN(), basic_block_def::preds, recog_memoized(), reload_completed, remove_edge(), returnjump_p(), single_succ_edge(), targetm, TRAP_CODE, valid_insn_p(), and XEXP.
Referenced by find_cond_trap(), and find_if_header().
|
static |
Tests for case 1 above.
References BB_END, BB_PARTITION, cfun, cheap_bb_rtx_cost_p(), COSTS_N_INSNS, dead_or_predicable(), delete_basic_block(), df_bb_replace(), df_set_bb_dirty(), dump_file, EDGE_COMPLEX, EXIT_BLOCK_PTR_FOR_FN, FALLTHRU_EDGE, find_if_case_1(), force_nonfallthru_and_redirect(), forwarder_block_p(), gcc_assert, gcc_checking_assert, if_case_blocks_ok_p(), basic_block_def::index, profile_probability::invert(), JUMP_LABEL, JUMP_P, basic_block_def::next_bb, NULL_RTX, num_possible_if_blocks, num_true_changes, num_updated_if_blocks, optimize_bb_for_speed_p(), predictable_edge_p(), basic_block_def::prev_bb, redirect_edge_and_branch_force(), redirect_edge_succ(), single_pred_p(), single_succ_edge(), and single_succ_p().
Referenced by find_if_case_1(), and find_if_header().
|
static |
Test for case 2 above.
References CDI_POST_DOMINATORS, cheap_bb_rtx_cost_p(), COSTS_N_INSNS, current_loops, dead_or_predicable(), delete_basic_block(), df_set_bb_dirty(), dominated_by_p(), dump_file, EDGE_COMPLEX, find_if_case_2(), if_case_blocks_ok_p(), basic_block_def::index, profile_probability::invert(), loop::latch, basic_block_def::loop_father, NUM_FIXED_BLOCKS, num_possible_if_blocks, num_true_changes, num_updated_if_blocks, optimize_bb_for_speed_p(), predictable_edge_p(), single_pred_p(), single_succ_edge(), and single_succ_p().
Referenced by find_if_case_2(), and find_if_header().
|
static |
Find a block ending in a simple IF condition and try to transform it in some way. When converting a multi-block condition, put the new code in the first such block and delete the rest. Return a pointer to this first block if some transformation was done. Return NULL otherwise.
References CDI_POST_DOMINATORS, cond_exec_find_if_block(), df_get_bb_dirty(), dom_info_state(), DOM_NO_FAST_QUERY, dump_file, EDGE_COMPLEX, EDGE_COUNT, EDGE_SUCC, ce_if_block::else_bb, find_cond_trap(), find_if_case_1(), find_if_case_2(), find_if_header(), ifcvt_changed_p, noce_find_if_block(), NULL, optab_handler(), ce_if_block::pass, reload_completed, basic_block_def::succs, targetm, ce_if_block::test_bb, ce_if_block::then_bb, and word_mode.
Referenced by find_if_header(), and if_convert().
|
static |
Return the first non-jump active insn in the basic block.
References BB_END, BB_HEAD, DEBUG_INSN_P, first_active_insn(), JUMP_P, LABEL_P, NEXT_INSN(), NOTE_P, and NULL.
Referenced by bb_valid_for_noce_process_p(), block_has_only_trap(), cond_exec_process_if_block(), cond_move_process_if_block(), and first_active_insn().
Return the register or constant that EXP selects on: EXP itself for a register or a constant, the inner register of a subreg, and NULL_RTX for anything else.
References CONST_INT_P, exp(), get_base_reg_or_constant(), NULL_RTX, REG_P, SUBREG_P, and SUBREG_REG.
Referenced by get_base_reg_or_constant(), and noce_try_cond_arith().
|
static |
Look for IF-THEN-ELSE cases in which one of THEN or ELSE is
transformable, but not necessarily the other. There need be no
JOIN block.
Return TRUE if we were successful at converting the block.
Cases we'd like to look at:
(1)
if (test) goto over; // x not live
x = a;
goto label;
over:
becomes
x = a;
if (! test) goto label;
(2)
if (test) goto E; // x not live
x = big();
goto L;
E:
x = b;
goto M;
becomes
x = b;
if (test) goto M;
x = big();
goto L;
(3) // This one's really only interesting for targets that can do
// multiway branching, e.g. IA-64 BBB bundles. For other targets
// it results in multiple branches on a cache line, which often
// does not sit well with predictors.
if (test1) goto E; // predicted not taken
x = a;
if (test2) goto F;
...
E:
x = b;
J:
becomes
x = a;
if (test1) goto E;
if (test2) goto F;
Notes:
(A) Don't do (2) if the branch is predicted against the block we're
eliminating. Do it anyway if we can eliminate a branch; this requires
that the sole successor of the eliminated block postdominate the other
side of the if.
(B) With CE, on (3) we can steal from both sides of the if, creating
if (test1) x = a;
if (!test1) x = b;
if (test1) goto J;
if (test2) goto F;
...
J:
Again, this is most useful if J postdominates.
(C) CE substitutes for helpful life information.
(D) These heuristics need a lot of work. Return true if the if-case formed by TEST_BB, THEN_BB and ELSE_BB is one we may convert at all. If we are partitioning hot/cold basic blocks, we don't want to mess up unconditional or indirect jumps that cross between hot and cold sections. Basic block partitioning may result in some jumps that appear to be optimizable (or blocks that appear to be mergeable), but which really must be left untouched (they are required to make it safely across partition boundaries). See the comments at the top of bb-reorder.cc:partition_hot_cold_basic_blocks for complete details. TEST_BB must also end in a conditional jump with no other side-effects.
References BB_END, CROSSING_JUMP_P, if_case_blocks_ok_p(), JUMP_P, and onlyjump_p().
Referenced by find_if_case_1(), find_if_case_2(), and if_case_blocks_ok_p().
|
static |
Main entry point for all if-conversion. PHASE selects the ce1, ce2 or ce3 run: before combine, after combine, or after reload.
References AVOID_CFG_MODIFICATIONS, calculate_dominance_info(), CDI_DOMINATORS, CDI_POST_DOMINATORS, cfun, checking_verify_flow_info(), clear_aux_for_blocks(), df_analyze(), df_clear_flags(), df_get_bb_dirty(), df_live, df_live_add_problem(), df_live_set_all_dirty(), DF_LR_RUN_DCE, df_remove_problem(), df_set_flags(), direct_optab_handler(), dump_file, dump_flags, find_if_header(), fixup_partitions(), FOR_EACH_BB_FN, free_dominance_info(), get_insns(), have_cbranchcc4, if_convert(), ifcvt_changed_p, ifcvt_pass_phase, loop_optimizer_finalize(), loop_optimizer_init(), mark_loop_exit_edges(), max_reg_num(), max_regno, NULL, num_possible_if_blocks, num_true_changes, num_updated_if_blocks, and print_rtl_with_bb().
Referenced by if_convert(), and rest_of_handle_if_conversion().
|
static |
Fill INSN_INFO with one entry per active insn in BB. Find local swap-style
idioms and mark the first insn (1) that is only a temporary as not needing
a conditional move, as it is going to be dead afterwards anyway.
(1) int tmp = a;
a = b;
b = tmp;
ifcvt
-->
tmp = a;
a = cond ? b : a_old;
b = cond ? tmp : b_old;
Additionally, store the index of insns like (2) when a subsequent
SET reads from their destination.
(2) int c = a;
int d = c;
ifcvt
-->
c = cond ? a : c_old;
d = cond ? d : c; // Need to use c rather than c_old here.
References active_insn_p(), bitmap_bit_p, bitmap_set_bit, df_get_live_out(), FOR_BB_INSNS, gcc_checking_assert, HARD_REGISTER_P, i, init_noce_multiple_sets_info(), noce_multiple_sets_info::need_cmov, NULL_RTX, reg_mentioned_p(), REG_P, REGNO, SET_DEST, SET_SRC, single_set(), noce_multiple_sets_info::target, noce_multiple_sets_info::temporary, and noce_multiple_sets_info::unmodified_insn.
Referenced by init_noce_multiple_sets_info(), and noce_convert_multiple_sets().
Helper for bb_valid_for_noce_process_p. Validate that the rtx insn INSN is a single set that does not set the conditional register CC and is in general valid for if-conversion.
References contains_ccmode_rtx_p(), insn_valid_noce_process_p(), noce_operand_ok(), NONJUMP_INSN_P, SET_DEST, set_of(), SET_SRC, and single_set().
Referenced by bb_valid_for_noce_process_p(), and insn_valid_noce_process_p().
|
static |
Return the last non-jump active insn in the basic block.
References BB_END, BB_HEAD, DEBUG_INSN_P, GET_CODE, JUMP_P, LABEL_P, last_active_insn(), NONJUMP_INSN_P, NOTE_P, NULL, PATTERN(), and PREV_INSN().
Referenced by bb_valid_for_noce_process_p(), cond_exec_process_if_block(), last_active_insn(), noce_emit_all_but_last(), and noce_process_if_block().
| rtl_opt_pass * make_pass_if_after_combine | ( | gcc::context * | ctxt | ) |
References IFCVT_AFTER_COMBINE, and make_pass_if_after_combine().
Referenced by make_pass_if_after_combine(), and make_pass_rtl_dse3().
| rtl_opt_pass * make_pass_if_after_reload | ( | gcc::context * | ctxt | ) |
References IFCVT_AFTER_RELOAD, and make_pass_if_after_reload().
Referenced by make_pass_if_after_reload(), and make_pass_value_profile_transformations().
| rtl_opt_pass * make_pass_rtl_ifcvt | ( | gcc::context * | ctxt | ) |
References IFCVT_BEFORE_COMBINE, and make_pass_rtl_ifcvt().
Referenced by make_pass_rtl_dse3(), and make_pass_rtl_ifcvt().
|
static |
Merge BB into COMBO_BB. BB has no successor edges left, so if COMBO_BB still has another successor the BARRIER that follows BB is no longer needed and it is in fact incorrect to leave it in the insn stream.
References BARRIER_P, BB_END, delete_insn(), EDGE_COUNT, end(), merge_block_into_combo(), merge_blocks(), NEXT_INSN(), NOTE_INSN_BASIC_BLOCK_P, NOTE_P, num_true_changes, and basic_block_def::succs.
Referenced by merge_block_into_combo(), and merge_if_block().
|
static |
Merge the blocks and mark for local life update.
References BB_END, block_fallthru(), CALL_P, can_throw_internal(), cfun, const_true_rtx, df_set_bb_dirty(), EDGE_COUNT, EDGE_SUCC, ce_if_block::else_bb, EXIT_BLOCK_PTR_FOR_FN, find_reg_note(), gcc_assert, GET_CODE, ce_if_block::join_bb, JUMP_P, ce_if_block::last_test_bb, merge_block_into_combo(), merge_blocks(), merge_if_block(), NONJUMP_INSN_P, NULL, ce_if_block::num_multiple_test_blocks, num_true_changes, num_updated_if_blocks, PATTERN(), basic_block_def::preds, SIBLING_CALL_P, single_succ(), single_succ_edge(), single_succ_p(), basic_block_def::succs, ce_if_block::test_bb, ce_if_block::then_bb, tidy_fallthru_edge(), and TRAP_CONDITION.
Referenced by cond_exec_process_if_block(), and merge_if_block().
Return true if X can be safely forced into a register by copy_to_mode_reg / force_operand.
References ARITHMETIC_P, general_operand(), GET_CODE, GET_MODE, INTEGRAL_MODE_P, noce_can_force_operand(), optab_handler(), SUBREG_P, SUBREG_REG, UNARY_P, and XEXP.
Referenced by bb_ok_for_noce_convert_multiple_sets(), noce_can_force_operand(), noce_emit_move_insn(), and noce_try_sign_mask().
|
static |
Return true if SEQ writes a condition-code register that still holds a value which is live on exit from TEST_BB. An if-converted sequence is emitted immediately before the jump that ends TEST_BB, and the conversion then removes that jump, so a condition code that is live out of TEST_BB is one which a later block still reads. Expanding a conditional move can emit a fresh comparison, and that would destroy it.
References bitmap_bit_p, CLEAR_HARD_REG_SET, df_get_live_out(), EXECUTE_IF_SET_IN_HARD_REG_SET, noce_cc_reg_set::fixed_regno1, noce_cc_reg_set::fixed_regno2, INVALID_REGNUM, NEXT_INSN(), noce_clobbers_live_cc_p(), noce_record_cc_reg_set(), note_stores(), noce_cc_reg_set::set, and targetm.
Referenced by end_ifcvt_sequence(), noce_clobbers_live_cc_p(), and noce_convert_multiple_sets().
|
static |
Commit the wound-up candidate SEQ produced by a noce transform for IF_INFO. Reject it (returning false, emitting nothing) if it failed to build, or if CHECK_PROFITABLE and the target deems it not worthwhile. Otherwise emit it before the branch, record NAME as the winning transform and return true. This is the shared tail of the noce_try_* matchers.
References emit_insn_before_setloc(), noce_if_info::insn_a, INSN_LOCATION(), noce_if_info::jump, noce_commit_sequence(), targetm, and noce_if_info::transform_name.
Referenced by noce_commit_sequence(), noce_try_addcc(), noce_try_cmove(), noce_try_cmove_arith(), noce_try_cond_arith(), noce_try_ifelse_collapse(), noce_try_inverse_constants(), noce_try_shifted_store_flag(), noce_try_sign_bit_splat(), noce_try_sign_mask(), noce_try_store_flag(), noce_try_store_flag_constants(), noce_try_store_flag_logical(), and noce_try_store_flag_mask().
Return the arithmetic operation in X, looking through an extension.
References GET_CODE, noce_cond_arith_operation(), noce_cond_zero_binary_op_supported(), NULL_RTX, and XEXP.
Referenced by noce_cond_arith_operation(), and noce_try_cond_arith().
Check if OP is supported by conditional zero based if conversion, returning TRUE if satisfied otherwise FALSE. OP is the operation to check.
References GET_CODE, and noce_cond_zero_binary_op_supported().
Referenced by noce_cond_arith_operation(), noce_cond_zero_binary_op_supported(), and noce_try_shifted_store_flag().
|
static |
We have something like:
if (x > y)
{ i = EXPR_A; j = EXPR_B; k = EXPR_C; }
Make it:
tmp_i = (x > y) ? EXPR_A : i;
tmp_j = (x > y) ? EXPR_B : j;
tmp_k = (x > y) ? EXPR_C : k;
i = tmp_i;
j = tmp_j;
k = tmp_k;
Subsequent passes are expected to clean up the extra moves.
Look for special cases such as writes to one register which are
read back in another SET, as might occur in a swap idiom or
similar.
These look like:
if (x > y)
i = a;
j = i;
Which we want to rewrite to:
tmp_i = (x > y) ? a : i;
tmp_j = (x > y) ? tmp_i : j;
i = tmp_i;
j = tmp_j;
We can catch these when looking at (SET x y) by keeping a list of the
registers we would have targeted before if-conversion and looking back
through it for an overlap with Y. If we find one, we rewire the
conditional set to use the temporary we introduced earlier.
IF_INFO contains the useful information about the block structure and
jump instructions. For an IF-THEN-ELSE-JOIN, first evaluate the else
arm's sets into temporaries and retain their final values for the
conditional moves. Return true if the replacement is valid and profitable
and its CFG changes have been committed, otherwise return false.
References bitmap_bit_p, bitmap_set_bit, CALL_P, noce_if_info::cond_earliest, noce_if_info::else_bb, emit_insn_before_setloc(), end_sequence(), FOR_EACH_VEC_ELT, FOR_EACH_VEC_ELT_REVERSE, gcc_assert, gcc_checking_assert, get_insns(), i, init_noce_multiple_sets_info(), insn_cost(), INSN_LOCATION(), noce_if_info::jump, JUMP_P, noce_multiple_sets_info::need_cmov, NEXT_INSN(), noce_clobbers_live_cc_p(), noce_convert_multiple_sets(), noce_convert_multiple_sets_1(), noce_emit_move_insn(), noce_finish_if_conversion(), noce_get_condition(), NULL_RTX, noce_if_info::original_cost, recog_memoized(), reg_obstack, REG_P, REGNO, set_used_flags(), noce_if_info::speed_p, start_sequence(), noce_multiple_sets_info::target, targetm, noce_multiple_sets_info::temporary, noce_if_info::test_bb, noce_if_info::then_bb, noce_if_info::transform_name, noce_multiple_sets_info::unmodified_insn, and unshare_all_rtl_in_chain().
Referenced by noce_convert_multiple_sets(), and noce_process_if_block().
|
static |
Try to emit the multiple-set conversion described by IF_INFO, selecting on the already decoded jump condition COND. INSN_INFO holds THEN_COUNT then-arm entries followed by entries for the else-only definitions recorded in ELSE_ONLY_INDICES. For a diamond, evaluate ELSE_INSN_INFO first and retain its final values for the conditional moves. LAST_NEEDS_COMPARISON is -1 on the first attempt. Record in it the last set that needs a temporary to preserve the comparison, then use that boundary on the second attempt. Set USE_COND_EARLIEST if the emitted sequence uses IF_INFO->cond_earliest. Return true if the complete sequence was emitted.
References active_insn_p(), cond_exec_get_condition(), CONSTANT_P, copy_rtx(), copy_to_mode_reg(), curr_insn_location(), noce_if_info::else_bb, emit_insn(), end_sequence(), FOR_BB_INSNS, FOR_EACH_SUBRTX, FOR_EACH_VEC_ELT, gcc_checking_assert, gen_reg_rtx(), GET_CODE, get_insns(), get_last_insn(), GET_MODE, HARD_REGISTER_P, i, INSN_LOCATION(), noce_if_info::jump, modified_in_p(), noce_multiple_sets_info::need_cmov, NEXT_INSN(), noce_convert_multiple_sets_1(), noce_seq_clobbers_cc_cmp_p(), NONDEBUG_INSN_P, NULL, NULL_RTX, PATTERN(), reg_overlap_mentioned_p(), REG_P, noce_multiple_sets_info::rewired_src, rtx_equal_p(), set_curr_insn_location(), SET_DEST, SET_SRC, simplify_replace_rtx(), single_set(), noce_multiple_sets_info::target, noce_multiple_sets_info::temporary, noce_if_info::then_else_reversed, try_emit_cmove_seq(), noce_multiple_sets_info::unmodified_insn, and XEXP.
Referenced by noce_convert_multiple_sets(), and noce_convert_multiple_sets_1().
|
static |
Return the dependency level for an instruction reading SRC. A use of a register defined at level N requires level N + 1.
References i, MAX, noce_dependency_level(), and reg_overlap_mentioned_p().
Referenced by noce_dependency_level(), and noce_parallel_seq_cost().
|
static |
Emit copies of all the active instructions in BB except the last. This is a helper for noce_try_cmove_arith.
References active_insn_p(), as_a(), copy_rtx(), emit_insn(), FOR_BB_INSNS, last_active_insn(), noce_emit_all_but_last(), and PATTERN().
Referenced by noce_emit_all_but_last(), and noce_emit_bb().
|
static |
Helper for noce_try_cmove_arith. Emit a copy of the insns up to and including the penultimate one in BB if it is not simple (as indicated by SIMPLE). Then emit LAST_INSN as the last insn in the block. The reason for that is that LAST_INSN may have been modified by the preparation in noce_try_cmove_arith.
References noce_emit_all_but_last(), noce_emit_bb(), and noce_emit_insn().
Referenced by noce_emit_bb(), and noce_try_cmove_arith().
|
static |
Emit a conditional move selecting VTRUE or VFALSE into X, and return the destination it landed in, or NULL_RTX on failure. CODE, CMP_A and CMP_B give the canonicalized comparison. CC_CMP and REV_CC_CMP, when given, are the non-canonicalized condition and its reverse, which let a target emit the move without materializing its own compare.
References noce_if_info::cond, noce_if_info::cond_earliest, const0_rtx, emit_conditional_move(), emit_insn(), emit_move_insn(), end_sequence(), gen_reg_rtx(), gen_rtx_SUBREG(), general_operand(), GET_CODE, GET_MODE, GET_MODE_CLASS, have_cbranchcc4, noce_if_info::jump, noce_emit_cmove(), NULL, NULL_RTX, recog_memoized(), reload_completed, start_sequence(), SUBREG_BYTE, SUBREG_PROMOTED_GET, SUBREG_PROMOTED_SET, SUBREG_PROMOTED_VAR_P, and SUBREG_REG.
Referenced by cond_move_convert_if_block(), noce_emit_cmove(), noce_try_cmove(), noce_try_cmove_arith(), noce_try_cond_arith(), and try_emit_cmove_seq().
Helper for noce_try_cmove_arith. Emit the pattern TO_EMIT and return the resulting insn or NULL if it's not a valid insn.
References emit_insn(), gcc_assert, noce_emit_insn(), NULL, and recog_memoized().
Referenced by noce_emit_bb(), and noce_emit_insn().
Emit instruction to move an rtx, possibly into STRICT_LOW_PART. X is the destination/target and Y is the value to copy.
References BITS_PER_WORD, CONSTANT_P, emit_insn(), emit_move_insn(), end_sequence(), expand_binop(), expand_unop(), gcc_assert, GET_CODE, get_insns(), GET_MODE, GET_MODE_BITSIZE(), GET_RTX_CLASS, INTVAL, MEM_P, noce_can_force_operand(), noce_emit_move_insn(), NULL_RTX, OBJECT_P, OPTAB_DIRECT, recog_memoized(), REG_P, RTX_BIN_ARITH, RTX_COMM_ARITH, RTX_UNARY, start_sequence(), store_bit_field(), SUBREG_BYTE, XEXP, and y.
Referenced by cond_move_convert_if_block(), noce_convert_multiple_sets(), noce_emit_move_insn(), noce_process_if_block(), noce_try_abs(), noce_try_addcc(), noce_try_bitop(), noce_try_cmove(), noce_try_cmove_arith(), noce_try_cond_arith(), noce_try_ifelse_collapse(), noce_try_inverse_constants(), noce_try_minmax(), noce_try_move(), noce_try_shifted_store_flag(), noce_try_sign_mask(), noce_try_store_flag(), noce_try_store_flag_constants(), noce_try_store_flag_mask(), and try_emit_cmove_seq().
|
static |
Helper function for noce_try_store_flag*. Return NULL_RTX on failure, including when REVERSEP is requested but the condition cannot be reversed; callers may rely on this and need not pre-check.
References noce_if_info::cond, noce_if_info::cond_earliest, emit_insn(), emit_store_flag(), end_sequence(), general_operand(), GET_CODE, GET_MODE, GET_MODE_BITSIZE(), noce_if_info::jump, JUMP_LABEL, known_le, label_ref_label(), MAX_FIXED_MODE_SIZE, noce_emit_store_flag(), NULL_RTX, pc_set(), recog_memoized(), noce_if_info::rev_cond, reversed_comparison_code(), SCALAR_INT_MODE_P, SET_SRC, start_sequence(), STORE_FLAG_VALUE, noce_if_info::then_else_reversed, and XEXP.
Referenced by noce_emit_store_flag(), noce_try_addcc(), noce_try_cmove(), noce_try_shifted_store_flag(), noce_try_store_flag(), noce_try_store_flag_constants(), noce_try_store_flag_logical(), and noce_try_store_flag_mask().
|
static |
Determine if a given basic block heads a simple IF-THEN-JOIN or an IF-THEN-ELSE-JOIN block. If so, we'll try to convert the insns to not require the branch, using only transformations that do not require conditional execution. Return TRUE if we were successful at converting the block.
References BB_END, noce_if_info::cond, noce_if_info::cond_earliest, noce_if_info::cond_inverted, cond_move_process_if_block(), dump_file, EDGE_COMPLEX, noce_if_info::else_bb, gcc_assert, GET_MODE, basic_block_def::index, insn_cost(), noce_if_info::join_bb, noce_if_info::jump, noce_if_info::max_seq_cost, noce_find_if_block(), noce_get_condition(), noce_process_if_block(), NULL_BLOCK, NULL_RTX, num_possible_if_blocks, onlyjump_p(), optimize_bb_for_speed_p(), noce_if_info::original_cost, reload_completed, noce_if_info::rev_cond, single_pred_p(), single_succ(), single_succ_edge(), single_succ_p(), noce_if_info::speed_p, targetm, noce_if_info::test_bb, noce_if_info::then_bb, noce_if_info::then_else_reversed, and XEXP.
Referenced by find_if_header(), and noce_find_if_block().
|
static |
Finish a successful noce if-conversion of IF_INFO whose replacement insns have already been emitted before the branch. Delete the now-dead THEN block, and ELSE too if this was a diamond. An IF-THEN-JOIN also has an edge from TEST_BB straight to JOIN_BB that bypassed THEN, and that goes as well. An IF-THEN-ELSE-JOIN has no such edge, and deleting ELSE_BB removes its two edges instead. Redirect TEST_BB to JOIN_BB and merge the two when the tail no longer needs its own block. Count the converted if-block and the CFG changes it took.
References can_merge_blocks_p(), delete_basic_block(), noce_if_info::else_bb, find_edge(), noce_if_info::join_bb, merge_blocks(), noce_finish_if_conversion(), num_true_changes, num_updated_if_blocks, redirect_edge_and_branch_force(), remove_edge(), single_succ_edge(), noce_if_info::test_bb, and noce_if_info::then_bb.
Referenced by cond_move_process_if_block(), noce_convert_multiple_sets(), noce_finish_if_conversion(), and noce_process_if_block().
|
static |
For most cases, the simplified condition we found is the best choice, but this is not the case for the min/max/abs transforms. For these we wish to know that it is A or B in the condition.
References noce_if_info::a, noce_if_info::b, BLOCK_FOR_INSN(), canonicalize_condition(), noce_if_info::cond, noce_if_info::cond_earliest, CONST_INT_P, find_reg_equal_equiv_note(), GEN_INT, GET_CODE, GET_MODE, have_cbranchcc4, HOST_WIDE_INT_MAX, HOST_WIDE_INT_MIN, INSN_P, INTVAL, noce_if_info::jump, JUMP_LABEL, label_ref_label(), modified_in_p(), NEXT_INSN(), noce_get_alt_condition(), NULL, PATTERN(), pc_set(), PREV_INSN(), prev_nonnote_nondebug_insn(), reg_mentioned_p(), reg_overlap_mentioned_p(), rtx_equal_p(), SET, SET_DEST, SET_SRC, swap_condition(), noce_if_info::then_else_reversed, noce_if_info::x, and XEXP.
Referenced by noce_get_alt_condition(), noce_try_abs(), and noce_try_minmax().
Similar to get_condition, only the resulting condition must be valid at JUMP, instead of at EARLIEST. If THEN_ELSE_REVERSED is true, the fallthrough does not go to the THEN block of the caller, and we have to reverse the condition.
References any_condjump_p(), canonicalize_condition(), GET_CODE, GET_MODE, GET_MODE_CLASS, have_cbranchcc4, JUMP_LABEL, label_ref_label(), noce_get_condition(), NULL_RTX, pc_set(), REG_P, reverse_condition(), SET_SRC, side_effects_p(), targetm, and XEXP.
Referenced by dead_or_predicable(), find_cond_trap(), noce_convert_multiple_sets(), noce_find_if_block(), and noce_get_condition().
|
static |
Return true if X contains an EXT_CODE extension from its mode to OUTER_MODE.
References GET_MODE, GET_MODE_MASK, GET_MODE_PRECISION(), HWI_COMPUTABLE_MODE_P(), noce_operand_known_extended_p(), nonzero_bits(), num_sign_bit_copies(), and poly_int< N, C >::to_constant().
Referenced by noce_operand_known_extended_p(), and noce_try_cond_arith().
Forward references.
Return true if OP is ok for if-then-else processing.
References may_trap_p(), MEM_P, noce_operand_ok(), side_effects_p(), and XEXP.
Referenced by bb_ok_for_noce_convert_multiple_sets(), bb_valid_for_noce_process_p(), insn_valid_noce_process_p(), noce_operand_ok(), noce_process_if_block(), and noce_try_store_flag_constants().
|
static |
Return the estimated cost of the original, un-converted if-region described by IF_INFO whose THEN and ELSE arms cost THEN_COST and ELSE_COST. BASE_COST already accounts for the branch, and any compare, that the conversion removes. When optimizing for speed (SPEED_P) only one arm runs, so charge the branch-probability-weighted average of the two. When optimizing for size both arms are emitted, so sum them.
References average_cost(), find_edge(), noce_original_region_cost(), noce_if_info::test_bb, and noce_if_info::then_bb.
Referenced by noce_original_region_cost(), and noce_process_if_block().
Return true if INSN is a unit-cost register SET supported by the parallel cost model. Store the SET in *SET.
References contains_mem_rtx_p(), COSTS_N_INSNS, may_trap_p(), noce_parallel_costed_insn_p(), REG_P, SET_DEST, set_rtx_cost(), SET_SRC, side_effects_p(), and single_set().
Referenced by noce_parallel_costed_insn_p(), and noce_parallel_seq_cost().
Estimate the cost of SEQ using the target issue rate. Unit-cost register operations are grouped by RAW dependency level. The cost of each level is its instruction count divided by the issue rate, rounded up. Fall back to serial cost if any instruction cannot be modeled. In an instrumented build of all SPEC CPU2017 Integer rate benchmarks for RISC-V, the analysis handled 16,947 of 30,120 candidates (56.26%). It reduced the cost for 15,024 of the handled candidates (88.65%). The parallel-to-serial cost ratios for the handled candidates were: 0.8 < ratio <= 1.0 11.54 percent 0.6 < ratio <= 0.8 47.31 percent 0.4 < ratio <= 0.6 40.24 percent 0.2 < ratio <= 0.4 0.91 percent 0.0 < ratio <= 0.2 0.00 percent.
References CEIL, COSTS_N_INSNS, i, MAX, MIN, NEXT_INSN(), noce_dependency_level(), noce_parallel_costed_insn_p(), noce_parallel_seq_cost(), NONDEBUG_INSN_P, seq_cost(), SET_DEST, SET_SRC, and targetm.
Referenced by default_noce_conversion_profitable_p(), and noce_parallel_seq_cost().
|
static |
Given a simple IF-THEN-JOIN or IF-THEN-ELSE-JOIN block, attempt to convert it without using conditional execution. Return TRUE if we were successful at converting the block.
References a, noce_if_info::a, b, noce_if_info::b, BB_END, bb_ok_for_noce_convert_multiple_sets(), bb_valid_for_noce_process_p(), bitmap_count_bits(), bitmap_ior(), BLOCK_FOR_INSN(), noce_if_info::cond, noce_if_info::cond_earliest, CONST_INT_P, dump_file, noce_if_info::else_bb, noce_if_info::else_simple, emit_insn_before_setloc(), end_sequence(), find_reg_note(), gcc_assert, gen_reg_rtx(), GET_CODE, get_insns(), GET_MODE, HARD_REGISTER_P, noce_if_info::insn_a, noce_if_info::insn_b, INSN_LOCATION(), noce_if_info::jump, last_active_insn(), MAX_CONDITIONAL_EXECUTE, MEM_P, modified_between_p(), modified_in_p(), noce_convert_multiple_sets(), noce_emit_move_insn(), noce_finish_if_conversion(), noce_operand_ok(), noce_original_region_cost(), noce_process_if_block(), noce_simple_bbs(), noce_try_abs(), noce_try_addcc(), noce_try_bitop(), noce_try_cmove(), noce_try_cmove_arith(), noce_try_cond_arith(), noce_try_ifelse_collapse(), noce_try_inverse_constants(), noce_try_minmax(), noce_try_move(), noce_try_shifted_store_flag(), noce_try_sign_bit_splat(), noce_try_sign_mask(), noce_try_store_flag(), noce_try_store_flag_constants(), noce_try_store_flag_logical(), noce_try_store_flag_mask(), NONJUMP_INSN_P, NULL, NULL_RTX, optimize_bb_for_speed_p(), noce_if_info::orig_x, noce_if_info::original_cost, PREV_INSN(), prev_nonnote_nondebug_insn(), reg_overlap_mentioned_p(), REG_P, remove_note(), reorder_insns(), rtx_interchangeable_p(), SET_DEST, SET_SRC, set_used_flags(), side_effects_p(), single_set(), start_sequence(), targetm, noce_if_info::test_bb, noce_if_info::then_bb, noce_if_info::then_else_reversed, noce_if_info::then_simple, noce_if_info::transform_name, unshare_all_rtl_in_chain(), noce_if_info::x, and XEXP.
Referenced by noce_find_if_block(), and noce_process_if_block().
If DEST is a hard condition-code register, add it to the set in DATA. PAT is the SET or CLOBBER that writes DEST.
References add_to_hard_reg_set(), noce_cc_reg_set::fixed_regno1, noce_cc_reg_set::fixed_regno2, GET_MODE, GET_MODE_CLASS, HARD_REGISTER_P, noce_record_cc_reg_set(), REG_P, REGNO, noce_cc_reg_set::set, and targetm.
Referenced by noce_clobbers_live_cc_p(), and noce_record_cc_reg_set().
|
static |
Set *DIFF to ITRUE - IFALSE truncated to MODE and return true. Return false, leaving *DIFF alone, when that difference is not representable and so cannot be used to build a store-flag sequence.
References noce_representable_diff_p(), and trunc_int_for_mode().
Referenced by noce_representable_diff_p(), noce_try_cmove(), and noce_try_store_flag_constants().
|
static |
Return the condition to use when the arms of IF_INFO's if-region are swapped, and set *CODE to its comparison code. When the reversed condition has no rtx of its own the original condition is returned alongside the reversed code, which is the form the store-flag and conditional-move expanders take. *CODE is UNKNOWN if the condition cannot be reversed.
References noce_if_info::cond, GET_CODE, noce_if_info::jump, noce_reversed_cond(), noce_if_info::rev_cond, and reversed_comparison_code().
Referenced by noce_reversed_cond(), noce_reversed_cond_code(), noce_try_addcc(), noce_try_cmove_arith(), and noce_try_cond_arith().
|
inlinestatic |
Return the comparison code for reversed condition for IF_INFO, or UNKNOWN if reversing the condition is not possible.
References noce_reversed_cond(), and noce_reversed_cond_code().
Referenced by noce_reversed_cond_code(), noce_try_addcc(), noce_try_cmove_arith(), and noce_try_store_flag_constants().
Return true if any insn in SEQ modifies CC_CMP, or REV_CC_CMP when there is one. Such a sequence cannot be used to select on that condition.
References modified_in_p(), NEXT_INSN(), and noce_seq_clobbers_cc_cmp_p().
Referenced by noce_convert_multiple_sets_1(), and noce_seq_clobbers_cc_cmp_p().
|
static |
Return true iff the then and else basic block (if it exists) consist of a single simple set instruction.
References noce_if_info::else_bb, noce_if_info::else_simple, noce_simple_bbs(), and noce_if_info::then_simple.
Referenced by noce_process_if_block(), noce_simple_bbs(), noce_try_abs(), noce_try_addcc(), noce_try_bitop(), noce_try_cmove(), noce_try_cond_arith(), noce_try_ifelse_collapse(), noce_try_inverse_constants(), noce_try_minmax(), noce_try_move(), noce_try_shifted_store_flag(), noce_try_sign_bit_splat(), noce_try_sign_mask(), noce_try_store_flag(), noce_try_store_flag_constants(), noce_try_store_flag_logical(), and noce_try_store_flag_mask().
Return true if X is a constant or register operand suitable for simple conditional-move handling.
References CONSTANT_P, noce_simple_cmove_operand_p(), and register_operand().
Referenced by bb_ok_for_noce_convert_multiple_sets(), check_cond_move_block(), noce_simple_cmove_operand_p(), and noce_try_cmove().
TEMP holds an all-ones or all-zeros splat of a tested sign bit. Return an rtx that narrows it to VAL or zero, expanded into TARGET where possible, or NULL_RTX if the expansion failed. The obvious form is a mask, but since the value is known to be -1 or 0 a shift is sometimes cheaper: a logical right shift constructs 2^n-1 and a left shift constructs ~(2^n-1). Some targets do not have efficient shifts, so build the RTL for each applicable form and expand the cheapest.
References clz_hwi(), ctz_hwi(), exact_log2(), expand_simple_binop(), GEN_INT, GET_MODE_PRECISION(), noce_splat_to_const(), OPTAB_WIDEN, optimize_insn_for_speed_p(), rtx_cost(), SET, and poly_int< N, C >::to_constant().
Referenced by noce_splat_to_const(), and noce_try_sign_bit_splat().
|
static |
Convert "if (a < 0) x = -a; else x = a;" to "x = abs(a);", "if (a < 0) x = ~a; else x = a;" to "x = one_cmpl_abs(a);", etc.
References a, noce_if_info::a, b, noce_if_info::b, BLOCK_FOR_INSN(), noce_if_info::cond, noce_if_info::cond_earliest, CONST0_RTX, const1_rtx, CONSTANT_POOL_ADDRESS_P, constm1_rtx, emit_insn_before_setloc(), end_ifcvt_sequence(), end_sequence(), expand_abs_nojump(), expand_one_cmpl_abs_nojump(), expand_simple_unop(), find_reg_equal_equiv_note(), GET_CODE, GET_MODE, get_pool_constant(), HONOR_SIGNED_ZEROS(), noce_if_info::insn_a, INSN_LOCATION(), noce_if_info::jump, MEM_P, noce_emit_move_insn(), noce_get_alt_condition(), noce_simple_bbs(), noce_try_abs(), NULL_RTX, prev_nonnote_nondebug_insn(), REG_P, noce_if_info::rev_cond, rtx_equal_p(), SET_DEST, SET_SRC, single_set(), start_sequence(), noce_if_info::transform_name, noce_if_info::x, and XEXP.
Referenced by noce_process_if_block(), and noce_try_abs().
|
static |
Convert "if (test) foo++" into "foo += (test != 0)", and similarly for "foo--".
References noce_if_info::a, noce_if_info::b, const1_rtx, constm1_rtx, emit_conditional_add(), end_ifcvt_sequence(), end_sequence(), expand_simple_binop(), gen_reg_rtx(), general_operand(), GET_CODE, GET_MODE, INTVAL, noce_commit_sequence(), noce_emit_move_insn(), noce_emit_store_flag(), noce_reversed_cond(), noce_reversed_cond_code(), noce_simple_bbs(), noce_try_addcc(), OPTAB_WIDEN, rtx_equal_p(), start_sequence(), STORE_FLAG_VALUE, noce_if_info::x, and XEXP.
Referenced by noce_process_if_block(), and noce_try_addcc().
|
static |
Optimize away "if (x & C) x |= C" and similar bit manipulation transformations.
References a, noce_if_info::a, noce_if_info::b, noce_if_info::cond, const0_rtx, const1_rtx, CONST_INT_P, emit_insn_before_setloc(), end_ifcvt_sequence(), gen_int_mode(), GET_CODE, GET_MODE, GET_MODE_BITSIZE(), GET_MODE_MASK, HOST_BITS_PER_WIDE_INT, HOST_WIDE_INT_1, HOST_WIDE_INT_1U, noce_if_info::insn_a, INSN_LOCATION(), INTVAL, is_a(), noce_if_info::jump, noce_emit_move_insn(), noce_simple_bbs(), noce_try_bitop(), NULL_RTX, rtx_equal_p(), simplify_gen_binary(), start_sequence(), noce_if_info::transform_name, noce_if_info::x, and XEXP.
Referenced by noce_process_if_block(), and noce_try_bitop().
|
static |
Try only simple constants and registers here. More complex cases are handled in noce_try_cmove_arith, which the dispatch table reaches after the store-flag matchers have had a go.
References noce_if_info::a, noce_if_info::b, noce_if_info::cond, CONST_INT_P, end_ifcvt_sequence(), end_sequence(), expand_simple_binop(), gen_int_mode(), GET_CODE, GET_MODE, INTVAL, noce_commit_sequence(), noce_emit_cmove(), noce_emit_move_insn(), noce_emit_store_flag(), noce_representable_diff_p(), noce_simple_bbs(), noce_simple_cmove_operand_p(), noce_try_cmove(), OPTAB_WIDEN, start_sequence(), targetm, noce_if_info::x, and XEXP.
Referenced by noce_process_if_block(), and noce_try_cmove().
|
static |
Try more complex cases involving conditional_move.
References a, noce_if_info::a, as_a(), b, noce_if_info::b, bbs_ok_for_cmove_arith(), can_conditionally_move_p(), noce_if_info::cond, copy_rtx(), cse_not_expected, noce_if_info::else_bb, noce_if_info::else_simple, end_ifcvt_sequence(), end_sequence(), FOR_BB_INSNS, gcc_assert, gen_reg_rtx(), gen_rtx_MEM(), general_operand(), get_address_mode(), GET_CODE, GET_MODE, noce_if_info::insn_a, noce_if_info::insn_b, may_trap_or_fault_p(), MEM_ADDR_SPACE, MEM_ALIAS_SET, MEM_ALIGN, MEM_P, MEM_VOLATILE_P, MIN, modified_in_p(), noce_commit_sequence(), noce_emit_bb(), noce_emit_cmove(), noce_emit_move_insn(), noce_reversed_cond(), noce_reversed_cond_code(), noce_try_cmove_arith(), NULL, NULL_RTX, noce_if_info::orig_x, PATTERN(), rtx_equal_p(), SET_DEST, set_mem_addr_space(), set_mem_alias_set(), set_mem_align(), single_set(), start_sequence(), noce_if_info::then_bb, noce_if_info::then_simple, noce_if_info::x, and XEXP.
Referenced by noce_process_if_block(), and noce_try_cmove_arith().
|
static |
Try to convert if-then-else with conditional zero, returning TRUE on
success or FALSE on failure. IF_INFO describes the if-conversion scenario
under consideration.
It verifies the branch structure on the left and transforms it into the
branchless sequence on the right, with a backend-provided conditional zero
or orig for operand z. If true, tmp is z, 0 otherwise (y op 0 is the same
as y for most op).
if (cond) | tmp = cond ? z : 0
x = y op z | x = y op tmp
else |
x = y |
AND is special as it needs to be handled differently.
tmp = !cond ? y : 0
x = (y & z) | tmp
Also for AND try:
tmp = cond ? z : -1
x = y op tmp
to see if it is cheaper to produce `!cond ? y : 0` or `cond ? z : -1`.
References a, noce_if_info::a, b, noce_if_info::b, COMMUTATIVE_ARITH_P, noce_if_info::cond, const0_rtx, CONST_INT_P, constm1_rtx, copy_rtx(), end_ifcvt_sequence(), end_sequence(), expand_simple_binop(), gcc_assert, gcc_checking_assert, rtl_hooks::gen_lowpart_no_emit, gen_reg_rtx(), get_base_reg_or_constant(), GET_CODE, GET_MODE, noce_commit_sequence(), noce_cond_arith_operation(), noce_emit_cmove(), noce_emit_move_insn(), noce_operand_known_extended_p(), noce_reversed_cond(), noce_simple_bbs(), noce_try_cond_arith(), NULL_RTX, OPTAB_WIDEN, push_to_sequence(), REG_P, rtx_equal_p(), SCALAR_INT_MODE_P, seq_cost(), noce_if_info::speed_p, start_sequence(), subreg_lowpart_p(), SUBREG_P, SUBREG_REG, noce_if_info::x, and XEXP.
Referenced by noce_process_if_block(), and noce_try_cond_arith().
|
static |
Try forming an IF_THEN_ELSE (cond, b, a) and collapsing that through simplify_rtx. Sometimes that can eliminate the IF_THEN_ELSE. If that is the case, emit the result into x.
References noce_if_info::a, noce_if_info::b, noce_if_info::cond, end_ifcvt_sequence(), GET_CODE, GET_MODE, noce_commit_sequence(), noce_emit_move_insn(), noce_simple_bbs(), noce_try_ifelse_collapse(), simplify_gen_ternary(), start_sequence(), and noce_if_info::x.
Referenced by noce_process_if_block(), and noce_try_ifelse_collapse().
|
static |
Convert "if (test) x = -A; else x = A" into x = A; if (test) x = -x if the machine can do the conditional negate form of this cheaply. Try this before noce_try_cmove that will just load the immediates into two registers and do a conditional select between them. If the target has a conditional negate or conditional invert operation we can save a potentially expensive constant synthesis.
References noce_if_info::a, noce_if_info::b, noce_if_info::cond, CONST_INT_P, emit_conditional_neg_or_complement(), end_ifcvt_sequence(), end_sequence(), gen_reg_rtx(), get_insns(), GET_MODE, HOST_WIDE_INT_MIN, INTVAL, noce_commit_sequence(), noce_emit_move_insn(), noce_simple_bbs(), noce_try_inverse_constants(), REG_P, start_sequence(), and noce_if_info::x.
Referenced by noce_process_if_block(), and noce_try_inverse_constants().
|
static |
Convert "if (a < b) x = a; else x = b;" to "x = min(a, b);", etc.
References noce_if_info::a, noce_if_info::b, noce_if_info::cond, noce_if_info::cond_earliest, emit_insn_before_setloc(), end_ifcvt_sequence(), end_sequence(), expand_simple_binop(), GET_CODE, GET_MODE, HONOR_NANS(), HONOR_SIGNED_ZEROS(), noce_if_info::insn_a, INSN_LOCATION(), noce_if_info::jump, noce_emit_move_insn(), noce_get_alt_condition(), noce_simple_bbs(), noce_try_minmax(), NULL_RTX, OPTAB_WIDEN, noce_if_info::rev_cond, rtx_equal_p(), start_sequence(), swap_condition(), noce_if_info::transform_name, noce_if_info::x, and XEXP.
Referenced by noce_process_if_block(), and noce_try_minmax().
|
static |
Convert "if (a != b) x = a; else x = b" into "x = a" and "if (a == b) x = a; else x = b" into "x = b".
References noce_if_info::a, noce_if_info::b, noce_if_info::cond, emit_insn_before_setloc(), end_ifcvt_sequence(), GET_CODE, HONOR_NANS(), HONOR_SIGNED_ZEROS(), noce_if_info::insn_a, INSN_LOCATION(), noce_if_info::jump, noce_emit_move_insn(), noce_simple_bbs(), noce_try_move(), rtx_equal_p(), rtx_interchangeable_p(), start_sequence(), noce_if_info::transform_name, noce_if_info::x, XEXP, and y.
Referenced by noce_process_if_block(), and noce_try_move().
|
static |
Convert "if (test) x = a; else x = a OP c " where c is 2^n. We can shift the output of a set flag insn left to generate 2^n cheaply, then apply OP unconditionally. This works even if the target does not have a conditional zero idiom. On targets such as RISC-V this sequence may also encode better. This is based on noce_try_store_flag_constants.
References a, noce_if_info::a, b, noce_if_info::b, CONST_INT_P, end_ifcvt_sequence(), end_sequence(), exact_log2(), expand_simple_binop(), GEN_INT, gen_reg_rtx(), GET_CODE, GET_MODE, INTVAL, noce_commit_sequence(), noce_cond_zero_binary_op_supported(), noce_emit_move_insn(), noce_emit_store_flag(), noce_simple_bbs(), noce_try_shifted_store_flag(), NULL_RTX, OPTAB_WIDEN, pow2p_hwi(), rtx_equal_p(), start_sequence(), STORE_FLAG_VALUE, noce_if_info::x, and XEXP.
Referenced by noce_process_if_block(), and noce_try_shifted_store_flag().
|
static |
If a sign bit test is selecting across constants, we may be able to generate efficient code utilizing the -1/0 result of a sign bit splat idiom. Do this before trying the generalized conditional move as these (when applicable) are hopefully faster than a conditional move.
References noce_if_info::a, noce_if_info::b, noce_if_info::cond, CONST0_RTX, CONST_INT_P, CONSTM1_RTX, emit_move_insn(), end_ifcvt_sequence(), expand_simple_binop(), expand_simple_unop(), GEN_INT, GET_CODE, GET_MODE, GET_MODE_BITSIZE(), INTVAL, noce_commit_sequence(), noce_simple_bbs(), noce_splat_to_const(), noce_try_sign_bit_splat(), NULL_RTX, OPTAB_WIDEN, REG_P, start_sequence(), poly_int< N, C >::to_constant(), noce_if_info::x, and XEXP.
Referenced by noce_process_if_block(), and noce_try_sign_bit_splat().
|
static |
Convert "if (m < 0) x = b; else x = 0;" to "x = (m >> C) & b;".
References noce_if_info::a, noce_if_info::b, BLOCK_FOR_INSN(), noce_if_info::cond, const0_rtx, constm1_rtx, COSTS_N_INSNS, emit_store_flag(), end_ifcvt_sequence(), end_sequence(), expand_binop(), gen_reg_rtx(), GET_CODE, GET_MODE, noce_if_info::insn_b, may_trap_or_fault_p(), noce_can_force_operand(), noce_commit_sequence(), noce_emit_move_insn(), noce_simple_bbs(), noce_try_sign_mask(), NULL_RTX, OPTAB_DIRECT, set_src_cost(), side_effects_p(), noce_if_info::speed_p, start_sequence(), noce_if_info::test_bb, noce_if_info::x, and XEXP.
Referenced by noce_process_if_block(), and noce_try_sign_mask().
|
static |
Convert "if (test) x = 1; else x = 0". Only try 0 and STORE_FLAG_VALUE here. Other combinations will be tried in noce_try_store_flag_constants after noce_try_cmove has had a go at the conversion.
References noce_if_info::a, noce_if_info::b, const0_rtx, CONST_INT_P, end_ifcvt_sequence(), end_sequence(), INTVAL, noce_commit_sequence(), noce_emit_move_insn(), noce_emit_store_flag(), noce_simple_bbs(), noce_try_store_flag(), start_sequence(), STORE_FLAG_VALUE, and noce_if_info::x.
Referenced by noce_process_if_block(), and noce_try_store_flag().
|
static |
Convert "if (test) x = a; else x = b", for A and B constant. Also allow A = y + c1, B = y + c2, with a common y between A and B.
References a, noce_if_info::a, b, noce_if_info::b, CONST_INT_P, end_ifcvt_sequence(), end_sequence(), exact_log2(), expand_simple_binop(), gcc_unreachable, GEN_INT, gen_int_mode(), gen_reg_rtx(), GET_CODE, GET_MODE, INTVAL, noce_commit_sequence(), noce_emit_move_insn(), noce_emit_store_flag(), noce_operand_ok(), noce_representable_diff_p(), noce_reversed_cond_code(), noce_simple_bbs(), noce_try_store_flag_constants(), NULL_RTX, OPTAB_WIDEN, pow2p_hwi(), reg_overlap_mentioned_p(), REG_P, rtx_equal_p(), start_sequence(), STORE_FLAG_VALUE, trunc_int_for_mode(), noce_if_info::x, and XEXP.
Referenced by noce_process_if_block(), and noce_try_store_flag_constants().
|
static |
This is trying to capture cases like dest = cond ? a : -1. The basic idea is to use a store-flag insn to generate a -1/0 value (directly or indirectly), then IOR that with the other input.
References a, noce_if_info::a, b, noce_if_info::b, CONSTM1_RTX, emit_move_insn(), end_ifcvt_sequence(), end_sequence(), gen_reg_rtx(), GET_MODE, noce_commit_sequence(), noce_emit_store_flag(), noce_simple_bbs(), noce_try_store_flag_logical(), REG_P, noce_if_info::rev_cond, start_sequence(), STORE_FLAG_VALUE, SUBREG_P, and noce_if_info::x.
Referenced by noce_process_if_block(), and noce_try_store_flag_logical().
|
static |
Convert "if (test) x = 0;" to "x &= -(test == 0);"
References noce_if_info::a, noce_if_info::b, const0_rtx, end_ifcvt_sequence(), end_sequence(), expand_simple_binop(), gen_reg_rtx(), GET_MODE, noce_commit_sequence(), noce_emit_move_insn(), noce_emit_store_flag(), noce_simple_bbs(), noce_try_store_flag_mask(), OPTAB_WIDEN, REG_P, rtx_equal_p(), start_sequence(), and noce_if_info::x.
Referenced by noce_process_if_block(), and noce_try_store_flag_mask().
|
static |
If-conversion and CFG cleanup.
References cleanup_cfg(), CLEANUP_EXPENSIVE, CLEANUP_FORCE_FAST_DCE, dump_file, dump_flags, dump_flow_info(), dump_reg_info(), if_convert(), IFCVT_BEFORE_COMBINE, num_updated_if_blocks, and rest_of_handle_if_conversion().
Referenced by rest_of_handle_if_conversion().
Return true if RTXs A and B can be safely interchanged.
References a, b, GET_CODE, get_mem_attrs(), mem_attrs_eq_p(), rtx_equal_p(), and rtx_interchangeable_p().
Referenced by noce_process_if_block(), noce_try_move(), and rtx_interchangeable_p().
|
static |
Helper function to emit a cmov sequence encapsulated in start_sequence () and end_sequence (). If NEED_CMOV is true we call noce_emit_cmove to create a cmove sequence. Otherwise emit a simple move. If successful, store the first instruction of the sequence in TEMP_DEST and the sequence costs in SEQ_COST.
References end_sequence(), GET_CODE, get_insns(), noce_emit_cmove(), noce_emit_move_insn(), NULL, NULL_RTX, seq_cost(), noce_if_info::speed_p, start_sequence(), noce_if_info::then_else_reversed, try_emit_cmove_seq(), XEXP, and y.
Referenced by noce_convert_multiple_sets_1(), and try_emit_cmove_seq().
|
static |
True if the target has the cbranchcc4 optab.
Referenced by cc_in_cond(), if_convert(), noce_emit_cmove(), noce_get_alt_condition(), and noce_get_condition().
|
static |
Whether this pass over the function converted anything, so that another pass may find further opportunities in what it left behind. Every successful conversion sets it, not only the conditional-execution one.
Referenced by cond_exec_process_if_block(), find_if_header(), and if_convert().
|
static |
The if-conversion pass currently running.
Referenced by cheap_bb_rtx_cost_p(), and if_convert().
|
static |
# of IF-THEN or IF-THEN-ELSE blocks we looked at
Referenced by cond_exec_find_if_block(), find_if_case_1(), find_if_case_2(), if_convert(), and noce_find_if_block().
|
static |
# of changes made.
Referenced by find_cond_trap(), find_if_case_1(), find_if_case_2(), if_convert(), merge_block_into_combo(), merge_if_block(), and noce_finish_if_conversion().
|
static |
# of IF-THEN or IF-THEN-ELSE blocks were converted to conditional execution.
Referenced by find_cond_trap(), find_if_case_1(), find_if_case_2(), if_convert(), merge_if_block(), noce_finish_if_conversion(), and rest_of_handle_if_conversion().