[GHC] #14622: Add `joinState# :: State# s -> State# s -> State# s` primop

GHC ghc-devs at haskell.org
Thu Dec 28 16:59:55 UTC 2017


#14622: Add `joinState# :: State# s -> State# s -> State# s` primop
-------------------------------------+-------------------------------------
           Reporter:  reinerp        |             Owner:  (none)
               Type:  feature        |            Status:  new
  request                            |
           Priority:  normal         |         Milestone:
          Component:  Compiler       |           Version:  8.2.2
           Keywords:                 |  Operating System:  Unknown/Multiple
       Architecture:                 |   Type of failure:  None/Unknown
  Unknown/Multiple                   |
          Test Case:                 |        Blocked By:
           Blocking:                 |   Related Tickets:
Differential Rev(s):                 |         Wiki Page:
-------------------------------------+-------------------------------------
 The state threading in GHC.Prim requires the user to impose a total order
 on memory reads and writes within a state thread. In some cases, this
 total order constrains the compiler more than necessary. For example, if
 the programmer knows that `addr1` and `addr2` don't alias, then they might
 like to express that the two writes in the following can be reordered
 relative to each other:

 {{{#!hs
 doTwoWrites :: Addr# -> Addr# -> State# s -> State# s
 doTwoWrites addr1 addr2 s =
   writeWord8OffAddr# addr2 0# 123## (
   writeWord8OffAddr# addr1 0# 234## s)
 }}}

 If we had the following primop, then we could express that flexibility in
 reordering:

 {{{#!hs
 -- | Produces a state that has a data dependency on the two input
 -- states. Generates no machine code.
 joinState# :: State# s -> State# s -> State# s
 }}}

 That is, we'd write the above function as:

 {{{#!hs
 doTwoWrites :: Addr# -> Addr# -> State# s -> State# s
 doTwoWrites addr1 addr2 s =
   joinState#
     (writeWord8OffAddr# addr2 0# 123## s)
     (writeWord8OffAddr# addr1 0# 234## s)
 }}}

 This would give us fine-grained fork/join of `State#` threads, with fork
 provided by copying of `State# s` objects and join provided by
 `joinState#`. This lets the programmer express arbitrary DAGs of
 dependencies between memory operations, rather than just linear chains of
 dependencies.

 Low priority; I don't have a specific use case with a missed optimization.

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


More information about the ghc-tickets mailing list