public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Limiting the use of pointer registers
@ 2009-05-24 11:38 Michael Hope
  2009-05-25  4:31 ` Ian Lance Taylor
  2009-05-25  4:36 ` Michael Meissner
  0 siblings, 2 replies; 3+ messages in thread
From: Michael Hope @ 2009-05-24 11:38 UTC (permalink / raw)
  To: gcc

Hi there.  I'm working on a port to an architecture where the pointer
registers X and Y are directly backed by small 128 byte caches.
Changing one of these registers to a different memory row causes a
cache load cycle, so using them for memory access is fine but using
them as general purpose registers is expensive.

How can I prevent the register allocator from using these for anything
but memory access?  I have a register class called ADDR_REGS that
contains just X and Y and one called DATA_REGS which contains the
general registers R10 to R1E.  GENERAL_REGS is the same as DATA_REGS.
The order they appear in in reg_class is DATA_REGS, GENERAL_REGS, then
ADDR_REGS.  I've defined the constrains for most of the patterns to
only take 'r' which prevents X or Y being used as operands for those
patterns.  I have to allow X and Y to be used in movsi and addsi3 to
allow indirect memory addresses to be calculated.

Unfortunately Pmode is SImode so I can't tell the difference between
pointer and normal values in PREFERRED_RELOAD_CLASS,
LIMIT_RELOAD_CLASS, or TARGET_SECONDARY_RELOAD.  I tried setting
REGISTER_MOVE_COST and MEMORY_MOVE_COST to 100 when the source or
destination is ADDR_REGS but this didn't affect the output.

I suspect that I'll have to do the same as the accumulator and hide X
and Y from the register allocator.  Pretend that any general register
can access memory and then use post reload split to turn the patterns
into X based patterns for the later phases to tidy up.

One more question.  The backing caches aren't coherent so X and Y
can't read and write to the same 128 bytes of memory at the same time.
 Does GCC have any other information about the location of a pointer
that I could use?  Something like:
 * Pointer is to text memory or read only data, so it is safe to read from
 * Pointer 1 is in the stack and pointer 2 is in BSS, so they are
definitely far apart
 * Pointer 1 is to to one on stack item and pointer 2 is to a stack
item at least 128 bytes apart
 * The call stack is known and pointer 1 and pointer 2 point to different rows

My fallback plan is to add a variable attribute so the programmer can
mark the pointer as non overlapping and push the problem onto them.
Something clever would be nice though :)

Sorry for all the questions - this is quite a difficult architecture.
I hope to collect all the answers and do a write up for others to use
when I'm done.

-- Michael

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Limiting the use of pointer registers
  2009-05-24 11:38 Limiting the use of pointer registers Michael Hope
@ 2009-05-25  4:31 ` Ian Lance Taylor
  2009-05-25  4:36 ` Michael Meissner
  1 sibling, 0 replies; 3+ messages in thread
From: Ian Lance Taylor @ 2009-05-25  4:31 UTC (permalink / raw)
  To: Michael Hope; +Cc: gcc

Michael Hope <michaelh@juju.net.nz> writes:

> How can I prevent the register allocator from using these for anything
> but memory access?

Unfortunately, you can't.  You can make them the last registers the
allocator will use, but if you say that they can hold Pmode values then
the register allocator will use them.

> I suspect that I'll have to do the same as the accumulator and hide X
> and Y from the register allocator.  Pretend that any general register
> can access memory and then use post reload split to turn the patterns
> into X based patterns for the later phases to tidy up.

I agree.

>
> One more question.  The backing caches aren't coherent so X and Y
> can't read and write to the same 128 bytes of memory at the same time.
>  Does GCC have any other information about the location of a pointer
> that I could use?  Something like:
>  * Pointer is to text memory or read only data, so it is safe to read from
>  * Pointer 1 is in the stack and pointer 2 is in BSS, so they are
> definitely far apart
>  * Pointer 1 is to to one on stack item and pointer 2 is to a stack
> item at least 128 bytes apart
>  * The call stack is known and pointer 1 and pointer 2 point to different rows

