RISC-V: Rework branch costing model for if-conversion
The generic branch costing model for if-conversion assumes a fixed cost of COSTS_N_INSNS (2) for a conditional branch, and that one half of that cost comes from a preceding condition-set instruction, such as with MODE_CC targets, and then the other half of that cost is for the actual branch instruction. This is hardcoded for `if_info.original_cost' in `noce_find_if_block' and regardless of the cost set for branches via BRANCH_COST. Then `default_max_noce_ifcvt_seq_cost' instructs if-conversion to prefer a branchless sequence as costly as high as triple the BRANCH_COST value set. This is apparently to make up for the inability to accurately guess the branch penalty. Consequently for the BRANCH_COST of 3 we commonly set for tuning, if-conversion will consider branchless sequences costing 3 * 3 - 2 = 7 instruction units more than a corresponding branch sequence. For the BRANCH_COST of 4 such as with `sifive-7-series' tuning this is even worse, at 3 * 4 - 2 = 10. Effectively it means a branchless sequence will always be chosen if available, even a very inefficient one. Rework the branch costing model to better match our architecture, observing in particular that we have no preparatory instructions for branches so that the cost of a branch is naked BRANCH_COST plus any extra overhead the processing of a branch's source RTX might incur. Provide TARGET_INSN_COST and TARGET_MAX_NOCE_IFCVT_SEQ_COST handlers than that return suitable cost based on BRANCH_COST. The latter hook usually returns a value that is lower than the cost of the corresponding branched sequence. This is because we don't really want to produce a branchless sequence that is more expensive than the original branched sequence. If this turns out too conservative for some corner case, then this choice might be revisited. Then we don't want to fiddle with `noce_find_if_block' without a lot of cross-target verification, so add TARGET_NOCE_CONVERSION_PROFITABLE_P defined such that it subtracts the fixed COSTS_N_INSNS (2) cost from the cost of the original branched sequence supplied and instead adds actual branch cost calculated from the conditional branch instruction used. It is then further tweaked according to simple analysis of the replacement branchless sequence produced so as to cancel the cost of an extraneous zero extend operation produced by `noce_try_store_flag_mask' as observed with gcc/testsuite/gcc.target/riscv/pr105314.c. Tweak the testsuite accordingly and set `-mbranch-cost=' explicitly for the relevant cases so that the expected if-conversion transformation is made regardless of the default BRANCH_COST value of tuning in effect. Some of these settings will be lowered later on as deficiencies in branchless sequence generation have been fixed that lower their cost calculated by if-conversion. gcc/ * config/riscv/riscv.cc (riscv_insn_cost): New function. (riscv_max_noce_ifcvt_seq_cost): Likewise. (riscv_noce_conversion_profitable_p): Likewise. (TARGET_INSN_COST): New macro. (TARGET_MAX_NOCE_IFCVT_SEQ_COST): New macro. (TARGET_NOCE_CONVERSION_PROFITABLE_P): New macro. gcc/testsuite/ * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c: Explicitly set the branch cost. * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c: Likewise. * gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c: Likewise. * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c: Likewise. * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c: Likewise. * gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c: Likewise.
Showing
- gcc/config/riscv/riscv.cc 120 additions, 0 deletionsgcc/config/riscv/riscv.cc
- gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c 2 additions, 2 deletions...cv/zicond-primitiveSemantics_compare_imm_return_imm_imm.c
- gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c 2 additions, 2 deletions...cv/zicond-primitiveSemantics_compare_imm_return_imm_reg.c
- gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c 2 additions, 2 deletions...cv/zicond-primitiveSemantics_compare_imm_return_reg_reg.c
- gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c 2 additions, 2 deletions...cv/zicond-primitiveSemantics_compare_reg_return_imm_imm.c
- gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c 2 additions, 2 deletions...cv/zicond-primitiveSemantics_compare_reg_return_imm_reg.c
- gcc/testsuite/gcc.target/riscv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c 2 additions, 2 deletions...cv/zicond-primitiveSemantics_compare_reg_return_reg_reg.c
Loading
Please register or sign in to comment