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]

Re: Register allocation trouble


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


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