[project @ 2001-02-20 15:44:26 by simonpj]
[ghc-hetmet.git] / ghc / compiler / coreSyn / CoreUtils.lhs
index b5e7133..f0649d1 100644 (file)
@@ -14,11 +14,13 @@ module CoreUtils (
        exprType, coreAltsType, 
        exprIsBottom, exprIsDupable, exprIsTrivial, exprIsCheap, 
        exprIsValue,exprOkForSpeculation, exprIsBig, 
-       exprIsConApp_maybe,
+       exprIsConApp_maybe, exprIsAtom,
        idAppIsBottom, idAppIsCheap,
+       exprArity,
 
        -- Expr transformation
-       etaReduceExpr, exprEtaExpandArity,
+       etaReduce, etaExpand,
+       exprArity, exprEtaExpandArity, 
 
        -- Size
        coreBindsSize,
@@ -48,19 +50,19 @@ import PrimOp               ( primOpOkForSpeculation, primOpIsCheap,
                          primOpIsDupable )
 import Id              ( Id, idType, idFlavour, idStrictness, idLBVarInfo, 
                          mkWildId, idArity, idName, idUnfolding, idInfo, 
-                         isDataConId_maybe, isPrimOpId_maybe
+                         isDataConId_maybe, isPrimOpId_maybe, mkSysLocal, hasNoBinding
                        )
 import IdInfo          ( LBVarInfo(..),  
                          IdFlavour(..),
                          megaSeqIdInfo )
 import Demand          ( appIsBottom )
-import Type            ( Type, mkFunTy, mkForAllTy,
-                         splitFunTy_maybe, tyVarsOfType, tyVarsOfTypes,
-                         applyTys, isUnLiftedType, seqType,
-                          mkUTy
+import Type            ( Type, mkFunTy, mkForAllTy, splitFunTy_maybe, 
+                         applyTys, isUnLiftedType, seqType, mkUTy, mkTyVarTy,
+                         splitForAllTy_maybe, splitNewType_maybe
                        )
 import TysWiredIn      ( boolTy, trueDataCon, falseDataCon )
 import CostCentre      ( CostCentre )
+import UniqSupply      ( UniqSupply, splitUniqSupply, uniqFromSupply )
 import Maybes          ( maybeToBool )
 import Outputable
 import TysPrim         ( alphaTy )     -- Debugging only
@@ -154,9 +156,26 @@ Drop trivial InlineMe's.  This is somewhat important, because if we have an unfo
 that looks like        (Note InlineMe (Var v)), the InlineMe doesn't go away because it may
 not be *applied* to anything.
 
+We don't use exprIsTrivial here, though, because we sometimes generate worker/wrapper
+bindings like
+       fw = ...
+       f  = inline_me (coerce t fw)
+As usual, the inline_me prevents the worker from getting inlined back into the wrapper.
+We want the split, so that the coerces can cancel at the call site.  
+
+However, we can get left with tiresome type applications.  Notably, consider
+       f = /\ a -> let t = e in (t, w)
+Then lifting the let out of the big lambda gives
+       t' = /\a -> e
+       f = /\ a -> let t = inline_me (t' a) in (t, w)
+The inline_me is to stop the simplifier inlining t' right back
+into t's RHS.  In the next phase we'll substitute for t (since
+its rhs is trivial) and *then* we could get rid of the inline_me.
+But it hardly seems worth it, so I don't bother.
+
 \begin{code}
-mkInlineMe e | exprIsTrivial e = e
-            | otherwise       = Note InlineMe e
+mkInlineMe (Var v) = Var v
+mkInlineMe e      = Note InlineMe e
 \end{code}
 
 
@@ -239,7 +258,17 @@ mkIfThenElse guard then_expr else_expr
 
 \begin{code}
 exprIsTrivial (Var v)
-  | Just op <- isPrimOpId_maybe v      = primOpIsDupable op
+  | hasNoBinding v                    = idArity v == 0
+       -- WAS: | Just op <- isPrimOpId_maybe v      = primOpIsDupable op
+       -- The idea here is that a constructor worker, like $wJust, is
+       -- really short for (\x -> $wJust x), becuase $wJust has no binding.
+       -- So it should be treated like a lambda.
+       -- Ditto unsaturated primops.
+       -- This came up when dealing with eta expansion/reduction for
+       --      x = $wJust
+       -- Here we want to eta-expand.  This looks like an optimisation,
+       -- but it's important (albeit tiresome) that CoreSat doesn't increase 
+       -- anything's arity
   | otherwise                          = True
 exprIsTrivial (Type _)                = True
 exprIsTrivial (Lit lit)               = True
@@ -247,6 +276,15 @@ exprIsTrivial (App e arg)                 = isTypeArg arg && exprIsTrivial e
 exprIsTrivial (Note _ e)              = exprIsTrivial e
 exprIsTrivial (Lam b body) | isTyVar b = exprIsTrivial body
 exprIsTrivial other                   = False
+
+exprIsAtom :: CoreExpr -> Bool
+-- Used to decide whether to let-binding an STG argument
+-- when compiling to ILX => type applications are not allowed
+exprIsAtom (Var v)    = True   -- primOpIsDupable?
+exprIsAtom (Lit lit)  = True
+exprIsAtom (Type ty)  = True
+exprIsAtom (Note _ e) = exprIsAtom e
+exprIsAtom other      = False
 \end{code}
 
 
@@ -492,7 +530,22 @@ exprIsConApp_maybe expr
                Just unf -> exprIsConApp_maybe unf
 
     analyse other = Nothing
-\end{code} 
+\end{code}
+
+The arity of an expression (in the code-generator sense, i.e. the
+number of lambdas at the beginning).
+
+\begin{code}
+exprArity :: CoreExpr -> Int
+exprArity (Lam x e)
+  | isTyVar x = exprArity e
+  | otherwise = 1 + exprArity e
+exprArity (Note _ e)
+  -- Ignore coercions.   Top level sccs are removed by the final 
+  -- profiling pass, so we ignore those too.
+  = exprArity e
+exprArity _ = 0
+\end{code}
 
 
 %************************************************************************
@@ -501,7 +554,7 @@ exprIsConApp_maybe expr
 %*                                                                     *
 %************************************************************************
 
-@etaReduceExpr@ trys an eta reduction at the top level of a Core Expr.
+@etaReduce@ trys an eta reduction at the top level of a Core Expr.
 
 e.g.   \ x y -> f x y  ===>  f
 
@@ -510,11 +563,11 @@ The idea is that lambdas are often quite helpful: they indicate
 head normal forms, so we don't want to chuck them away lightly.
 
 \begin{code}
-etaReduceExpr :: CoreExpr -> CoreExpr
+etaReduce :: CoreExpr -> CoreExpr
                -- ToDo: we should really check that we don't turn a non-bottom
                -- lambda into a bottom variable.  Sigh
 
-etaReduceExpr expr@(Lam bndr body)
+etaReduce expr@(Lam bndr body)
   = check (reverse binders) body
   where
     (binders, body) = collectBinders expr
@@ -531,13 +584,18 @@ etaReduceExpr expr@(Lam bndr body)
 
     check _ _ = expr   -- Bale out
 
-etaReduceExpr expr = expr              -- The common case
+etaReduce expr = expr          -- The common case
 \end{code}
        
 
 \begin{code}
-exprEtaExpandArity :: CoreExpr -> Int  -- The number of args the thing can be applied to
-                                       -- without doing much work
+exprEtaExpandArity :: CoreExpr -> (Int, Bool)  
+-- The Int is number of value args the thing can be 
+--     applied to without doing much work
+-- The Bool is True iff there are enough explicit value lambdas
+--     at the top to make this arity apparent
+--     (but ignore it when arity==0)
+
 -- This is used when eta expanding
 --     e  ==>  \xy -> e x y
 --
@@ -548,20 +606,27 @@ exprEtaExpandArity :: CoreExpr -> Int     -- The number of args the thing can be ap
 -- Hence "generous" arity
 
 exprEtaExpandArity e
-  = go e `max` 0       -- Never go -ve!
+  = go 0 e
   where
-    go (Var v)                                 = idArity v
-    go (App f (Type _))                        = go f
-    go (App f a)  | exprIsCheap a      = go f - 1
-    go (Lam x e)  | isId x             = go e + 1
-                 | otherwise           = go e
-    go (Note n e) | ok_note n          = go e
-    go (Case scrut _ alts)
-      | exprIsCheap scrut              = min_zero [go rhs | (_,_,rhs) <- alts]
-    go (Let b e)       
-      | all exprIsCheap (rhssOfBind b) = go e
+    go ar (Lam x e)  | isId x          = go (ar+1) e
+                    | otherwise        = go ar e
+    go ar (Note n e) | ok_note n       = go ar e
+    go ar other                        = (ar + ar', ar' == 0)
+                                       where
+                                         ar' = go1 other `max` 0
+
+    go1 (Var v)                                = idArity v
+    go1 (Lam x e)  | isId x            = go1 e + 1
+                  | otherwise          = go1 e
+    go1 (Note n e) | ok_note n         = go1 e
+    go1 (App f (Type _))                       = go1 f
+    go1 (App f a)  | exprIsCheap a     = go1 f - 1
+    go1 (Case scrut _ alts)
+      | exprIsCheap scrut              = min_zero [go1 rhs | (_,_,rhs) <- alts]
+    go1 (Let b e)      
+      | all exprIsCheap (rhssOfBind b) = go1 e
     
-    go other                           = 0
+    go1 other                          = 0
     
     ok_note (Coerce _ _) = True
     ok_note InlineCall   = True
@@ -587,6 +652,55 @@ min_zero (x:xs) = go x xs
 \end{code}
 
 
+\begin{code}
+etaExpand :: Int               -- Add this number of value args
+         -> UniqSupply
+         -> CoreExpr -> Type   -- Expression and its type
+         -> CoreExpr
+-- (etaExpand n us e ty) returns an expression with 
+-- the same meaning as 'e', but with arity 'n'.  
+
+-- Given e' = etaExpand n us e ty
+-- We should have
+--     ty = exprType e = exprType e'
+--
+-- etaExpand deals with for-alls and coerces. For example:
+--             etaExpand 1 E
+-- where  E :: forall a. T
+--       newtype T = MkT (A -> B)
+--
+-- would return
+--     (/\b. coerce T (\y::A -> (coerce (A->B) (E b) y)
+
+-- (case x of { I# x -> /\ a -> coerce T E)
+
+etaExpand n us expr ty
+  | n == 0     -- Saturated, so nothing to do
+  = expr
+
+  | otherwise  -- An unsaturated constructor or primop; eta expand it
+  = case splitForAllTy_maybe ty of { 
+         Just (tv,ty') -> Lam tv (etaExpand n us (App expr (Type (mkTyVarTy tv))) ty')
+
+       ; Nothing ->
+  
+       case splitFunTy_maybe ty of {
+         Just (arg_ty, res_ty) -> Lam arg1 (etaExpand (n-1) us2 (App expr (Var arg1)) res_ty)
+                               where
+                                  arg1       = mkSysLocal SLIT("eta") uniq arg_ty
+                                  (us1, us2) = splitUniqSupply us
+                                  uniq       = uniqFromSupply us1 
+                                  
+       ; Nothing -> 
+  
+       case splitNewType_maybe ty of {
+         Just ty' -> mkCoerce ty ty' (etaExpand n us (mkCoerce ty' ty expr) ty') ;
+  
+         Nothing -> pprTrace "Bad eta expand" (ppr expr $$ ppr ty) expr
+       }}}
+\end{code}
+
+
 %************************************************************************
 %*                                                                     *
 \subsection{Equality}