2 /* --------------------------------------------------------------------------
5 * This is a very simple lambda lifter - it doesn't try to do Johnsson-style
6 * lambda lifting (yet).
8 * The Hugs 98 system is Copyright (c) Mark P Jones, Alastair Reid, the
9 * Yale Haskell Group, and the Oregon Graduate Institute of Science and
10 * Technology, 1994-1999, All rights reserved. It is distributed as
11 * free software under the license in the file "License", which is
12 * included in the distribution.
14 * $RCSfile: lift.c,v $
16 * $Date: 1999/11/29 18:59:29 $
17 * ------------------------------------------------------------------------*/
26 /* --------------------------------------------------------------------------
27 * Local function prototypes:
28 * ------------------------------------------------------------------------*/
30 static List liftedBinds = NIL;
31 static Bool makeInlineable = FALSE;
32 static Int inlineCounter = 0;
34 static StgExpr abstractExpr ( List vars, StgExpr e );
35 static inline Bool isTopLevel( StgVar v );
36 static List filterFreeVars( List vs );
37 static List liftLetBinds ( List binds, Bool topLevel );
38 static void liftAlt ( StgCaseAlt alt );
39 static void liftPrimAlt ( StgPrimAlt alt );
40 static void liftExpr ( StgExpr e );
42 /* --------------------------------------------------------------------------
44 * ------------------------------------------------------------------------*/
46 /* abstract variables out of an expression */
47 static StgExpr abstractExpr( List vars, StgExpr e )
50 List sub = NIL; /* association list */
51 for(; nonNull(vars); vars=tl(vars)) {
52 StgVar var = hd(vars);
53 StgVar arg = mkStgVar(NIL,NIL);
54 stgVarRep(arg) = stgVarRep(var);
55 args = cons(arg,args);
56 sub = cons(pair(var,arg),sub);
58 return makeStgLambda(rev(args),substExpr(sub,e));
61 /* ToDo: should be conservative estimate but isn't */
62 /* Will a variable be floated out to top level - conservative estimate? */
63 static inline Bool isTopLevel( StgVar v )
65 if (isNull(stgVarBody(v))) {
66 return FALSE; /* only let bound vars can be floated */
67 } else if (stgVarInfo(v) == NONE) {
68 return TRUE; /* those at top level are already there */
74 static List filterFreeVars( List vs )
80 for(; nonNull(vs); vs=tl(vs)) {
90 static List liftLetBinds( List binds, Bool topLevel )
93 for(; nonNull(binds); binds=tl(binds)) {
94 StgVar bind = hd(binds);
95 StgRhs rhs = stgVarBody(bind);
96 List fvs = filterFreeVars(stgVarInfo(bind));
98 switch (whatIs(rhs)) {
108 StgVar v = mkStgVar(abstractExpr(fvs,rhs),NONE);
109 liftedBinds = cons(v,liftedBinds);
110 if (makeInlineable) {
113 sprintf(s,"lam%d",inlineCounter++);
114 n = newName(findText(s),NIL);
116 stgVarBody(bind) = makeStgApp(n, fvs);
118 stgVarBody(bind) = makeStgApp(v, fvs);
128 static void liftAlt( StgCaseAlt alt )
130 if (isDefaultAlt(alt))
131 liftExpr(stgDefaultBody(alt)); else
132 liftExpr(stgCaseAltBody(alt));
135 static void liftPrimAlt( StgPrimAlt alt )
137 liftExpr(stgPrimAltBody(alt));
140 static void liftExpr( StgExpr e )
144 stgLetBinds(e) = liftLetBinds(stgLetBinds(e),FALSE);
145 liftExpr(stgLetBody(e));
148 liftExpr(stgLambdaBody(e));
151 liftExpr(stgCaseScrut(e));
152 mapProc(liftAlt,stgCaseAlts(e));
155 liftExpr(stgPrimCaseScrut(e));
156 mapProc(liftPrimAlt,stgPrimCaseAlts(e));
166 internal("liftExpr");
170 /* Lift a list of top-level binds. */
171 List liftBinds( List binds )
175 for(bs=binds; nonNull(bs); bs=tl(bs)) {
176 StgVar bind = hd(bs);
179 if (lastModule() != modulePrelude) {
180 fprintf(stderr, "\n");
182 fprintf(stderr, "\n");
185 freeVarsBind(NIL,bind);
186 stgVarInfo(bind) = NONE; /* mark as top level */
190 binds = liftLetBinds(binds,TRUE);
191 binds = revOnto(liftedBinds,binds);
196 /* --------------------------------------------------------------------------
198 * ------------------------------------------------------------------------*/
200 Void liftControl(what)
204 /* deliberate fall though */
214 /*-------------------------------------------------------------------------*/