Switch more uniqFromSupply+splitUniqSupply's to takeUniqFromSupply
[ghc-hetmet.git] / compiler / coreSyn / CoreArity.lhs
index f0f6c75..1abfebe 100644 (file)
@@ -63,44 +63,16 @@ And in any case it seems more robust to have exprArity be a bit more intelligent
 But note that  (\x y z -> f x y z)
 should have arity 3, regardless of f's arity.
 
-Note [exprArity invariant]
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-exprArity has the following invariant:
-
-  * If typeArity (exprType e) = n,
-    then manifestArity (etaExpand e n) = n
-    That is, etaExpand can always expand as much as typeArity says
-    So the case analysis in etaExpand and in typeArity must match
-  * exprArity e <= typeArity (exprType e)      
-
-  * Hence if (exprArity e) = n, then manifestArity (etaExpand e n) = n
-
-    That is, if exprArity says "the arity is n" then etaExpand really 
-    can get "n" manifest lambdas to the top.
-
-Why is this important?  Because 
-  - In TidyPgm we use exprArity to fix the *final arity* of 
-    each top-level Id, and in
-  - In CorePrep we use etaExpand on each rhs, so that the visible lambdas
-    actually match that arity, which in turn means
-    that the StgRhs has the right number of lambdas
-
-An alternative would be to do the eta-expansion in TidyPgm, at least
-for top-level bindings, in which case we would not need the trim_arity
-in exprArity.  That is a less local change, so I'm going to leave it for today!
-
-
 \begin{code}
 manifestArity :: CoreExpr -> Arity
 -- ^ manifestArity sees how many leading value lambdas there are
-manifestArity (Lam v e) | isId v    = 1 + manifestArity e
-                       | otherwise = manifestArity e
-manifestArity (Note _ e)           = manifestArity e
-manifestArity (Cast e _)            = manifestArity e
-manifestArity _                     = 0
+manifestArity (Lam v e) | isId v       = 1 + manifestArity e
+                       | otherwise     = manifestArity e
+manifestArity (Note n e) | notSccNote n        = manifestArity e
+manifestArity (Cast e _)               = manifestArity e
+manifestArity _                        = 0
 
+---------------
 exprArity :: CoreExpr -> Arity
 -- ^ An approximate, fast, version of 'exprEtaExpandArity'
 exprArity e = go e
@@ -108,7 +80,7 @@ exprArity e = go e
     go (Var v)                            = idArity v
     go (Lam x e) | isId x         = go e + 1
                 | otherwise       = go e
-    go (Note _ e)                  = go e
+    go (Note n e) | notSccNote n   = go e
     go (Cast e co)                 = go e `min` length (typeArity (snd (coercionKind co)))
                                                -- Note [exprArity invariant]
     go (App e (Type _))            = go e
@@ -117,6 +89,7 @@ exprArity e = go e
     go _                          = 0
 
 
+---------------
 typeArity :: Type -> [OneShot]
 -- How many value arrows are visible in the type?
 -- We look through foralls, and newtypes
@@ -140,8 +113,46 @@ typeArity ty
 
   | otherwise
   = []
+
+---------------
+exprBotStrictness_maybe :: CoreExpr -> Maybe (Arity, StrictSig)
+-- A cheap and cheerful function that identifies bottoming functions
+-- and gives them a suitable strictness signatures.  It's used during
+-- float-out
+exprBotStrictness_maybe e
+  = case getBotArity (arityType False e) of
+       Nothing -> Nothing
+       Just ar -> Just (ar, mkStrictSig (mkTopDmdType (replicate ar topDmd) BotRes))
 \end{code}
 
