From: meissner@osf.org (Michael Meissner)
Subject: Re: Goals, Cost, and Flexibility (was Re: "Training" of programmers)
Organization: Open Software Foundation
	<1992Sep24.235308.18105@odin.corp.sgi.com> <1661@idacrd.UUCP>
	<ADAMS.92Sep25172127@PDV2.pdv2.fmr.maschinenbau.th-darmstadt.de>
	<CLIFFC.92Sep25182902@helena.rice.edu>
Date: Sat, 26 Sep 1992 12:30:54 GMT

In article <CLIFFC.92Sep25182902@helena.rice.edu> cliffc@rice.edu
(Cliff Click) writes:

| In short, fast code avoids memory whenever possible.  A fast int<->float 
| register path lets the compiler "spill" to the other register set when the
| current one gets full.  

On the other hand, things can get VERY hairy if you spill integer
registers to FP registers in kernel or standalone code.  For example,
consider what happens if the compiler decides to do one of these
spills in the init sequence of the kernel, before the FP unit has been
initialized yet, or when the kernel 'knows' it does not use floating
point, and does not save FP registers at interrupt level, and one of
the functions with such a spill is called.

Before you say these are made up examples, I have seen both cases.
When I switched from GCC 1.39 to GCC 2.0, the reload phase became more
willing to spill int registers into FP registers.  I could not boot an
OSF/1 kernel because somewhere in the init sequence, before the
coprocessor was enabled, the compiler had done such a build.  I fixed
GCC not to allow such transfers for the time being.  When I worked at
Data General on the MV/Eclipse, the native UNIX kernel (DG/UX) had
random flakes.  The problem was eventually traced down to the compiler
using the 64-bit FP registers to do block moves, and one such routine
was called at interrupt level, and to save time, the kernel was only
saving the integer registers.

| Bad: Writing to memory requires you to have a pointer to a spill location 
| handy.  Sometimes due to local storage requirements and other temps 
| generating a stack frame offset takes 2 or more instructions.  Thus the store
| to cache might take 2 instructions (cycles) to set up, and 2, possibly 3
| more cycles to do the store.  Addressing might require AN ADDITIONAL REGISTER
| for building the spill offset causing you to spill earlier than you might
| otherwise have.  And the same costs occur again on the reload.

I think it is rare that spilling would require more than 1 instruction
to store and load.  At Data General, we played around with unloading
the register holding the frame pointer.  Lets, see the MV/Eclipse only
has 4 integer registers, and only 2 of those can be used as index
registers, but I think because of spill problems mentioned above, the
code generator never really did this.  On the MIPS, you would have to
have a stack frame that is more than 32K (64K for 88k), in order to
open up the possibility that the spill would generate more than 1
instruction (or unload the stack/frame pointer).  If a compiler was
worried about this, it could rearrange the stack, such that the large
arrays would get allocated at the high end of the stack, and group the
spills closer to the stack/frame pointer.
--
Michael Meissner	email: meissner@osf.org		phone: 617-621-8861
Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142

You are in a twisty little passage of standards, all conflicting.