[GHC] #8335: Create more specialized entries to GC

GHC ghc-devs at haskell.org
Fri Sep 20 13:24:55 CEST 2013


#8335: Create more specialized entries to GC
------------------------------------+-------------------------------------
       Reporter:  jstolarek         |             Owner:
           Type:  task              |            Status:  new
       Priority:  normal            |         Milestone:
      Component:  Compiler          |           Version:  7.7
       Keywords:                    |  Operating System:  Unknown/Multiple
   Architecture:  Unknown/Multiple  |   Type of failure:  None/Unknown
     Difficulty:  Unknown           |         Test Case:
     Blocked By:                    |          Blocking:
Related Tickets:                    |
------------------------------------+-------------------------------------
 Consider this Cmm code (taken from #8326):

 {{{
     {offset
        cFd: // stack check
            if ((Sp + -16) < SpLim) goto cFr; else goto cFs;
        cFr: // not enough place on the stack, call GC
            R2 = R2;
            R1 = A.f_closure;
            call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8;
        cFs: // scrutinize (x ># 0#)
            _sEU::I64 = R2;
            _sEV::I64 = %MO_S_Gt_W64(R2, 0);
            if (_sEV::I64 != 1) goto cFg; else goto cFo;
        cFg: // False branch
            Hp = Hp + 16;
            if (Hp > HpLim) goto cFy; else goto cFx;
        cFy: // not enough heap, call GC
            HpAlloc = 16;
            I64[Sp - 16] = cFf;
            R1 = _sEV::I64;
            I64[Sp - 8] = _sEU::I64;
            Sp = Sp - 16;
            call stg_gc_unbx_r1(R1) returns to cFf, args: 8, res: 8, upd:
 8;
        cFf: // re-do the False branch
            _sEU::I64 = I64[Sp + 8];
            Sp = Sp + 16;
            _sEV::I64 = R1;
            goto cFg;
        cFx: // RHS of False branch
            I64[Hp - 8] = GHC.Types.I#_con_info;
            I64[Hp] = -_sEU::I64;
            R1 = Hp - 7;
            call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
        cFo: // True branch
            Hp = Hp + 16;
            if (Hp > HpLim) goto cFv; else goto cFu;
        cFv: // not enough heap, call GC
            HpAlloc = 16;
            I64[Sp - 16] = cFn;
            R1 = _sEV::I64;
            I64[Sp - 8] = _sEU::I64;
            Sp = Sp - 16;
            call stg_gc_unbx_r1(R1) returns to cFn, args: 8, res: 8, upd:
 8;
        cFn: // re-do the True branch
            _sEU::I64 = I64[Sp + 8];
            Sp = Sp + 16;
            _sEV::I64 = R1;
            goto cFo;
        cFu: // RHS of True branch
            I64[Hp - 8] = GHC.Types.I#_con_info;
            I64[Hp] = _sEU::I64;
            R1 = Hp - 7;
            call (P64[Sp])(R1) args: 8, res: 0, upd: 8;
      }
 }}}

 We perform two different calls to garbage collection here. Calling GC
 after making initial stack check obviously can't use any stack, so we pass
 parameter to GC in regsiters:

 {{{
 R2 = R2;
 R1 = A.f_closure;
 call (stg_gc_fun)(R2, R1) args: 8, res: 0, upd: 8;
 }}}

 But in the calls that are made later on inside the function we do put some
 parameters on the stack, thus increasing stack usage:

 {{{
 cFv: // not enough heap, call GC
     HpAlloc = 16;
     I64[Sp - 16] = cFn;
     R1 = _sEV::I64;
     I64[Sp - 8] = _sEU::I64;
     Sp = Sp - 16;
     call stg_gc_unbx_r1(R1) returns to cFn, args: 8, res: 8, upd: 8;
 }}}
 If we had more specialized entries to GC that would allow us to pass
 parameters in registers (or in some fixed memory location associated with
 TCO?) then this function would not require any stack at all. Note that
 there is a separate issue here - `_sEV` variable is in fact dead and
 should be eliminated (see #8327).

-- 
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/8335>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler



More information about the ghc-tickets mailing list