summaryrefslogtreecommitdiff
path: root/compiler/GHC/Core/Unfold.hs
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2020-03-31 17:17:56 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2020-04-01 10:22:10 +0100
commit7052d7c7ce3418db9e66ad6ff31e80b2a2c724bb (patch)
tree407119957b7941f23e6b6e2764ad512ddd70f19d /compiler/GHC/Core/Unfold.hs
parent0002db1bf436cbd32f97b659a52b1eee4e8b21db (diff)
downloadhaskell-wip/T17966.tar.gz
Major improvements to the specialiserwip/T17966
This patch is joint work of Alexis King and Simon PJ. It does some significant refactoring of the type-class specialiser. Main highlights: * We can specialise functions with types like f :: Eq a => a -> Ord b => b => blah where the classes aren't all at the front (#16473). Here we can correctly specialise 'f' based on a call like f @Int @Bool dEqInt x dOrdBool This change really happened in an earlier patch commit 2d0cf6252957b8980d89481ecd0b79891da4b14b Author: Sandy Maguire <sandy@sandymaguire.me> Date: Thu May 16 12:12:10 2019 -0400 work that this new patch builds directly on that work, and refactors it a bit. * We can specialise functions with implicit parameters (#17930) g :: (?foo :: Bool, Show a) => a -> String Previously we could not, but now they behave just like a non-class argument as in 'f' above. * We can specialise under-saturated calls, where some (but not all of the dictionary arguments are provided (#17966). For example, we can specialise the above 'f' based on a call map (f @Int dEqInt) xs even though we don't (and can't) give Ord dictionary. This may sound exotic, but #17966 is a program from the wild, and showed significant perf loss for functions like f, if you need saturation of all dictionaries. * We fix a buglet in which a floated dictionary had a bogus demand (#17810), by using zapIdDemandInfo in the NonRec case of specBind. * A tiny side benefit: we can drop dead arguments to specialised functions; see Note [Drop dead args from specialisations] * Fixed a bug in deciding what dictionaries are "interesting"; see Note [Keep the old dictionaries interesting] This is all achieved by by building on Sandy Macguire's work in defining SpecArg, which mkCallUDs uses to describe the arguments of the call. Main changes: * Main work is in specHeader, which marched down the [InBndr] from the function definition and the [SpecArg] from the call site, together. * specCalls no longer has an arity check; the entire mechanism now handles unders-saturated calls fine. * mkCallUDs decides on an argument-by-argument basis whether to specialise a particular dictionary argument; this is new. See mk_spec_arg in mkCallUDs. It looks as if there are many more lines of code, but I think that all the extra lines are comments!
Diffstat (limited to 'compiler/GHC/Core/Unfold.hs')
-rw-r--r--compiler/GHC/Core/Unfold.hs11
1 files changed, 6 insertions, 5 deletions
diff --git a/compiler/GHC/Core/Unfold.hs b/compiler/GHC/Core/Unfold.hs
index 411a954428..4b7cb80daf 100644
--- a/compiler/GHC/Core/Unfold.hs
+++ b/compiler/GHC/Core/Unfold.hs
@@ -172,15 +172,16 @@ mkInlinableUnfolding dflags expr
where
expr' = simpleOptExpr dflags expr
-specUnfolding :: DynFlags -> [Var] -> (CoreExpr -> CoreExpr) -> Arity
+specUnfolding :: DynFlags -> Id -> [Var] -> (CoreExpr -> CoreExpr) -> Arity
-> Unfolding -> Unfolding
-- See Note [Specialising unfoldings]
-- specUnfolding spec_bndrs spec_app arity_decrease unf
-- = \spec_bndrs. spec_app( unf )
--
-specUnfolding dflags spec_bndrs spec_app arity_decrease
+specUnfolding dflags fn spec_bndrs spec_app arity_decrease
df@(DFunUnfolding { df_bndrs = old_bndrs, df_con = con, df_args = args })
- = ASSERT2( arity_decrease == count isId old_bndrs - count isId spec_bndrs, ppr df )
+ = ASSERT2( arity_decrease == count isId old_bndrs - count isId spec_bndrs
+ , ppr df $$ ppr spec_bndrs $$ ppr (spec_app (Var fn)) $$ ppr arity_decrease )
mkDFunUnfolding spec_bndrs con (map spec_arg args)
-- There is a hard-to-check assumption here that the spec_app has
-- enough applications to exactly saturate the old_bndrs
@@ -194,7 +195,7 @@ specUnfolding dflags spec_bndrs spec_app arity_decrease
-- The beta-redexes created by spec_app will be
-- simplified away by simplOptExpr
-specUnfolding dflags spec_bndrs spec_app arity_decrease
+specUnfolding dflags _ spec_bndrs spec_app arity_decrease
(CoreUnfolding { uf_src = src, uf_tmpl = tmpl
, uf_is_top = top_lvl
, uf_guidance = old_guidance })
@@ -211,7 +212,7 @@ specUnfolding dflags spec_bndrs spec_app arity_decrease
in mkCoreUnfolding src top_lvl new_tmpl guidance
-specUnfolding _ _ _ _ _ = noUnfolding
+specUnfolding _ _ _ _ _ _ = noUnfolding
{- Note [Specialising unfoldings]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~