S/390: Further reload tweaks

Ulrich Weigand Ulrich.Weigand@de.ibm.com
Thu Sep 5 08:05:00 GMT 2002


Hello,

this patch allows a couple more insns to make full use of the new Q
constraint.  This showed up another inefficiency on 31-bit: now,
the secondary-reload path is taken more often, and the fact that
reload_insi wants a double-word register really makes register
allocation worse.

However, it looks like I don't actually need a double-word scratch
register; the cases where I thought I needed this were actually
caused by another bug I've fixed in the meantime: we need to apply
replacements already scheduled by reload before doing anything else.
If that is done, the only invalid parts should be out-of-range
constants (either CONST_INT or literal pool MEM references), and
there can be at most one of them.

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux.

Bye,
Ulrich


ChangeLog:

      * config/s390/s390.c (s390_expand_plus_operand): Do not require
      double-word scratch register.
      config/s390/s390.md ("reload_indi", "reload_insi"): Adapt.

      ("*tmqi_ext", "*tmdi_mem", "*tmsi_mem", "*tmhi_mem", "*tmqi_mem",
      "*cli"): Replace s_operand by memory_operand.
      ("cmpstrdi", "cmpstrsi"): Replace s_operand by general_operand.

Index: gcc/config/s390/s390.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.c,v
retrieving revision 1.49
diff -c -p -r1.49 s390.c
*** gcc/config/s390/s390.c    3 Sep 2002 16:30:32 -0000     1.49
--- gcc/config/s390/s390.c    4 Sep 2002 21:35:01 -0000
*************** s390_plus_operand (op, mode)
*** 1365,1387 ****
     SCRATCH may be used as scratch register.  */

  void
! s390_expand_plus_operand (target, src, scratch_in)
       register rtx target;
       register rtx src;
