4221 on new codegen

Simon Marlow marlowsd at gmail.com
Wed Feb 2 10:25:20 CET 2011


On 02/02/2011 00:29, Edward Z. Yang wrote:
> More Hoopling later, I see this segment in the rewrite function:
>
>        middle m@(CmmUnsafeForeignCall _ fs _) live = return $
>          case map spill  (filter (flip elemRegSet (on_stack live)) fs) ++
>               map reload (uniqSetToList (kill fs (in_regs live))) of
>            []      ->  Nothing
>            reloads ->  Just $ mkMiddles (m : reloads)
>
> So, if I understand this code correctly, it unilaterally reloads
> /anything/ in the registers according to the analysis at that point.
>
> Well, I could see that resulting in the behavior below.
>
> It's not so clear to me what the correct rewrite is; according to
> Marlow's comment on IRC, we ought not to be spilling/reloading foreign
> calls yet, so maybe the whole bit should get excised? Otherwise, it seems
> to me that transfer function needs to accomodate unsafe foreign
> functions.

Right, there's no need to spill/reload anything around an *unsafe* 
foreign call in the Cmm code generator.  The NCG's register allocator 
will do any necessary spilling/reloading around foreign calls.

Cheers,
	Simon



> Cheers,
> Edward
>
> Excerpts from Simon Marlow's message of Tue Feb 01 03:44:41 -0500 2011:
>> On 01/02/2011 00:01, Edward Z. Yang wrote:
>>> Current theory:
>>>
>>>     c1jj:
>>>         _s1ep::I32 = I32[(slot<_s1ep::I32>   + 4)];   // CmmAssign
>>>         _s1fP::I32 = I32[(slot<_s1fP::I32>   + 4)];   // CmmAssign
>>>         // outOfLine should follow:
>>>         _s1eq::F64 = F64[_s1fP::I32 + 3];   // CmmAssign
>>>         I32[(young<c1jh>   + 4)] = c1jh;   // CmmStore
>>>         foreign call "ccall" arg hints:  [PtrHint,]  result hints:  [] call_fn_blob(...) returns to c1jh args: ([_s1ep::I32,
>>>                                                                                                                  _s1eq::F64]) ress: ([_s1ev::F64]) with update frame 4;   // CmmForeignCall
>>>     c1jh:
>>>         _s1ev::F64 = F64[(slot<_s1ev::F64>   + 8)];   // CmmAssign
>>>         // emitReturn: Sequel: Assign
>>>         _s1ev::F64 = _s1ev::F64;   // CmmAssign
>>>         F64[(slot<_s1ev::F64>   + 8)] = _s1ev::F64;   // CmmStore
>>>         goto u1Ak;   // CmmBranch
>>>
>>> Note the line immediately after c1jh, where we reload the ostensibly
>>> spilled _s1ev back into a register. Except that it was never spilled
>>> there in the first place, and we just clobbered the real value. Oops.
>>>
>>> Is this interpretation correct?
>>
>> It sounds plausible, but I really have no idea.  The code generator does
>> not have to generate spill/reloads around foreign calls, the register
>> allocator will do that.
>>
>> Cheers,
>>      Simon




More information about the Glasgow-haskell-users mailing list