[GHC] #16098: More efficient implementation plan for primops with continuation arguments

GHC ghc-devs at haskell.org
Thu Dec 27 06:44:36 UTC 2018


#16098: More efficient implementation plan for primops with continuation arguments
-------------------------------------+-------------------------------------
           Reporter:  osa1           |             Owner:  (none)
               Type:  task           |            Status:  new
           Priority:  normal         |         Milestone:
          Component:  Compiler       |           Version:  8.6.3
           Keywords:                 |  Operating System:  Unknown/Multiple
       Architecture:                 |   Type of failure:  None/Unknown
  Unknown/Multiple                   |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:  #14375
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 Original idea from #14375: in some of the primops that take continuation
 arguments we currently have to allocate the continuations but sometimes we
 immediately enter one of these continuations. One example is

 {{{
 maskAsyncExceptions# :: (State# RealWorld -> (# State# RealWorld, a #))
                      -> (State# RealWorld -> (# State# RealWorld, a #))
 }}}

 which is implemented as

 {{{
 stg_maskAsyncExceptionszh /* explicit stack */
 {
     /* Args: R1 :: IO a */
     STK_CHK_P_LL (WDS(1)/* worst case */, stg_maskAsyncExceptionszh, R1);

     if ((TO_W_(StgTSO_flags(CurrentTSO)) & TSO_BLOCKEX) == 0) {
         /* avoid growing the stack unnecessarily */
         if (Sp(0) == stg_maskAsyncExceptionszh_ret_info) {
             Sp_adj(1);
         } else {
             Sp_adj(-1);
             Sp(0) = stg_unmaskAsyncExceptionszh_ret_info;
         }
     } else {
         if ((TO_W_(StgTSO_flags(CurrentTSO)) & TSO_INTERRUPTIBLE) == 0) {
             Sp_adj(-1);
             Sp(0) = stg_maskUninterruptiblezh_ret_info;
         }
     }

     StgTSO_flags(CurrentTSO) = %lobits32(
         TO_W_(StgTSO_flags(CurrentTSO)) | TSO_BLOCKEX |
 TSO_INTERRUPTIBLE);

     TICK_UNKNOWN_CALL();
     TICK_SLOW_CALL_fast_v();
     jump stg_ap_v_fast [R1];
 }
 }}}

 Here we want to have better compilation for `maskAsyncExceptions# c` where
 we
 don't allocate for `c`.

 There are some ideas in ticket:14375#comment:1, but the idea was later
 superseded by ticket:14375#comment:7, which suggests

 - Making continuation arguments explicit in STG so that an
 `maskAsyncExceptions#`
   would now look like this in STG: `maskAsyncExceptions# (\s. e)`.
 - Then in the code gen generating stack frame push (plus `StgTSO` updates)
 and
   then emitting code for `e` directly. (I don't understand if `bind s:=s2`
 part
   in the comment is necessary?)

 Some primops take more than one callback, e.g.

 {{{
 catch# :: (State# RealWorld -> (# State# RealWorld, a #) )
        -> (b -> State# RealWorld -> (# State# RealWorld, a #) )
        -> State# RealWorld
        -> (# State# RealWorld, a #)
 }}}

 Which is implemented as

 {{{
 stg_catchzh ( P_ io,      /* :: IO a */
               P_ handler  /* :: Exception -> IO a */ )
 {
     W_ exceptions_blocked;

     STK_CHK_GEN();

     exceptions_blocked =
         TO_W_(StgTSO_flags(CurrentTSO)) & (TSO_BLOCKEX |
 TSO_INTERRUPTIBLE);
     TICK_CATCHF_PUSHED();

     /* Apply R1 to the realworld token */
     TICK_UNKNOWN_CALL();
     TICK_SLOW_CALL_fast_v();

     jump stg_ap_v_fast
         (CATCH_FRAME_FIELDS(,,stg_catch_frame_info, CCCS, 0,
                             exceptions_blocked, handler))
         (io);
 }
 }}}

 For this example ticket:14375#comment:7 suggest using join points for the
 `handler` argument (and using the non-allocating callback scheme for the
 `io`
 argument), but I suggest we focus on more efficient implementation of
 callbacks
 that are immediately entered, and worry about the join point stuff in
 another
 ticket.

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


More information about the ghc-tickets mailing list