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 meiss...@linux.vnet.ibm.com