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 "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"
Macros | |
#define | MAX_CONDITIONAL_EXECUTE |
#define | IFCVT_MULTIPLE_DUMPS 1 |
#define | NULL_BLOCK ((basic_block) NULL) |
Variables | |
static bool | ifcvt_after_combine |
static bool | have_cbranchcc4 |
static int | num_possible_if_blocks |
static int | num_updated_if_blocks |
static int | num_true_changes |
static bool | cond_exec_changed_p |
#define IFCVT_MULTIPLE_DUMPS 1 |
#define MAX_CONDITIONAL_EXECUTE |
If-conversion support. Copyright (C) 2000-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/>.
Referenced by cond_exec_find_if_block(), cond_exec_process_if_block(), and cond_move_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().
|
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.
Referenced by noce_process_if_block().
|
static |
Return true iff basic block TEST_BB is suitable for conversion to a series of conditional moves. Also check that we have more than one set (other routines can handle a single set better than we would), and fewer than PARAM_MAX_RTL_IF_CONVERSION_INSNS sets. While going through the insns store the sum of their potential costs in COST.
References active_insn_p(), can_conditionally_move_p(), contains_mem_rtx_p(), count, FOR_BB_INSNS, GET_MODE, insn_cost(), noce_can_force_operand(), noce_operand_ok(), NULL_RTX, optimize_bb_for_speed_p(), REG_P, SET_DEST, SET_SRC, and single_set().
Referenced by 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, BITMAP_ALLOC, BITMAP_FREE, 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 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(), BITMAP_ALLOC, bitmap_bit_p, BITMAP_FREE, 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 noce_try_cmove_arith().
|
static |
Return the basic block reached by falling though the basic block BB.
References find_fallthru_edge(), NULL_BLOCK, and basic_block_def::succs.
Referenced by 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, 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 find_cond_trap().
|
static |
Return true if a block has two edges, one of which falls through to the next block, and the other jumps to a specific block, so that we can tell if the block is part of an && test or an || test. Returns either -1 or the number of non-note, non-jump, non-USE/CLOBBER insns in the block.
References BB_END, BB_HEAD, CALL_P, DEBUG_INSN_P, EDGE_COMPLEX, EDGE_COUNT, end(), FOR_EACH_EDGE, GET_CODE, INSN_P, JUMP_P, NEXT_INSN(), NULL_RTX, PATTERN(), and basic_block_def::succs.
Referenced by cond_exec_find_if_block().
Return the CC reg if it is used in COND.
References GET_MODE, GET_MODE_CLASS, have_cbranchcc4, NULL_RTX, and XEXP.
Referenced by bb_valid_for_noce_process_p(), 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 BB_END, BB_HEAD, CALL_P, cfun, count, ifcvt_after_combine, profile_probability::initialized_p(), insn_cost(), NEXT_INSN(), NONJUMP_INSN_P, optimize_bb_for_speed_p(), optimize_function_for_speed_p(), REG_BR_PROB_BASE, SET_DEST, single_set(), and profile_probability::to_reg_br_prob_base().
Referenced by 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 indexed by register pointer, then store the register pointer in REGS. COND is the condition we will test.
References BB_END, cc_in_cond(), 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(), NONDEBUG_INSN_P, onlyjump_p(), hash_map< KeyId, Value, Traits >::put(), reg_overlap_mentioned_p(), REG_P, register_operand(), SET_DEST, set_of(), SET_SRC, side_effects_p(), single_set(), SUBREG_REG, and targetm.
Referenced by 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_process_if_block(), dump_file, EDGE_COMPLEX, EDGE_COUNT, ce_if_block::else_bb, noce_if_info::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, noce_if_info::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, noce_if_info::test_bb, ce_if_block::then_bb, and noce_if_info::then_bb.
Referenced by find_if_header().
Return the condition for a jump. Do not do any special processing.
References any_condjump_p(), GET_CODE, GET_MODE, JUMP_LABEL, label_ref_label(), NULL_RTX, pc_set(), reversed_comparison_code(), SET_SRC, and XEXP.
Referenced by 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, attempt to convert it to conditional execution. 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_changed_p, cond_exec_get_condition(), 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, 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().
|
static |
Go through a bunch of insns, converting them to conditional execution format if possible. Return TRUE if all of the non-note insns were processed.
References CALL_P, COND_EXEC_CODE, 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(), 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, 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_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 can_merge_blocks_p(), check_cond_move_block(), noce_if_info::cond, cond_move_convert_if_block(), CONSTANT_P, delete_basic_block(), noce_if_info::else_bb, emit_insn_before_setloc(), end_ifcvt_sequence(), end_sequence(), find_edge(), first_active_insn(), gcc_assert, gcc_checking_assert, hash_map< KeyId, Value, Traits >::get(), INSN_LOCATION(), noce_if_info::join_bb, noce_if_info::jump, MAX_CONDITIONAL_EXECUTE, merge_blocks(), num_true_changes, num_updated_if_blocks, redirect_edge_and_branch_force(), remove_edge(), rtx_equal_p(), single_succ_edge(), start_sequence(), targetm, noce_if_info::test_bb, noce_if_info::then_bb, and vNULL.
Referenced by noce_find_if_block().
Return true if X contains a conditional code mode rtx.
References ALL, FOR_EACH_SUBRTX, GET_MODE, and GET_MODE_CLASS.
Referenced by insn_valid_noce_process_p().
|
static |
Forward references.
Count the number of non-jump active insns in BB.
References active_insn_p(), BB_END, BB_HEAD, count, JUMP_P, and NEXT_INSN().
Referenced by cond_exec_process_if_block().
|
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. 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_ALLOC, bitmap_and_into(), bitmap_bit_p, bitmap_empty_p(), BITMAP_FREE, bitmap_intersect_p(), bitmap_set_bit, block_label(), BRANCH_EDGE, can_move_insns_across(), cancel_changes(), cfun, noce_if_info::cond, cond_exec_get_condition(), cond_exec_process_insns(), confirm_change_group(), 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(), noce_if_info::jump, 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, noce_if_info::test_bb, profile_probability::uninitialized(), update_br_prob_note(), verify_changes(), XEXP, and XINT.
Referenced by find_if_case_1(), and find_if_case_2().
bool default_noce_conversion_profitable_p | ( | rtx_insn * | seq, |
struct 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 noce_if_info::max_seq_cost, seq_cost(), and noce_if_info::speed_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_sequence(), get_insns(), JUMP_P, NEXT_INSN(), NULL, recog_memoized(), set_of(), set_used_flags(), unshare_all_rtl_in_chain(), and noce_if_info::x.
Referenced by cond_move_process_if_block(), noce_try_abs(), noce_try_addcc(), noce_try_bitop(), noce_try_cmove(), noce_try_cmove_arith(), noce_try_cond_zero_arith(), noce_try_ifelse_collapse(), noce_try_inverse_constants(), noce_try_minmax(), noce_try_move(), noce_try_sign_mask(), noce_try_store_flag(), noce_try_store_flag_constants(), and noce_try_store_flag_mask().
|
static |
Return the active insn after INSN inside basic block CURR_BB.
References BB_END, CALL_P, curr_bb, JUMP_P, NEXT_INSN(), NONJUMP_INSN_P, NULL, and NULL_RTX.
Referenced by cond_exec_process_if_block().
|
static |
Return the active insn before INSN inside basic block CURR_BB.
References BB_HEAD, CALL_P, curr_bb, JUMP_P, NONJUMP_INSN_P, NULL, NULL_RTX, and PREV_INSN().
Referenced by cond_exec_process_if_block().
|
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(), noce_if_info::cond, noce_if_info::cond_earliest, copy_rtx(), current_ir_type(), delete_basic_block(), delete_insn(), df_set_bb_dirty(), dump_file, EDGE_COUNT, noce_if_info::else_bb, emit_barrier_after(), emit_insn_before_setloc(), emit_jump_insn_after(), gen_cond_trap(), GET_CODE, GET_MODE, basic_block_def::index, INSN_LOCATION(), IR_RTL_CFGLAYOUT, noce_if_info::jump, 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, noce_if_info::test_bb, noce_if_info::then_bb, TRAP_CODE, valid_insn_p(), noce_if_info::x, and XEXP.
Referenced by find_if_header().
|
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.
Tests for case 1 above.
References BB_END, BB_PARTITION, cfun, cheap_bb_rtx_cost_p(), COSTS_N_INSNS, CROSSING_JUMP_P, dead_or_predicable(), delete_basic_block(), df_bb_replace(), df_set_bb_dirty(), dump_file, EDGE_COMPLEX, noce_if_info::else_bb, EXIT_BLOCK_PTR_FOR_FN, FALLTHRU_EDGE, force_nonfallthru_and_redirect(), forwarder_block_p(), gcc_assert, gcc_checking_assert, basic_block_def::index, profile_probability::invert(), noce_if_info::jump, JUMP_LABEL, JUMP_P, basic_block_def::next_bb, NULL_RTX, num_possible_if_blocks, num_true_changes, num_updated_if_blocks, onlyjump_p(), 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(), single_succ_p(), noce_if_info::test_bb, and noce_if_info::then_bb.
Referenced by find_if_header().
|
static |
Test for case 2 above.
References BB_END, CDI_POST_DOMINATORS, cheap_bb_rtx_cost_p(), COSTS_N_INSNS, CROSSING_JUMP_P, current_loops, dead_or_predicable(), delete_basic_block(), df_set_bb_dirty(), dominated_by_p(), dump_file, EDGE_COMPLEX, noce_if_info::else_bb, basic_block_def::index, profile_probability::invert(), JUMP_P, loop::latch, basic_block_def::loop_father, NUM_FIXED_BLOCKS, num_possible_if_blocks, num_true_changes, num_updated_if_blocks, onlyjump_p(), optimize_bb_for_speed_p(), predictable_edge_p(), single_pred_p(), single_succ_edge(), single_succ_p(), noce_if_info::test_bb, and noce_if_info::then_bb.
Referenced by 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_changed_p, 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(), noce_find_if_block(), NULL, optab_handler(), ce_if_block::pass, reload_completed, basic_block_def::succs, targetm, ce_if_block::test_bb, noce_if_info::test_bb, ce_if_block::then_bb, and word_mode.
Referenced by if_convert().
|
static |
Return the first non-jump active insn in the basic block.
References BB_END, BB_HEAD, DEBUG_INSN_P, 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(), and cond_move_process_if_block().
Helper function to return REG itself, otherwise NULL_RTX for other RTX_CODE.
References exp(), NULL_RTX, and REG_P.
Referenced by noce_bbs_ok_for_cond_zero_arith().
|
static |
Main entry point for all if-conversion. AFTER_COMBINE is true if we are after combine pass.
References AVOID_CFG_MODIFICATIONS, calculate_dominance_info(), CDI_DOMINATORS, CDI_POST_DOMINATORS, cfun, checking_verify_flow_info(), clear_aux_for_blocks(), cond_exec_changed_p, 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, ifcvt_after_combine, 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 rest_of_handle_if_conversion().
|
static |
Find local swap-style idioms in BB 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, count, df_get_live_out(), FOR_BB_INSNS, gcc_checking_assert, i, noce_multiple_sets_info::need_cmov, NULL, 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 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(), noce_operand_ok(), NONJUMP_INSN_P, SET_DEST, set_of(), SET_SRC, and single_set().
Referenced by bb_valid_for_noce_process_p().
|
static |
Return the last non-jump active (non-jump) insn in the basic block.
References BB_END, BB_HEAD, DEBUG_INSN_P, GET_CODE, JUMP_P, LABEL_P, NONJUMP_INSN_P, NOTE_P, NULL, PATTERN(), and PREV_INSN().
Referenced by bb_valid_for_noce_process_p(), cond_exec_process_if_block(), noce_emit_all_but_last(), and noce_process_if_block().
rtl_opt_pass * make_pass_if_after_combine | ( | gcc::context * | ctxt | ) |
rtl_opt_pass * make_pass_if_after_reload | ( | gcc::context * | ctxt | ) |
rtl_opt_pass * make_pass_rtl_ifcvt | ( | gcc::context * | ctxt | ) |
|
static |
Merge the blocks and mark for local life update.
References BARRIER_P, BB_END, block_fallthru(), CALL_P, can_throw_internal(), cfun, const_true_rtx, delete_insn(), df_set_bb_dirty(), EDGE_COUNT, EDGE_SUCC, ce_if_block::else_bb, noce_if_info::else_bb, end(), EXIT_BLOCK_PTR_FOR_FN, find_reg_note(), gcc_assert, GET_CODE, ce_if_block::join_bb, noce_if_info::join_bb, JUMP_P, last, ce_if_block::last_test_bb, merge_blocks(), NEXT_INSN(), NONJUMP_INSN_P, NOTE_INSN_BASIC_BLOCK_P, NOTE_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, noce_if_info::test_bb, ce_if_block::then_bb, noce_if_info::then_bb, tidy_fallthru_edge(), and TRAP_CONDITION.
Referenced by cond_exec_process_if_block().
|
static |
Check if IF-BB and THEN-BB satisfy the condition for conditional zero based if conversion, returning TRUE if satisfied otherwise FALSE. IF_INFO describes the if-conversion scenario under consideration. COMMON_PTR points to the common REG of canonicalized IF_INFO->A and IF_INFO->B. CZERO_CODE_PTR points to the comparison code to use in czero RTX. A_PTR points to the A expression of canonicalized IF_INFO->A. TO_REPLACE points to the RTX to be replaced by czero RTX destnation.
References a, noce_if_info::a, b, noce_if_info::b, COMMUTATIVE_ARITH_P, noce_if_info::cond, const0_rtx, copy_rtx(), get_base_reg(), GET_CODE, noce_cond_zero_binary_op_supported(), noce_reversed_cond_code(), noce_simple_bbs(), NULL_RTX, REG_P, rtx_equal_p(), and XEXP.
Referenced by noce_try_cond_zero_arith().
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, noce_can_force_operand(), 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().
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.
Referenced by noce_bbs_ok_for_cond_zero_arith().
|
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.
References BITMAP_ALLOC, bitmap_bit_p, BITMAP_FREE, bitmap_set_bit, CALL_P, can_merge_blocks_p(), delete_basic_block(), emit_insn_before_setloc(), end_sequence(), find_edge(), FOR_EACH_VEC_ELT_REVERSE, gcc_assert, gcc_checking_assert, get_insns(), i, init_noce_multiple_sets_info(), INSN_LOCATION(), noce_if_info::join_bb, noce_if_info::jump, JUMP_P, merge_blocks(), NEXT_INSN(), noce_convert_multiple_sets_1(), noce_emit_move_insn(), noce_get_condition(), num_true_changes, num_updated_if_blocks, recog_memoized(), redirect_edge_and_branch_force(), reg_obstack, REG_P, REGNO, remove_edge(), set_used_flags(), single_succ_edge(), 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, unshare_all_rtl_in_chain(), XEXP, and y.
Referenced by noce_process_if_block().
|
static |
This goes through all relevant insns of IF_INFO->then_bb and tries to create conditional moves. Information for the insns is kept in INSN_INFO.
References active_insn_p(), cond_exec_get_condition(), CONSTANT_P, copy_rtx(), count, emit_insn(), end_sequence(), FOR_BB_INSNS, FOR_EACH_SUBRTX, FOR_EACH_VEC_ELT, gcc_checking_assert, gen_reg_rtx(), GET_CODE, GET_MODE, i, noce_if_info::jump, modified_in_p(), noce_multiple_sets_info::need_cmov, NEXT_INSN(), noce_get_condition(), NONDEBUG_INSN_P, NULL, NULL_RTX, PATTERN(), reg_overlap_mentioned_p(), REG_P, noce_multiple_sets_info::rewired_src, SET_DEST, SET_SRC, simplify_replace_rtx(), single_set(), noce_multiple_sets_info::target, noce_multiple_sets_info::temporary, noce_if_info::then_bb, noce_if_info::then_else_reversed, try_emit_cmove_seq(), noce_multiple_sets_info::unmodified_insn, and XEXP.
Referenced by noce_convert_multiple_sets().
|
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, last_active_insn(), and PATTERN().
Referenced by 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(), and noce_emit_insn().
Referenced by noce_try_cmove_arith().
|
static |
Helper function for noce_try_cmove and noce_try_cmove_arith.
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_insns(), GET_MODE, GET_MODE_CLASS, have_cbranchcc4, noce_if_info::jump, 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_try_cmove(), noce_try_cmove_arith(), and try_emit_cmove_seq().
|
static |
Emit a conditional zero, returning TARGET or NULL_RTX upon failure. IF_INFO describes the if-conversion scenario under consideration. CZERO_CODE selects the condition (EQ/NE). NON_ZERO_OP is the nonzero operand of the conditional move TARGET is the desired output register.
References add_insn(), noce_if_info::cond, const0_rtx, GET_MODE, make_insn_raw(), NULL_RTX, recog_memoized(), and XEXP.
Referenced by noce_try_cond_zero_arith().
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, NULL, and recog_memoized().
Referenced by noce_emit_bb().
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(), 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_process_if_block(), noce_try_abs(), noce_try_addcc(), noce_try_bitop(), noce_try_cmove(), noce_try_cmove_arith(), noce_try_cond_zero_arith(), noce_try_ifelse_collapse(), noce_try_inverse_constants(), noce_try_minmax(), noce_try_move(), 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*.
References noce_if_info::cond, noce_if_info::cond_earliest, emit_insn(), emit_store_flag(), end_sequence(), general_operand(), GET_CODE, get_insns(), GET_MODE, noce_if_info::jump, JUMP_LABEL, label_ref_label(), normalize(), 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_try_addcc(), noce_try_cmove(), noce_try_store_flag(), noce_try_store_flag_constants(), 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(), COSTS_N_INSNS, dump_file, EDGE_COMPLEX, noce_if_info::else_bb, gcc_assert, GET_MODE, basic_block_def::index, noce_if_info::join_bb, noce_if_info::jump, noce_if_info::max_seq_cost, 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().
|
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(), 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_try_abs(), and noce_try_minmax().
|
static |
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(), 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_convert_multiple_sets_1(), and noce_find_if_block().
Return true if OP is ok for if-then-else processing.
References may_trap_p(), MEM_P, 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_process_if_block(), and noce_try_store_flag_constants().
|
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, average_cost(), b, noce_if_info::b, BB_END, bb_ok_for_noce_convert_multiple_sets(), bb_valid_for_noce_process_p(), BLOCK_FOR_INSN(), can_merge_blocks_p(), noce_if_info::cond, noce_if_info::cond_earliest, CONST_INT_P, COSTS_N_INSNS, delete_basic_block(), dump_file, noce_if_info::else_bb, noce_if_info::else_simple, emit_insn_before_setloc(), end_sequence(), find_edge(), 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::join_bb, noce_if_info::jump, last_active_insn(), MEM_P, merge_blocks(), modified_between_p(), modified_in_p(), noce_convert_multiple_sets(), noce_emit_move_insn(), noce_operand_ok(), noce_simple_bbs(), noce_try_abs(), noce_try_addcc(), noce_try_bitop(), noce_try_cmove(), noce_try_cmove_arith(), noce_try_cond_zero_arith(), noce_try_ifelse_collapse(), noce_try_inverse_constants(), noce_try_minmax(), noce_try_move(), noce_try_sign_mask(), noce_try_store_flag(), noce_try_store_flag_constants(), noce_try_store_flag_mask(), NONJUMP_INSN_P, NULL, NULL_RTX, num_true_changes, num_updated_if_blocks, optimize_bb_for_speed_p(), noce_if_info::orig_x, noce_if_info::original_cost, PREV_INSN(), prev_nonnote_nondebug_insn(), redirect_edge_and_branch_force(), reg_overlap_mentioned_p(), REG_P, remove_edge(), remove_note(), reorder_insns(), rtx_interchangeable_p(), SET_DEST, SET_SRC, set_used_flags(), side_effects_p(), single_set(), single_succ_edge(), start_sequence(), targetm, noce_if_info::test_bb, noce_if_info::then_bb, 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().
|
inlinestatic |
Return the comparison code for reversed condition for IF_INFO, or UNKNOWN if reversing the condition is not possible.
References noce_if_info::cond, GET_CODE, noce_if_info::jump, noce_if_info::rev_cond, and reversed_comparison_code().
Referenced by noce_bbs_ok_for_cond_zero_arith(), noce_try_addcc(), noce_try_cmove_arith(), noce_try_store_flag(), noce_try_store_flag_constants(), and noce_try_store_flag_mask().
|
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, and noce_if_info::then_simple.
Referenced by noce_bbs_ok_for_cond_zero_arith(), noce_process_if_block(), noce_try_abs(), noce_try_addcc(), noce_try_bitop(), noce_try_cmove(), noce_try_ifelse_collapse(), noce_try_inverse_constants(), noce_try_minmax(), noce_try_move(), noce_try_sign_mask(), noce_try_store_flag(), noce_try_store_flag_constants(), and noce_try_store_flag_mask().
|
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(), 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().
|
static |
Convert "if (test) foo++" into "foo += (test != 0)", and similarly for "foo--".
References noce_if_info::a, noce_if_info::b, noce_if_info::cond, const1_rtx, constm1_rtx, emit_conditional_add(), emit_insn_before_setloc(), end_ifcvt_sequence(), end_sequence(), expand_simple_binop(), gen_reg_rtx(), general_operand(), GET_CODE, GET_MODE, noce_if_info::insn_a, INSN_LOCATION(), INTVAL, noce_if_info::jump, noce_emit_move_insn(), noce_emit_store_flag(), noce_reversed_cond_code(), noce_simple_bbs(), normalize(), NULL_RTX, OPTAB_WIDEN, noce_if_info::rev_cond, reversed_comparison_code(), rtx_equal_p(), start_sequence(), STORE_FLAG_VALUE, targetm, noce_if_info::transform_name, noce_if_info::x, and XEXP.
Referenced by noce_process_if_block().
|
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(), 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().
|
static |
Try only simple constants and registers here. More complex cases are handled in noce_try_cmove_arith after noce_try_store_flag_arith has had a go at it.
References noce_if_info::a, noce_if_info::b, noce_if_info::cond, CONST_INT_P, CONSTANT_P, emit_insn_before_setloc(), end_ifcvt_sequence(), end_sequence(), expand_simple_binop(), gen_int_mode(), GET_CODE, GET_MODE, noce_if_info::insn_a, INSN_LOCATION(), INTVAL, noce_if_info::jump, noce_emit_cmove(), noce_emit_move_insn(), noce_emit_store_flag(), noce_simple_bbs(), OPTAB_WIDEN, register_operand(), start_sequence(), targetm, noce_if_info::transform_name, trunc_int_for_mode(), noce_if_info::x, and XEXP.
Referenced by noce_process_if_block().
|
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, emit_insn_before_setloc(), 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, INSN_LOCATION(), noce_if_info::jump, may_trap_or_fault_p(), MEM_ADDR_SPACE, MEM_ALIAS_SET, MEM_ALIGN, MEM_P, MEM_VOLATILE_P, MIN, modified_in_p(), noce_emit_bb(), noce_emit_cmove(), noce_emit_move_insn(), noce_reversed_cond_code(), NULL, NULL_RTX, noce_if_info::orig_x, PATTERN(), noce_if_info::rev_cond, reversed_comparison_code(), rtx_equal_p(), SET_DEST, set_mem_addr_space(), set_mem_alias_set(), set_mem_align(), single_set(), start_sequence(), targetm, noce_if_info::then_bb, noce_if_info::then_simple, noce_if_info::transform_name, noce_if_info::x, and XEXP.
Referenced by noce_process_if_block().
|
static |
Try to covert if-then-else with conditional zero, returning TURE on success or FALSE on failure. IF_INFO describes the if-conversion scenario under consideration.
References a, emit_insn_before_setloc(), end_ifcvt_sequence(), end_sequence(), expand_simple_binop(), gen_reg_rtx(), GET_CODE, GET_MODE, noce_if_info::insn_a, INSN_LOCATION(), noce_if_info::jump, noce_bbs_ok_for_cond_zero_arith(), noce_emit_czero(), noce_emit_move_insn(), NULL, NULL_RTX, OPTAB_WIDEN, rtx_equal_p(), start_sequence(), targetm, noce_if_info::transform_name, and noce_if_info::x.
Referenced by noce_process_if_block().
|
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, emit_insn_before_setloc(), end_ifcvt_sequence(), GET_CODE, GET_MODE, noce_if_info::insn_a, INSN_LOCATION(), noce_if_info::jump, noce_emit_move_insn(), noce_simple_bbs(), simplify_gen_ternary(), start_sequence(), noce_if_info::transform_name, and noce_if_info::x.
Referenced by noce_process_if_block().
|
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(), emit_insn_before_setloc(), end_ifcvt_sequence(), end_sequence(), gen_reg_rtx(), get_insns(), GET_MODE, HOST_WIDE_INT_MIN, noce_if_info::insn_a, INSN_LOCATION(), INTVAL, noce_if_info::jump, noce_emit_move_insn(), noce_simple_bbs(), REG_P, start_sequence(), noce_if_info::transform_name, and noce_if_info::x.
Referenced by noce_process_if_block().
|
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(), 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().
|
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(), 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().
|
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_insn_before_setloc(), emit_store_flag(), end_ifcvt_sequence(), end_sequence(), expand_binop(), gen_reg_rtx(), GET_CODE, GET_MODE, noce_if_info::insn_a, noce_if_info::insn_b, INSN_LOCATION(), noce_if_info::jump, may_trap_or_fault_p(), noce_can_force_operand(), noce_emit_move_insn(), noce_simple_bbs(), 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::transform_name, noce_if_info::x, and XEXP.
Referenced by noce_process_if_block().
|
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, emit_insn_before_setloc(), end_ifcvt_sequence(), end_sequence(), noce_if_info::insn_a, INSN_LOCATION(), INTVAL, noce_if_info::jump, noce_emit_move_insn(), noce_emit_store_flag(), noce_reversed_cond_code(), noce_simple_bbs(), start_sequence(), STORE_FLAG_VALUE, noce_if_info::transform_name, and noce_if_info::x.
Referenced by noce_process_if_block().
|
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, emit_insn_before_setloc(), end_ifcvt_sequence(), end_sequence(), exact_log2(), expand_simple_binop(), gcc_unreachable, GEN_INT, gen_int_mode(), gen_reg_rtx(), GET_CODE, GET_MODE, noce_if_info::insn_a, INSN_LOCATION(), INTVAL, noce_if_info::jump, noce_emit_move_insn(), noce_emit_store_flag(), noce_operand_ok(), noce_reversed_cond_code(), noce_simple_bbs(), normalize(), NULL_RTX, OPTAB_WIDEN, pow2p_hwi(), reg_overlap_mentioned_p(), REG_P, rtx_equal_p(), start_sequence(), STORE_FLAG_VALUE, targetm, noce_if_info::transform_name, trunc_int_for_mode(), noce_if_info::x, and XEXP.
Referenced by noce_process_if_block().
|
static |
Convert "if (test) x = 0;" to "x &= -(test == 0);"
References noce_if_info::a, noce_if_info::b, const0_rtx, emit_insn_before_setloc(), end_ifcvt_sequence(), end_sequence(), expand_simple_binop(), gen_reg_rtx(), GET_MODE, noce_if_info::insn_a, INSN_LOCATION(), noce_if_info::jump, noce_emit_move_insn(), noce_emit_store_flag(), noce_reversed_cond_code(), noce_simple_bbs(), OPTAB_WIDEN, REG_P, rtx_equal_p(), start_sequence(), targetm, noce_if_info::transform_name, and noce_if_info::x.
Referenced by noce_process_if_block().
|
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(), and num_updated_if_blocks.
Return true if RTXs A and B can be safely interchanged.
References a, b, GET_CODE, get_mem_attrs(), mem_attrs_eq_p(), and rtx_equal_p().
Referenced by noce_process_if_block(), and noce_try_move().
|
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, XEXP, and y.
Referenced by noce_convert_multiple_sets_1().
|
static |
Whether conditional execution changes were made.
Referenced by cond_exec_process_if_block(), find_if_header(), and if_convert().
|
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 |
True if after combine pass.
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 cond_move_process_if_block(), find_cond_trap(), find_if_case_1(), find_if_case_2(), if_convert(), merge_if_block(), noce_convert_multiple_sets(), and noce_process_if_block().
|
static |
# of IF-THEN or IF-THEN-ELSE blocks were converted to conditional execution.
Referenced by cond_move_process_if_block(), find_cond_trap(), find_if_case_1(), find_if_case_2(), if_convert(), merge_if_block(), noce_convert_multiple_sets(), noce_process_if_block(), and rest_of_handle_if_conversion().