
#13104: runRW# ruins join points -------------------------------------+------------------------------------- Reporter: lukemaurer | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 8.1 Keywords: JoinPoints | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- Found this while poking around in the example for #12781. Suppose we have code like this: {{{ let loop :: Int -> State# RealWorld -> (State# RealWorld, Int) loop n = ... loop (n+1) {- tail call -} ... in runRW# @ 'PtrRepLifted @ Int (loop 0) }}} We would love for `loop` to be a join point, but it can't be because it's invoked in the argument to `runRW#`. In this situation, we're often rescued by Float In, which we might hope to give us this: {{{ runRW# @ 'PtrRepLifted @ Int ( let loop :: Int -> State# RealWorld -> (State# RealWorld, Int) loop n s = ... loop (n+1) s' {- tail call -} ... in loop 0 ) }}} Two problems: 1. Float In won't do this to begin with because `loop 0` is a partial application. 2. It's still not eligible to be a join point, again because `loop 0` is a partial application. What we would //like// to see is this: {{{ runRW# @ 'PtrRepLifted @ Int ( \s0 -> let loop :: Int -> State# RealWorld -> (State# RealWorld, Int) loop n s = ... loop (n+1) s' {- tail call -} ... in loop 0 s0 ) }}} Now we're golden. But someone has to have thought to eta-expand the argument to `runRW#` first. (Float In should then float `loop` into the lambda because, due to the state hack, the lambda is considered one-shot.) Perhaps the simplifier should //always// eta-expand the argument to `runRW#`? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/13104 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler