discussion of X86 floating point on comp.lang.ml
Matthew Fluet
fluet@CS.Cornell.EDU
Thu, 19 Oct 2000 17:46:59 -0400 (EDT)
> All in all looks good, but dynamic counts might be more useful.
I'll look into getting some dynamic counts. I looked through the assembly
a little, and two of the blocks in which there was spilling of floating
point registers were in blocks that ended up with the labels "sphere_0"
and "intersect_0". I suspect they have fairly high dynamic counts.
> I'm curious by your comment that you spill oldest floats first. I would have
> thought that you would spill those that are next used farthest in the future.
> I.e., ignoring loops and branches, you know the future.
You're seeing artefacts of my development process. In the original
register allocation phase (i.e., without calculating or using any liveness
information), I never looked into the future. Instead, I assigned each
entry in the register file a weight that was increased on its use or def
and decreased if it was completely unused for a function. Things with low
weights hadn't been used in a long time, so conceivably had become dead
and were candidates for kicking out of the register file.
With liveness, I am doing a pass up the block and have parts of that
future information. To an extent, this is complicated by the difference
between temporaries (like psuedo-regs) which can be dead in a block and
not need to be committed to memory and non-temporaries (like MLton stack
slots, heap values) which can go dead in a block and do need to be
committed to memory. I added in one slight hack to approximate the fact
that uses "far" in the future shouldn't be kept in registers -- I cap the
length of the future use/def list at 16 entries. This means that a use
followed by a use more than 16 entries down the line looks like a last use
and will be removed from the register file.
That might be a little unclear, and it is a bit of a hack. The real issue
was on large programs, the initGlobals block is just so huge and I ended
up with a future list of ~ 1500 because each individual globalpointer was
used exactly once.
In any case, Henry's comment is well founded, particularly since I've got
this information in almost useable form. I'll look into making better
decisions about what stays and goes in the register allocation.