1 /* -*- mode: hugs-c; -*- */
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: 1998/12/02 13:22:17 $
15 * ------------------------------------------------------------------------*/
27 /* --------------------------------------------------------------------------
28 * Local function prototypes:
29 * ------------------------------------------------------------------------*/
31 static List liftedBinds = NIL;
33 static StgExpr abstractExpr ( List vars, StgExpr e );
34 static inline Bool isTopLevel( StgVar v );
35 static List filterFreeVars( List vs );
36 static List liftLetBinds ( List binds );
37 static void liftAlt ( StgCaseAlt alt );
38 static void liftPrimAlt ( StgPrimAlt alt );
39 static void liftExpr ( StgExpr e );
41 /* --------------------------------------------------------------------------
43 * ------------------------------------------------------------------------*/
45 /* abstract variables out of an expression */
46 static StgExpr abstractExpr( List vars, StgExpr e )
49 List sub = NIL; /* association list */
50 for(; nonNull(vars); vars=tl(vars)) {
51 StgVar var = hd(vars);
52 StgVar arg = mkStgVar(NIL,NIL);
53 args = cons(arg,args);
54 sub = cons(pair(var,arg),sub);
56 return makeStgLambda(rev(args),substExpr(sub,e));
59 /* ToDo: should be conservative estimate but isn't */
60 /* Will a variable be floated out to top level - conservative estimate? */
61 static inline Bool isTopLevel( StgVar v )
63 if (isNull(stgVarBody(v))) {
64 return FALSE; /* only let bound vars can be floated */
65 } else if (stgVarInfo(v) == NONE) {
66 return TRUE; /* those at top level are already there */
69 StgRhs rhs = stgVarBody(v);
70 switch (whatIs(rhs)) {
73 return isNull(stgVarInfo(v));
83 static List filterFreeVars( List vs )
89 for(; nonNull(vs); vs=tl(vs)) {
99 static List liftLetBinds( List binds )
102 for(; nonNull(binds); binds=tl(binds)) {
103 StgVar bind = hd(binds);
104 StgRhs rhs = stgVarBody(bind);
105 List fvs = filterFreeVars(stgVarInfo(bind));
106 /* stgVarInfo(bind) = NIL; */ /* ToDo: discard fv list */
108 switch (whatIs(rhs)) {
113 StgVar v = mkStgVar(rhs,NONE);
114 stgVarBody(bind) = mkStgLet(singleton(v),v);
116 liftedBinds = cons(bind,liftedBinds);
119 /* deliberate fall through */
128 StgVar v = mkStgVar(abstractExpr(fvs,rhs),NONE);
130 liftedBinds = cons(v,liftedBinds);
131 stgVarBody(bind) = makeStgApp(v, fvs);
135 StgVar r = mkStgVar(rhs,NIL); /* copy the var */
136 StgVar v = mkStgVar(mkStgLet(singleton(r),r),NONE);
137 stgVarBody(bind) = v; /* indirection to r */
139 liftedBinds = cons(v,liftedBinds);
140 bs = cons(bind,bs); /* keep the old binding */
143 /* deliberate fall through */
152 static void liftAlt( StgCaseAlt alt )
154 liftExpr(stgCaseAltBody(alt));
157 static void liftPrimAlt( StgPrimAlt alt )
159 liftExpr(stgPrimAltBody(alt));
162 static void liftExpr( StgExpr e )
166 stgLetBinds(e) = liftLetBinds(stgLetBinds(e));
167 liftExpr(stgLetBody(e));
170 liftExpr(stgLambdaBody(e));
173 liftExpr(stgCaseScrut(e));
174 mapProc(liftAlt,stgCaseAlts(e));
177 liftExpr(stgPrimCaseScrut(e));
178 mapProc(liftPrimAlt,stgPrimCaseAlts(e));
188 internal("liftExpr");
192 List liftBinds( List binds )
195 for(bs=binds; nonNull(bs); bs=tl(bs)) {
196 StgVar bind = hd(bs);
197 freeVarsBind(NIL,bind);
198 stgVarInfo(bind) = NONE; /* mark as top level */
201 binds = liftLetBinds(binds);
202 binds = revOnto(liftedBinds,binds);
207 /* --------------------------------------------------------------------------
209 * ------------------------------------------------------------------------*/
211 Void liftControl(what)
215 /* deliberate fall though */
225 /*-------------------------------------------------------------------------*/