!      register rtx scratch_in;
  {
!   rtx sum1, sum2, scratch;
    struct s390_address ad;

-   /* ??? reload apparently does not ensure that the scratch register
-      and the target do not overlap.  We absolutely require this to be
-      the case, however.  Therefore the reload_in[sd]i patterns ask for
-      a double-sized scratch register, and if one part happens to be
-      equal to the target, we use the other one.  */
-   scratch = gen_rtx_REG (Pmode, REGNO (scratch_in));
-   if (rtx_equal_p (scratch, target))
-     scratch = gen_rtx_REG (Pmode, REGNO (scratch_in) + 1);
-
    /* src must be a PLUS; get its two operands.  */
    if (GET_CODE (src) != PLUS || GET_MODE (src) != Pmode)
      abort ();
--- 1365,1378 ----
     SCRATCH may be used as scratch register.  */

  void
! s390_expand_plus_operand (target, src, scratch)
       register rtx target;
       register rtx src;
!      register rtx scratch;
  {
!   rtx sum1, sum2;
    struct s390_address ad;

    /* src must be a PLUS; get its two operands.  */
    if (GET_CODE (src) != PLUS || GET_MODE (src) != Pmode)
      abort ();
*************** s390_expand_plus_operand (target, src, s
*** 1391,1451 ****
       float registers occur in an address.  */
    sum1 = find_replacement (&XEXP (src, 0));
    sum2 = find_replacement (&XEXP (src, 1));
-
-   /* Accept already strictly valid addresses.  */
    src = gen_rtx_PLUS (Pmode, sum1, sum2);
-   if (s390_decompose_address (src, &ad)
-       && (!ad.base || REG_OK_FOR_BASE_STRICT_P (ad.base))
-       && (!ad.indx || REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
-     {
-       src = legitimize_la_operand (src);
-       emit_insn (gen_rtx_SET (VOIDmode, target, src));
-       return;
-     }
-
-   /* If one of the two operands is equal to the target,
-      make it the first one.  If one is a constant, make
-      it the second one.  */
-   if (rtx_equal_p (target, sum2)
-       || GET_CODE (sum1) == CONST_INT)
-     {
-       rtx tem = sum2;
-       sum2 = sum1;
-       sum1 = tem;
-     }

!   /* If the first operand is not an address register,
!      we reload it into the target.  */
!   if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
      {
!       emit_move_insn (target, sum1);
!       sum1 = target;
!     }

!   /* Likewise for the second operand.  However, take
!      care not to clobber the target if we already used
!      it for the first operand.  Use the scratch instead.
!      Also, allow an immediate offset if it is in range.  */
!   if ((true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
!       && !(GET_CODE (sum2) == CONST_INT
!            && INTVAL (sum2) >= 0 && INTVAL (sum2) < 4096))
!     {
!       if (!rtx_equal_p (target, sum1))
!         {
!           emit_move_insn (target, sum2);
!           sum2 = target;
!         }
!       else
!         {
!           emit_move_insn (scratch, sum2);
!           sum2 = scratch;
!         }
      }

    /* Emit the LOAD ADDRESS pattern.  Note that reload of PLUS
       is only ever performed on addresses, so we can mark the
       sum as legitimate for LA in any case.  */
-   src = gen_rtx_PLUS (Pmode, sum1, sum2);
    src = legitimize_la_operand (src);
    emit_insn (gen_rtx_SET (VOIDmode, target, src));
  }
--- 1382,1423 ----
       float registers occur in an address.  */
    sum1 = find_replacement (&XEXP (src, 0));
    sum2 = find_replacement (&XEXP (src, 1));
    src = gen_rtx_PLUS (Pmode, sum1, sum2);

!   /* If the address is already strictly valid, there's nothing to do.  */
!   if (!s390_decompose_address (src, &ad)
!       || (ad.base && !REG_OK_FOR_BASE_STRICT_P (ad.base))
!       || (ad.indx && !REG_OK_FOR_INDEX_STRICT_P (ad.indx)))
      {
!       /* Otherwise, one of the operands cannot be an address register;
!          we reload its value into the scratch register.  */
!       if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
!     {
!       emit_move_insn (scratch, sum1);
!       sum1 = scratch;
!     }
!       if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
!     {
!       emit_move_insn (scratch, sum2);
!       sum2 = scratch;
!     }
!
!       /* According to the way these invalid addresses are generated
!          in reload.c, it should never happen (at least on s390) that
!          *neither* of the PLUS components, after find_replacements
!          was applied, is an address register.  */
!       if (sum1 == scratch && sum2 == scratch)
!     {
!       debug_rtx (src);
!       abort ();
!     }

!       src = gen_rtx_PLUS (Pmode, sum1, sum2);
      }

    /* Emit the LOAD ADDRESS pattern.  Note that reload of PLUS
       is only ever performed on addresses, so we can mark the
       sum as legitimate for LA in any case.  */
    src = legitimize_la_operand (src);
    emit_insn (gen_rtx_SET (VOIDmode, target, src));
  }
Index: gcc/config/s390/s390.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.md,v
retrieving revision 1.26
diff -c -p -r1.26 s390.md
*** gcc/config/s390/s390.md   3 Sep 2002 18:33:56 -0000     1.26
--- gcc/config/s390/s390.md   4 Sep 2002 21:35:07 -0000
***************
*** 278,284 ****

  (define_insn "*tmqi_ext"
    [(set (reg 33)
!         (compare (zero_extract:SI (match_operand:QI 0 "s_operand" "Q")
                                (match_operand:SI 1 "const_int_operand" "n")
                                    (match_operand:SI 2 "const_int_operand" "n"))
                   (const_int 0)))]
--- 278,284 ----

  (define_insn "*tmqi_ext"
    [(set (reg 33)
!         (compare (zero_extract:SI (match_operand:QI 0 "memory_operand" "Q")
                                (match_operand:SI 1 "const_int_operand" "n")
                                    (match_operand:SI 2 "const_int_operand" "n"))
                   (const_int 0)))]
***************
*** 345,351 ****

  (define_insn "*tmdi_mem"
    [(set (reg 33)
!         (compare (and:DI (match_operand:DI 0 "s_operand" "%Q")
                           (match_operand:DI 1 "immediate_operand" "n"))
                   (match_operand:DI 2 "immediate_operand" "n")))]
    "TARGET_64BIT
--- 345,351 ----

  (define_insn "*tmdi_mem"
    [(set (reg 33)
!         (compare (and:DI (match_operand:DI 0 "memory_operand" "%Q")
                           (match_operand:DI 1 "immediate_operand" "n"))
                   (match_operand:DI 2 "immediate_operand" "n")))]
    "TARGET_64BIT
***************
*** 365,371 ****

  (define_insn "*tmsi_mem"
    [(set (reg 33)
!         (compare (and:SI (match_operand:SI 0 "s_operand" "%Q")
                           (match_operand:SI 1 "immediate_operand" "n"))
                   (match_operand:SI 2 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
--- 365,371 ----

  (define_insn "*tmsi_mem"
    [(set (reg 33)
!         (compare (and:SI (match_operand:SI 0 "memory_operand" "%Q")
                           (match_operand:SI 1 "immediate_operand" "n"))
                   (match_operand:SI 2 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
***************
*** 384,390 ****

  (define_insn "*tmhi_mem"
    [(set (reg 33)
!         (compare (and:SI (subreg:SI (match_operand:HI 0 "s_operand" "%Q") 0)
                           (match_operand:SI 1 "immediate_operand" "n"))
                   (match_operand:SI 2 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
--- 384,390 ----

  (define_insn "*tmhi_mem"
    [(set (reg 33)
!         (compare (and:SI (subreg:SI (match_operand:HI 0 "memory_operand" "%Q") 0)
                           (match_operand:SI 1 "immediate_operand" "n"))
                   (match_operand:SI 2 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
***************
*** 403,409 ****

  (define_insn "*tmqi_mem"
    [(set (reg 33)
!         (compare (and:SI (subreg:SI (match_operand:QI 0 "s_operand" "%Q") 0)
                           (match_operand:SI 1 "immediate_operand" "n"))
                   (match_operand:SI 2 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))"
--- 403,409 ----

  (define_insn "*tmqi_mem"
    [(set (reg 33)
!         (compare (and:SI (subreg:SI (match_operand:QI 0 "memory_operand" "%Q") 0)
                           (match_operand:SI 1 "immediate_operand" "n"))
                   (match_operand:SI 2 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))"
***************
*** 645,651 ****

  (define_insn "*cli"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "s_operand" "Q")
                   (match_operand:QI 1 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, CCUmode)"
    "cli\\t%0,%b1"
--- 645,651 ----

  (define_insn "*cli"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "memory_operand" "Q")
                   (match_operand:QI 1 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, CCUmode)"
    "cli\\t%0,%b1"
***************
*** 1947,1954 ****

  (define_expand "cmpstrdi"
     [(set (match_operand:DI 0 "register_operand" "")
!          (compare:DI (match_operand:BLK 1 "s_operand" "")
!                   (match_operand:BLK 2 "s_operand" "") ) )
               (use (match_operand:DI 3  "general_operand" ""))
               (use (match_operand:DI 4  "" ""))]
     "TARGET_64BIT"
--- 1947,1954 ----

  (define_expand "cmpstrdi"
     [(set (match_operand:DI 0 "register_operand" "")
!          (compare:DI (match_operand:BLK 1 "general_operand" "")
!                   (match_operand:BLK 2 "general_operand" "") ) )
               (use (match_operand:DI 3  "general_operand" ""))
               (use (match_operand:DI 4  "" ""))]
     "TARGET_64BIT"
***************
*** 2008,2015 ****

  (define_expand "cmpstrsi"
     [(set (match_operand:SI 0 "register_operand" "")
!          (compare:SI (match_operand:BLK 1 "s_operand" "")
!                   (match_operand:BLK 2 "s_operand" "") ) )
               (use (match_operand:SI 3  "general_operand" ""))
               (use (match_operand:SI 4  "" ""))]
     ""
--- 2008,2015 ----

  (define_expand "cmpstrsi"
     [(set (match_operand:SI 0 "register_operand" "")
!          (compare:SI (match_operand:BLK 1 "general_operand" "")
!                   (match_operand:BLK 2 "general_operand" "") ) )
               (use (match_operand:SI 3  "general_operand" ""))
               (use (match_operand:SI 4  "" ""))]
     ""
***************
*** 3187,3193 ****
  (define_expand "reload_indi"
    [(parallel [(match_operand:DI 0 "register_operand" "=a")
                (match_operand:DI 1 "s390_plus_operand" "")
!               (match_operand:TI 2 "register_operand" "=&a")])]
    "TARGET_64BIT"
    "
  {
--- 3187,3193 ----
  (define_expand "reload_indi"
    [(parallel [(match_operand:DI 0 "register_operand" "=a")
                (match_operand:DI 1 "s390_plus_operand" "")
!               (match_operand:DI 2 "register_operand" "=&a")])]
    "TARGET_64BIT"
    "
  {
***************
*** 3348,3354 ****
  (define_expand "reload_insi"
    [(parallel [(match_operand:SI 0 "register_operand" "=a")
                (match_operand:SI 1 "s390_plus_operand" "")
!               (match_operand:DI 2 "register_operand" "=&a")])]
    "!TARGET_64BIT"
    "
  {
--- 3348,3354 ----
  (define_expand "reload_insi"
    [(parallel [(match_operand:SI 0 "register_operand" "=a")
                (match_operand:SI 1 "s390_plus_operand" "")
!               (match_operand:SI 2 "register_operand" "=&a")])]
    "!TARGET_64BIT"
    "
  {


Mit freundlichen Gruessen / Best Regards

Ulrich Weigand

--
  Dr. Ulrich Weigand
  Linux for S/390 Design & Development
  IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
  Phone: +49-7031/16-3727   ---   Email: Ulrich.Weigand@de.ibm.com



More information about the Gcc-patches mailing list