Ouch.  You can get alias set information but I don't think it will help.
In some cases you can look in REG_ATTRS to at least get the original
decl that the register is associated with.  This information is not
always there, and it won't always be useful, but it may at least let you
distinguish between a function pointer and a data pointer.  After
reload, you need to look at ORIGINAL_REGNO to get the original register
number (if any) and look at regno_reg_rtx[orig_regno].

Ian

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: Limiting the use of pointer registers
  2009-05-24 11:38 Limiting the use of pointer registers Michael Hope
  2009-05-25  4:31 ` Ian Lance Taylor
@ 2009-05-25  4:36 ` Michael Meissner
  1 sibling, 0 replies; 3+ messages in thread
From: Michael Meissner @ 2009-05-25  4:36 UTC (permalink / raw)
  To: Michael Hope; +Cc: gcc

On Sun, May 24, 2009 at 10:23:05PM +1200, Michael Hope wrote:
> Hi there.  I'm working on a port to an architecture where the pointer
> registers X and Y are directly backed by small 128 byte caches.
> Changing one of these registers to a different memory row causes a
> cache load cycle, so using them for memory access is fine but using
> them as general purpose registers is expensive.
> 
> How can I prevent the register allocator from using these for anything
> but memory access?  I have a register class called ADDR_REGS that
> contains just X and Y and one called DATA_REGS which contains the
> general registers R10 to R1E.  GENERAL_REGS is the same as DATA_REGS.
> The order they appear in in reg_class is DATA_REGS, GENERAL_REGS, then
> ADDR_REGS.  I've defined the constrains for most of the patterns to
> only take 'r' which prevents X or Y being used as operands for those
> patterns.  I have to allow X and Y to be used in movsi and addsi3 to
> allow indirect memory addresses to be calculated.
> 
> Unfortunately Pmode is SImode so I can't tell the difference between
> pointer and normal values in PREFERRED_RELOAD_CLASS,
> LIMIT_RELOAD_CLASS, or TARGET_SECONDARY_RELOAD.  I tried setting
> REGISTER_MOVE_COST and MEMORY_MOVE_COST to 100 when the source or
> destination is ADDR_REGS but this didn't affect the output.
> 
> I suspect that I'll have to do the same as the accumulator and hide X
> and Y from the register allocator.  Pretend that any general register
> can access memory and then use post reload split to turn the patterns
> into X based patterns for the later phases to tidy up.

One thought is to make Pmode PSImode instead of SImode.  You may have to define
a bunch of duplicate insns that do arithmetic on PSImode values instead of
SImode values, and you may run into some problems about PSImode because it
isn't widely used.

I am in the middle of writing a paper right now, where I mention that one of
the things I've felt was wrong since I've been hacking GCC is that the RTL
backend assumes pointers are just integers.

> One more question.  The backing caches aren't coherent so X and Y
> can't read and write to the same 128 bytes of memory at the same time.
>  Does GCC have any other information about the location of a pointer
> that I could use?  Something like:
>  * Pointer is to text memory or read only data, so it is safe to read from
>  * Pointer 1 is in the stack and pointer 2 is in BSS, so they are
> definitely far apart
>  * Pointer 1 is to to one on stack item and pointer 2 is to a stack
> item at least 128 bytes apart
>  * The call stack is known and pointer 1 and pointer 2 point to different rows

Look at the mem_attrs structure in rtl.h.  However, it looks like you have a
very challenging machine on your hands.

> My fallback plan is to add a variable attribute so the programmer can
> mark the pointer as non overlapping and push the problem onto them.
> Something clever would be nice though :)

Another place where the named address spaces stuff I worked on last year might
be useful.

> Sorry for all the questions - this is quite a difficult architecture.
> I hope to collect all the answers and do a write up for others to use
> when I'm done.
> 
> -- Michael

-- 
Michael Meissner, IBM
4 Technology Place Drive, MS 2203A, Westford, MA, 01886, USA
meissner@linux.vnet.ibm.com

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2009-05-25  2:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-24 11:38 Limiting the use of pointer registers Michael Hope
2009-05-25  4:31 ` Ian Lance Taylor
2009-05-25  4:36 ` Michael Meissner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).