This is the mail archive of the gcc@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]

[RFC] avoiding too narrow register classes in reload


I see that reload avoids committing a pseudo that needs reloading to a
single-register class.  On this port I'm working on, I happen to have
one class that contains only two registers, which unfortunately happen
to be the first two registers used for argument passing and for
returning values.

So it's quite common for the register allocator to decide it's a good
idea to choose this class (or the two single-register classes for each
of the registers) as the preferred class for pseudos that are ever
passed as one of the first two arguments to a function, or that are
ever assigned the return value of a function call.

The following patchlet to reload fixes the problem I ran into.  What
the surrounding code does is to verify whether the current alternative
is a superset of the preferred class.  If so, it narrows the
alternative to this preferred class, instead of using the wider class.
This is what causes the problem I'm running into: if this alternative
is selected (and it will often be), we end up forced to use one of the
first two argument registers for the reload, and this will fail if the
reload is needed in the middle of a function call sequence.  Defining
SMALL_REGISTER_CLASSES to 1 had no effect whatsoever (at least as far
as this particular reload as concerned).

Since CLASS_LIKELY_SPILLED_P is defined, by default, to non-zero if
the register class size is 1, I figured I might as well replace tests
for the register class size such that they used
CLASS_LIKELY_SPILLED_P, without significant semantics changes.  I
couldn't decide whether to create an alternate macro or target hook to
convey the meaning that reload shouldn't choose this narrower class,
so I thought I'd run the idea through you first.

Does this look like a reasonable approach?  Should I introduce a
separate macro, or do you agree using CLASS_LIKELY_SPILLED_P
reasonable for this purpose?  Should other locations that compare
reg_class_size with 1 be adjusted similarly?

Thanks in advance for any feedback,

--- reload.c
+++ reload.c
@@ -3461,7 +3461,11 @@ find_reloads (rtx insn, int replace, int
 	  if (! win && ! did_match
 	      && this_alternative[i] != (int) NO_REGS
 	      && GET_MODE_SIZE (operand_mode[i]) <= UNITS_PER_WORD
-	      && reg_class_size[(int) preferred_class[i]] > 1)
+	      /* However, if the subset is a small class very
+		 likely to be spilled, go with the wider class
+		 anyway.  */
+	      && preferred_class[i] != NO_REGS
+	      && ! CLASS_LIKELY_SPILLED_P (preferred_class[i]))
 	    {
 	      if (! reg_class_subset_p (this_alternative[i],
 					preferred_class[i]))


-- 
Alexandre Oliva             http://www.ic.unicamp.br/~oliva/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}


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