Segher Boessenkool <seg...@kernel.crashing.org> writes: > On Wed, Oct 02, 2019 at 10:22:22PM +0100, Richard Sandiford wrote: >> My change to the -fipa-ra bookkeeping used ALL_REGS as the supposedly >> safe default assumption, but ALL_REGS isn't literally all registers, >> just a close approximation. >> >> This caused a bootstrap failure on arm-linux-gnu, where the condition >> code register isn't in ALL_REGS and so was being masked out of some >> call-clobbered sets. > > The documentation says > > @findex ALL_REGS > @findex NO_REGS > In general, each register will belong to several classes. In fact, one > class must be named @code{ALL_REGS} and contain all the registers. Another > class must be named @code{NO_REGS} and contain no registers. Often the > union of two classes will be another class; however, this is not required. > > so is the arm port wrong, or is the documentation wrong? I think the arm > port simply forgets to include CC_REG, VFPCC_REG, SFP_REG, AFP_REG: > > #define REG_CLASS_CONTENTS \ > ... > { 0x00000000, 0x00000000, 0x00000000, 0x00000010 }, /* CC_REG */ \ > { 0x00000000, 0x00000000, 0x00000000, 0x00000020 }, /* VFPCC_REG */ \ > { 0x00000000, 0x00000000, 0x00000000, 0x00000040 }, /* SFP_REG */ \ > { 0x00000000, 0x00000000, 0x00000000, 0x00000080 }, /* AFP_REG */ \ > { 0xFFFF7FFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x0000000F } /* ALL_REGS */ \ > > and that last number should be 0x000000ff instead?
In this particular case I think the port's wrong because ALL_REGS has to be a superset of all other classes. But AIUI it's OK for fixed registers not to be in any register class, even ALL_REGS. E.g. REGNO_REG_CLASS is allowed to return NO_REGS for fixed registers, which wouldn't make sense if every register is at least a member of ALL_REGS. This goes back to at least 1992: /* Certain fixed registers might be of the class NO_REGS. This means that not only can they not be allocated by the compiler, but they cannot be used in substitutions or canonicalizations either. */ (from cse.c). This isn't actually documented AFAICT. But it is useful for registers that are only allowed to appear in special instructions that the port generates itself. (Or at least it was useful. operand_reg_set was supposed to be a more flexible way of doing this.) As it happens, CC_REGNUM only has class CC_REG for Thumb, not A32 mode: /* For efficiency and historical reasons LO_REGS, HI_REGS and CC_REGS are not used in arm mode. */ The explanation makes sense for LO_REGS and HI_REGS, not so sure about CC_REGS though. There's also the problem that if you don't actually need a register to be in a class for its own sake, but only because the documentation says so, then it's less clear how individual registers should be grouped into classes. E.g. is having separate SFP_REG and AFP_REG classes right (as above), or should they really be members of a single class? In practice it doesn't matter because nothing ever uses these classes; REGNO_REG_CLASS returns NO_REGS for the registers instead. And it looks like VFPCC_REGNUM can be given CC_REG for Thumb2, despite not being in CC_REG but in its own class VFPCC_REG. My take from this is that defining register classes correctly is hard when it's just a paper exercise, so it's better for registers only to be in classes if there's a specific need. But I guess it can be taken in completely the opposite way too :-) It looks like the following ports are the ones that have fixed registers not in ALL_REGS: amdgcn arm avr hppa m32c mips rl78 rx tilepro v850 (tested by building targets with an assert in reginfo.c). Not too long a list if someone wanted to rework this. But I think it should be done with clear rules about what register classes mean for fixed registers that are never matched by constraints, and about whether and when REGNO_REG_CLASS can ignore the class that the register is actually in and return NO_REGS instead. Thanks, Richard