comparison src/mono_reduce.sml @ 318:60907c06b4c4

Optimization removes linear let-bindings of impure expressions
author Adam Chlipala <adamc@hcoop.net>
date Thu, 11 Sep 2008 11:30:39 -0400
parents 04ebfe929a98
children 1fd2a29a7c85
comparison
equal deleted inserted replaced
317:6a4e365db60c 318:60907c06b4c4
170 consider (xps, env) 170 consider (xps, env)
171 end 171 end
172 172
173 | _ => Maybe 173 | _ => Maybe
174 174
175 datatype event =
176 WritePage
177 | ReadDb
178 | WriteDb
179 | UseRel of int
180 | Unsure
181
182 fun p_event e =
183 let
184 open Print.PD
185 in
186 case e of
187 WritePage => string "WritePage"
188 | ReadDb => string "ReadDb"
189 | WriteDb => string "WriteDb"
190 | UseRel n => string ("UseRel" ^ Int.toString n)
191 | Unsure => string "Unsure"
192 end
193
194 fun patBinds (p, _) =
195 case p of
196 PWild => 0
197 | PVar _ => 1
198 | PPrim _ => 0
199 | PCon (_, _, NONE) => 0
200 | PCon (_, _, SOME p) => patBinds p
201 | PRecord xpts => foldl (fn ((_, p, _), n) => n + patBinds p) 0 xpts
202 | PNone _ => 0
203 | PSome (_, p) => patBinds p
204
205 fun summarize d (e, _) =
206 case e of
207 EPrim _ => []
208 | ERel n => if n >= d then [UseRel (n - d)] else []
209 | ENamed _ => []
210 | ECon (_, _, NONE) => []
211 | ECon (_, _, SOME e) => summarize d e
212 | ENone _ => []
213 | ESome (_, e) => summarize d e
214 | EFfi _ => []
215 | EFfiApp (_, _, es) => List.concat (map (summarize d) es)
216 | EApp _ => [Unsure]
217 | EAbs _ => []
218
219 | ERecord xets => List.concat (map (summarize d o #2) xets)
220 | EField (e, _) => summarize d e
221
222 | ECase (e, pes, _) =>
223 let
224 val lss = map (fn (p, e) => summarize (d + patBinds p) e) pes
225 in
226 case lss of
227 [] => raise Fail "Empty pattern match"
228 | ls :: lss =>
229 if List.all (fn ls' => ls' = ls) lss then
230 summarize d e @ ls
231 else
232 [Unsure]
233 end
234 | EStrcat (e1, e2) => summarize d e1 @ summarize d e2
235
236 | EError (e, _) => summarize d e @ [Unsure]
237
238 | EWrite e => summarize d e @ [WritePage]
239
240 | ESeq (e1, e2) => summarize d e1 @ summarize d e2
241 | ELet (_, _, e1, e2) => summarize d e1 @ summarize (d + 1) e2
242
243 | EClosure (_, es) => List.concat (map (summarize d) es)
244
245 | EQuery {query, body, initial, ...} =>
246 List.concat [summarize d query,
247 summarize d body,
248 summarize d initial,
249 [ReadDb]]
250
251 | EDml e => summarize d e @ [WriteDb]
252
175 fun exp env e = 253 fun exp env e =
176 case e of 254 case e of
177 ERel n => 255 ERel n =>
178 (case E.lookupERel env n of 256 (case E.lookupERel env n of
179 (_, _, SOME e') => #1 e' 257 (_, _, SOME e') => #1 e'
227 | ELet (x, t, e, (EAbs (x', t' as (TRecord [], _), ran, e'), loc)) => 305 | ELet (x, t, e, (EAbs (x', t' as (TRecord [], _), ran, e'), loc)) =>
228 EAbs (x', t', ran, (ELet (x, t, liftExpInExp 0 e, swapExpVars 0 e'), loc)) 306 EAbs (x', t', ran, (ELet (x, t, liftExpInExp 0 e, swapExpVars 0 e'), loc))
229 307
230 | ELet (x, t, e', b) => 308 | ELet (x, t, e', b) =>
231 if impure e' then 309 if impure e' then
232 e 310 let
311 val effs_e' = summarize 0 e'
312 val effs_b = summarize 0 b
313
314 fun does eff = List.exists (fn eff' => eff' = eff) effs_e'
315 val writesPage = does WritePage
316 val readsDb = does ReadDb
317 val writesDb = does WriteDb
318
319 fun verifyUnused eff =
320 case eff of
321 UseRel r => r <> 0
322 | Unsure => false
323 | _ => true
324
325 fun verifyCompatible effs =
326 case effs of
327 [] => false
328 | eff :: effs =>
329 case eff of
330 Unsure => false
331 | UseRel r =>
332 if r = 0 then
333 List.all verifyUnused effs
334 else
335 verifyCompatible effs
336 | WritePage => not writesPage andalso verifyCompatible effs
337 | ReadDb => not writesDb andalso verifyCompatible effs
338 | WriteDb => not writesDb andalso not readsDb andalso verifyCompatible effs
339 in
340 (*Print.prefaces "verifyCompatible"
341 [("e'", MonoPrint.p_exp env e'),
342 ("b", MonoPrint.p_exp (E.pushERel env x t NONE) b),
343 ("effs_e'", Print.p_list p_event effs_e'),
344 ("effs_b", Print.p_list p_event effs_b)];*)
345 if verifyCompatible effs_b then
346 #1 (reduceExp env (subExpInExp (0, e') b))
347 else
348 e
349 end
233 else 350 else
234 #1 (reduceExp env (subExpInExp (0, e') b)) 351 #1 (reduceExp env (subExpInExp (0, e') b))
235 352
236 | EStrcat ((EPrim (Prim.String s1), _), (EPrim (Prim.String s2), _)) => 353 | EStrcat ((EPrim (Prim.String s1), _), (EPrim (Prim.String s2), _)) =>
237 EPrim (Prim.String (s1 ^ s2)) 354 EPrim (Prim.String (s1 ^ s2))