This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
S/390: Further reload tweaks
- From: "Ulrich Weigand" <Ulrich dot Weigand at de dot ibm dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 5 Sep 2002 17:04:45 +0200
- Subject: S/390: Further reload tweaks
- Sensitivity:
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