From bcf8c1cc28d59046bc6a297785dd0aa89a4ab07a Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Fri, 16 Sep 2005 14:25:27 +0000 Subject: [PATCH] s390-protos.h (s390_overlap_p): Prototype added. 2005-09-16 Andreas Krebbel * config/s390/s390-protos.h (s390_overlap_p): Prototype added. * config/s390/s390.c (s390_overlap_p): New function. * config/s390/s390.md ("*mvc" peephole2, "*nc" peephole2, "*oc" peephole2, "*xc" peephole2): Added overlap check to the peephole2 condition. From-SVN: r104342 --- gcc/ChangeLog | 8 +++++++ gcc/config/s390/s390-protos.h | 1 + gcc/config/s390/s390.c | 42 +++++++++++++++++++++++++++++++++++ gcc/config/s390/s390.md | 8 +++++++ 4 files changed, 59 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 820a062acfd4..f7ccd52ea396 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2005-09-16 Andreas Krebbel + + * config/s390/s390-protos.h (s390_overlap_p): Prototype added. + * config/s390/s390.c (s390_overlap_p): New function. + * config/s390/s390.md ("*mvc" peephole2, "*nc" peephole2, "*oc" + peephole2, "*xc" peephole2): Added overlap check to the peephole2 + condition. + 2005-09-16 Richard Guenther * ipa-pure-const.c (static_execute): Free auxiliar information. diff --git a/gcc/config/s390/s390-protos.h b/gcc/config/s390/s390-protos.h index c9480591b230..7bafcf3f404c 100644 --- a/gcc/config/s390/s390-protos.h +++ b/gcc/config/s390/s390-protos.h @@ -38,6 +38,7 @@ extern int s390_const_double_ok_for_constraint_p (rtx, int, const char *); extern int s390_single_part (rtx, enum machine_mode, enum machine_mode, int); extern unsigned HOST_WIDE_INT s390_extract_part (rtx, enum machine_mode, int); extern bool s390_split_ok_p (rtx, rtx, enum machine_mode, int); +extern bool s390_overlap_p (rtx, rtx, HOST_WIDE_INT); extern bool s390_offset_p (rtx, rtx, rtx); extern int tls_symbolic_operand (rtx); diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 129d7ed6f29f..a543e59126eb 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -1074,6 +1074,48 @@ s390_split_ok_p (rtx dst, rtx src, enum machine_mode mode, int first_subword) return true; } +/* Return true if it can be proven that [MEM1, MEM1 + SIZE] + and [MEM2, MEM2 + SIZE] do overlap and false + otherwise. */ + +bool +s390_overlap_p (rtx mem1, rtx mem2, HOST_WIDE_INT size) +{ + rtx addr1, addr2, addr_delta; + HOST_WIDE_INT delta; + + if (GET_CODE (mem1) != MEM || GET_CODE (mem2) != MEM) + return true; + + if (size == 0) + return false; + + addr1 = XEXP (mem1, 0); + addr2 = XEXP (mem2, 0); + + addr_delta = simplify_binary_operation (MINUS, Pmode, addr2, addr1); + + /* This overlapping check is used by peepholes merging memory block operations. + Overlapping operations would otherwise be recognized by the S/390 hardware + and would fall back to a slower implementation. Allowing overlapping + operations would lead to slow code but not to wrong code. Therefore we are + somewhat optimistict if we cannot prove that the memory blocks are + overlapping. + That's why we return false here although this may accept operations on + overlapping memory areas. */ + if (!addr_delta || GET_CODE (addr_delta) != CONST_INT) + return false; + + delta = INTVAL (addr_delta); + + if (delta == 0 + || (delta > 0 && delta < size) + || (delta < 0 && -delta < size)) + return true; + + return false; +} + /* Check whether the address of memory reference MEM2 equals exactly the address of memory reference MEM1 plus DELTA. Return true if we can prove this to be the case, false otherwise. */ diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md index 84e58d7838d8..3f119c9255a2 100644 --- a/gcc/config/s390/s390.md +++ b/gcc/config/s390/s390.md @@ -1650,6 +1650,8 @@ (use (match_operand 5 "const_int_operand" ""))])] "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])) && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" [(parallel [(set (match_dup 6) (match_dup 7)) @@ -5124,6 +5126,8 @@ (clobber (reg:CC CC_REGNUM))])] "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])) && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" [(parallel [(set (match_dup 6) (and:BLK (match_dup 6) (match_dup 7))) @@ -5412,6 +5416,8 @@ (clobber (reg:CC CC_REGNUM))])] "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])) && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" [(parallel [(set (match_dup 6) (ior:BLK (match_dup 6) (match_dup 7))) @@ -5651,6 +5657,8 @@ (clobber (reg:CC CC_REGNUM))])] "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])) && INTVAL (operands[2]) + INTVAL (operands[5]) <= 256" [(parallel [(set (match_dup 6) (xor:BLK (match_dup 6) (match_dup 7))) -- 2.47.2