[GHC] #14223: Casts get in the way of join points

GHC ghc-devs at haskell.org
Tue Sep 12 22:01:12 UTC 2017


#14223: Casts get in the way of join points
-------------------------------------+-------------------------------------
        Reporter:  nomeata           |                Owner:  (none)
            Type:  task              |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.2.1
      Resolution:                    |             Keywords:  JoinPoints
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:                    |  Differential Rev(s):
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by nomeata):

 Oh, wait, does loopification solve this? Let’s see.

 We start with
 {{{
 letrec
   go :: [Bool] -> All
   go  = \ (ds :: [Bool]) ->
     case ds of {
       [] -> GHC.Types.True `cast` (… :: Coercible Bool All)
       : y ys -> if y then go ys
                      else GHC.Types.False `cast` (… :: Coercible Bool All)
 in (go xs) `cast` (… :: Coercible All Bool)
 }}}
 and loopify:
 {{{
 let
   go :: [Bool] -> All
   go  = \ (ds :: [Bool]) ->
     joinrec
       j :: [Bool] -> All
       j = \ds ->
         case ds of {
           [] -> GHC.Types.True `cast` (… :: Coercible Bool All)
           : y ys -> if y then jump j ys
                          else GHC.Types.False `cast` (… :: Coercible Bool
 All)
     in jump j xs
 in (go xs) `cast` (… :: Coercible All Bool)
 }}}
 What now? Maybe `go` will inline:
 {{{
 (    joinrec
       j :: [Bool] -> All
       j = \ds ->
         case ds of {
           [] -> GHC.Types.True `cast` (… :: Coercible Bool All)
           : y ys -> if y then jump j ys
                          else GHC.Types.False `cast` (… :: Coercible Bool
 All)
     in jump j xs
 ) `cast` (… :: Coercible All Bool)
 }}}
 And surely there is a “`cast`-of-`joinrec`” transformation, right? Then
 we’ll get
 {{{
     joinrec
       j :: [Bool] -> All
       j = \ds ->
         case ds of {
           [] -> GHC.Types.True `cast` (… :: Coercible Bool All) `cast` (…
 :: Coercible All Bool)
           : y ys -> if y then jump j ys
                          else GHC.Types.False `cast` (… :: Coercible Bool
 All) `cast` (… :: Coercible All Bool)
     in jump j xs
 }}}
 and we can cancel the casts and get
 {{{
     joinrec
       j :: [Bool] -> All
       j = \ds ->
         case ds of {
           [] -> GHC.Types.True
           : y ys -> if y then call j ys
                          else GHC.Types.False
     in jump j xs
 }}}
 and all is well. So maybe #14068 is enough.

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


More information about the ghc-tickets mailing list