[GHC] #11778: Preserve demandInfo on lambda binders in the simpifier
GHC
ghc-devs at haskell.org
Thu Mar 31 09:28:40 UTC 2016
#11778: Preserve demandInfo on lambda binders in the simpifier
-------------------------------------+-------------------------------------
Reporter: nomeata | Owner:
Type: task | Status: new
Priority: normal | Milestone:
Component: Compiler | Version: 8.1
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:
-------------------------------------+-------------------------------------
In ticket:11731#comment:30, simonpj writes:
> Meanwhile, there is a separate issue in ticket:11731#comment:20. It
seems that for any un-saturated lambda, we nuke (a) the `occInfo` on the
binders (fair enough; the next run of the occurrence analyser will
regenerate it), and (b) the `demandInfo` on the binders. The reasoning is
explained in comment:20.
>
> But (b) is permanent; it won't be re-generated until the next run of the
demand analyser. And, worse, it applies to function definitions
> {{{
> f = \xy . x+y
> }}}
> Here `x` and `y` will be marked as strictly demanded, but that info will
get stripped after the first run of the simplifier. Try it on
> {{{
> f :: [Int] -> [Int] -> Int
> f x y = head x + head y
> }}}
> After the demand analyser we have
> {{{
> f = \ (x_amY [Dmd=<S,1*U>] :: [Int]) (y_amZ [Dmd=<S,1*U>] :: [Int]) ->
...
> }}}
> but after the first run of the simplifier we get
> {{{
> f = \ (x_amY :: [Int]) (y_amZ :: [Int]) -> ...
> }}}
> (`f` itself still has a strictness signature that says it is strict in
both args.)
>
> Does this matter? Well, the main reason is that if `f` is inlined, we'd
like to get a strict `let`. And now we won't.
>
> Happily I think it is easily fixed. The key thing is that when doing
beta-reduction, which effectively does `(\x.e) b` into `let x=b in e`, we
must kill off x's demand/occurrence info if the lambda is not saturated.
>
> So, idea, in `Simplify.hs`:
>
> * Give an extra `Bool` to `simplLam` indictating "saturated".
>
> * Compute (value) saturation in the `simplExprF1 env expr@(Lam {})
cont`, before calling `simpLam`, but do no zapping.
>
> * In `simplLam`, in the beta-reduction case,
> {{{
> simplLam env (bndr:bndrs) body (ApplyToVal { sc_arg = arg, sc_env =
arg_se
> , sc_cont = cont })
> = do { tick (BetaReduction bndr)
> ; simplNonRecE env' (zap_unfolding bndr) (arg, arg_se) (bndrs,
body) cont }
> }}}
> do the binder-zapping right there, if "saturated" is not true. (That
neatly puts it with the unfolding-zapping code.)
>
> Now the non-beta-reduced lambdas won't be zapped, which is right.
>
> Would you like to try that?
--
Ticket URL: <http://ghc.haskell.org/trac/ghc/ticket/11778>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
More information about the ghc-tickets
mailing list