
#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