[GHC] #14068: Loopification using join points

GHC ghc-devs at haskell.org
Wed Feb 21 15:56:11 UTC 2018


#14068: Loopification using join points
-------------------------------------+-------------------------------------
        Reporter:  nomeata           |                Owner:  nomeata
            Type:  bug               |               Status:  new
        Priority:  normal            |            Milestone:
       Component:  Compiler          |              Version:  8.0.1
      Resolution:                    |             Keywords:  JoinPoints
Operating System:  Unknown/Multiple  |         Architecture:
                                     |  Unknown/Multiple
 Type of failure:  None/Unknown      |            Test Case:
      Blocked By:                    |             Blocking:
 Related Tickets:  #13966 #14067     |  Differential Rev(s):  Phab:D3811
  #14827                             |
       Wiki Page:                    |
-------------------------------------+-------------------------------------

Comment (by nomeata):

 Is it possible that this happens (using the examle from the top of
 `SpecConstr`)?

 Before:
 {{{
 Rec {
 drop n xs = case xs of
   []     -> []
   (y:ys) -> case n of
      I# n# -> case n# of
        0 -> []
        _ -> drop (I# (n# -# 1#)) xs
 }
 }}}
 here SpecConstr kicks, creating a rule and specializing, yielding the nice

 {{{
 Rec {
 $sdrop n# xs = case xs of
   []     -> []
   (y:ys) -> case n# of
        0 -> []
        _ -> $sdrop (n# -# 1#) xs
 }
 RULE drop (I# n) xs = $sdrop n xs
 }}}

 But with loopification, we start with
 {{{
 drop n xs =
   joinrec j n xs = case xs of
     []     -> []
     (y:ys) -> case n of
        I# n# -> case n# of
          0 -> []
          _ -> call j (I# (n# -# 1#)) xs
   in j n xs
 }}}
 (yay!), and now we liberate case can do its work, and we get (I think)
 {{{
 drop n xs =
   case xs of
     []     -> []
     (y:ys) -> case n of
        I# n# ->
          joinrec j n xs = case xs of
             []     -> []
             (y:ys) -> case n# of
                0 -> []
                _ -> call j (I# (n# -# 1#)) xs
          in j n (y:ys)
 }}}
 but now spec-constr no longer kicks! It’s comments say (abbreviated):

 > So we look for a self-recursive function AND at a recursive call,
 > one or more parameters is an explicit constructor application AND
 > that same parameter is scrutinised by a case somewhere in the RHS
 > of the function

 This used to be true for the original, recursive `drop`, but not for the
 loopified: `drop` is not recursive, `j` does not scrutinize the parameter.

 So we don’t create a specialization for `drop`, causing extra allocations
 when there are calls to `drop (I$ n)` somewhere.

 Now in some cases this might be ok, namely when we can inline `drop`
 (which is no longer recursive). But `drop` contains this big `joinrec`, so
 it’s too big to be inlined?

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


More information about the ghc-tickets mailing list