On 15.04.2014 12:54, Jeff Law wrote:
On 04/14/14 18:58, pshor...@dataworx.com.au wrote:
I'm porting to a 16 bit micro and noticed that when optimization is
enabled (function.c:2101), most (non-volatile, non-addressed) stack
variables are copied into virtual registers. I assume this is so the
register allocator will attempt to allocate them to physical
registers.
Unfortunately, in those cases where there are a lot of stack
parameters
and those virtual registers are spilled to local variables a lot of
code
and stack space is wasted copying an image of the stack parameters
into
a spill slot instead of the overflow dropping back to use the original
stack parameter space.
For example ...
add sp,-20
st r0,[sp]
st r1,[sp+2]
ld r0,[sp+24]
st r0,[sp+4]
ld r2,[sp+26]
st r2,[sp+6]
ld r3,[sp+28]
st r3,[sp+8]
ld r0,[sp+30]
st r0,[sp+10]
I'm aware that there are cases where the stack parameters are
unsuitable
as spill locations (due to partial values, alignment etc) but the
majority of cases I see such as the example above the stack parameters
are viable spill locations. In the case illustrated above the required
stack space has blown out significantly and there are a host of
redundant load/store operations that could be eliminated if the spill
were to the stack parameters.
For small micros such as MSP430 & friends and many of the Renasis
MCUs,
some of which only have 2K or ram on board, this could be a real
issue.
Although I reproduced the same behaviour on i386 using a stock
compiler,
I was wondering if there was something missing in my port that
prevents
spilling to stack locations, or a cleanup pass that addresses this
issue ?
The only way to know for sure is to dig through the debugging dumps to
understand why any given pseudo register was not assigned to a hard
register.
If you're doing a new port, I would also recommend taking the time to
investigate and possibly tune it to utilize LRA. It's been our
experience that LRA, after tuning, produces superior code when
compared to the old reload pass.
Jeff
Thanks Jeff,
The register spilling isn't the problem, this is a situation where there
are more variables than registers so spilling is expected.
The problem is that spilled vregs that correspond to stack parameters...
that already have appropriate memory available, are spilling to a new
local spill variable.
I've just built the trunk msp430 and h8300 ports and they both spill
correctly to the stack parameters when compiling the same test code...
so I'll hunt through those ports so see if I can find something I've
missed.
I have ported to the LRA, however on this register poor CPU it seems to
fail to allocate registers in cases where the old reload pass works just
fine... maybe my LRA port also has problems :-)
Cheers, Paul.