2 /* --------------------------------------------------------------------------
5 * This is a very simple lambda lifter - it doesn't try to do Johnsson-style
6 * lambda lifting (yet).
8 * Copyright (c) The University of Nottingham and Yale University, 1994-1997.
9 * All rights reserved. See NOTICE for details and conditions of use etc...
10 * Hugs version 1.4, December 1997
12 * $RCSfile: lift.c,v $
14 * $Date: 1999/02/03 17:08:31 $
15 * ------------------------------------------------------------------------*/
24 /* --------------------------------------------------------------------------
25 * Local function prototypes:
26 * ------------------------------------------------------------------------*/
28 static List liftedBinds = NIL;
30 static StgExpr abstractExpr ( List vars, StgExpr e );
31 static inline Bool isTopLevel( StgVar v );
32 static List filterFreeVars( List vs );
33 static List liftLetBinds ( List binds );
34 static void liftAlt ( StgCaseAlt alt );
35 static void liftPrimAlt ( StgPrimAlt alt );
36 static void liftExpr ( StgExpr e );
38 /* --------------------------------------------------------------------------
40 * ------------------------------------------------------------------------*/
42 /* abstract variables out of an expression */
43 static StgExpr abstractExpr( List vars, StgExpr e )
46 List sub = NIL; /* association list */
47 for(; nonNull(vars); vars=tl(vars)) {
48 StgVar var = hd(vars);
49 StgVar arg = mkStgVar(NIL,NIL);
50 args = cons(arg,args);
51 sub = cons(pair(var,arg),sub);
53 return makeStgLambda(rev(args),substExpr(sub,e));
56 /* ToDo: should be conservative estimate but isn't */
57 /* Will a variable be floated out to top level - conservative estimate? */
58 static inline Bool isTopLevel( StgVar v )
60 if (isNull(stgVarBody(v))) {
61 return FALSE; /* only let bound vars can be floated */
62 } else if (stgVarInfo(v) == NONE) {
63 return TRUE; /* those at top level are already there */
66 StgRhs rhs = stgVarBody(v);
67 switch (whatIs(rhs)) {
70 return isNull(stgVarInfo(v));
80 static List filterFreeVars( List vs )
86 for(; nonNull(vs); vs=tl(vs)) {
96 static List liftLetBinds( List binds )
99 for(; nonNull(binds); binds=tl(binds)) {
100 StgVar bind = hd(binds);
101 StgRhs rhs = stgVarBody(bind);
102 List fvs = filterFreeVars(stgVarInfo(bind));
103 /* stgVarInfo(bind) = NIL; */ /* ToDo: discard fv list */
105 switch (whatIs(rhs)) {
110 StgVar v = mkStgVar(rhs,NONE);
111 stgVarBody(bind) = mkStgLet(singleton(v),v);
113 liftedBinds = cons(bind,liftedBinds);
116 /* deliberate fall through */
125 StgVar v = mkStgVar(abstractExpr(fvs,rhs),NONE);
127 liftedBinds = cons(v,liftedBinds);
128 stgVarBody(bind) = makeStgApp(v, fvs);
132 StgVar r = mkStgVar(rhs,NIL); /* copy the var */
133 StgVar v = mkStgVar(mkStgLet(singleton(r),r),NONE);
134 stgVarBody(bind) = v; /* indirection to r */
136 liftedBinds = cons(v,liftedBinds);
137 bs = cons(bind,bs); /* keep the old binding */
140 /* deliberate fall through */
149 static void liftAlt( StgCaseAlt alt )
151 liftExpr(stgCaseAltBody(alt));
154 static void liftPrimAlt( StgPrimAlt alt )
156 liftExpr(stgPrimAltBody(alt));
159 static void liftExpr( StgExpr e )
163 stgLetBinds(e) = liftLetBinds(stgLetBinds(e));
164 liftExpr(stgLetBody(e));
167 liftExpr(stgLambdaBody(e));
170 liftExpr(stgCaseScrut(e));
171 mapProc(liftAlt,stgCaseAlts(e));
174 liftExpr(stgPrimCaseScrut(e));
175 mapProc(liftPrimAlt,stgPrimCaseAlts(e));
185 internal("liftExpr");
189 List liftBinds( List binds )
192 for(bs=binds; nonNull(bs); bs=tl(bs)) {
193 StgVar bind = hd(bs);
194 freeVarsBind(NIL,bind);
195 stgVarInfo(bind) = NONE; /* mark as top level */
198 binds = liftLetBinds(binds);
199 binds = revOnto(liftedBinds,binds);
204 /* --------------------------------------------------------------------------
206 * ------------------------------------------------------------------------*/
208 Void liftControl(what)
212 /* deliberate fall though */
222 /*-------------------------------------------------------------------------*/