Reorganisation of the source tree
[ghc-hetmet.git] / compiler / simplCore / SAT.lhs
diff --git a/compiler/simplCore/SAT.lhs b/compiler/simplCore/SAT.lhs
new file mode 100644 (file)
index 0000000..81f3c4c
--- /dev/null
@@ -0,0 +1,214 @@
+%
+% (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
+%
+%************************************************************************
+%*                                                                     *
+\section[SAT]{Static Argument Transformation pass}
+%*                                                                     *
+%************************************************************************
+
+96/03: We aren't using the static-argument transformation right now.
+
+May be seen as removing invariants from loops:
+Arguments of recursive functions that do not change in recursive
+calls are removed from the recursion, which is done locally
+and only passes the arguments which effectively change.
+
+Example:
+map = /\ ab -> \f -> \xs -> case xs of
+                            []    -> []
+                            (a:b) -> f a : map f b
+
+as map is recursively called with the same argument f (unmodified)
+we transform it to
+
+map = /\ ab -> \f -> \xs -> let map' ys = case ys of
+                                          []    -> []
+                                          (a:b) -> f a : map' b
+                           in map' xs
+
+Notice that for a compiler that uses lambda lifting this is
+useless as map' will be transformed back to what map was.
+
+We could possibly do the same for big lambdas, but we don't as
+they will eventually be removed in later stages of the compiler,
+therefore there is no penalty in keeping them.
+
+Experimental Evidence: Heap: +/- 7%
+                      Instrs: Always improves for 2 or more Static Args.
+
+\begin{code}
+module SAT ( doStaticArgs ) where
+
+#include "HsVersions.h"
+
+import Panic   ( panic )
+
+doStaticArgs = panic "SAT.doStaticArgs (ToDo)"
+
+{- LATER: to end of file:
+
+import SATMonad
+import Util
+\end{code}
+
+\begin{code}
+doStaticArgs :: [CoreBind] -> UniqSupply -> [CoreBind]
+
+doStaticArgs binds
+  = do {
+       showPass "Static argument";
+       let { binds' = initSAT (mapSAT sat_bind binds) };
+       endPass "Static argument" 
+               False           -- No specific flag for dumping SAT
+               binds'
+    }
+  where
+    sat_bind (NonRec binder expr)
+      = emptyEnvSAT  `thenSAT_`
+       satExpr expr `thenSAT` (\ expr' ->
+       returnSAT (NonRec binder expr') )
+    sat_bind (Rec [(binder,rhs)])
+      = emptyEnvSAT                      `thenSAT_`
+       insSAEnv binder (getArgLists rhs) `thenSAT_`
+       satExpr rhs                       `thenSAT` (\ rhs' ->
+       saTransform binder rhs')
+    sat_bind (Rec pairs)
+      = emptyEnvSAT            `thenSAT_`
+       mapSAT satExpr rhss     `thenSAT` \ rhss' ->
+       returnSAT (Rec (zipEqual "doStaticArgs" binders rhss'))
+      where
+       (binders, rhss) = unzip pairs
+\end{code}
+
+\begin{code}
+satAtom (VarArg v)
+  = updSAEnv (Just (v,([],[]))) `thenSAT_`
+    returnSAT ()
+
+satAtom _ = returnSAT ()
+\end{code}
+
+\begin{code}
+satExpr :: CoreExpr -> SatM CoreExpr
+
+satExpr var@(Var v)
+  = updSAEnv (Just (v,([],[]))) `thenSAT_`
+    returnSAT var
+
+satExpr lit@(Lit _) = returnSAT lit
+
+satExpr e@(Prim prim ty args)
+  = mapSAT satAtom args            `thenSAT_`
+    returnSAT e
+
+satExpr (Lam binders body)
+  = satExpr body               `thenSAT` \ body' ->
+    returnSAT (Lam binders body')
+
+satExpr (CoTyLam tyvar body)
+  = satExpr body          `thenSAT` (\ body' ->
+    returnSAT (CoTyLam tyvar body') )
+
+satExpr app@(App _ _)
+  = getAppArgs app
+
+satExpr app@(CoTyApp _ _)
+  = getAppArgs app
+
+satExpr (Case expr alts)
+  = satExpr expr       `thenSAT` \ expr' ->
+    sat_alts alts      `thenSAT` \ alts' ->
+    returnSAT (Case expr' alts')
+  where
+    sat_alts (AlgAlts alts deflt)
+      = mapSAT satAlgAlt alts      `thenSAT` \ alts' ->
+       sat_default deflt           `thenSAT` \ deflt' ->
+       returnSAT (AlgAlts alts' deflt')
+      where
+       satAlgAlt (con, params, rhs)
+         = satExpr rhs          `thenSAT` \ rhs' ->
+           returnSAT (con, params, rhs')
+
+    sat_alts (PrimAlts alts deflt)
+      = mapSAT satPrimAlt alts     `thenSAT` \ alts' ->
+       sat_default deflt           `thenSAT` \ deflt' ->
+       returnSAT (PrimAlts alts' deflt')
+      where
+       satPrimAlt (lit, rhs)
+         = satExpr rhs `thenSAT` \ rhs' ->
+           returnSAT (lit, rhs')
+
+    sat_default NoDefault
+      = returnSAT NoDefault
+    sat_default (BindDefault binder rhs)
+      = satExpr rhs                 `thenSAT` \ rhs' ->
+       returnSAT (BindDefault binder rhs')
+
+satExpr (Let (NonRec binder rhs) body)
+  = satExpr body               `thenSAT` \ body' ->
+    satExpr rhs                        `thenSAT` \ rhs' ->
+    returnSAT (Let (NonRec binder rhs') body')
+
+satExpr (Let (Rec [(binder,rhs)]) body)
+  = satExpr body                     `thenSAT` \ body' ->
+    insSAEnv binder (getArgLists rhs) `thenSAT_`
+    satExpr rhs                              `thenSAT` \ rhs' ->
+    saTransform binder rhs'          `thenSAT` \ binding ->
+    returnSAT (Let binding body')
+
+satExpr (Let (Rec binds) body)
+  = let
+       (binders, rhss) = unzip binds
+    in
+    satExpr body                   `thenSAT` \ body' ->
+    mapSAT satExpr rhss                    `thenSAT` \ rhss' ->
+    returnSAT (Let (Rec (zipEqual "satExpr:Rec" binders rhss')) body')
+
+satExpr (Note note expr)
+  = satExpr expr                   `thenSAT` \ expr2 ->
+    returnSAT (Note note expr2)
+\end{code}
+
+\begin{code}
+getAppArgs :: CoreExpr -> SatM CoreExpr
+
+getAppArgs app
+  = get app            `thenSAT` \ (app',result) ->
+    updSAEnv result    `thenSAT_`
+    returnSAT app'
+  where
+    get :: CoreExpr
+       -> SatM (CoreExpr, Maybe (Id, SATInfo))
+
+    get (CoTyApp e ty)
+      = get e          `thenSAT` \ (e',result) ->
+       returnSAT (
+         CoTyApp e' ty,
+         case result of
+           Nothing          -> Nothing
+           Just (v,(tv,lv)) -> Just (v,(tv++[Static ty],lv))
+       )
+
+    get (App e a)
+      = get e          `thenSAT` \ (e', result) ->
+       satAtom a       `thenSAT_`
+       let si = case a of
+                  (VarArg v) -> Static v
+                  _             -> NotStatic
+       in
+         returnSAT (
+           App e' a,
+           case result of
+               Just (v,(tv,lv)) -> Just (v,(tv,lv++[si]))
+               Nothing          -> Nothing
+         )
+
+    get var@(Var v)
+      = returnSAT (var, Just (v,([],[])))
+
+    get e
+      = satExpr e      `thenSAT` \ e2 ->
+       returnSAT (e2, Nothing)
+-}
+\end{code}