Commit 120c4c72 authored by simonpj@microsoft.com's avatar simonpj@microsoft.com
Browse files

Do not do SpecConstr on functions that unconditionally diverge

There is no point in specialising a function that is guaranteed to
diverge, and doing so screwed up arity stuff.  

See Note [Do not specialise diverging functions].
parent b74af13a
...@@ -365,6 +365,19 @@ specialising the loops arising from stream fusion, for example in NDP where ...@@ -365,6 +365,19 @@ specialising the loops arising from stream fusion, for example in NDP where
we were getting literally hundreds of (mostly unused) specialisations of we were getting literally hundreds of (mostly unused) specialisations of
a local function. a local function.
Note [Do not specialise diverging functions]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Specialising a function that just diverges is a waste of code.
Furthermore, it broke GHC (simpl014) thus:
{-# STR Sb #-}
f = \x. case x of (a,b) -> f x
If we specialise f we get
f = \x. case x of (a,b) -> fspec a b
But fspec doesn't have decent strictnes info. As it happened,
(f x) :: IO t, so the state hack applied and we eta expanded fspec,
and hence f. But now f's strictness is less than its arity, which
breaks an invariant.
----------------------------------------------------- -----------------------------------------------------
Stuff not yet handled Stuff not yet handled
----------------------------------------------------- -----------------------------------------------------
...@@ -1006,8 +1019,9 @@ specialise ...@@ -1006,8 +1019,9 @@ specialise
specialise env bind_calls (fn, arg_bndrs, body, arg_occs) specialise env bind_calls (fn, arg_bndrs, body, arg_occs)
spec_info@(SI specs spec_count mb_unspec) spec_info@(SI specs spec_count mb_unspec)
| notNull arg_bndrs, -- Only specialise functions | not (isBottomingId fn) -- Note [Do not specialise diverging functions]
Just all_calls <- lookupVarEnv bind_calls fn , notNull arg_bndrs -- Only specialise functions
, Just all_calls <- lookupVarEnv bind_calls fn
= do { (boring_call, pats) <- callsToPats env specs arg_occs all_calls = do { (boring_call, pats) <- callsToPats env specs arg_occs all_calls
-- ; pprTrace "specialise" (vcat [ppr fn <+> ppr arg_occs, -- ; pprTrace "specialise" (vcat [ppr fn <+> ppr arg_occs,
-- text "calls" <+> ppr all_calls, -- text "calls" <+> ppr all_calls,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment