From f9dcf14aae8f725ed63499d70980eb7029fdd2d5 Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Fri, 1 Dec 2017 15:33:15 +0000 Subject: [PATCH] S/390: Split MVC instruction for better forwarding Certain lengths used in an MVC instruction might disable operand forwarding. Split MVCs into up to 2 forwardable ones if possible. gcc/ChangeLog: 2017-12-01 Andreas Krebbel * config/s390/predicates.md (plus16_Q_operand): New predicate. * config/s390/s390.md: Disable MVC merging peephole if it would disable operand forwarding. (new peephole2): Split MVCs if it would turn them into up to 2 forwardable MVCs. From-SVN: r255319 --- gcc/ChangeLog | 8 ++++++++ gcc/config/s390/predicates.md | 19 +++++++++++++++++++ gcc/config/s390/s390.md | 22 +++++++++++++++++++++- 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0213e8b0929..77d4c7c81a8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2017-12-01 Andreas Krebbel + + * config/s390/predicates.md (plus16_Q_operand): New predicate. + * config/s390/s390.md: Disable MVC merging peephole if it would + disable operand forwarding. + (new peephole2): Split MVCs if it would turn them into up to 2 + forwardable MVCs. + 2017-12-01 Richard Biener PR tree-optimization/83232 diff --git a/gcc/config/s390/predicates.md b/gcc/config/s390/predicates.md index bbff8d856c2..e140b689b02 100644 --- a/gcc/config/s390/predicates.md +++ b/gcc/config/s390/predicates.md @@ -67,6 +67,25 @@ return true; }) +;; Return true of the address of the mem operand plus 16 is still a +;; valid Q constraint address. + +(define_predicate "plus16_Q_operand" + (and (match_code "mem") + (match_operand 0 "general_operand")) +{ + rtx addr = XEXP (op, 0); + if (REG_P (addr)) + return true; + + if (GET_CODE (addr) != PLUS + || !REG_P (XEXP (addr, 0)) + || !CONST_INT_P (XEXP (addr, 1))) + return false; + + return SHORT_DISP_IN_RANGE (INTVAL (XEXP (addr, 1)) + 16); +}) + ;; Return true if OP is a valid operand for the BRAS instruction. ;; Allow SYMBOL_REFs and @PLT stubs. diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 1d63523d3b0..093f6f91cef 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -2720,7 +2720,9 @@ [(set (match_operand:BLK 3 "memory_operand" "") (match_operand:BLK 4 "memory_operand" "")) (use (match_operand 5 "const_int_operand" ""))])] - "s390_offset_p (operands[0], operands[3], operands[2]) + "((INTVAL (operands[2]) > 16 && INTVAL (operands[5]) > 16) + || (INTVAL (operands[2]) + INTVAL (operands[5]) <= 16)) + && s390_offset_p (operands[0], operands[3], operands[2]) && s390_offset_p (operands[1], operands[4], operands[2]) && !s390_overlap_p (operands[0], operands[1], INTVAL (operands[2]) + INTVAL (operands[5])) @@ -2732,6 +2734,24 @@ operands[7] = gen_rtx_MEM (BLKmode, XEXP (operands[1], 0)); operands[8] = GEN_INT (INTVAL (operands[2]) + INTVAL (operands[5]));") +(define_peephole2 + [(parallel + [(set (match_operand:BLK 0 "plus16_Q_operand" "") + (match_operand:BLK 1 "plus16_Q_operand" "")) + (use (match_operand 2 "const_int_operand" ""))])] + "INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32" + [(parallel + [(set (match_dup 0) (match_dup 1)) + (use (const_int 16))]) + (parallel + [(set (match_dup 3) (match_dup 4)) + (use (match_dup 5))])] + "operands[3] = change_address (operands[0], VOIDmode, + plus_constant (Pmode, XEXP (operands[0], 0), 16)); + operands[4] = change_address (operands[1], VOIDmode, + plus_constant (Pmode, XEXP (operands[1], 0), 16)); + operands[5] = GEN_INT (INTVAL (operands[2]) - 16);") + ; ; load_multiple pattern(s). -- 2.30.2