summaryrefslogtreecommitdiff
path: root/compiler/simplCore/SimplUtils.hs
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/simplCore/SimplUtils.hs
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/simplCore/SimplUtils.hs')
-rw-r--r--compiler/simplCore/SimplUtils.hs29
1 files changed, 21 insertions, 8 deletions
diff --git a/compiler/simplCore/SimplUtils.hs b/compiler/simplCore/SimplUtils.hs
index 3b48924ed1..2e985c5713 100644
--- a/compiler/simplCore/SimplUtils.hs
+++ b/compiler/simplCore/SimplUtils.hs
@@ -19,7 +19,7 @@ module SimplUtils (
-- The continuation type
SimplCont(..), DupFlag(..),
isSimplified,
- contIsDupable, contResultType, contHoleType,
+ contIsDupable, contResultType, contHoleType, applyContToJoinType,
contIsTrivial, contArgs,
countArgs,
mkBoringStop, mkRhsStop, mkLazyArgStop, contIsRhsOrArg,
@@ -47,6 +47,7 @@ import CoreArity
import CoreUnfold
import Name
import Id
+import IdInfo
import Var
import Demand
import SimplMonad
@@ -361,6 +362,10 @@ contHoleType (ApplyToVal { sc_arg = e, sc_env = se, sc_dup = dup, sc_cont = k })
contHoleType (Select { sc_dup = d, sc_bndr = b, sc_env = se })
= perhapsSubstTy d se (idType b)
+applyContToJoinType :: JoinArity -> SimplCont -> OutType -> OutType
+applyContToJoinType ar cont ty
+ = setJoinResTy ar (contResultType cont) ty
+
-------------------
countArgs :: SimplCont -> Int
-- Count all arguments, including types, coercions, and other values
@@ -629,7 +634,7 @@ interestingArg env e = go env 0 e
-- n is # value args to which the expression is applied
go env n (Var v)
| SimplEnv { seIdSubst = ids, seInScope = in_scope } <- env
- = case lookupVarEnv ids v of
+ = case snd <$> lookupVarEnv ids v of
Nothing -> go_var n (refineFromInScope in_scope v)
Just (DoneId v') -> go_var n (refineFromInScope in_scope v')
Just (DoneEx e) -> go (zapSubstEnv env) n e
@@ -1054,7 +1059,9 @@ preInlineUnconditionally dflags env top_lvl bndr rhs
| isCoVar bndr = False -- Note [Do not inline CoVars unconditionally]
| otherwise = case idOccInfo bndr of
IAmDead -> True -- Happens in ((\x.1) v)
- OneOcc in_lam True int_cxt -> try_once in_lam int_cxt
+ occ@OneOcc { occ_one_br = True }
+ -> try_once (occ_in_lam occ)
+ (occ_int_cxt occ)
_ -> False
where
mode = getMode env
@@ -1180,7 +1187,8 @@ postInlineUnconditionally dflags env top_lvl bndr occ_info rhs unfolding
-- False -> case x of ...
-- This is very important in practice; e.g. wheel-seive1 doubles
-- in allocation if you miss this out
- OneOcc in_lam _one_br int_cxt -- OneOcc => no code-duplication issue
+ OneOcc { occ_in_lam = in_lam, occ_int_cxt = int_cxt }
+ -- OneOcc => no code-duplication issue
-> smallEnoughToInline dflags unfolding -- Small enough to dup
-- ToDo: consider discount on smallEnoughToInline if int_cxt is true
--
@@ -1398,9 +1406,10 @@ because the latter is not well-kinded.
************************************************************************
-}
-tryEtaExpandRhs :: SimplEnv -> OutId -> OutExpr -> SimplM (Arity, OutExpr)
+tryEtaExpandRhs :: SimplEnv -> RecFlag -> OutId -> OutExpr
+ -> SimplM (Arity, OutExpr)
-- See Note [Eta-expanding at let bindings]
-tryEtaExpandRhs env bndr rhs
+tryEtaExpandRhs env is_rec bndr rhs
= do { dflags <- getDynFlags
; (new_arity, new_rhs) <- try_expand dflags
@@ -1419,8 +1428,12 @@ tryEtaExpandRhs env bndr rhs
new_arity2 = idCallArity bndr
new_arity = max new_arity1 new_arity2
, new_arity > old_arity -- And the current manifest arity isn't enough
- = do { tick (EtaExpansion bndr)
- ; return (new_arity, etaExpand new_arity rhs) }
+ = if is_rec == Recursive && isJoinId bndr
+ then WARN(True, text "Can't eta-expand recursive join point:" <+>
+ ppr bndr)
+ return (old_arity, rhs)
+ else do { tick (EtaExpansion bndr)
+ ; return (new_arity, etaExpand new_arity rhs) }
| otherwise
= return (old_arity, rhs)