summaryrefslogtreecommitdiff
path: root/compiler/iface
diff options
context:
space:
mode:
authorLuke Maurer <maurerl@cs.uoregon.edu>2017-02-01 11:56:01 -0500
committerDavid Feuer <David.Feuer@gmail.com>2017-02-01 13:44:52 -0500
commit8d5cf8bf584fd4849917c29d82dcf46ee75dd035 (patch)
tree9d1b012562fd7ec1d1089b7d87e061884ba71f1c /compiler/iface
parent4fa439e3ee2822f893bd364a6cbfe410a0c1e29f (diff)
downloadhaskell-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.hs36
-rw-r--r--compiler/iface/TcIface.hs13
-rw-r--r--compiler/iface/ToIface.hs5
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