This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]