Mercurial > urweb
comparison src/especialize.sml @ 482:9117a7bf229c
Especialize working reasonably well; need to add new closure representation pass
author | Adam Chlipala <adamc@hcoop.net> |
---|---|
date | Sun, 09 Nov 2008 11:53:52 -0500 |
parents | 40c737913075 |
children | a0f47540d8ad |
comparison
equal
deleted
inserted
replaced
481:2280193bf298 | 482:9117a7bf229c |
---|---|
39 val compare = Order.joinL U.Exp.compare | 39 val compare = Order.joinL U.Exp.compare |
40 end | 40 end |
41 | 41 |
42 structure KM = BinaryMapFn(K) | 42 structure KM = BinaryMapFn(K) |
43 structure IM = IntBinaryMap | 43 structure IM = IntBinaryMap |
44 structure IS = IntBinarySet | |
44 | 45 |
45 val sizeOf = U.Exp.fold {kind = fn (_, n) => n, | 46 val sizeOf = U.Exp.fold {kind = fn (_, n) => n, |
46 con = fn (_, n) => n, | 47 con = fn (_, n) => n, |
47 exp = fn (_, n) => n + 1} | 48 exp = fn (_, n) => n + 1} |
48 0 | 49 0 |
99 } | 100 } |
100 | 101 |
101 fun kind (k, st) = (k, st) | 102 fun kind (k, st) = (k, st) |
102 fun con (c, st) = (c, st) | 103 fun con (c, st) = (c, st) |
103 | 104 |
104 fun exp (e, st : state) = | |
105 let | |
106 fun getApp e = | |
107 case e of | |
108 ENamed f => SOME (f, [], []) | |
109 | EField ((ERecord xes, _), (CName x, _), _) => | |
110 (case List.find (fn ((CName x', _), _,_) => x' = x | |
111 | _ => false) xes of | |
112 NONE => NONE | |
113 | SOME (_, (e, _), _) => getApp e) | |
114 | EApp (e1, e2) => | |
115 (case getApp (#1 e1) of | |
116 NONE => NONE | |
117 | SOME (f, xs, xs') => | |
118 let | |
119 val k = | |
120 if List.null xs' then | |
121 skeyIn e2 | |
122 else | |
123 NONE | |
124 in | |
125 case k of | |
126 NONE => SOME (f, xs, xs' @ [e2]) | |
127 | SOME k => SOME (f, xs @ [k], xs') | |
128 end) | |
129 | _ => NONE | |
130 in | |
131 case getApp e of | |
132 NONE => (e, st) | |
133 | SOME (f, [], xs') => (#1 (foldl (fn (arg, e) => (EApp (e, arg), ErrorMsg.dummySpan)) | |
134 (ENamed f, ErrorMsg.dummySpan) xs'), st) | |
135 | SOME (f, xs, xs') => | |
136 case IM.find (#funcs st, f) of | |
137 NONE => | |
138 let | |
139 val e = foldl (fn (arg, e) => (EApp (e, skeyOut arg), ErrorMsg.dummySpan)) | |
140 (ENamed f, ErrorMsg.dummySpan) xs | |
141 in | |
142 (#1 (foldl (fn (arg, e) => (EApp (e, arg), ErrorMsg.dummySpan)) | |
143 e xs'), st) | |
144 end | |
145 | SOME {name, args, body, typ, tag} => | |
146 case KM.find (args, xs) of | |
147 SOME f' => ((*Print.prefaces "Pre-existing" [("e", CorePrint.p_exp CoreEnv.empty (e, ErrorMsg.dummySpan))];*) | |
148 (#1 (foldl (fn (e, arg) => (EApp (e, arg), ErrorMsg.dummySpan)) | |
149 (ENamed f', ErrorMsg.dummySpan) xs'), | |
150 st)) | |
151 | NONE => | |
152 let | |
153 (*val () = Print.prefaces "New" [("e", CorePrint.p_exp CoreEnv.empty (e, ErrorMsg.dummySpan))]*) | |
154 | |
155 fun subBody (body, typ, xs) = | |
156 case (#1 body, #1 typ, xs) of | |
157 (_, _, []) => SOME (body, typ) | |
158 | (EAbs (_, _, _, body'), TFun (_, typ'), x :: xs) => | |
159 let | |
160 val body'' = E.subExpInExp (0, skeyOut x) body' | |
161 in | |
162 (*Print.prefaces "espec" [("body'", CorePrint.p_exp CoreEnv.empty body'), | |
163 ("body''", CorePrint.p_exp CoreEnv.empty body'')];*) | |
164 subBody (body'', | |
165 typ', | |
166 xs) | |
167 end | |
168 | _ => NONE | |
169 in | |
170 case subBody (body, typ, xs) of | |
171 NONE => (e, st) | |
172 | SOME (body', typ') => | |
173 let | |
174 val f' = #maxName st | |
175 (*val () = print ("f' = " ^ Int.toString f' ^ "\n")*) | |
176 val funcs = IM.insert (#funcs st, f, {name = name, | |
177 args = KM.insert (args, xs, f'), | |
178 body = body, | |
179 typ = typ, | |
180 tag = tag}) | |
181 val st = { | |
182 maxName = f' + 1, | |
183 funcs = funcs, | |
184 decls = #decls st | |
185 } | |
186 | |
187 val (body', st) = specExp st body' | |
188 val e' = foldl (fn (e, arg) => (EApp (e, arg), ErrorMsg.dummySpan)) | |
189 (ENamed f', ErrorMsg.dummySpan) xs' | |
190 in | |
191 (#1 e', | |
192 {maxName = #maxName st, | |
193 funcs = #funcs st, | |
194 decls = (name, f', typ', body', tag) :: #decls st}) | |
195 end | |
196 end | |
197 end | |
198 | |
199 and specExp st = U.Exp.foldMap {kind = kind, con = con, exp = exp} st | |
200 | |
201 fun decl (d, st) = (d, st) | |
202 | |
203 val specDecl = U.Decl.foldMap {kind = kind, con = con, exp = exp, decl = decl} | |
204 | |
205 fun specialize' file = | 105 fun specialize' file = |
206 let | 106 let |
107 fun default (_, fs) = fs | |
108 | |
109 fun actionableExp (e, fs) = | |
110 case e of | |
111 ERecord xes => | |
112 foldl (fn (((CName s, _), e, _), fs) => | |
113 if s = "Action" orelse s = "Link" then | |
114 let | |
115 fun findHead (e, _) = | |
116 case e of | |
117 ENamed n => IS.add (fs, n) | |
118 | EApp (e, _) => findHead e | |
119 | _ => fs | |
120 in | |
121 findHead e | |
122 end | |
123 else | |
124 fs | |
125 | (_, fs) => fs) | |
126 fs xes | |
127 | _ => fs | |
128 | |
129 val actionable = | |
130 U.File.fold {kind = default, | |
131 con = default, | |
132 exp = actionableExp, | |
133 decl = default} | |
134 IS.empty file | |
135 | |
136 fun exp (e, st : state) = | |
137 let | |
138 fun getApp e = | |
139 case e of | |
140 ENamed f => SOME (f, [], []) | |
141 | EApp (e1, e2) => | |
142 (case getApp (#1 e1) of | |
143 NONE => NONE | |
144 | SOME (f, xs, xs') => | |
145 let | |
146 val k = | |
147 if List.null xs' then | |
148 skeyIn e2 | |
149 else | |
150 NONE | |
151 in | |
152 case k of | |
153 NONE => SOME (f, xs, xs' @ [e2]) | |
154 | SOME k => SOME (f, xs @ [k], xs') | |
155 end) | |
156 | _ => NONE | |
157 in | |
158 case getApp e of | |
159 NONE => (e, st) | |
160 | SOME (f, [], []) => (e, st) | |
161 | SOME (f, [], xs') => | |
162 (case IM.find (#funcs st, f) of | |
163 NONE => (e, st) | |
164 | SOME {typ, body, ...} => | |
165 let | |
166 val functionInside = U.Con.exists {kind = fn _ => false, | |
167 con = fn TFun _ => true | |
168 | CFfi ("Basis", "transaction") => true | |
169 | _ => false} | |
170 | |
171 fun hasFunarg (t, xs) = | |
172 case (t, xs) of | |
173 ((TFun (dom, ran), _), _ :: xs) => | |
174 functionInside dom | |
175 orelse hasFunarg (ran, xs) | |
176 | _ => false | |
177 in | |
178 if List.all (fn (ERel _, _) => false | _ => true) xs' | |
179 andalso not (IS.member (actionable, f)) | |
180 andalso hasFunarg (typ, xs') then | |
181 (#1 (foldl (fn (arg, e) => (EApp (e, arg), ErrorMsg.dummySpan)) | |
182 body xs'), | |
183 st) | |
184 else | |
185 (e, st) | |
186 end) | |
187 | SOME (f, xs, xs') => | |
188 case IM.find (#funcs st, f) of | |
189 NONE => (e, st) | |
190 | SOME {name, args, body, typ, tag} => | |
191 case KM.find (args, xs) of | |
192 SOME f' => (#1 (foldl (fn (arg, e) => (EApp (e, arg), ErrorMsg.dummySpan)) | |
193 (ENamed f', ErrorMsg.dummySpan) xs'), | |
194 st) | |
195 | NONE => | |
196 let | |
197 fun subBody (body, typ, xs) = | |
198 case (#1 body, #1 typ, xs) of | |
199 (_, _, []) => SOME (body, typ) | |
200 | (EAbs (_, _, _, body'), TFun (_, typ'), x :: xs) => | |
201 let | |
202 val body'' = E.subExpInExp (0, skeyOut x) body' | |
203 in | |
204 subBody (body'', | |
205 typ', | |
206 xs) | |
207 end | |
208 | _ => NONE | |
209 in | |
210 case subBody (body, typ, xs) of | |
211 NONE => (e, st) | |
212 | SOME (body', typ') => | |
213 let | |
214 val f' = #maxName st | |
215 val funcs = IM.insert (#funcs st, f, {name = name, | |
216 args = KM.insert (args, | |
217 xs, f'), | |
218 body = body, | |
219 typ = typ, | |
220 tag = tag}) | |
221 val st = { | |
222 maxName = f' + 1, | |
223 funcs = funcs, | |
224 decls = #decls st | |
225 } | |
226 | |
227 val (body', st) = specExp st body' | |
228 val e' = foldl (fn (arg, e) => (EApp (e, arg), ErrorMsg.dummySpan)) | |
229 (ENamed f', ErrorMsg.dummySpan) xs' | |
230 in | |
231 (#1 e', | |
232 {maxName = #maxName st, | |
233 funcs = #funcs st, | |
234 decls = (name, f', typ', body', tag) :: #decls st}) | |
235 end | |
236 end | |
237 end | |
238 | |
239 and specExp st = U.Exp.foldMap {kind = kind, con = con, exp = exp} st | |
240 | |
241 fun decl (d, st) = (d, st) | |
242 | |
243 val specDecl = U.Decl.foldMap {kind = kind, con = con, exp = exp, decl = decl} | |
244 | |
245 | |
246 | |
207 fun doDecl (d, (st : state, changed)) = | 247 fun doDecl (d, (st : state, changed)) = |
208 let | 248 let |
209 val funcs = #funcs st | 249 val funcs = #funcs st |
210 val funcs = | 250 val funcs = |
211 case #1 d of | 251 case #1 d of |
221 | 261 |
222 val st = {maxName = #maxName st, | 262 val st = {maxName = #maxName st, |
223 funcs = funcs, | 263 funcs = funcs, |
224 decls = []} | 264 decls = []} |
225 | 265 |
266 (*val () = Print.prefaces "decl" [("d", CorePrint.p_decl CoreEnv.empty d)]*) | |
226 val (d', st) = specDecl st d | 267 val (d', st) = specDecl st d |
268 (*val () = print "/decl\n"*) | |
227 | 269 |
228 val funcs = #funcs st | 270 val funcs = #funcs st |
229 val funcs = | 271 val funcs = |
230 case #1 d of | 272 case #1 d of |
231 DVal (x, n, c, e as (EAbs _, _), tag) => | 273 DVal (x, n, c, e as (EAbs _, _), tag) => |
265 fun specialize file = | 307 fun specialize file = |
266 let | 308 let |
267 val (changed, file) = specialize' file | 309 val (changed, file) = specialize' file |
268 in | 310 in |
269 if changed then | 311 if changed then |
270 specialize file | 312 specialize (ReduceLocal.reduce file) |
271 else | 313 else |
272 file | 314 file |
273 end | 315 end |
274 | 316 |
275 | 317 |