Unsafe foreign calls (fat machine instructions) do not kill all registers.
authorEdward Z. Yang <ezyang@mit.edu>
Mon, 11 Apr 2011 10:54:34 +0000 (11:54 +0100)
committerEdward Z. Yang <ezyang@mit.edu>
Mon, 11 Apr 2011 15:56:05 +0000 (16:56 +0100)
commit8a0ab97b1daefb57b53d6cf08a01bd597d09e32d
treebe3fdf7f5c4182d1db6f67a7fcf924c70b3211ee
parent1fb38442d3a55ac92795aa6c5ed4df82011df724
Unsafe foreign calls (fat machine instructions) do not kill all registers.

The new code generator was doing some interesting spilling across
unsafe foreign calls:

     _c1ao::I32 = Hp - 4;
     I32[Sp - 20] = _c1ao::I32;
     foreign "ccall"
       newCAF((BaseReg, PtrHint), (R1, PtrHint))[_unsafe_call_];
     _c1ao::I32 = I32[Sp - 20];

This is fairly unnecessary, and resulted from over-conservative
liveness analysis from CmmLive.  We can see that the old code
generator only saved volatile registers across unsafe foreign calls:
spilling variables was done by saveVolatileVarsAndRegs, which was
only performed for ordinary calls.

This commit removes the excess kill from the liveness analysis, as well
as the *redundant* excess kill from spilling-and-reloading, and adds a
note to CmmNode to this effect.  The only registers we need to kill
are the ones that the foreign call assigns to, just like any other
machine instruction.

Signed-off-by: Edward Z. Yang <ezyang@mit.edu>
compiler/cmm/CmmLive.hs
compiler/cmm/CmmNode.hs
compiler/cmm/CmmSpillReload.hs