summaryrefslogtreecommitdiff
path: root/compiler/deSugar
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2014-05-08 11:21:16 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2014-08-28 11:14:05 +0100
commit6e0f6ededff6018a88dd390590a09f79842ccfa5 (patch)
treec2d4f46cfdcf8b236d9ac751c48f0b0ccced7503 /compiler/deSugar
parente9cd1d5e9d6f0e019d6433a3c7dd9585b3f7ae6b (diff)
downloadhaskell-6e0f6ededff6018a88dd390590a09f79842ccfa5.tar.gz
Refactor unfoldings
There are two main refactorings here 1. Move the uf_arity field out of CoreUnfolding into UnfWhen It's a lot tidier there. If I've got this right, no behaviour should change. 2. Define specUnfolding and use it in DsBinds and Specialise a) commons-up some shared code b) makes sure that Specialise correctly specialises DFun unfoldings (which it didn't before) The two got put together because both ended up interacting in the specialiser. They cause zero difference to nofib.
Diffstat (limited to 'compiler/deSugar')
-rw-r--r--compiler/deSugar/DsBinds.lhs24
1 files changed, 10 insertions, 14 deletions
diff --git a/compiler/deSugar/DsBinds.lhs b/compiler/deSugar/DsBinds.lhs
index 172d19b9ac..18b6856ec1 100644
--- a/compiler/deSugar/DsBinds.lhs
+++ b/compiler/deSugar/DsBinds.lhs
@@ -463,8 +463,11 @@ dsSpec mb_poly_rhs (L loc (SpecPrag poly_id spec_co spec_inl))
Right (rule_bndrs, _fn, args) -> do
{ dflags <- getDynFlags
- ; let spec_unf = specUnfolding bndrs args (realIdUnfolding poly_id)
- spec_id = mkLocalId spec_name spec_ty
+ ; let fn_unf = realIdUnfolding poly_id
+ unf_fvs = stableUnfoldingVars fn_unf `orElse` emptyVarSet
+ in_scope = mkInScopeSet (unf_fvs `unionVarSet` exprsFreeVars args)
+ spec_unf = specUnfolding dflags (mkEmptySubst in_scope) bndrs args fn_unf
+ spec_id = mkLocalId spec_name spec_ty
`setInlinePragma` inl_prag
`setIdUnfolding` spec_unf
rule = mkRule False {- Not auto -} is_local_id
@@ -474,11 +477,14 @@ dsSpec mb_poly_rhs (L loc (SpecPrag poly_id spec_co spec_inl))
(mkVarApps (Var spec_id) bndrs)
; spec_rhs <- dsHsWrapper spec_co poly_rhs
- ; let spec_pair = makeCorePair dflags spec_id False (dictArity bndrs) spec_rhs
; when (isInlinePragma id_inl && wopt Opt_WarnPointlessPragmas dflags)
(warnDs (specOnInline poly_name))
- ; return (Just (unitOL spec_pair, rule))
+
+ ; return (Just (unitOL (spec_id, spec_rhs), rule))
+ -- NB: do *not* use makeCorePair on (spec_id,spec_rhs), because
+ -- makeCorePair overwrites the unfolding, which we have
+ -- just created using specUnfolding
} } }
where
is_local_id = isJust mb_poly_rhs
@@ -515,16 +521,6 @@ dsSpec mb_poly_rhs (L loc (SpecPrag poly_id spec_co spec_inl))
| otherwise = spec_prag_act -- Specified by user
-specUnfolding :: [Var] -> [CoreExpr] -> Unfolding -> Unfolding
-specUnfolding new_bndrs new_args df@(DFunUnfolding { df_bndrs = bndrs, df_args = args })
- = ASSERT2( equalLength new_args bndrs, ppr df $$ ppr new_args $$ ppr new_bndrs )
- df { df_bndrs = new_bndrs, df_args = map (substExpr (text "specUnfolding") subst) args }
- where
- subst = mkOpenSubst (mkInScopeSet fvs) (bndrs `zip` new_args)
- fvs = (exprsFreeVars args `delVarSetList` bndrs) `extendVarSetList` new_bndrs
-
-specUnfolding _ _ _ = noUnfolding
-
specOnInline :: Name -> MsgDoc
specOnInline f = ptext (sLit "SPECIALISE pragma on INLINE function probably won't fire:")
<+> quotes (ppr f)