https://gcc.gnu.org/g:49ed694b75738244b63d412c8540e1e4ae9ca414
commit r16-8076-g49ed694b75738244b63d412c8540e1e4ae9ca414 Author: Takayuki 'January June' Suwa <[email protected]> Date: Thu Mar 12 03:18:45 2026 +0900 xtensa: Rename/reduce from split_DI_SF_DF_const to convert_SF_const in 'xt_largeconst2' The order in which split_DI_SF_DF_const in the target-specific pass 'xt_largeconst2' is processed has been changed to be after split2, so that the splitting of D[IF]mode assignments to S[IF]mode by the split parts of movd[if]_internal MD patterns is now performed earlier. Therefore, in split_DI_SF_DF_const, there is no need to split the allocation of the D[IF]mode constant, and only the function to change the allocation of the SFmode constant to SImode remains. This patch reduces the functionality of split_DI_SF_DF_const as described above and renames it to convert_SF_const. gcc/ChangeLog: * config/xtensa/xtensa.cc (xtensa_split_operand_pair) Move the common code from the split part of movd[if]_internal MD patterns into this function, since this function is only called from the split part of that patterns. Also, during non-debug optimization, re-register new literal pool entries with the split values themselves instead of splitting the memory reference of the source numeric constant placed in the pool. (split_DI_SF_DF_const): Rename to convert_SF_const and remove the split function of D[IF]mode constant assignment. (do_largeconst2): Change the call from split_DI_SF_DF_const to convert_SF_const. * config/xtensa/xtensa.md (movdi_internal, movdf_internal): Reduce their split parts to just a call to xtensa_split_operand_pair. Diff: --- gcc/config/xtensa/xtensa.cc | 136 ++++++++++++++++++++------------------------ gcc/config/xtensa/xtensa.md | 10 ---- 2 files changed, 62 insertions(+), 84 deletions(-) diff --git a/gcc/config/xtensa/xtensa.cc b/gcc/config/xtensa/xtensa.cc index 35395025efe1..91f15cfafe63 100644 --- a/gcc/config/xtensa/xtensa.cc +++ b/gcc/config/xtensa/xtensa.cc @@ -1075,6 +1075,8 @@ xtensa_expand_scc (rtx operands[4], machine_mode cmp_mode) void xtensa_split_operand_pair (rtx operands[4], machine_mode mode) { + rtx x; + switch (GET_CODE (operands[1])) { case REG: @@ -1085,6 +1087,17 @@ xtensa_split_operand_pair (rtx operands[4], machine_mode mode) case MEM: operands[3] = adjust_address (operands[1], mode, GET_MODE_SIZE (mode)); operands[2] = adjust_address (operands[1], mode, 0); + /* Split the pool entry as well as the pooled values themselves, + when non-debug optimizing. This improves the chances that the + entries will be shared and subject to further optimization + opportunities. */ + if (optimize && !optimize_debug && constantpool_mem_p (operands[2])) + { + x = avoid_constant_pool_reference (operands[2]); + operands[2] = force_const_mem (mode, x); + x = avoid_constant_pool_reference (operands[3]); + operands[3] = force_const_mem (mode, x); + } break; case CONST_INT: @@ -1111,6 +1124,12 @@ xtensa_split_operand_pair (rtx operands[4], machine_mode mode) default: gcc_unreachable (); } + + if (reg_overlap_mentioned_p (operands[0], operands[3])) + { + std::swap (operands[0], operands[1]); + std::swap (operands[2], operands[3]); + } } @@ -5630,9 +5649,9 @@ FPreg_neg_scaled_simm12b (rtx_insn *insn) return false; } -/* Split DI/SF/DFmode constant assignments into pairs of SImode ones. This - is also the pre-processing for constantsynth optimization that follows - immediately after. +/* Convert SFmode constant assignments into SImode ones. This is also the + pre-processing for constantsynth optimization that follows immediately + after. Note that all constant values and assignments are treated as SImode because: @@ -5645,85 +5664,54 @@ FPreg_neg_scaled_simm12b (rtx_insn *insn) returned true (the current and default configuration). */ static bool -split_DI_SF_DF_const (rtx_insn *insn) +convert_SF_const (rtx_insn *insn) { - rtx pat, dest, src, dest0, dest1, src0, src1, src0c, src1c; - int regno; + rtx pat, dest, src, dest0, src0, src0c; + /* It is more efficient to assign SFmode literal constants using their + bit-equivalent SImode ones, thus we convert them so. */ if (GET_CODE (pat = PATTERN (insn)) != SET - || ! REG_P (dest = SET_DEST (pat)) || ! GP_REG_P (regno = REGNO (dest))) + || ! REG_P (dest = SET_DEST (pat)) || ! GP_REG_P (REGNO (dest)) + || GET_MODE (dest) != SFmode) return false; - /* It is more efficient to assign SFmode literal constants using their - bit-equivalent SImode ones, thus we convert them so. */ src = avoid_constant_pool_reference (SET_SRC (pat)); - if (GET_MODE (dest) == SFmode - && CONST_DOUBLE_P (src) && GET_MODE (src) == SFmode) + if (CONST_INT_P (src)) + src0 = src; + else if (CONST_DOUBLE_P (src) && GET_MODE (src) == SFmode) { long l; REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (src), l); - src0 = GEN_INT ((int32_t)l), dest0 = gen_rtx_REG (SImode, regno); - if (dump_file) - { - fputs ("split_DI_SF_DF_const: ", dump_file); - dump_value_slim (dump_file, src, 0); - fprintf (dump_file, - "f -> " HOST_WIDE_INT_PRINT_DEC " (" - HOST_WIDE_INT_PRINT_HEX ")\n", - INTVAL (src0), INTVAL (src0)); - } - src0c = NULL_RTX; - if (!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS - && ! xtensa_simm12b (INTVAL (src0))) - src0c = src0, src0 = force_const_mem (SImode, src0); - remove_reg_equal_equiv_notes (insn); - validate_change (insn, &PATTERN (insn), gen_rtx_SET (dest0, src0), 0); - if (src0c) - add_reg_note (insn, REG_EQUIV, copy_rtx (src0c)); - return true; + src0 = GEN_INT ((int32_t)l); } + else + return false; - /* Splitting a D[IF]mode literal constant into two with split_double() - results in a pair of CONST_INTs, so they are assigned in SImode - regardless of the original source mode. */ - if ((GET_MODE (dest) == DImode && CONST_INT_P (src)) - || (GET_MODE (dest) == DFmode - && CONST_DOUBLE_P (src) && GET_MODE (src) == DFmode)) + dest0 = gen_rtx_REG (SImode, REGNO (dest)); + if (dump_file) { - dest0 = gen_rtx_REG (SImode, regno); - dest1 = gen_rtx_REG (SImode, regno + 1); - split_double (src, &src0, &src1); - if (dump_file) - { - fputs ("split_DI_SF_DF_const: ", dump_file); - dump_value_slim (dump_file, src, 0); - fprintf (dump_file, - " -> " HOST_WIDE_INT_PRINT_DEC " (" - HOST_WIDE_INT_PRINT_HEX "), " - HOST_WIDE_INT_PRINT_DEC " (" - HOST_WIDE_INT_PRINT_HEX ")\n", - INTVAL (src0), INTVAL (src0), - INTVAL (src1), INTVAL (src1)); - } - src1c = src0c = NULL_RTX; - if (!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS) - { - if (! xtensa_simm12b (INTVAL (src0))) - src0c = src0, src0 = force_const_mem (SImode, src0); - if (! xtensa_simm12b (INTVAL (src1))) - src1c = src1, src1 = force_const_mem (SImode, src1); - } - remove_reg_equal_equiv_notes (insn); - validate_change (insn, &PATTERN (insn), gen_rtx_SET (dest0, src0), 0); - if (src0c) - add_reg_note (insn, REG_EQUIV, copy_rtx (src0c)); - insn = emit_insn_after (gen_rtx_SET (dest1, src1), insn); - if (src1c) - add_reg_note (insn, REG_EQUIV, copy_rtx (src1c)); - return true; + fputs ("convert_SF_const: ", dump_file); + dump_value_slim (dump_file, src, 0); + if (CONST_DOUBLE_P (src)) + fputc ('f', dump_file); + fprintf (dump_file, + " -> " HOST_WIDE_INT_PRINT_DEC + " (" HOST_WIDE_INT_PRINT_HEX ")\n", + INTVAL (src0), INTVAL (src0)); + dump_insn_slim (dump_file, insn); } + src0c = NULL_RTX; + if (!TARGET_CONST16 && !TARGET_AUTO_LITPOOLS + && ! xtensa_simm12b (INTVAL (src0))) + src0c = src0, src0 = force_const_mem (SImode, src0); + remove_reg_equal_equiv_notes (insn); + validate_change (insn, &PATTERN (insn), gen_rtx_SET (dest0, src0), 0); + if (src0c) + add_reg_note (insn, REG_EQUIV, copy_rtx (src0c)); + if (dump_file) + dump_insn_slim (dump_file, insn); - return false; + return true; } /* The constant-synthesis optimization (constantsynth for short). @@ -6259,8 +6247,8 @@ do_largeconst2 (void) rtx_insn *insn; constantsynth_info cs_info; - /* Verify the legitimacy of replacing constant assignments in - DI/SF/DFmode with those in SImode. */ + /* Verify the legitimacy of replacing constant assignments in SFmode + with those in SImode. */ gcc_assert (targetm.can_change_mode_class == hook_bool_mode_mode_reg_class_t_true); @@ -6273,10 +6261,10 @@ do_largeconst2 (void) if (FPreg_neg_scaled_simm12b (insn)) continue; - /* Split DI/SF/DFmode constant assignments into pairs of SImode - ones. This is also the pre-processing for constantsynth opti- - mization that follows immediately after. */ - split_DI_SF_DF_const (insn); + /* Convert SFmode constant assignments into SImode ones. This is + also the pre-processing for constantsynth optimization that + follows immediately after. */ + convert_SF_const (insn); /* constantsynth pass 1. Detect and record large constant assignments within a function. */ diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md index a9947c612c27..6916adefc8bd 100644 --- a/gcc/config/xtensa/xtensa.md +++ b/gcc/config/xtensa/xtensa.md @@ -1237,11 +1237,6 @@ (set (match_dup 1) (match_dup 3))] { xtensa_split_operand_pair (operands, SImode); - if (reg_overlap_mentioned_p (operands[0], operands[3])) - { - std::swap (operands[0], operands[1]); - std::swap (operands[2], operands[3]); - } } [(set_attr "mode" "DI")]) @@ -1525,11 +1520,6 @@ (set (match_dup 1) (match_dup 3))] { xtensa_split_operand_pair (operands, SFmode); - if (reg_overlap_mentioned_p (operands[0], operands[3])) - { - std::swap (operands[0], operands[1]); - std::swap (operands[2], operands[3]); - } } [(set_attr "mode" "DF")])
