Hi, with the attached patch the jump over the extraction of CC into a GPR for the good case (CC0) is removed. Starting with tbegin being flagged as "returns_twice" this generates slow code and prevents the backend optimization for nonescaping transaction from working correctly.
This fixes the following testsuite fails: < FAIL: gcc.target/s390/htm-nofloat-2.c scan-assembler-not \\tstd\\t < FAIL: gcc.target/s390/htm-nofloat-2.c scan-assembler-not \\tld\\t Bootstrapped and regtested on s390 and s390x. Committed to mainline and 4.8 branch. Bye, -Andreas- 2014-01-10 Andreas Krebbel <andreas.kreb...@de.ibm.com> * config/s390/s390.c (s390_expand_tbegin): Remove jump over CC extraction in good case. --- gcc/config/s390/s390.c | 41 ++++++++----------------------------!!!!! 1 file changed, 8 insertions(+), 28 deletions(-), 5 modifications(!) Index: gcc/config/s390/s390.c =================================================================== *** gcc/config/s390/s390.c.orig --- gcc/config/s390/s390.c *************** s390_gimplify_va_arg (tree valist, tree *** 10005,10020 **** void s390_expand_tbegin (rtx dest, rtx tdb, rtx retry, bool clobber_fprs_p) { - const int CC0 = 1 << 3; - const int CC1 = 1 << 2; - const int CC3 = 1 << 0; - rtx abort_label = gen_label_rtx (); - rtx leave_label = gen_label_rtx (); rtx retry_plus_two = gen_reg_rtx (SImode); rtx retry_reg = gen_reg_rtx (SImode); rtx retry_label = NULL_RTX; - rtx jump; - int very_unlikely = REG_BR_PROB_BASE / 100 - 1; if (retry != NULL_RTX) { --- 10005,10013 ---- *************** s390_expand_tbegin (rtx dest, rtx tdb, r *** 10031,10068 **** emit_insn (gen_tbegin_nofloat_1 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK), tdb)); - jump = s390_emit_jump (abort_label, - gen_rtx_NE (VOIDmode, - gen_rtx_REG (CCRAWmode, CC_REGNUM), - gen_rtx_CONST_INT (VOIDmode, CC0))); - - JUMP_LABEL (jump) = abort_label; - LABEL_NUSES (abort_label) = 1; - add_int_reg_note (jump, REG_BR_PROB, very_unlikely); - - /* Initialize CC return value. */ - emit_move_insn (dest, const0_rtx); - - s390_emit_jump (leave_label, NULL_RTX); - LABEL_NUSES (leave_label) = 1; - emit_barrier (); - - /* Abort handler code. */ - - emit_label (abort_label); emit_move_insn (dest, gen_rtx_UNSPEC (SImode, gen_rtvec (1, gen_rtx_REG (CCRAWmode, CC_REGNUM)), UNSPEC_CC_TO_INT)); if (retry != NULL_RTX) { rtx count = gen_reg_rtx (SImode); jump = s390_emit_jump (leave_label, gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCRAWmode, CC_REGNUM), ! gen_rtx_CONST_INT (VOIDmode, CC1 | CC3))); ! LABEL_NUSES (leave_label) = 2; ! add_int_reg_note (jump, REG_BR_PROB, very_unlikely); /* CC2 - transient failure. Perform retry with ppa. */ emit_move_insn (count, retry_plus_two); --- 10024,10048 ---- emit_insn (gen_tbegin_nofloat_1 (gen_rtx_CONST_INT (VOIDmode, TBEGIN_MASK), tdb)); emit_move_insn (dest, gen_rtx_UNSPEC (SImode, gen_rtvec (1, gen_rtx_REG (CCRAWmode, CC_REGNUM)), UNSPEC_CC_TO_INT)); if (retry != NULL_RTX) { + const int CC0 = 1 << 3; + const int CC1 = 1 << 2; + const int CC3 = 1 << 0; + rtx jump; rtx count = gen_reg_rtx (SImode); + rtx leave_label = gen_label_rtx (); + + /* Exit for success and permanent failures. */ jump = s390_emit_jump (leave_label, gen_rtx_EQ (VOIDmode, gen_rtx_REG (CCRAWmode, CC_REGNUM), ! gen_rtx_CONST_INT (VOIDmode, CC0 | CC1 | CC3))); ! LABEL_NUSES (leave_label) = 1; /* CC2 - transient failure. Perform retry with ppa. */ emit_move_insn (count, retry_plus_two); *************** s390_expand_tbegin (rtx dest, rtx tdb, r *** 10073,10081 **** retry_reg)); JUMP_LABEL (jump) = retry_label; LABEL_NUSES (retry_label) = 1; } - - emit_label (leave_label); } /* Builtins. */ --- 10053,10060 ---- retry_reg)); JUMP_LABEL (jump) = retry_label; LABEL_NUSES (retry_label) = 1; + emit_label (leave_label); } } /* Builtins. */