On 07/21/2017 05:50 AM, Andrew Stubbs wrote: > Hi all, > > I have an architecture that has two register files. Let's call them > class A and class B. There are some differences between their > capabilities, but for the purposes of this problem, they can be > considered to be identical, both holding SImode values, and both able to > receive values without a secondary reload. > > In order to load data into A, the address register must also be in A. > Similarly, in order to load data into B, the address register must also > be in B. > > So I set up my (simplified) pattern: > > (set (match_operand:SI "register_operand" "=a,b") > (match_operand:SI "memory_operand" "Ra,Rb")) > > where > "a" is a register in A > "b" is a register in B > "Ra" is a mem with base address in A > "Rb" is a mem with base address in B > > (Obviously, there are stores and moves and whatnot too, but you get the > idea.) > > The problem is that the register allocator cannot see inside Ra and Rb > to know that it must allocate the base register correctly. It only knows > that, some of the time, the instruction "does not satisfy its constraints". Wen determining if any particular memory address is legitimate, you need to know something about the other operand. Ie, in a load from memory the validity of the base register varies based on the target register of the load.
GCC, in general, doesn't support that -- when determining address validity if knows the address and the size of the memory reference. You don't know if it's a load or a store, nor do you know anything about the other operand. Last I looked, this was deeply baked into reload. I haven't looked recently to see if that's changed nor have I looked at LRA to see if it handles this scenario better. So not only do you have a constraint issue, you have a problem with GO_IF_LEGITIMATE_ADDRESS (or whatever the hook is called these days). > > I believe the register allocator relies on base_reg_class to choose a > class for the base register, but that just says "AB" (the union of class > A and class B), because it has no context to say otherwise. Only the > constraints define what hard registers are acceptable, and all they see > is pseudoregs during reload. > > Similarly for the other hooks I've investigated: they don't have enough > context to know what's going on, and the rtx given always has pseudo > registers anyway. Note that you may be able to look at reg_renumber to see a tentative assignment. But yes, you've got a fundamental problem in that there's not enough context to make correct decisions. > > The only solutions I can think of are to either preallocate the loads to > register classes via some means MODE_CODE_BASE_REG_CLASS can see > (address spaces, perhaps), or to have an alternative that catches the > mismatching cases and splits to a load and move, or set the base class > to A and always load via secondary reload for B. > > Any suggestions would be greatly appreciated. I wish I had suggestions. This was a long standing nasty problem on the PA as well. For example, you needed to look at the destination register of for a load from memory to know if the displacement in the memory address was valid, or whether or not certain indexing address modes were valid. We went through many iterations of hacks, none of which were particularly clean, all of which were weak in terms of GCC's ability to use the addressing modes available when it was profitable. You're likely to have to define some secondary reloads. Good luck, jeff > > Andrew