This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Committed: fix default_secondary_reload and the CRIS port.
- From: Hans-Peter Nilsson <hans-peter dot nilsson at axis dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Fri, 25 Nov 2005 21:17:49 +0100
- Subject: Committed: fix default_secondary_reload and the CRIS port.
The new secondary-reload machinery has a bug and exposed a bug: it broke
build of cris-*-*. The default_secondary_reload function requires that
scratch and intermediary registers is "=&" i.e. non-overlapping output. For
output reloads I can agree, so that was a bug in the CRIS port. For inputs,
that's wrong. Consider the following cris.md pattern (which expresses that
we can't move a "x" from memory in modes smaller than the register size
i.e. BW: (HI QI):
(define_expand "reload_in<mode>"
[(set (match_operand:BW 2 "register_operand" "=r")
(match_operand:BW 1 "memory_operand" "m"))
(set (match_operand:BW 0 "register_operand" "=x")
(match_dup 2))]
""
"")
If some register dies in the address of operand 1, it's likely to be
beneficial to re-use it for operand 2, the intermediate/scratch register.
(It should obviously not overlap with "x", but that's expressed by the
register classes and there are no degrees expressable regarding overlap.)
As this patch only effectively *lifts* an assertion, no more tests were
performed than checking that there are no regressions for cris-axis-elf and
cris-axis-linux-gnu between "Thu Nov 24 18:45:30 UTC 2005 (revision
107467M)" and "Fri Nov 25 08:42:41 UTC 2005 (revision 107495M)" with this
patch.
Committed as obvious.
* config/cris/cris.md ("reload_out<mode>"): Mark operand 2 as
earlyclobber.
* targhooks.c (default_secondary_reload): Don't require operand 2
for an input reload to be earlyclobber.
Index: targhooks.c
===================================================================
--- targhooks.c (revision 107495)
+++ targhooks.c (working copy)
@@ -514,10 +514,15 @@ default_secondary_reload (bool in_p ATTR
}
scratch_constraint = insn_data[(int) icode].operand[2].constraint;
- /* The scratch register's constraint must start with "=&". */
+ /* The scratch register's constraint must start with "=&",
+ except for an input reload, where only "=" is necessary,
+ and where it might be beneficial to re-use registers from
+ the input. */
gcc_assert (scratch_constraint[0] == '='
- && scratch_constraint[1] == '&');
- scratch_constraint += 2;
+ && (in_p || scratch_constraint[1] == '&'));
+ scratch_constraint++;
+ if (*scratch_constraint == '&')
+ scratch_constraint++;
scratch_letter = *scratch_constraint;
scratch_class
= (scratch_letter == 'r' ? GENERAL_REGS
Index: config/cris/cris.md
===================================================================
--- config/cris/cris.md (revision 107495)
+++ config/cris/cris.md (working copy)
@@ -1151,7 +1151,7 @@ (define_expand "reload_in<mode>"
"")
(define_expand "reload_out<mode>"
- [(set (match_operand:BW 2 "register_operand" "=r")
+ [(set (match_operand:BW 2 "register_operand" "=&r")
(match_operand:BW 1 "register_operand" "x"))
(set (match_operand:BW 0 "memory_operand" "=m")
(match_dup 2))]
brgds, H-P