This is the mail archive of the
mailing list for the GCC project.
Limiting the use of pointer registers
- From: Michael Hope <michaelh at juju dot net dot nz>
- To: gcc at gcc dot gnu dot org
- Date: Sun, 24 May 2009 22:23:05 +1200
- Subject: Limiting the use of pointer registers
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.