Hello, This patch is just for code simplification, Main changes are that I now use adjust_address instead of adjust_automodify_address and the prob variables are globalized to ease tuning and avoid duplication.
No regression for sh-none-elf. Prerequisite for upcoming builtin_strlen patch. Many thanks Christian
Index: gcc/ChangeLog =================================================================== --- gcc/ChangeLog (revision 204346) +++ gcc/ChangeLog (working copy) @@ -1,3 +1,9 @@ +2013-11-05 Christian Bruel <christian.br...@st.com> + + * gcc/config/sh/sh-mem.cc (sh_expand_cmpnstr, sh_expand_cmpstr): + Factorize probabilities, Use adjust_address instead of + adjust_automodify_address when possible. Enable for optimize. + 2013-11-04 Richard Sandiford <rdsandif...@googlemail.com> * config/avr/avr-log.c (avr_double_int_pop_digit): Delete. Index: gcc/config/sh/sh-mem.cc =================================================================== --- gcc/config/sh/sh-mem.cc (revision 204346) +++ gcc/config/sh/sh-mem.cc (working copy) @@ -179,32 +179,31 @@ expand_block_move (rtx *operands) return false; } +static int prob_unlikely = REG_BR_PROB_BASE / 10; +static int prob_likely = REG_BR_PROB_BASE / 4; + /* Emit code to perform a strcmp. OPERANDS[0] is the destination. OPERANDS[1] is the first string. OPERANDS[2] is the second string. - OPERANDS[3] is the align. */ + OPERANDS[3] is the known alignment. */ bool sh_expand_cmpstr (rtx *operands) { - rtx s1 = copy_rtx (operands[1]); - rtx s2 = copy_rtx (operands[2]); - rtx s1_addr = copy_addr_to_reg (XEXP (s1, 0)); - rtx s2_addr = copy_addr_to_reg (XEXP (s2, 0)); + rtx addr1 = operands[1]; + rtx addr2 = operands[2]; + rtx s1_addr = copy_addr_to_reg (XEXP (addr1, 0)); + rtx s2_addr = copy_addr_to_reg (XEXP (addr2, 0)); rtx tmp0 = gen_reg_rtx (SImode); rtx tmp1 = gen_reg_rtx (SImode); rtx tmp2 = gen_reg_rtx (SImode); rtx tmp3 = gen_reg_rtx (SImode); + rtx jump; rtx L_return = gen_label_rtx (); rtx L_loop_byte = gen_label_rtx (); rtx L_end_loop_byte = gen_label_rtx (); - - rtx jump, addr1, addr2; - int prob_unlikely = REG_BR_PROB_BASE / 10; - int prob_likely = REG_BR_PROB_BASE / 4; - rtx L_loop_long = gen_label_rtx (); rtx L_end_loop_long = gen_label_rtx (); @@ -220,8 +219,8 @@ sh_expand_cmpstr (rtx *operands) add_int_reg_note (jump, REG_BR_PROB, prob_likely); } - addr1 = adjust_automodify_address (s1, SImode, s1_addr, 0); - addr2 = adjust_automodify_address (s2, SImode, s2_addr, 0); + addr1 = adjust_automodify_address (addr1, SImode, s1_addr, 0); + addr2 = adjust_automodify_address (addr2, SImode, s2_addr, 0); /* tmp2 is aligned, OK to load. */ emit_move_insn (tmp3, addr2); @@ -276,8 +275,8 @@ sh_expand_cmpstr (rtx *operands) emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr, -4)); /* start byte loop. */ - addr1 = adjust_automodify_address (s1, QImode, s1_addr, 0); - addr2 = adjust_automodify_address (s2, QImode, s2_addr, 0); + addr1 = adjust_address (addr1, QImode, 0); + addr2 = adjust_address (addr2, QImode, 0); emit_label (L_loop_byte); @@ -317,27 +316,23 @@ sh_expand_cmpstr (rtx *operands) OPERANDS[1] is the first string. OPERANDS[2] is the second string. OPERANDS[3] is the length. - OPERANDS[4] is the align. */ + OPERANDS[4] is the known alignment. */ bool sh_expand_cmpnstr (rtx *operands) { - rtx s1 = copy_rtx (operands[1]); - rtx s2 = copy_rtx (operands[2]); - - rtx s1_addr = copy_addr_to_reg (XEXP (s1, 0)); - rtx s2_addr = copy_addr_to_reg (XEXP (s2, 0)); + rtx addr1 = operands[1]; + rtx addr2 = operands[2]; + rtx s1_addr = copy_addr_to_reg (XEXP (addr1, 0)); + rtx s2_addr = copy_addr_to_reg (XEXP (addr2, 0)); rtx tmp0 = gen_reg_rtx (SImode); rtx tmp1 = gen_reg_rtx (SImode); rtx tmp2 = gen_reg_rtx (SImode); + rtx jump; rtx L_return = gen_label_rtx (); rtx L_loop_byte = gen_label_rtx (); rtx L_end_loop_byte = gen_label_rtx (); - rtx jump, addr1, addr2; - int prob_unlikely = REG_BR_PROB_BASE / 10; - int prob_likely = REG_BR_PROB_BASE / 4; - rtx len = force_reg (SImode, operands[3]); int constp = (CONST_INT_P (operands[3])); int bytes = (constp ? INTVAL (operands[3]) : 0); @@ -366,10 +361,10 @@ sh_expand_cmpnstr (rtx *operands) add_int_reg_note (jump, REG_BR_PROB, prob_likely); } - addr1 = adjust_automodify_address (s1, SImode, s1_addr, 0); - addr2 = adjust_automodify_address (s2, SImode, s2_addr, 0); + addr1 = adjust_automodify_address (addr1, SImode, s1_addr, 0); + addr2 = adjust_automodify_address (addr2, SImode, s2_addr, 0); - /* words count. */ + /* word count. Do we have iterations ? */ emit_insn (gen_lshrsi3 (lenw, len, GEN_INT (2))); /*start long loop. */ @@ -429,48 +424,48 @@ sh_expand_cmpnstr (rtx *operands) emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr, -4)); } - addr1 = adjust_automodify_address (s1, QImode, s1_addr, 0); - addr2 = adjust_automodify_address (s2, QImode, s2_addr, 0); + addr1 = adjust_address (addr1, QImode, 0); + addr2 = adjust_address (addr2, QImode, 0); - emit_label (L_loop_byte); + emit_label (L_loop_byte); - emit_insn (gen_extendqisi2 (tmp2, addr2)); - emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr, 1)); + emit_insn (gen_extendqisi2 (tmp2, addr2)); + emit_move_insn (s2_addr, plus_constant (Pmode, s2_addr, 1)); - emit_insn (gen_extendqisi2 (tmp1, addr1)); - emit_move_insn (s1_addr, plus_constant (Pmode, s1_addr, 1)); + emit_insn (gen_extendqisi2 (tmp1, addr1)); + emit_move_insn (s1_addr, plus_constant (Pmode, s1_addr, 1)); - emit_insn (gen_cmpeqsi_t (tmp2, const0_rtx)); - jump = emit_jump_insn (gen_branch_true (L_end_loop_byte)); - add_int_reg_note (jump, REG_BR_PROB, prob_unlikely); + emit_insn (gen_cmpeqsi_t (tmp2, const0_rtx)); + jump = emit_jump_insn (gen_branch_true (L_end_loop_byte)); + add_int_reg_note (jump, REG_BR_PROB, prob_unlikely); - emit_insn (gen_cmpeqsi_t (tmp1, tmp2)); - if (flag_delayed_branch) - emit_insn (gen_zero_extendqisi2 (tmp2, gen_lowpart (QImode, tmp2))); - jump = emit_jump_insn (gen_branch_false (L_end_loop_byte)); - add_int_reg_note (jump, REG_BR_PROB, prob_unlikely); + emit_insn (gen_cmpeqsi_t (tmp1, tmp2)); + if (flag_delayed_branch) + emit_insn (gen_zero_extendqisi2 (tmp2, gen_lowpart (QImode, tmp2))); + jump = emit_jump_insn (gen_branch_false (L_end_loop_byte)); + add_int_reg_note (jump, REG_BR_PROB, prob_unlikely); - if (TARGET_SH2) - emit_insn (gen_dect (len, len)); - else - { - emit_insn (gen_addsi3 (len, len, GEN_INT (-1))); - emit_insn (gen_tstsi_t (len, len)); - } + if (TARGET_SH2) + emit_insn (gen_dect (len, len)); + else + { + emit_insn (gen_addsi3 (len, len, GEN_INT (-1))); + emit_insn (gen_tstsi_t (len, len)); + } - jump = emit_jump_insn (gen_branch_false (L_loop_byte)); - add_int_reg_note (jump, REG_BR_PROB, prob_likely); - /* end byte loop. */ + jump = emit_jump_insn (gen_branch_false (L_loop_byte)); + add_int_reg_note (jump, REG_BR_PROB, prob_likely); + /* end byte loop. */ - emit_label (L_end_loop_byte); + emit_label (L_end_loop_byte); - if (! flag_delayed_branch) - emit_insn (gen_zero_extendqisi2 (tmp2, gen_lowpart (QImode, tmp2))); - emit_insn (gen_zero_extendqisi2 (tmp1, gen_lowpart (QImode, tmp1))); + if (! flag_delayed_branch) + emit_insn (gen_zero_extendqisi2 (tmp2, gen_lowpart (QImode, tmp2))); + emit_insn (gen_zero_extendqisi2 (tmp1, gen_lowpart (QImode, tmp1))); - emit_label (L_return); + emit_label (L_return); - emit_insn (gen_subsi3 (operands[0], tmp1, tmp2)); + emit_insn (gen_subsi3 (operands[0], tmp1, tmp2)); - return true; + return true; } Index: gcc/config/sh/sh.md =================================================================== --- gcc/config/sh/sh.md (revision 204346) +++ gcc/config/sh/sh.md (working copy) @@ -12059,7 +12059,7 @@ label: (compare:SI (match_operand:BLK 1 "memory_operand") (match_operand:BLK 2 "memory_operand"))) (use (match_operand 3 "immediate_operand"))] - "TARGET_SH1" + "TARGET_SH1 && optimize" { if (! optimize_insn_for_size_p () && sh_expand_cmpstr (operands)) DONE; @@ -12073,7 +12073,7 @@ label: (match_operand:BLK 2 "memory_operand"))) (use (match_operand:SI 3 "immediate_operand")) (use (match_operand:SI 4 "immediate_operand"))] - "TARGET_SH1" + "TARGET_SH1 && optimize" { if (! optimize_insn_for_size_p () && sh_expand_cmpnstr (operands)) DONE;