2 % (c) The GRASP/AQUA Project, Glasgow University, 1992-1995
4 \section[TreelessForm]{Convert Arbitrary expressions into treeless form}
6 >#include "HsVersions.h"
8 > module TreelessForm (
9 > convertToTreelessForm
15 > import CmdLineOpts ( SwitchResult, switchIsOn )
16 > import CoreUtils ( coreExprType )
17 > import Id ( replaceIdInfo, getIdInfo )
19 > import Maybes ( Maybe(..) )
21 > import SimplEnv ( SwitchChecker(..) )
29 Very simplistic approach to begin with:
31 case e of {...} ====> let x = e in case x of {...}
32 x e1 ... en ====> let x1 = e1 in ... let xn = en in (x x1 ... xn)
34 ToDo: make this better.
36 > convertToTreelessForm
41 > convertToTreelessForm sw e
48 > convExpr e = case e of
50 > Var (DefArgExpr e) ->
51 > panic "TreelessForm(substTy): Var (DefArgExpr _)"
54 > panic "TreelessForm(substTy): Var (Label _ _)"
56 > Var (DefArgVar id) -> returnUs e
61 > mapUs convAtom es `thenUs` \es ->
62 > returnUs (Con c ts es)
65 > mapUs convAtom es `thenUs` \es ->
66 > returnUs (Prim op ts es)
69 > convExpr e `thenUs` \e ->
73 > convExpr e `thenUs` \e ->
74 > returnUs (CoTyLam alpha e)
77 > convExpr e `thenUs` \e ->
79 > LitArg l -> returnUs (App e v)
82 > DefArgVar _ -> panic "TreelessForm(convExpr): DefArgVar"
83 > DefArgExpr (Var (DefArgVar id))
84 > | (not.deforestable) id ->
87 > newLet e' (\id -> App e (VarArg
91 > convExpr e `thenUs` \e ->
92 > returnUs (CoTyApp e ty)
95 > convCaseAlts ps `thenUs` \ps ->
97 > Var (DefArgVar id) | (not.deforestable) id ->
98 > returnUs (Case e ps)
99 > Prim op ts es -> returnUs (Case e ps)
100 > _ -> d2c e `thenUs` \e' ->
101 > newLet e (\v -> Case v ps)
103 > Let (NonRec id e) e' ->
104 > convExpr e `thenUs` \e ->
105 > convExpr e' `thenUs` \e' ->
106 > returnUs (Let (NonRec id e) e')
109 >-- convRecBinds bs e `thenUs` \(bs,e) ->
110 >-- returnUs (Let (Rec bs) e)
111 > convExpr e `thenUs` \e ->
112 > mapUs convRecBind bs `thenUs` \bs ->
113 > returnUs (Let (Rec bs) e)
115 > convRecBind (v,e) =
116 > convExpr e `thenUs` \e ->
120 > convExpr e `thenUs` \e ->
123 Mark all the recursive functions as deforestable. Might as well,
124 since they will be in treeless form anyway. This helps to cope with
125 overloaded functions, where the compiler earlier lifts out the
126 dictionary deconstruction.
128 > convRecBinds bs e =
129 > convExpr e `thenUs` \e' ->
130 > mapUs convExpr es `thenUs` \es' ->
131 > mapUs (subst s) es' `thenUs` \es'' ->
132 > subst s e' `thenUs` \e'' ->
133 > returnUs (zip vs' es', e')
136 > vs' = map mkDeforestable vs
137 > s = zip vs (map (Var . DefArgVar) vs')
138 > mkDeforestable v = replaceIdInfo v (addInfo (getIdInfo v) DoDeforest)
140 > convAtom :: DefAtom -> UniqSM DefAtom
142 > convAtom (VarArg v) =
143 > convArg v `thenUs` \v ->
144 > returnUs (VarArg v)
145 > convAtom (LitArg l) =
146 > returnUs (LitArg l) -- XXX
148 > convArg :: DefBindee -> UniqSM DefBindee
150 > convArg (DefArgExpr e) =
151 > convExpr e `thenUs` \e ->
152 > returnUs (DefArgExpr e)
153 > convArg e@(Label _ _) =
154 > panic "TreelessForm(convArg): Label _ _"
155 > convArg e@(DefArgVar id) =
156 > panic "TreelessForm(convArg): DefArgVar _ _"
158 > convCaseAlts :: DefCaseAlternatives -> UniqSM DefCaseAlternatives
160 > convCaseAlts (AlgAlts as def) =
161 > mapUs convAlgAlt as `thenUs` \as ->
162 > convDefault def `thenUs` \def ->
163 > returnUs (AlgAlts as def)
164 > convCaseAlts (PrimAlts as def) =
165 > mapUs convPrimAlt as `thenUs` \as ->
166 > convDefault def `thenUs` \def ->
167 > returnUs (PrimAlts as def)
169 > convAlgAlt (c, vs, e) =
170 > convExpr e `thenUs` \e ->
171 > returnUs (c, vs, e)
172 > convPrimAlt (l, e) =
173 > convExpr e `thenUs` \e ->
176 > convDefault NoDefault =
178 > convDefault (BindDefault id e) =
179 > convExpr e `thenUs` \e ->
180 > returnUs (BindDefault id e)
182 > newLet :: DefExpr -> (DefExpr -> DefExpr) -> UniqSM DefExpr
184 > d2c e `thenUs` \core_expr ->
185 > newDefId (coreExprType core_expr) `thenUs` \new_id ->
186 > returnUs (Let (NonRec new_id e) (body (Var (DefArgVar new_id))))