+Note [exprArity invariant]
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+exprArity has the following invariant:
+
+  * If typeArity (exprType e) = n,
+    then manifestArity (etaExpand e n) = n
+    That is, etaExpand can always expand as much as typeArity says
+    So the case analysis in etaExpand and in typeArity must match
+  * exprArity e <= typeArity (exprType e)      
+
+  * Hence if (exprArity e) = n, then manifestArity (etaExpand e n) = n
+
+    That is, if exprArity says "the arity is n" then etaExpand really 
+    can get "n" manifest lambdas to the top.
+
+Why is this important?  Because 
+  - In TidyPgm we use exprArity to fix the *final arity* of 
+    each top-level Id, and in
+  - In CorePrep we use etaExpand on each rhs, so that the visible lambdas
+    actually match that arity, which in turn means
+    that the StgRhs has the right number of lambdas
+
+An alternative would be to do the eta-expansion in TidyPgm, at least
+for top-level bindings, in which case we would not need the trim_arity
+in exprArity.  That is a less local change, so I'm going to leave it for today!
+
 Note [Newtype classes and eta expansion]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 We have to be careful when eta-expanding through newtypes.  In general
@@ -204,21 +215,10 @@ When we come to an application we check that the arg is trivial.
 
 %************************************************************************
 %*                                                                     *
-          Eta expansion
+          Computing the "arity" of an expression
 %*                                                                     *
 %************************************************************************
 
-\begin{code}
-exprBotStrictness_maybe :: CoreExpr -> Maybe (Arity, StrictSig)
--- A cheap and cheerful function that identifies bottoming functions
--- and gives them a suitable strictness signatures.  It's used during
--- float-out
-exprBotStrictness_maybe e
-  = case getBotArity (arityType False e) of
-       Nothing -> Nothing
-       Just ar -> Just (ar, mkStrictSig (mkTopDmdType (replicate ar topDmd) BotRes))
-\end{code}     
-
 Note [Definition of arity]
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 The "arity" of an expression 'e' is n if
@@ -554,7 +554,8 @@ arityType dicts_cheap (Let b e)
        -- See Note [Dictionary-like types] in TcType.lhs for why we use
        -- isDictLikeTy here rather than isDictTy
 
-arityType dicts_cheap (Note _ e) = arityType dicts_cheap e
+arityType dicts_cheap (Note n e) 
+  | notSccNote n                 = arityType dicts_cheap e
 arityType dicts_cheap (Cast e _) = arityType dicts_cheap e
 arityType _           _          = vanillaArityType
 \end{code}
@@ -566,10 +567,41 @@ arityType _           _          = vanillaArityType
 %*                                                                     *
 %************************************************************************
 
-IMPORTANT NOTE: The eta expander is careful not to introduce "crap".
-In particular, given a CoreExpr satisfying the 'CpeRhs' invariant (in
-CorePrep), it returns a CoreExpr satisfying the same invariant. See
-Note [Eta expansion and the CorePrep invariants] in CorePrep.
+We go for:
+   f = \x1..xn -> N  ==>   f = \x1..xn y1..ym -> N y1..ym
+                                (n >= 0)
+
+where (in both cases) 
+
+       * The xi can include type variables
+
+       * The yi are all value variables
+
+       * N is a NORMAL FORM (i.e. no redexes anywhere)
+         wanting a suitable number of extra args.
+
+The biggest reason for doing this is for cases like
+
+       f = \x -> case x of
+                   True  -> \y -> e1
+                   False -> \y -> e2
+
+Here we want to get the lambdas together.  A good exmaple is the nofib
+program fibheaps, which gets 25% more allocation if you don't do this
+eta-expansion.
+
+We may have to sandwich some coerces between the lambdas
+to make the types work.   exprEtaExpandArity looks through coerces
+when computing arity; and etaExpand adds the coerces as necessary when
+actually computing the expansion.
+
+
+Note [No crap in eta-expanded code]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+The eta expander is careful not to introduce "crap".  In particular,
+given a CoreExpr satisfying the 'CpeRhs' invariant (in CorePrep), it
+returns a CoreExpr satisfying the same invariant. See Note [Eta
+expansion and the CorePrep invariants] in CorePrep.
 
 This means the eta-expander has to do a bit of on-the-fly
 simplification but it's not too hard.  The alernative, of relying on