diff options
author | Luke Maurer <maurerl@cs.uoregon.edu> | 2017-02-01 11:56:01 -0500 |
---|---|---|
committer | David Feuer <David.Feuer@gmail.com> | 2017-02-01 13:44:52 -0500 |
commit | 8d5cf8bf584fd4849917c29d82dcf46ee75dd035 (patch) | |
tree | 9d1b012562fd7ec1d1089b7d87e061884ba71f1c /compiler/iface | |
parent | 4fa439e3ee2822f893bd364a6cbfe410a0c1e29f (diff) | |
download | haskell-8d5cf8bf584fd4849917c29d82dcf46ee75dd035.tar.gz |
Join points
This major patch implements Join Points, as described in
https://ghc.haskell.org/trac/ghc/wiki/SequentCore. You have
to read that page, and especially the paper it links to, to
understand what's going on; but it is very cool.
It's Luke Maurer's work, but done in close collaboration with Simon PJ.
This Phab is a squash-merge of wip/join-points branch of
http://github.com/lukemaurer/ghc. There are many, many interdependent
changes.
Reviewers: goldfire, mpickering, bgamari, simonmar, dfeuer, austin
Subscribers: simonpj, dfeuer, mpickering, Mikolaj, thomie
Differential Revision: https://phabricator.haskell.org/D2853
Diffstat (limited to 'compiler/iface')
-rw-r--r-- | compiler/iface/IfaceSyn.hs | 36 | ||||
-rw-r--r-- | compiler/iface/TcIface.hs | 13 | ||||
-rw-r--r-- | compiler/iface/ToIface.hs | 5 |
3 files changed, 42 insertions, 12 deletions
diff --git a/compiler/iface/IfaceSyn.hs b/compiler/iface/IfaceSyn.hs index d4dd51e1b7..7740977263 100644 --- a/compiler/iface/IfaceSyn.hs +++ b/compiler/iface/IfaceSyn.hs @@ -10,7 +10,7 @@ module IfaceSyn ( IfaceDecl(..), IfaceFamTyConFlav(..), IfaceClassOp(..), IfaceAT(..), IfaceConDecl(..), IfaceConDecls(..), IfaceEqSpec, - IfaceExpr(..), IfaceAlt, IfaceLetBndr(..), + IfaceExpr(..), IfaceAlt, IfaceLetBndr(..), IfaceJoinInfo(..), IfaceBinding(..), IfaceConAlt(..), IfaceIdInfo(..), IfaceIdDetails(..), IfaceUnfolding(..), IfaceInfoItem(..), IfaceRule(..), IfaceAnnotation(..), IfaceAnnTarget, @@ -502,7 +502,10 @@ data IfaceBinding -- IfaceLetBndr is like IfaceIdBndr, but has IdInfo too -- It's used for *non-top-level* let/rec binders -- See Note [IdInfo on nested let-bindings] -data IfaceLetBndr = IfLetBndr IfLclName IfaceType IfaceIdInfo +data IfaceLetBndr = IfLetBndr IfLclName IfaceType IfaceIdInfo IfaceJoinInfo + +data IfaceJoinInfo = IfaceNotJoinPoint + | IfaceJoinPoint JoinArity {- Note [Empty case alternatives] @@ -1158,8 +1161,8 @@ ppr_con_bs :: IfaceConAlt -> [IfLclName] -> SDoc ppr_con_bs con bs = ppr con <+> hsep (map ppr bs) ppr_bind :: (IfaceLetBndr, IfaceExpr) -> SDoc -ppr_bind (IfLetBndr b ty info, rhs) - = sep [hang (ppr b <+> dcolon <+> ppr ty) 2 (ppr info), +ppr_bind (IfLetBndr b ty info ji, rhs) + = sep [hang (ppr b <+> dcolon <+> ppr ty) 2 (ppr ji <+> ppr info), equals <+> pprIfaceExpr noParens rhs] ------------------ @@ -1207,6 +1210,10 @@ instance Outputable IfaceInfoItem where ppr HsNoCafRefs = text "HasNoCafRefs" ppr HsLevity = text "Never levity-polymorphic" +instance Outputable IfaceJoinInfo where + ppr IfaceNotJoinPoint = empty + ppr (IfaceJoinPoint ar) = angleBrackets (text "join" <+> ppr ar) + instance Outputable IfaceUnfolding where ppr (IfCompulsory e) = text "<compulsory>" <+> parens (ppr e) ppr (IfCoreUnfold s e) = (if s @@ -1407,8 +1414,8 @@ freeNamesIfLetBndr :: IfaceLetBndr -> NameSet -- Remember IfaceLetBndr is used only for *nested* bindings -- The IdInfo can contain an unfolding (in the case of -- local INLINE pragmas), so look there too -freeNamesIfLetBndr (IfLetBndr _name ty info) = freeNamesIfType ty - &&& freeNamesIfIdInfo info +freeNamesIfLetBndr (IfLetBndr _name ty info _ji) = freeNamesIfType ty + &&& freeNamesIfIdInfo info freeNamesIfTvBndr :: IfaceTvBndr -> NameSet freeNamesIfTvBndr (_fs,k) = freeNamesIfKind k @@ -2075,14 +2082,27 @@ instance Binary IfaceBinding where _ -> do { ac <- get bh; return (IfaceRec ac) } instance Binary IfaceLetBndr where - put_ bh (IfLetBndr a b c) = do + put_ bh (IfLetBndr a b c d) = do put_ bh a put_ bh b put_ bh c + put_ bh d get bh = do a <- get bh b <- get bh c <- get bh - return (IfLetBndr a b c) + d <- get bh + return (IfLetBndr a b c d) + +instance Binary IfaceJoinInfo where + put_ bh IfaceNotJoinPoint = putByte bh 0 + put_ bh (IfaceJoinPoint ar) = do + putByte bh 1 + put_ bh ar + get bh = do + h <- getByte bh + case h of + 0 -> return IfaceNotJoinPoint + _ -> liftM IfaceJoinPoint $ get bh instance Binary IfaceTyConParent where put_ bh IfNoParent = putByte bh 0 diff --git a/compiler/iface/TcIface.hs b/compiler/iface/TcIface.hs index e08a3d71f6..f6a4f41965 100644 --- a/compiler/iface/TcIface.hs +++ b/compiler/iface/TcIface.hs @@ -1367,12 +1367,13 @@ tcIfaceExpr (IfaceCase scrut case_bndr alts) = do alts' <- mapM (tcIfaceAlt scrut' tc_app) alts return (Case scrut' case_bndr' (coreAltsType alts') alts') -tcIfaceExpr (IfaceLet (IfaceNonRec (IfLetBndr fs ty info) rhs) body) +tcIfaceExpr (IfaceLet (IfaceNonRec (IfLetBndr fs ty info ji) rhs) body) = do { name <- newIfaceName (mkVarOccFS fs) ; ty' <- tcIfaceType ty ; id_info <- tcIdInfo False {- Don't ignore prags; we are inside one! -} name ty' info ; let id = mkLocalIdOrCoVarWithInfo name ty' id_info + `asJoinId_maybe` tcJoinInfo ji ; rhs' <- tcIfaceExpr rhs ; body' <- extendIfaceIdEnv [id] (tcIfaceExpr body) ; return (Let (NonRec id rhs') body') } @@ -1384,11 +1385,11 @@ tcIfaceExpr (IfaceLet (IfaceRec pairs) body) ; body' <- tcIfaceExpr body ; return (Let (Rec pairs') body') } } where - tc_rec_bndr (IfLetBndr fs ty _) + tc_rec_bndr (IfLetBndr fs ty _ ji) = do { name <- newIfaceName (mkVarOccFS fs) ; ty' <- tcIfaceType ty - ; return (mkLocalIdOrCoVar name ty') } - tc_pair (IfLetBndr _ _ info, rhs) id + ; return (mkLocalIdOrCoVar name ty' `asJoinId_maybe` tcJoinInfo ji) } + tc_pair (IfLetBndr _ _ info _, rhs) id = do { rhs' <- tcIfaceExpr rhs ; id_info <- tcIdInfo False {- Don't ignore prags; we are inside one! -} (idName id) (idType id) info @@ -1509,6 +1510,10 @@ tcIdInfo ignore_prags name ty info = do | otherwise = info ; return (info1 `setUnfoldingInfo` unf) } +tcJoinInfo :: IfaceJoinInfo -> Maybe JoinArity +tcJoinInfo (IfaceJoinPoint ar) = Just ar +tcJoinInfo IfaceNotJoinPoint = Nothing + tcUnfolding :: Name -> Type -> IdInfo -> IfaceUnfolding -> IfL Unfolding tcUnfolding name _ info (IfCoreUnfold stable if_expr) = do { dflags <- getDynFlags diff --git a/compiler/iface/ToIface.hs b/compiler/iface/ToIface.hs index 696d0ffc0f..37d41f4393 100644 --- a/compiler/iface/ToIface.hs +++ b/compiler/iface/ToIface.hs @@ -325,6 +325,7 @@ toIfaceLetBndr :: Id -> IfaceLetBndr toIfaceLetBndr id = IfLetBndr (occNameFS (getOccName id)) (toIfaceType (idType id)) (toIfaceIdInfo (idInfo id)) + (toIfaceJoinInfo (isJoinId_maybe id)) -- Put into the interface file any IdInfo that CoreTidy.tidyLetBndr -- has left on the Id. See Note [IdInfo on nested let-bindings] in IfaceSyn @@ -382,6 +383,10 @@ toIfaceIdInfo id_info levity_hsinfo | isNeverLevPolyIdInfo id_info = Just HsLevity | otherwise = Nothing +toIfaceJoinInfo :: Maybe JoinArity -> IfaceJoinInfo +toIfaceJoinInfo (Just ar) = IfaceJoinPoint ar +toIfaceJoinInfo Nothing = IfaceNotJoinPoint + -------------------------- toIfUnfolding :: Bool -> Unfolding -> Maybe IfaceInfoItem toIfUnfolding lb (CoreUnfolding { uf_tmpl = rhs |